Skip to content

Commit dfd5d2f

Browse files
feat: initial implementation (#1)
1 parent ff026ca commit dfd5d2f

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

Diff for: src/__tests__/index.test.tsx

+76-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,76 @@
1-
it.todo('write a test');
1+
type RegexComponent = string | RegexQuantifier;
2+
3+
type RegexQuantifier = OneOrMore | Optionally;
4+
5+
type OneOrMore = {
6+
type: 'oneOrMore';
7+
children: RegexComponent[];
8+
};
9+
10+
function oneOrMore(...children: RegexComponent[]): OneOrMore {
11+
return {
12+
type: 'oneOrMore',
13+
children,
14+
};
15+
}
16+
17+
type Optionally = {
18+
type: 'optionally';
19+
children: RegexComponent[];
20+
};
21+
22+
function optionally(...children: RegexComponent[]): Optionally {
23+
return {
24+
type: 'optionally',
25+
children,
26+
};
27+
}
28+
29+
function compile(...children: RegexComponent[]): string {
30+
return children.map((c) => compileSingle(c)).join('');
31+
}
32+
33+
function compileSingle(component: RegexComponent): string {
34+
if (typeof component === 'string') {
35+
return component;
36+
}
37+
38+
const { type, children } = component;
39+
if (type === 'oneOrMore') {
40+
return `${wrapGroup(compile(...children))}+`;
41+
}
42+
43+
if (type === 'optionally') {
44+
return `${wrapGroup(compile(...children))}?`;
45+
}
46+
47+
throw new Error(`Unknown component ${component}`);
48+
}
49+
50+
function wrapGroup(input: string): string {
51+
return input.length === 1 ? input : `(${input})`;
52+
}
53+
54+
function regex(...children: RegexComponent[]): RegExp {
55+
const pattern = compile(...children);
56+
return new RegExp(pattern);
57+
}
58+
59+
test('basic quantifies', () => {
60+
expect(compile('a')).toEqual('a');
61+
expect(compile('a', 'b')).toEqual('ab');
62+
63+
expect(compile(oneOrMore('a'))).toEqual('a+');
64+
expect(compile(optionally('a'))).toEqual('a?');
65+
66+
expect(compile('a', oneOrMore('b'))).toEqual('ab+');
67+
expect(compile('a', oneOrMore('bc'))).toEqual('a(bc)+');
68+
expect(compile('a', oneOrMore('bc'))).toEqual('a(bc)+');
69+
70+
expect(compile(optionally('a'), 'b')).toEqual('a?b');
71+
});
72+
73+
test('regex constructor', () => {
74+
expect(regex('a').test('a')).toBeTruthy();
75+
expect(regex('a').test('b')).toBeFalsy();
76+
});

0 commit comments

Comments
 (0)