links-notation 0.11.2 → 0.13.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/.eslintrc.json +28 -0
- package/.prettierignore +4 -0
- package/.prettierrc +4 -0
- package/README.md +52 -7
- package/README.ru.md +3 -6
- package/bun.lock +200 -0
- package/dist/index.js +582 -119
- package/package.json +6 -3
- package/src/FormatConfig.js +19 -0
- package/src/FormatOptions.js +52 -0
- package/src/Link.js +340 -40
- package/src/LinksGroup.js +2 -2
- package/src/Parser.js +57 -22
- package/src/grammar.pegjs +105 -4
- package/src/index.js +3 -1
- package/src/parser-generated.js +401 -88
- package/tests/ApiTests.test.js +104 -7
- package/tests/EdgeCaseParser.test.js +12 -12
- package/tests/FormatConfig.test.js +148 -0
- package/tests/IndentationConsistency.test.js +1 -1
- package/tests/IndentedIdSyntax.test.js +39 -39
- package/tests/Link.test.js +3 -3
- package/tests/LinksGroup.test.js +35 -5
- package/tests/MixedIndentationModes.test.js +35 -35
- package/tests/MultiQuoteParser.test.js +463 -0
- package/tests/MultilineParser.test.js +17 -17
- package/tests/MultilineQuotedString.test.js +9 -9
- package/tests/NestedParser.test.js +36 -7
- package/tests/NestedSelfReference.test.js +104 -0
- package/tests/SingleLineParser.test.js +88 -8
|
@@ -4,7 +4,7 @@ import { formatLinks } from '../src/Link.js';
|
|
|
4
4
|
|
|
5
5
|
const parser = new Parser();
|
|
6
6
|
|
|
7
|
-
test('
|
|
7
|
+
test('Two links', () => {
|
|
8
8
|
const source = `(first: x y)
|
|
9
9
|
(second: a b)`;
|
|
10
10
|
const links = parser.parse(source);
|
|
@@ -12,7 +12,7 @@ test('TwoLinksTest', () => {
|
|
|
12
12
|
expect(target).toBe(source);
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
test('
|
|
15
|
+
test('Parse and stringify', () => {
|
|
16
16
|
const source = `(papa (lovesMama: loves mama))
|
|
17
17
|
(son lovesMama)
|
|
18
18
|
(daughter lovesMama)
|
|
@@ -22,7 +22,7 @@ test('ParseAndStringifyTest', () => {
|
|
|
22
22
|
expect(target).toBe(source);
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
test('
|
|
25
|
+
test('Parse and stringify test 2', () => {
|
|
26
26
|
const source = `father (lovesMom: loves mom)
|
|
27
27
|
son lovesMom
|
|
28
28
|
daughter lovesMom
|
|
@@ -32,7 +32,7 @@ all (love mom)`;
|
|
|
32
32
|
expect(target).toBe(source);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
test('
|
|
35
|
+
test('Parse and stringify with less parentheses', () => {
|
|
36
36
|
const source = `lovesMama: loves mama
|
|
37
37
|
papa lovesMama
|
|
38
38
|
son lovesMama
|
|
@@ -43,7 +43,7 @@ all (love mama)`;
|
|
|
43
43
|
expect(target).toBe(source);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
test('
|
|
46
|
+
test('Duplicate identifiers', () => {
|
|
47
47
|
const source = `(a: a b)
|
|
48
48
|
(a: b c)`;
|
|
49
49
|
const target = `(a: a b)
|
|
@@ -61,7 +61,7 @@ test('Test complex structure', () => {
|
|
|
61
61
|
Value
|
|
62
62
|
(property: name type)
|
|
63
63
|
(method: name params return)`;
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
const result = parser.parse(input);
|
|
66
66
|
expect(result.length).toBeGreaterThan(0);
|
|
67
67
|
});
|
|
@@ -75,44 +75,44 @@ simple_ref
|
|
|
75
75
|
nested1
|
|
76
76
|
nested2
|
|
77
77
|
)`;
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
const result = parser.parse(input);
|
|
80
80
|
expect(result.length).toBeGreaterThan(0);
|
|
81
81
|
});
|
|
82
82
|
|
|
83
83
|
test('Test multiline with id', () => {
|
|
84
84
|
// Test multi-line link with id
|
|
85
|
-
const input =
|
|
85
|
+
const input = '(id: value1 value2)';
|
|
86
86
|
const result = parser.parse(input);
|
|
87
87
|
expect(result.length).toBeGreaterThan(0);
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
test('Test multiple top level elements', () => {
|
|
91
91
|
// Test multiple top-level elements
|
|
92
|
-
const input =
|
|
92
|
+
const input = '(elem1: val1)\n(elem2: val2)';
|
|
93
93
|
const result = parser.parse(input);
|
|
94
94
|
expect(result.length).toBeGreaterThan(0);
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
test('Test multiline simple links', () => {
|
|
98
|
-
const input =
|
|
98
|
+
const input = '(1: 1 1)\n(2: 2 2)';
|
|
99
99
|
const parsed = parser.parse(input);
|
|
100
100
|
expect(parsed.length).toBeGreaterThan(0);
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
// Validate regular formatting
|
|
103
103
|
const output = formatLinks(parsed);
|
|
104
|
-
expect(output).toContain(
|
|
105
|
-
expect(output).toContain(
|
|
106
|
-
|
|
104
|
+
expect(output).toContain('(1: 1 1)');
|
|
105
|
+
expect(output).toContain('(2: 2 2)');
|
|
106
|
+
|
|
107
107
|
// Validate alternate formatting matches input
|
|
108
108
|
const outputAlternate = formatLinks(parsed);
|
|
109
109
|
expect(outputAlternate).toBe(input);
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
test('Test indented children', () => {
|
|
113
|
-
const input =
|
|
113
|
+
const input = 'parent\n child1\n child2';
|
|
114
114
|
const parsed = parser.parse(input);
|
|
115
|
-
|
|
115
|
+
|
|
116
116
|
// The parsed structure should have parent with children
|
|
117
117
|
expect(parsed.length).toBeGreaterThan(0);
|
|
118
|
-
});
|
|
118
|
+
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { test, expect } from
|
|
2
|
-
import { Parser } from
|
|
1
|
+
import { test, expect } from 'bun:test';
|
|
2
|
+
import { Parser } from '../src/Parser.js';
|
|
3
3
|
|
|
4
4
|
const parser = new Parser();
|
|
5
5
|
|
|
6
|
-
test(
|
|
6
|
+
test('TestMultilineDoubleQuotedReference', () => {
|
|
7
7
|
const input = `(
|
|
8
8
|
"long
|
|
9
9
|
string literal representing
|
|
@@ -32,7 +32,7 @@ long string literal
|
|
|
32
32
|
as another reference`);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
test(
|
|
35
|
+
test('TestSimpleMultilineDoubleQuoted', () => {
|
|
36
36
|
const input = `("line1
|
|
37
37
|
line2")`;
|
|
38
38
|
const result = parser.parse(input);
|
|
@@ -44,10 +44,10 @@ line2")`;
|
|
|
44
44
|
expect(link.id).toBe(null);
|
|
45
45
|
expect(link.values).toBeTruthy();
|
|
46
46
|
expect(link.values.length).toBe(1);
|
|
47
|
-
expect(link.values[0].id).toBe(
|
|
47
|
+
expect(link.values[0].id).toBe('line1\nline2');
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
test(
|
|
50
|
+
test('TestSimpleMultilineSingleQuoted', () => {
|
|
51
51
|
const input = `('line1
|
|
52
52
|
line2')`;
|
|
53
53
|
const result = parser.parse(input);
|
|
@@ -59,10 +59,10 @@ line2')`;
|
|
|
59
59
|
expect(link.id).toBe(null);
|
|
60
60
|
expect(link.values).toBeTruthy();
|
|
61
61
|
expect(link.values.length).toBe(1);
|
|
62
|
-
expect(link.values[0].id).toBe(
|
|
62
|
+
expect(link.values[0].id).toBe('line1\nline2');
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
test(
|
|
65
|
+
test('TestMultilineQuotedAsId', () => {
|
|
66
66
|
const input = `("multi
|
|
67
67
|
line
|
|
68
68
|
id": value1 value2)`;
|
|
@@ -72,7 +72,7 @@ id": value1 value2)`;
|
|
|
72
72
|
expect(result.length).toBe(1);
|
|
73
73
|
|
|
74
74
|
const link = result[0];
|
|
75
|
-
expect(link.id).toBe(
|
|
75
|
+
expect(link.id).toBe('multi\nline\nid');
|
|
76
76
|
expect(link.values).toBeTruthy();
|
|
77
77
|
expect(link.values.length).toBe(2);
|
|
78
78
|
});
|
|
@@ -105,7 +105,7 @@ test('Parse nested structure with indentation', () => {
|
|
|
105
105
|
expect(result[2].values.length).toBe(2);
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
-
test('
|
|
108
|
+
test('Indentation consistency', () => {
|
|
109
109
|
// Test that indentation must be consistent
|
|
110
110
|
const input = `parent
|
|
111
111
|
child1
|
|
@@ -135,7 +135,7 @@ test('Complex indentation', () => {
|
|
|
135
135
|
expect(result.length).toBe(6);
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
-
test('
|
|
138
|
+
test('Nested links', () => {
|
|
139
139
|
const input = '(1: (2: (3: 3)))';
|
|
140
140
|
const parsed = parser.parse(input);
|
|
141
141
|
expect(parsed.length).toBeGreaterThan(0);
|
|
@@ -143,24 +143,53 @@ test('Test nested links', () => {
|
|
|
143
143
|
// Validate regular formatting
|
|
144
144
|
const output = formatLinks(parsed);
|
|
145
145
|
expect(output).toBeTruthy();
|
|
146
|
-
|
|
146
|
+
|
|
147
147
|
// Validate that the structure is properly nested
|
|
148
148
|
expect(parsed.length).toBe(1);
|
|
149
149
|
});
|
|
150
150
|
|
|
151
|
-
test('
|
|
151
|
+
test('Indentation parser', () => {
|
|
152
152
|
const input = 'parent\n child1\n child2';
|
|
153
153
|
const result = parser.parse(input);
|
|
154
154
|
expect(result.length).toBeGreaterThan(0);
|
|
155
155
|
// Should have parent link
|
|
156
|
-
const hasParentLink = result.some(
|
|
156
|
+
const hasParentLink = result.some(
|
|
157
|
+
(l) => l.values && l.values.some((v) => v.id === 'parent')
|
|
158
|
+
);
|
|
157
159
|
expect(hasParentLink).toBe(true);
|
|
158
160
|
});
|
|
159
161
|
|
|
160
|
-
test('
|
|
162
|
+
test('Nested indentation parser', () => {
|
|
161
163
|
const input = 'parent\n child\n grandchild';
|
|
162
164
|
const result = parser.parse(input);
|
|
163
165
|
expect(result.length).toBeGreaterThan(0);
|
|
164
166
|
// Should create nested structure with proper hierarchy
|
|
165
167
|
expect(result.length).toBeGreaterThanOrEqual(1);
|
|
166
|
-
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test('Three level nesting roundtrip', () => {
|
|
171
|
+
const input = '(1: (2: (3: 3)))';
|
|
172
|
+
const parsed = parser.parse(input);
|
|
173
|
+
|
|
174
|
+
// Validate round-trip
|
|
175
|
+
const output = formatLinks(parsed);
|
|
176
|
+
expect(output).toBe(input);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('Deep nested structure roundtrip', () => {
|
|
180
|
+
const input = '(a: (b: (c: (d: d))))';
|
|
181
|
+
const parsed = parser.parse(input);
|
|
182
|
+
|
|
183
|
+
// Validate round-trip
|
|
184
|
+
const output = formatLinks(parsed);
|
|
185
|
+
expect(output).toBe(input);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test('Multiple nested links roundtrip', () => {
|
|
189
|
+
const input = '(parent: (child1: value1) (child2: value2))';
|
|
190
|
+
const parsed = parser.parse(input);
|
|
191
|
+
|
|
192
|
+
// Validate round-trip
|
|
193
|
+
const output = formatLinks(parsed);
|
|
194
|
+
expect(output).toBe(input);
|
|
195
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { test, expect } from 'bun:test';
|
|
2
|
+
import { Parser } from '../src/Parser.js';
|
|
3
|
+
|
|
4
|
+
test('Nested self-referenced object in pair value', () => {
|
|
5
|
+
// Test case from PARSER_BUG.md
|
|
6
|
+
// This should parse a dict with two pairs, where the second pair's value
|
|
7
|
+
// is itself a self-referenced dict definition (obj_1: dict ...)
|
|
8
|
+
const notation =
|
|
9
|
+
'(obj_0: dict ((str bmFtZQ==) (str ZGljdDE=)) ((str b3RoZXI=) (obj_1: dict ((str bmFtZQ==) (str ZGljdDI=)) ((str b3RoZXI=) obj_0))))';
|
|
10
|
+
|
|
11
|
+
const parser = new Parser();
|
|
12
|
+
const links = parser.parse(notation);
|
|
13
|
+
|
|
14
|
+
// Should parse exactly one top-level link
|
|
15
|
+
expect(links.length).toBe(1);
|
|
16
|
+
|
|
17
|
+
const link = links[0];
|
|
18
|
+
|
|
19
|
+
// Top-level link should have ID "obj_0"
|
|
20
|
+
expect(link.id).toBe('obj_0');
|
|
21
|
+
|
|
22
|
+
// Should have: type marker + 2 pairs = 3 values
|
|
23
|
+
expect(link.values.length).toBe(3);
|
|
24
|
+
|
|
25
|
+
// First value is the type marker "dict"
|
|
26
|
+
expect(link.values[0].id).toBe('dict');
|
|
27
|
+
|
|
28
|
+
// Second and third values are the two pairs
|
|
29
|
+
const pair1 = link.values[1];
|
|
30
|
+
const pair2 = link.values[2];
|
|
31
|
+
|
|
32
|
+
// Pair 1: ((str bmFtZQ==) (str ZGljdDE=))
|
|
33
|
+
// This is a parenthesized expression containing two sub-expressions
|
|
34
|
+
expect(pair1.id).toBe(null);
|
|
35
|
+
expect(pair1.values.length).toBe(2);
|
|
36
|
+
|
|
37
|
+
// First element of pair1: (str bmFtZQ==)
|
|
38
|
+
expect(pair1.values[0].id).toBe(null);
|
|
39
|
+
expect(pair1.values[0].values.length).toBe(2); // "str" and "bmFtZQ=="
|
|
40
|
+
expect(pair1.values[0].values[0].id).toBe('str');
|
|
41
|
+
expect(pair1.values[0].values[1].id).toBe('bmFtZQ==');
|
|
42
|
+
|
|
43
|
+
// Second element of pair1: (str ZGljdDE=)
|
|
44
|
+
expect(pair1.values[1].id).toBe(null);
|
|
45
|
+
expect(pair1.values[1].values.length).toBe(2); // "str" and "ZGljdDE="
|
|
46
|
+
expect(pair1.values[1].values[0].id).toBe('str');
|
|
47
|
+
expect(pair1.values[1].values[1].id).toBe('ZGljdDE=');
|
|
48
|
+
|
|
49
|
+
// Pair 2: ((str b3RoZXI=) (obj_1: dict ...))
|
|
50
|
+
// This is the critical test - the second element should be a self-referenced dict
|
|
51
|
+
expect(pair2.id).toBe(null);
|
|
52
|
+
expect(pair2.values.length).toBe(2);
|
|
53
|
+
|
|
54
|
+
// First element of pair2: (str b3RoZXI=)
|
|
55
|
+
expect(pair2.values[0].id).toBe(null);
|
|
56
|
+
expect(pair2.values[0].values.length).toBe(2);
|
|
57
|
+
expect(pair2.values[0].values[0].id).toBe('str');
|
|
58
|
+
expect(pair2.values[0].values[1].id).toBe('b3RoZXI=');
|
|
59
|
+
|
|
60
|
+
// Second element of pair2: (obj_1: dict ((str bmFtZQ==) (str ZGljdDI=)) ((str b3RoZXI=) obj_0))
|
|
61
|
+
// THIS IS THE KEY TEST - obj_1 should have its ID preserved
|
|
62
|
+
const obj1 = pair2.values[1];
|
|
63
|
+
expect(obj1.id).toBe('obj_1'); // This is the self-reference ID
|
|
64
|
+
expect(obj1.values).toBeTruthy(); // Should have nested values (dict definition)
|
|
65
|
+
expect(obj1.values.length).toBe(3); // type marker + 2 pairs
|
|
66
|
+
|
|
67
|
+
// obj_1's type marker
|
|
68
|
+
expect(obj1.values[0].id).toBe('dict');
|
|
69
|
+
|
|
70
|
+
// obj_1's first pair: ((str bmFtZQ==) (str ZGljdDI=))
|
|
71
|
+
const obj1_pair1 = obj1.values[1];
|
|
72
|
+
expect(obj1_pair1.values.length).toBe(2);
|
|
73
|
+
expect(obj1_pair1.values[0].values[0].id).toBe('str');
|
|
74
|
+
expect(obj1_pair1.values[0].values[1].id).toBe('bmFtZQ==');
|
|
75
|
+
expect(obj1_pair1.values[1].values[0].id).toBe('str');
|
|
76
|
+
expect(obj1_pair1.values[1].values[1].id).toBe('ZGljdDI=');
|
|
77
|
+
|
|
78
|
+
// obj_1's second pair: ((str b3RoZXI=) obj_0) - reference back to obj_0
|
|
79
|
+
const obj1_pair2 = obj1.values[2];
|
|
80
|
+
expect(obj1_pair2.values.length).toBe(2);
|
|
81
|
+
expect(obj1_pair2.values[0].values[0].id).toBe('str');
|
|
82
|
+
expect(obj1_pair2.values[0].values[1].id).toBe('b3RoZXI=');
|
|
83
|
+
expect(obj1_pair2.values[1].id).toBe('obj_0'); // Reference to obj_0
|
|
84
|
+
expect(obj1_pair2.values[1].values).toEqual([]); // Just a reference, no nested values
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('Self-reference as direct child works correctly', () => {
|
|
88
|
+
// This pattern should work (and did work before)
|
|
89
|
+
const notation =
|
|
90
|
+
'(obj_0: list (int 1) (int 2) (obj_1: list (int 3) (int 4) obj_0))';
|
|
91
|
+
|
|
92
|
+
const parser = new Parser();
|
|
93
|
+
const links = parser.parse(notation);
|
|
94
|
+
|
|
95
|
+
expect(links.length).toBe(1);
|
|
96
|
+
expect(links[0].id).toBe('obj_0');
|
|
97
|
+
expect(links[0].values.length).toBe(4); // list + 1 + 2 + obj_1
|
|
98
|
+
|
|
99
|
+
// The fourth value should be obj_1 with a self-reference
|
|
100
|
+
const obj1 = links[0].values[3];
|
|
101
|
+
expect(obj1.id).toBe('obj_1');
|
|
102
|
+
expect(obj1.values.length).toBe(4); // list + 3 + 4 + obj_0
|
|
103
|
+
expect(obj1.values[3].id).toBe('obj_0'); // Reference back to obj_0
|
|
104
|
+
});
|
|
@@ -4,28 +4,28 @@ import { formatLinks } from '../src/Link.js';
|
|
|
4
4
|
|
|
5
5
|
const parser = new Parser();
|
|
6
6
|
|
|
7
|
-
test('
|
|
7
|
+
test('Single link', () => {
|
|
8
8
|
const source = '(address: source target)';
|
|
9
9
|
const links = parser.parse(source);
|
|
10
10
|
const target = formatLinks(links);
|
|
11
11
|
expect(target).toBe(source);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
test('
|
|
14
|
+
test('Triplet single link', () => {
|
|
15
15
|
const source = '(papa has car)';
|
|
16
16
|
const links = parser.parse(source);
|
|
17
17
|
const target = formatLinks(links);
|
|
18
18
|
expect(target).toBe(source);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
test('
|
|
21
|
+
test('Bug test 1', () => {
|
|
22
22
|
const source = '(ignore conan-center-index repository)';
|
|
23
23
|
const links = parser.parse(source);
|
|
24
24
|
const target = formatLinks(links);
|
|
25
25
|
expect(target).toBe(source);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
test('
|
|
28
|
+
test('Quoted references', () => {
|
|
29
29
|
const source = `(a: 'b' "c")`;
|
|
30
30
|
const target = `(a: b c)`;
|
|
31
31
|
const links = parser.parse(source);
|
|
@@ -33,7 +33,7 @@ test('QuotedReferencesTest', () => {
|
|
|
33
33
|
expect(formattedLinks).toBe(target);
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
test('
|
|
36
|
+
test('Quoted references with spaces', () => {
|
|
37
37
|
const source = `('a a': 'b b' "c c")`;
|
|
38
38
|
const target = `('a a': 'b b' 'c c')`;
|
|
39
39
|
const links = parser.parse(source);
|
|
@@ -127,7 +127,7 @@ test('Test value link', () => {
|
|
|
127
127
|
expect(result.length).toBeGreaterThan(0);
|
|
128
128
|
});
|
|
129
129
|
|
|
130
|
-
test('
|
|
130
|
+
test('Parse quoted references values only', () => {
|
|
131
131
|
const source = `"has space" 'has:colon'`;
|
|
132
132
|
const parser = new Parser();
|
|
133
133
|
const links = parser.parse(source);
|
|
@@ -161,7 +161,7 @@ test('Test special characters in quotes', () => {
|
|
|
161
161
|
let input = '("key:with:colons": "value(with)parens")';
|
|
162
162
|
let result = parser.parse(input);
|
|
163
163
|
expect(result.length).toBeGreaterThan(0);
|
|
164
|
-
|
|
164
|
+
|
|
165
165
|
input = "('key with spaces': 'value: with special chars')";
|
|
166
166
|
result = parser.parse(input);
|
|
167
167
|
expect(result.length).toBeGreaterThan(0);
|
|
@@ -226,4 +226,84 @@ test('Test value link (parser)', () => {
|
|
|
226
226
|
expect(result.length).toBe(1);
|
|
227
227
|
expect(result[0].id).toBe(null);
|
|
228
228
|
expect(result[0].values.length).toBe(3);
|
|
229
|
-
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test('Multiline without id', () => {
|
|
232
|
+
// Test that '(:)' syntax is forbidden and should throw an error
|
|
233
|
+
const input = '(: value1 value2)';
|
|
234
|
+
// JS parser forbids this syntax
|
|
235
|
+
expect(() => parser.parse(input)).toThrow();
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test('Parse values only standalone colon', () => {
|
|
239
|
+
// Test that standalone ':' is forbidden and should throw an error
|
|
240
|
+
const input = ': value1 value2';
|
|
241
|
+
// JS parser forbids this syntax
|
|
242
|
+
expect(() => parser.parse(input)).toThrow();
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test('Quoted references with spaces in link', () => {
|
|
246
|
+
const input = '(id: "value with spaces")';
|
|
247
|
+
const result = parser.parse(input);
|
|
248
|
+
expect(result.length).toBe(1);
|
|
249
|
+
expect(result[0].id).toBe('id');
|
|
250
|
+
expect(result[0].values.length).toBe(1);
|
|
251
|
+
expect(result[0].values[0].id).toBe('value with spaces');
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test('Single line without id', () => {
|
|
255
|
+
// Test parsing a single line without ID (just values)
|
|
256
|
+
const input = '(value1 value2)';
|
|
257
|
+
const result = parser.parse(input);
|
|
258
|
+
expect(result.length).toBe(1);
|
|
259
|
+
expect(result[0].id).toBe(null);
|
|
260
|
+
expect(result[0].values.length).toBe(2);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
test('Link with id', () => {
|
|
264
|
+
const input = '(id: a b c)';
|
|
265
|
+
const result = parser.parse(input);
|
|
266
|
+
expect(result.length).toBe(1);
|
|
267
|
+
expect(result[0].id).toBe('id');
|
|
268
|
+
expect(result[0].values.length).toBe(3);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test('Quoted reference', () => {
|
|
272
|
+
const input = '"quoted value"';
|
|
273
|
+
const result = parser.parse(input);
|
|
274
|
+
expect(result.length).toBe(1);
|
|
275
|
+
expect(result[0].id).toBe(null);
|
|
276
|
+
expect(result[0].values.length).toBe(1);
|
|
277
|
+
expect(result[0].values[0].id).toBe('quoted value');
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
test('Quoted references with special chars', () => {
|
|
281
|
+
const input = '("special:char" "another@char")';
|
|
282
|
+
const result = parser.parse(input);
|
|
283
|
+
expect(result.length).toBe(1);
|
|
284
|
+
expect(result[0].id).toBe(null);
|
|
285
|
+
expect(result[0].values.length).toBe(2);
|
|
286
|
+
expect(result[0].values[0].id).toBe('special:char');
|
|
287
|
+
expect(result[0].values[1].id).toBe('another@char');
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
test('Simple reference', () => {
|
|
291
|
+
const input = 'simplereference';
|
|
292
|
+
const result = parser.parse(input);
|
|
293
|
+
expect(result.length).toBeGreaterThan(0);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
test('Single line link', () => {
|
|
297
|
+
const input = 'id: value1 value2';
|
|
298
|
+
const result = parser.parse(input);
|
|
299
|
+
expect(result.length).toBe(1);
|
|
300
|
+
expect(result[0].id).toBe('id');
|
|
301
|
+
expect(result[0].values.length).toBe(2);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
test('Single line with id', () => {
|
|
305
|
+
const input = 'myid: val1 val2';
|
|
306
|
+
const result = parser.parse(input);
|
|
307
|
+
expect(result.length).toBeGreaterThan(0);
|
|
308
|
+
expect(result[0].id).toBe('myid');
|
|
309
|
+
});
|