links-notation 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +219 -0
- package/README.ru.md +193 -0
- package/bun.lock +33 -0
- package/dist/index.js +1462 -0
- package/package.json +26 -0
- package/src/Link.js +155 -0
- package/src/LinksGroup.js +30 -0
- package/src/Parser.js +132 -0
- package/src/grammar.pegjs +86 -0
- package/src/index.js +3 -0
- package/src/parser-generated.js +1322 -0
- package/tests/ApiTests.test.js +74 -0
- package/tests/EdgeCaseParser.test.js +162 -0
- package/tests/IndentedIdSyntax.test.js +171 -0
- package/tests/Link.test.js +69 -0
- package/tests/LinksGroup.test.js +40 -0
- package/tests/MixedIndentationModes.test.js +188 -0
- package/tests/MultilineParser.test.js +118 -0
- package/tests/MultilineQuotedString.test.js +78 -0
- package/tests/NestedParser.test.js +166 -0
- package/tests/SingleLineParser.test.js +229 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { test, expect } from 'bun:test';
|
|
2
|
+
import { Parser } from '../src/Parser.js';
|
|
3
|
+
import { formatLinks } from '../src/Link.js';
|
|
4
|
+
|
|
5
|
+
const parser = new Parser();
|
|
6
|
+
|
|
7
|
+
test('TwoLinksTest', () => {
|
|
8
|
+
const source = `(first: x y)
|
|
9
|
+
(second: a b)`;
|
|
10
|
+
const links = parser.parse(source);
|
|
11
|
+
const target = formatLinks(links);
|
|
12
|
+
expect(target).toBe(source);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('ParseAndStringifyTest', () => {
|
|
16
|
+
const source = `(papa (lovesMama: loves mama))
|
|
17
|
+
(son lovesMama)
|
|
18
|
+
(daughter lovesMama)
|
|
19
|
+
(all (love mama))`;
|
|
20
|
+
const links = parser.parse(source);
|
|
21
|
+
const target = formatLinks(links);
|
|
22
|
+
expect(target).toBe(source);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('ParseAndStringifyTest2', () => {
|
|
26
|
+
const source = `father (lovesMom: loves mom)
|
|
27
|
+
son lovesMom
|
|
28
|
+
daughter lovesMom
|
|
29
|
+
all (love mom)`;
|
|
30
|
+
const links = parser.parse(source);
|
|
31
|
+
const target = formatLinks(links, true); // lessParentheses = true
|
|
32
|
+
expect(target).toBe(source);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('ParseAndStringifyWithLessParenthesesTest', () => {
|
|
36
|
+
const source = `lovesMama: loves mama
|
|
37
|
+
papa lovesMama
|
|
38
|
+
son lovesMama
|
|
39
|
+
daughter lovesMama
|
|
40
|
+
all (love mama)`;
|
|
41
|
+
const links = parser.parse(source);
|
|
42
|
+
const target = formatLinks(links, true); // lessParentheses = true
|
|
43
|
+
expect(target).toBe(source);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('DuplicateIdentifiersTest', () => {
|
|
47
|
+
const source = `(a: a b)
|
|
48
|
+
(a: b c)`;
|
|
49
|
+
const target = `(a: a b)
|
|
50
|
+
(a: b c)`;
|
|
51
|
+
const links = parser.parse(source);
|
|
52
|
+
const formattedLinks = formatLinks(links);
|
|
53
|
+
expect(formattedLinks).toBe(target);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('Test complex structure', () => {
|
|
57
|
+
const input = `(Type: Type Type)
|
|
58
|
+
Number
|
|
59
|
+
String
|
|
60
|
+
Array
|
|
61
|
+
Value
|
|
62
|
+
(property: name type)
|
|
63
|
+
(method: name params return)`;
|
|
64
|
+
|
|
65
|
+
const result = parser.parse(input);
|
|
66
|
+
expect(result.length).toBeGreaterThan(0);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('Test mixed formats', () => {
|
|
70
|
+
// Mix of single-line and multi-line formats
|
|
71
|
+
const input = `id1: value1
|
|
72
|
+
(id2: value2 value3)
|
|
73
|
+
simple_ref
|
|
74
|
+
(complex:
|
|
75
|
+
nested1
|
|
76
|
+
nested2
|
|
77
|
+
)`;
|
|
78
|
+
|
|
79
|
+
const result = parser.parse(input);
|
|
80
|
+
expect(result.length).toBeGreaterThan(0);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('Test multiline with id', () => {
|
|
84
|
+
// Test multi-line link with id
|
|
85
|
+
const input = "(id: value1 value2)";
|
|
86
|
+
const result = parser.parse(input);
|
|
87
|
+
expect(result.length).toBeGreaterThan(0);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('Test multiple top level elements', () => {
|
|
91
|
+
// Test multiple top-level elements
|
|
92
|
+
const input = "(elem1: val1)\n(elem2: val2)";
|
|
93
|
+
const result = parser.parse(input);
|
|
94
|
+
expect(result.length).toBeGreaterThan(0);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('Test multiline simple links', () => {
|
|
98
|
+
const input = "(1: 1 1)\n(2: 2 2)";
|
|
99
|
+
const parsed = parser.parse(input);
|
|
100
|
+
expect(parsed.length).toBeGreaterThan(0);
|
|
101
|
+
|
|
102
|
+
// Validate regular formatting
|
|
103
|
+
const output = formatLinks(parsed);
|
|
104
|
+
expect(output).toContain("(1: 1 1)");
|
|
105
|
+
expect(output).toContain("(2: 2 2)");
|
|
106
|
+
|
|
107
|
+
// Validate alternate formatting matches input
|
|
108
|
+
const outputAlternate = formatLinks(parsed);
|
|
109
|
+
expect(outputAlternate).toBe(input);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('Test indented children', () => {
|
|
113
|
+
const input = "parent\n child1\n child2";
|
|
114
|
+
const parsed = parser.parse(input);
|
|
115
|
+
|
|
116
|
+
// The parsed structure should have parent with children
|
|
117
|
+
expect(parsed.length).toBeGreaterThan(0);
|
|
118
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { test, expect } from "bun:test";
|
|
2
|
+
import { Parser } from "../src/Parser.js";
|
|
3
|
+
|
|
4
|
+
const parser = new Parser();
|
|
5
|
+
|
|
6
|
+
test("TestMultilineDoubleQuotedReference", () => {
|
|
7
|
+
const input = `(
|
|
8
|
+
"long
|
|
9
|
+
string literal representing
|
|
10
|
+
the reference"
|
|
11
|
+
|
|
12
|
+
'another
|
|
13
|
+
long string literal
|
|
14
|
+
as another reference'
|
|
15
|
+
)`;
|
|
16
|
+
const result = parser.parse(input);
|
|
17
|
+
|
|
18
|
+
expect(result.length).toBeGreaterThan(0);
|
|
19
|
+
expect(result.length).toBe(1);
|
|
20
|
+
|
|
21
|
+
const link = result[0];
|
|
22
|
+
expect(link.id).toBe(null);
|
|
23
|
+
expect(link.values).toBeTruthy();
|
|
24
|
+
expect(link.values.length).toBe(2);
|
|
25
|
+
|
|
26
|
+
expect(link.values[0].id).toBe(`long
|
|
27
|
+
string literal representing
|
|
28
|
+
the reference`);
|
|
29
|
+
|
|
30
|
+
expect(link.values[1].id).toBe(`another
|
|
31
|
+
long string literal
|
|
32
|
+
as another reference`);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("TestSimpleMultilineDoubleQuoted", () => {
|
|
36
|
+
const input = `("line1
|
|
37
|
+
line2")`;
|
|
38
|
+
const result = parser.parse(input);
|
|
39
|
+
|
|
40
|
+
expect(result.length).toBeGreaterThan(0);
|
|
41
|
+
expect(result.length).toBe(1);
|
|
42
|
+
|
|
43
|
+
const link = result[0];
|
|
44
|
+
expect(link.id).toBe(null);
|
|
45
|
+
expect(link.values).toBeTruthy();
|
|
46
|
+
expect(link.values.length).toBe(1);
|
|
47
|
+
expect(link.values[0].id).toBe("line1\nline2");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("TestSimpleMultilineSingleQuoted", () => {
|
|
51
|
+
const input = `('line1
|
|
52
|
+
line2')`;
|
|
53
|
+
const result = parser.parse(input);
|
|
54
|
+
|
|
55
|
+
expect(result.length).toBeGreaterThan(0);
|
|
56
|
+
expect(result.length).toBe(1);
|
|
57
|
+
|
|
58
|
+
const link = result[0];
|
|
59
|
+
expect(link.id).toBe(null);
|
|
60
|
+
expect(link.values).toBeTruthy();
|
|
61
|
+
expect(link.values.length).toBe(1);
|
|
62
|
+
expect(link.values[0].id).toBe("line1\nline2");
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("TestMultilineQuotedAsId", () => {
|
|
66
|
+
const input = `("multi
|
|
67
|
+
line
|
|
68
|
+
id": value1 value2)`;
|
|
69
|
+
const result = parser.parse(input);
|
|
70
|
+
|
|
71
|
+
expect(result.length).toBeGreaterThan(0);
|
|
72
|
+
expect(result.length).toBe(1);
|
|
73
|
+
|
|
74
|
+
const link = result[0];
|
|
75
|
+
expect(link.id).toBe("multi\nline\nid");
|
|
76
|
+
expect(link.values).toBeTruthy();
|
|
77
|
+
expect(link.values.length).toBe(2);
|
|
78
|
+
});
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { test, expect } from 'bun:test';
|
|
2
|
+
import { Parser } from '../src/Parser.js';
|
|
3
|
+
import { formatLinks } from '../src/Link.js';
|
|
4
|
+
|
|
5
|
+
const parser = new Parser();
|
|
6
|
+
|
|
7
|
+
test('SignificantWhitespaceTest', () => {
|
|
8
|
+
const source = `
|
|
9
|
+
users
|
|
10
|
+
user1
|
|
11
|
+
id
|
|
12
|
+
43
|
|
13
|
+
name
|
|
14
|
+
first
|
|
15
|
+
John
|
|
16
|
+
last
|
|
17
|
+
Williams
|
|
18
|
+
location
|
|
19
|
+
New York
|
|
20
|
+
age
|
|
21
|
+
23
|
|
22
|
+
user2
|
|
23
|
+
id
|
|
24
|
+
56
|
|
25
|
+
name
|
|
26
|
+
first
|
|
27
|
+
Igor
|
|
28
|
+
middle
|
|
29
|
+
Petrovich
|
|
30
|
+
last
|
|
31
|
+
Ivanov
|
|
32
|
+
location
|
|
33
|
+
Moscow
|
|
34
|
+
age
|
|
35
|
+
20`;
|
|
36
|
+
|
|
37
|
+
const target = `(users)
|
|
38
|
+
((users) (user1))
|
|
39
|
+
(((users) (user1)) (id))
|
|
40
|
+
((((users) (user1)) (id)) (43))
|
|
41
|
+
(((users) (user1)) (name))
|
|
42
|
+
((((users) (user1)) (name)) (first))
|
|
43
|
+
(((((users) (user1)) (name)) (first)) (John))
|
|
44
|
+
((((users) (user1)) (name)) (last))
|
|
45
|
+
(((((users) (user1)) (name)) (last)) (Williams))
|
|
46
|
+
(((users) (user1)) (location))
|
|
47
|
+
((((users) (user1)) (location)) (New York))
|
|
48
|
+
(((users) (user1)) (age))
|
|
49
|
+
((((users) (user1)) (age)) (23))
|
|
50
|
+
((users) (user2))
|
|
51
|
+
(((users) (user2)) (id))
|
|
52
|
+
((((users) (user2)) (id)) (56))
|
|
53
|
+
(((users) (user2)) (name))
|
|
54
|
+
((((users) (user2)) (name)) (first))
|
|
55
|
+
(((((users) (user2)) (name)) (first)) (Igor))
|
|
56
|
+
((((users) (user2)) (name)) (middle))
|
|
57
|
+
(((((users) (user2)) (name)) (middle)) (Petrovich))
|
|
58
|
+
((((users) (user2)) (name)) (last))
|
|
59
|
+
(((((users) (user2)) (name)) (last)) (Ivanov))
|
|
60
|
+
(((users) (user2)) (location))
|
|
61
|
+
((((users) (user2)) (location)) (Moscow))
|
|
62
|
+
(((users) (user2)) (age))
|
|
63
|
+
((((users) (user2)) (age)) (20))`;
|
|
64
|
+
|
|
65
|
+
const links = parser.parse(source);
|
|
66
|
+
const formattedLinks = formatLinks(links);
|
|
67
|
+
expect(formattedLinks).toBe(target);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('SimpleSignificantWhitespaceTest', () => {
|
|
71
|
+
const source = `a
|
|
72
|
+
b
|
|
73
|
+
c`;
|
|
74
|
+
const target = `(a)
|
|
75
|
+
((a) (b))
|
|
76
|
+
((a) (c))`;
|
|
77
|
+
const links = parser.parse(source);
|
|
78
|
+
const formattedLinks = formatLinks(links);
|
|
79
|
+
expect(formattedLinks).toBe(target);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('TwoSpacesSizedWhitespaceTest', () => {
|
|
83
|
+
const source = `
|
|
84
|
+
users
|
|
85
|
+
user1`;
|
|
86
|
+
const target = `(users)
|
|
87
|
+
((users) (user1))`;
|
|
88
|
+
const links = parser.parse(source);
|
|
89
|
+
const formattedLinks = formatLinks(links);
|
|
90
|
+
expect(formattedLinks).toBe(target);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('Parse nested structure with indentation', () => {
|
|
94
|
+
const input = `parent
|
|
95
|
+
child1
|
|
96
|
+
child2`;
|
|
97
|
+
const result = parser.parse(input);
|
|
98
|
+
expect(result.length).toBe(3);
|
|
99
|
+
// The parser creates (parent), ((parent) (child1)), ((parent) (child2))
|
|
100
|
+
expect(result[0].id).toBe(null);
|
|
101
|
+
expect(result[0].values[0].id).toBe('parent');
|
|
102
|
+
expect(result[1].id).toBe(null);
|
|
103
|
+
expect(result[1].values.length).toBe(2);
|
|
104
|
+
expect(result[2].id).toBe(null);
|
|
105
|
+
expect(result[2].values.length).toBe(2);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('Test indentation consistency', () => {
|
|
109
|
+
// Test that indentation must be consistent
|
|
110
|
+
const input = `parent
|
|
111
|
+
child1
|
|
112
|
+
child2`; // Inconsistent indentation
|
|
113
|
+
const result = parser.parse(input);
|
|
114
|
+
// This should parse but child2 won't be a child of parent due to different indentation
|
|
115
|
+
expect(result.length).toBeGreaterThan(0);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('Indentation-based children', () => {
|
|
119
|
+
const input = `parent
|
|
120
|
+
child1
|
|
121
|
+
child2
|
|
122
|
+
grandchild`;
|
|
123
|
+
const result = parser.parse(input);
|
|
124
|
+
expect(result.length).toBe(4);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('Complex indentation', () => {
|
|
128
|
+
const input = `root
|
|
129
|
+
level1a
|
|
130
|
+
level2a
|
|
131
|
+
level2b
|
|
132
|
+
level1b
|
|
133
|
+
level2c`;
|
|
134
|
+
const result = parser.parse(input);
|
|
135
|
+
expect(result.length).toBe(6);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('Test nested links', () => {
|
|
139
|
+
const input = '(1: (2: (3: 3)))';
|
|
140
|
+
const parsed = parser.parse(input);
|
|
141
|
+
expect(parsed.length).toBeGreaterThan(0);
|
|
142
|
+
|
|
143
|
+
// Validate regular formatting
|
|
144
|
+
const output = formatLinks(parsed);
|
|
145
|
+
expect(output).toBeTruthy();
|
|
146
|
+
|
|
147
|
+
// Validate that the structure is properly nested
|
|
148
|
+
expect(parsed.length).toBe(1);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('Test indentation (parser)', () => {
|
|
152
|
+
const input = 'parent\n child1\n child2';
|
|
153
|
+
const result = parser.parse(input);
|
|
154
|
+
expect(result.length).toBeGreaterThan(0);
|
|
155
|
+
// Should have parent link
|
|
156
|
+
const hasParentLink = result.some(l => l.values && l.values.some(v => v.id === 'parent'));
|
|
157
|
+
expect(hasParentLink).toBe(true);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test('Test nested indentation (parser)', () => {
|
|
161
|
+
const input = 'parent\n child\n grandchild';
|
|
162
|
+
const result = parser.parse(input);
|
|
163
|
+
expect(result.length).toBeGreaterThan(0);
|
|
164
|
+
// Should create nested structure with proper hierarchy
|
|
165
|
+
expect(result.length).toBeGreaterThanOrEqual(1);
|
|
166
|
+
});
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { test, expect } from 'bun:test';
|
|
2
|
+
import { Parser } from '../src/Parser.js';
|
|
3
|
+
import { formatLinks } from '../src/Link.js';
|
|
4
|
+
|
|
5
|
+
const parser = new Parser();
|
|
6
|
+
|
|
7
|
+
test('SingleLinkTest', () => {
|
|
8
|
+
const source = '(address: source target)';
|
|
9
|
+
const links = parser.parse(source);
|
|
10
|
+
const target = formatLinks(links);
|
|
11
|
+
expect(target).toBe(source);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('TripletSingleLinkTest', () => {
|
|
15
|
+
const source = '(papa has car)';
|
|
16
|
+
const links = parser.parse(source);
|
|
17
|
+
const target = formatLinks(links);
|
|
18
|
+
expect(target).toBe(source);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('BugTest1', () => {
|
|
22
|
+
const source = '(ignore conan-center-index repository)';
|
|
23
|
+
const links = parser.parse(source);
|
|
24
|
+
const target = formatLinks(links);
|
|
25
|
+
expect(target).toBe(source);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('QuotedReferencesTest', () => {
|
|
29
|
+
const source = `(a: 'b' "c")`;
|
|
30
|
+
const target = `(a: b c)`;
|
|
31
|
+
const links = parser.parse(source);
|
|
32
|
+
const formattedLinks = formatLinks(links);
|
|
33
|
+
expect(formattedLinks).toBe(target);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('QuotedReferencesWithSpacesTest', () => {
|
|
37
|
+
const source = `('a a': 'b b' "c c")`;
|
|
38
|
+
const target = `('a a': 'b b' 'c c')`;
|
|
39
|
+
const links = parser.parse(source);
|
|
40
|
+
const formattedLinks = formatLinks(links);
|
|
41
|
+
expect(formattedLinks).toBe(target);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('Parse simple reference', () => {
|
|
45
|
+
const input = 'test';
|
|
46
|
+
const result = parser.parse(input);
|
|
47
|
+
expect(result.length).toBe(1);
|
|
48
|
+
expect(result[0].id).toBe(null);
|
|
49
|
+
expect(result[0].values.length).toBe(1);
|
|
50
|
+
expect(result[0].values[0].id).toBe('test');
|
|
51
|
+
expect(result[0].values[0].values).toEqual([]);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('Parse reference with colon and values', () => {
|
|
55
|
+
const input = 'parent: child1 child2';
|
|
56
|
+
const result = parser.parse(input);
|
|
57
|
+
expect(result.length).toBe(1);
|
|
58
|
+
expect(result[0].id).toBe('parent');
|
|
59
|
+
expect(result[0].values.length).toBe(2);
|
|
60
|
+
expect(result[0].values[0].id).toBe('child1');
|
|
61
|
+
expect(result[0].values[1].id).toBe('child2');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('Parse multiline link', () => {
|
|
65
|
+
const input = '(parent: child1 child2)';
|
|
66
|
+
const result = parser.parse(input);
|
|
67
|
+
expect(result.length).toBe(1);
|
|
68
|
+
expect(result[0].id).toBe('parent');
|
|
69
|
+
expect(result[0].values.length).toBe(2);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('Parse quoted references', () => {
|
|
73
|
+
const input = `"has space" 'has:colon'`;
|
|
74
|
+
const result = parser.parse(input);
|
|
75
|
+
expect(result.length).toBe(1);
|
|
76
|
+
expect(result[0].id).toBe(null);
|
|
77
|
+
expect(result[0].values.length).toBe(2);
|
|
78
|
+
expect(result[0].values[0].id).toBe('has space');
|
|
79
|
+
expect(result[0].values[1].id).toBe('has:colon');
|
|
80
|
+
// Ensure formatting matches C# expectation
|
|
81
|
+
expect(formatLinks(result)).toBe(`('has space' 'has:colon')`);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('Parse values only', () => {
|
|
85
|
+
const input = ': value1 value2';
|
|
86
|
+
// Standalone ':' is now forbidden and should throw an error
|
|
87
|
+
expect(() => parser.parse(input)).toThrow();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('Test single-line link with id', () => {
|
|
91
|
+
const input = 'id: value1 value2';
|
|
92
|
+
const result = parser.parse(input);
|
|
93
|
+
expect(result.length).toBeGreaterThan(0);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('Test multi-line link with id', () => {
|
|
97
|
+
const input = '(id: value1 value2)';
|
|
98
|
+
const result = parser.parse(input);
|
|
99
|
+
expect(result.length).toBeGreaterThan(0);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('Test link without id (single-line)', () => {
|
|
103
|
+
const input = ': value1 value2';
|
|
104
|
+
// Standalone ':' is now forbidden and should throw an error
|
|
105
|
+
expect(() => parser.parse(input)).toThrow();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('Test link without id (multi-line)', () => {
|
|
109
|
+
const input = '(: value1 value2)';
|
|
110
|
+
// '(:)' syntax is now forbidden and should throw an error
|
|
111
|
+
expect(() => parser.parse(input)).toThrow();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('Test singlet link', () => {
|
|
115
|
+
const input = '(singlet)';
|
|
116
|
+
const result = parser.parse(input);
|
|
117
|
+
expect(result.length).toBe(1);
|
|
118
|
+
expect(result[0].id).toBe(null);
|
|
119
|
+
expect(result[0].values.length).toBe(1);
|
|
120
|
+
expect(result[0].values[0].id).toBe('singlet');
|
|
121
|
+
expect(result[0].values[0].values).toEqual([]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('Test value link', () => {
|
|
125
|
+
const input = '(value1 value2 value3)';
|
|
126
|
+
const result = parser.parse(input);
|
|
127
|
+
expect(result.length).toBeGreaterThan(0);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('ParseQuotedReferencesValuesOnly', () => {
|
|
131
|
+
const source = `"has space" 'has:colon'`;
|
|
132
|
+
const parser = new Parser();
|
|
133
|
+
const links = parser.parse(source);
|
|
134
|
+
expect(links).toBeTruthy();
|
|
135
|
+
expect(links.length).toBe(1);
|
|
136
|
+
expect(links[0].id).toBe(null);
|
|
137
|
+
expect(links[0].values.length).toBe(2);
|
|
138
|
+
expect(links[0].values[0].id).toBe('has space');
|
|
139
|
+
expect(links[0].values[1].id).toBe('has:colon');
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('Test quoted references', () => {
|
|
143
|
+
const input = '("id with spaces": "value with spaces")';
|
|
144
|
+
const result = parser.parse(input);
|
|
145
|
+
expect(result.length).toBeGreaterThan(0);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('Test single-quoted references', () => {
|
|
149
|
+
const input = "('id': 'value')";
|
|
150
|
+
const result = parser.parse(input);
|
|
151
|
+
expect(result.length).toBeGreaterThan(0);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test('Test nested links', () => {
|
|
155
|
+
const input = '(outer: (inner: value))';
|
|
156
|
+
const result = parser.parse(input);
|
|
157
|
+
expect(result.length).toBeGreaterThan(0);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test('Test special characters in quotes', () => {
|
|
161
|
+
let input = '("key:with:colons": "value(with)parens")';
|
|
162
|
+
let result = parser.parse(input);
|
|
163
|
+
expect(result.length).toBeGreaterThan(0);
|
|
164
|
+
|
|
165
|
+
input = "('key with spaces': 'value: with special chars')";
|
|
166
|
+
result = parser.parse(input);
|
|
167
|
+
expect(result.length).toBeGreaterThan(0);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test('Test deeply nested', () => {
|
|
171
|
+
const input = '(a: (b: (c: (d: (e: value)))))';
|
|
172
|
+
const result = parser.parse(input);
|
|
173
|
+
expect(result.length).toBeGreaterThan(0);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('Test hyphenated identifiers', () => {
|
|
177
|
+
const input = '(conan-center-index: repository info)';
|
|
178
|
+
const result = parser.parse(input);
|
|
179
|
+
expect(result.length).toBeGreaterThan(0);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test('Test multiple words in quotes', () => {
|
|
183
|
+
const input = '("New York": city state)';
|
|
184
|
+
const result = parser.parse(input);
|
|
185
|
+
expect(result.length).toBeGreaterThan(0);
|
|
186
|
+
expect(JSON.stringify(result)).toContain('New York');
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('Test simple ref', () => {
|
|
190
|
+
const input = 'simple_ref';
|
|
191
|
+
const result = parser.parse(input);
|
|
192
|
+
expect(result.length).toBeGreaterThan(0);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('Test simple reference (parser)', () => {
|
|
196
|
+
const input = 'hello';
|
|
197
|
+
const result = parser.parse(input);
|
|
198
|
+
expect(result.length).toBe(1);
|
|
199
|
+
expect(result[0].id).toBe(null);
|
|
200
|
+
expect(result[0].values.length).toBe(1);
|
|
201
|
+
expect(result[0].values[0].id).toBe('hello');
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test('Test quoted reference (parser)', () => {
|
|
205
|
+
const input = '"hello world"';
|
|
206
|
+
const result = parser.parse(input);
|
|
207
|
+
expect(result.length).toBe(1);
|
|
208
|
+
expect(result[0].id).toBe(null);
|
|
209
|
+
expect(result[0].values.length).toBe(1);
|
|
210
|
+
expect(result[0].values[0].id).toBe('hello world');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
test('Test singlet link (parser)', () => {
|
|
214
|
+
const input = '(singlet)';
|
|
215
|
+
const result = parser.parse(input);
|
|
216
|
+
expect(result.length).toBe(1);
|
|
217
|
+
expect(result[0].id).toBe(null);
|
|
218
|
+
expect(result[0].values.length).toBe(1);
|
|
219
|
+
expect(result[0].values[0].id).toBe('singlet');
|
|
220
|
+
expect(result[0].values[0].values).toEqual([]);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test('Test value link (parser)', () => {
|
|
224
|
+
const input = '(a b c)';
|
|
225
|
+
const result = parser.parse(input);
|
|
226
|
+
expect(result.length).toBe(1);
|
|
227
|
+
expect(result[0].id).toBe(null);
|
|
228
|
+
expect(result[0].values.length).toBe(3);
|
|
229
|
+
});
|