@markuplint/ml-core 3.13.0 → 4.0.0-alpha.2

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.
Files changed (95) hide show
  1. package/lib/configs.browser.js +1 -5
  2. package/lib/configs.js +33 -30
  3. package/lib/convert-ruleset.d.ts +1 -1
  4. package/lib/convert-ruleset.js +3 -8
  5. package/lib/debug.js +9 -14
  6. package/lib/index.d.ts +12 -12
  7. package/lib/index.js +13 -29
  8. package/lib/ml-core.d.ts +2 -2
  9. package/lib/ml-core.js +60 -66
  10. package/lib/ml-dom/helper/accname.d.ts +1 -1
  11. package/lib/ml-dom/helper/accname.js +9 -16
  12. package/lib/ml-dom/helper/create-node.d.ts +2 -2
  13. package/lib/ml-dom/helper/create-node.js +11 -15
  14. package/lib/ml-dom/helper/debug.d.ts +1 -1
  15. package/lib/ml-dom/helper/debug.js +2 -7
  16. package/lib/ml-dom/helper/getIndent.d.ts +2 -2
  17. package/lib/ml-dom/helper/getIndent.js +15 -19
  18. package/lib/ml-dom/helper/walkers.d.ts +1 -1
  19. package/lib/ml-dom/helper/walkers.js +2 -7
  20. package/lib/ml-dom/index.d.ts +9 -9
  21. package/lib/ml-dom/index.js +1 -5
  22. package/lib/ml-dom/manipulations/child-node-methods.d.ts +2 -2
  23. package/lib/ml-dom/manipulations/child-node-methods.js +13 -25
  24. package/lib/ml-dom/manipulations/get-children.d.ts +2 -2
  25. package/lib/ml-dom/manipulations/get-children.js +3 -7
  26. package/lib/ml-dom/node/attr.d.ts +5 -5
  27. package/lib/ml-dom/node/attr.js +28 -33
  28. package/lib/ml-dom/node/block.d.ts +4 -4
  29. package/lib/ml-dom/node/block.js +7 -11
  30. package/lib/ml-dom/node/character-data.d.ts +2 -2
  31. package/lib/ml-dom/node/character-data.js +11 -16
  32. package/lib/ml-dom/node/child-node.d.ts +6 -6
  33. package/lib/ml-dom/node/child-node.js +1 -5
  34. package/lib/ml-dom/node/comment.d.ts +2 -2
  35. package/lib/ml-dom/node/comment.js +2 -6
  36. package/lib/ml-dom/node/document-fragment.d.ts +2 -2
  37. package/lib/ml-dom/node/document-fragment.js +4 -9
  38. package/lib/ml-dom/node/document-type.d.ts +4 -4
  39. package/lib/ml-dom/node/document-type.js +7 -11
  40. package/lib/ml-dom/node/document.d.ts +13 -13
  41. package/lib/ml-dom/node/document.js +234 -242
  42. package/lib/ml-dom/node/dom-token-list.d.ts +1 -1
  43. package/lib/ml-dom/node/dom-token-list.js +25 -31
  44. package/lib/ml-dom/node/element.d.ts +8 -8
  45. package/lib/ml-dom/node/element.js +283 -301
  46. package/lib/ml-dom/node/named-node-map.d.ts +1 -1
  47. package/lib/ml-dom/node/named-node-map.js +10 -18
  48. package/lib/ml-dom/node/node-list.d.ts +2 -2
  49. package/lib/ml-dom/node/node-list.js +6 -14
  50. package/lib/ml-dom/node/node-store.d.ts +2 -2
  51. package/lib/ml-dom/node/node-store.js +9 -12
  52. package/lib/ml-dom/node/node.d.ts +8 -8
  53. package/lib/ml-dom/node/node.js +58 -66
  54. package/lib/ml-dom/node/parent-node.d.ts +2 -2
  55. package/lib/ml-dom/node/parent-node.js +22 -29
  56. package/lib/ml-dom/node/rule-mapper.d.ts +2 -2
  57. package/lib/ml-dom/node/rule-mapper.js +11 -16
  58. package/lib/ml-dom/node/text.d.ts +2 -2
  59. package/lib/ml-dom/node/text.js +6 -11
  60. package/lib/ml-dom/node/types.d.ts +10 -10
  61. package/lib/ml-dom/node/types.js +1 -2
  62. package/lib/ml-dom/node/unexpected-call-error.js +1 -4
  63. package/lib/ml-dom/token/token.js +19 -23
  64. package/lib/ml-rule/create-rule.d.ts +1 -1
  65. package/lib/ml-rule/create-rule.js +1 -5
  66. package/lib/ml-rule/create-test-rule.d.ts +2 -2
  67. package/lib/ml-rule/create-test-rule.js +3 -7
  68. package/lib/ml-rule/index.d.ts +3 -3
  69. package/lib/ml-rule/index.js +3 -6
  70. package/lib/ml-rule/ml-rule-context.d.ts +2 -2
  71. package/lib/ml-rule/ml-rule-context.js +7 -11
  72. package/lib/ml-rule/ml-rule.d.ts +3 -3
  73. package/lib/ml-rule/ml-rule.js +23 -30
  74. package/lib/ml-rule/types.d.ts +2 -2
  75. package/lib/ml-rule/types.js +1 -2
  76. package/lib/plugin/index.d.ts +2 -2
  77. package/lib/plugin/index.js +2 -5
  78. package/lib/plugin/plugin.d.ts +1 -1
  79. package/lib/plugin/plugin.js +1 -5
  80. package/lib/plugin/types.d.ts +1 -1
  81. package/lib/plugin/types.js +1 -2
  82. package/lib/ruleset/index.js +4 -8
  83. package/lib/test/index.d.ts +4 -4
  84. package/lib/test/index.js +13 -23
  85. package/lib/types.d.ts +2 -2
  86. package/lib/types.js +1 -2
  87. package/lib/utils/get-location-from-chars.js +1 -5
  88. package/lib/utils/index.d.ts +1 -1
  89. package/lib/utils/index.js +1 -5
  90. package/lib/utils/string-splice.js +1 -5
  91. package/package.json +19 -14
  92. package/test/ml-dom/helper/accname.spec.js +0 -85
  93. package/test/ml-dom/helper/create-node.spec.js +0 -18
  94. package/test/ml-dom/index.spec.js +0 -680
  95. package/test/ml-dom/ml-rule/create-rule.spec.js +0 -108
@@ -1,680 +0,0 @@
1
- const { createRule } = require('../../lib/ml-rule/create-test-rule');
2
- const { createTestDocument, createTestElement, createTestNodeList, createTestTokenList } = require('../../lib/test');
3
-
4
- describe('AST', () => {
5
- test('node count', () => {
6
- const nodeList = createTestNodeList('<div>text</div>');
7
- expect(nodeList.length).toBe(2);
8
- });
9
-
10
- test('raw', () => {
11
- const nodeList = createTestNodeList('<div>text</div>');
12
- expect(nodeList[0].raw).toBe('<div>');
13
- expect(nodeList[1].raw).toBe('text');
14
- expect(nodeList[0].closeTag?.raw).toBe('</div>');
15
- });
16
-
17
- test('raw', () => {
18
- const tokens = createTestTokenList(`
19
- <div>
20
- text
21
- </div>`);
22
- expect(tokens[0].raw).toBe('\n');
23
- expect(tokens[1].raw).toBe('<div>');
24
- expect(tokens[2].raw).toBe('\n\ttext\n');
25
- expect(tokens[3].raw).toBe('</div>');
26
- });
27
-
28
- test('raw', () => {
29
- const tokens = createTestTokenList(`
30
- <div>
31
- text
32
- </div>`);
33
- expect(tokens[0].raw).toBe('\n ');
34
- expect(tokens[1].raw).toBe('<div>');
35
- expect(tokens[2].raw).toBe('\n text\n ');
36
- expect(tokens[3].raw).toBe('</div>');
37
- expect(tokens[0].prevToken).toBe(null);
38
- expect(tokens[1].prevToken?.raw).toBe('\n ');
39
- expect(tokens[2].prevToken?.raw).toBe('<div>');
40
- expect(tokens[1].prevToken?.uuid).toBe(tokens[0].uuid);
41
- expect(tokens[2].prevToken?.uuid).toBe(tokens[1].uuid);
42
- });
43
-
44
- test('raw', () => {
45
- const tokens = createTestTokenList(`
46
- <div>
47
- <span>text</span>
48
- </div>`);
49
- expect(tokens[0].raw).toBe('\n ');
50
- expect(tokens[1].raw).toBe('<div>');
51
- expect(tokens[2].raw).toBe('\n ');
52
- expect(tokens[3].raw).toBe('<span>');
53
- expect(tokens[4].raw).toBe('text');
54
- expect(tokens[5].raw).toBe('</span>');
55
- expect(tokens[6].raw).toBe('\n ');
56
- expect(tokens[7].raw).toBe('</div>');
57
- });
58
-
59
- test('raw', () => {
60
- const tokens = createTestTokenList(`
61
- <div>
62
- <span>text</span>
63
- </div>`);
64
- expect(tokens[0].raw).toBe('\n');
65
- expect(tokens[1].raw).toBe('<div>');
66
- expect(tokens[2].raw).toBe('\n\t');
67
- expect(tokens[3].raw).toBe('<span>');
68
- expect(tokens[4].raw).toBe('text');
69
- expect(tokens[5].raw).toBe('</span>');
70
- expect(tokens[6].raw).toBe('\n');
71
- expect(tokens[7].raw).toBe('</div>');
72
- });
73
-
74
- test('classList', () => {
75
- const el = createTestElement('<div class="a b c"></div>');
76
- expect(Array.from(el.classList)).toStrictEqual(['a', 'b', 'c']);
77
- });
78
-
79
- test('fixNodeName', () => {
80
- const el = createTestElement('<div></div>');
81
- expect(el.raw).toBe('<div>');
82
- el.fixNodeName('x-div');
83
- expect(el.raw).toBe('<x-div>');
84
- });
85
-
86
- test('namespace', () => {
87
- const tokens = createTestTokenList(`<div>
88
- <svg>
89
- <a></a>
90
- <foreignObject>
91
- <div></div>
92
- </foreignObject>
93
- </svg>
94
- <a></a>
95
- </div>
96
- `);
97
- expect(tokens[0].nodeName).toBe('DIV');
98
- expect(tokens[0].namespaceURI).toBe('http://www.w3.org/1999/xhtml');
99
- expect(tokens[2].nodeName).toBe('svg');
100
- expect(tokens[2].namespaceURI).toBe('http://www.w3.org/2000/svg');
101
- expect(tokens[4].nodeName).toBe('a');
102
- expect(tokens[4].namespaceURI).toBe('http://www.w3.org/2000/svg');
103
- expect(tokens[7].nodeName).toBe('foreignObject');
104
- expect(tokens[7].namespaceURI).toBe('http://www.w3.org/2000/svg');
105
- expect(tokens[9].nodeName).toBe('DIV');
106
- expect(tokens[9].namespaceURI).toBe('http://www.w3.org/1999/xhtml');
107
- expect(tokens[16].nodeName).toBe('A');
108
- expect(tokens[16].namespaceURI).toBe('http://www.w3.org/1999/xhtml');
109
- });
110
-
111
- test('toString', () => {
112
- const raw = `
113
- <div>
114
- <span attr attr2 attr3="value" attr4=value>text</span>
115
- </div>`;
116
- const doc = createTestDocument(raw);
117
- expect(doc.toString()).toBe(raw);
118
- });
119
-
120
- test('IDL attribute in JSX', () => {
121
- expect(
122
- createTestElement('<label></label>', {
123
- parser: require('@markuplint/jsx-parser'),
124
- }).getAttributeNode('for')?.localName,
125
- ).toBeUndefined();
126
- expect(
127
- createTestElement('<label htmlFor></label>', {
128
- parser: require('@markuplint/jsx-parser'),
129
- }).getAttributeNode('for')?.localName,
130
- ).toBe('for');
131
- expect(
132
- createTestElement('<label htmlFor></label>', {
133
- parser: require('@markuplint/jsx-parser'),
134
- }).getAttributeNode('htmlFor')?.localName,
135
- ).toBeUndefined();
136
- });
137
-
138
- test('rule', () => {
139
- const document = createTestDocument('<div><span>text</span></div>', {
140
- config: {
141
- rules: {
142
- ruleA: true,
143
- ruleB: true,
144
- },
145
- nodeRules: [
146
- {
147
- selector: 'span',
148
- rules: {
149
- ruleA: false,
150
- },
151
- },
152
- ],
153
- },
154
- });
155
- const ruleA = createRule({
156
- name: 'ruleA',
157
- defaultValue: 'foo',
158
- defaultOptions: null,
159
- verify() {
160
- throw new Error();
161
- },
162
- });
163
- document.setRule(ruleA);
164
- expect(document.nodeList[1].rule.disabled).toBe(true);
165
- const ruleB = createRule({
166
- name: 'ruleB',
167
- defaultValue: 'foo',
168
- defaultOptions: null,
169
- verify() {
170
- throw new Error();
171
- },
172
- });
173
- document.setRule(ruleB);
174
- expect(document.nodeList[1].rule.disabled).toBe(false);
175
- });
176
- });
177
-
178
- describe('Selector', () => {
179
- test('nodeName case-sensitive', () => {
180
- expect(createTestElement('<DIV></DIV>').matches('div')).toBeTruthy();
181
- expect(createTestElement('<DIV></DIV>').matches('DIV')).toBeTruthy();
182
- expect(
183
- createTestElement('<Div></Div>', {
184
- parser: require('@markuplint/jsx-parser'),
185
- }).matches('DIV'),
186
- ).toBeFalsy();
187
- });
188
-
189
- test('Pug has PSBlock', () => {
190
- const el = createTestElement(
191
- `
192
- div#hoge.foo.bar
193
- if foo
194
- a(href="path/to")`,
195
- {
196
- parser: require('@markuplint/pug-parser'),
197
- },
198
- );
199
- // @ts-ignore
200
- const a = el.childNodes[0].childNodes[0];
201
- expect(el.matches('*')).toBeTruthy();
202
- expect(el.matches('div')).toBeTruthy();
203
- expect(el.matches('div#hoge')).toBeTruthy();
204
- expect(el.matches('div#fuga')).toBe(false);
205
- expect(el.matches('#hoge')).toBeTruthy();
206
- expect(el.matches('div.foo')).toBeTruthy();
207
- expect(el.matches('div.bar')).toBeTruthy();
208
- expect(el.matches('.foo')).toBeTruthy();
209
- expect(el.matches('.foo.bar')).toBeTruthy();
210
- expect(el.matches('.any')).toBe(false);
211
- expect(a.matches('*')).toBeTruthy();
212
- expect(a.matches('a')).toBeTruthy();
213
- expect(a.matches('div a')).toBeTruthy();
214
- expect(a.matches('div > a')).toBeTruthy();
215
- });
216
-
217
- test('Attribute potential name', () => {
218
- expect(
219
- createTestElement('<div tabIndex className><label htmlFor></label></div>', {
220
- parser: require('@markuplint/jsx-parser'),
221
- }).matches('[tabindex][class]:has(>label[for])'),
222
- ).toBeTruthy();
223
-
224
- expect(
225
- createTestElement('<svg><image clipPath /></svg>', {
226
- parser: require('@markuplint/jsx-parser'),
227
- }).matches('svg:has(>image[clip-path])'),
228
- ).toBeTruthy();
229
- });
230
- });
231
-
232
- describe('Rule', () => {
233
- test('regexSelector', () => {
234
- const document = createTestDocument('<img src="path/to/name.png" />', {
235
- config: {
236
- rules: {
237
- ruleA: true,
238
- },
239
- nodeRules: [
240
- {
241
- regexSelector: {
242
- nodeName: 'img',
243
- attrName: 'src',
244
- attrValue: '/(?<fileName>[a-z0-9_-]+)\\.png$/',
245
- },
246
- rules: {
247
- ruleA: {
248
- value: 'fileName is {{ fileName }}',
249
- options: {
250
- propA: 'fileName is {{ fileName }}',
251
- propB: ['fileName is {{ fileName }}'],
252
- propC: {
253
- prop: 'fileName is {{ fileName }}',
254
- },
255
- },
256
- },
257
- },
258
- },
259
- ],
260
- },
261
- });
262
- const ruleA = createRule({
263
- name: 'ruleA',
264
- defaultValue: 'foo',
265
- defaultOptions: null,
266
- verify() {
267
- throw new Error();
268
- },
269
- });
270
- document.setRule(ruleA);
271
- expect(document.nodeList[0].rule).toStrictEqual({
272
- disabled: false,
273
- reason: undefined,
274
- severity: 'error',
275
- value: 'fileName is name',
276
- options: {
277
- propA: 'fileName is name',
278
- propB: ['fileName is name'],
279
- propC: {
280
- prop: 'fileName is name',
281
- },
282
- },
283
- });
284
- });
285
-
286
- test('extend rule settings', () => {
287
- const document = createTestDocument('<span class="a"></span><div class="b"><span></span></div>', {
288
- config: {
289
- rules: {
290
- ruleA: {
291
- severity: 'error',
292
- reason: '123',
293
- },
294
- ruleB: {
295
- severity: 'info',
296
- reason: '456',
297
- },
298
- ruleC: false,
299
- ruleD: true,
300
- ruleE: {
301
- value: '789',
302
- },
303
- },
304
- nodeRules: [
305
- {
306
- selector: '.a',
307
- rules: {
308
- ruleA: {
309
- severity: 'info',
310
- reason: '456',
311
- },
312
- ruleB: {},
313
- ruleC: true,
314
- ruleD: false,
315
- ruleE: false,
316
- },
317
- },
318
- ],
319
- childNodeRules: [
320
- {
321
- selector: '.b',
322
- rules: {
323
- ruleA: {
324
- severity: 'info',
325
- reason: '456',
326
- },
327
- ruleB: {},
328
- ruleC: true,
329
- ruleD: false,
330
- ruleE: false,
331
- },
332
- },
333
- ],
334
- },
335
- });
336
-
337
- expect(document.nodeList[0].nodeName).toBe('SPAN');
338
- expect(document.nodeList[1].nodeName).toBe('DIV');
339
- expect(document.nodeList[2].nodeName).toBe('SPAN');
340
-
341
- const ruleA = createRule({
342
- name: 'ruleA',
343
- defaultValue: 'foo',
344
- defaultOptions: null,
345
- verify() {
346
- throw new Error();
347
- },
348
- });
349
- const ruleB = createRule({
350
- name: 'ruleB',
351
- defaultValue: 'bar',
352
- defaultOptions: null,
353
- verify() {
354
- throw new Error();
355
- },
356
- });
357
- const ruleC = createRule({
358
- name: 'ruleC',
359
- defaultValue: 'buz',
360
- defaultOptions: null,
361
- verify() {
362
- throw new Error();
363
- },
364
- });
365
- const ruleD = createRule({
366
- name: 'ruleD',
367
- defaultValue: 'fuz',
368
- defaultOptions: null,
369
- verify() {
370
- throw new Error();
371
- },
372
- });
373
- const ruleE = createRule({
374
- name: 'ruleE',
375
- defaultValue: 'piyo',
376
- defaultOptions: null,
377
- verify() {
378
- throw new Error();
379
- },
380
- });
381
-
382
- document.setRule(ruleA);
383
- const resultA = {
384
- disabled: false,
385
- reason: '456',
386
- severity: 'info',
387
- value: 'foo',
388
- options: null,
389
- };
390
- expect(document.nodeList[0].rule).toStrictEqual(resultA);
391
- expect(document.nodeList[1].rule).not.toStrictEqual(resultA);
392
- expect(document.nodeList[2].rule).toStrictEqual(resultA);
393
-
394
- document.setRule(ruleB);
395
- const resultB = {
396
- disabled: false,
397
- reason: '456',
398
- severity: 'info',
399
- value: 'bar',
400
- options: null,
401
- };
402
- expect(document.nodeList[0].rule).toStrictEqual(resultB);
403
- expect(document.nodeList[1].rule).toStrictEqual(resultB);
404
- expect(document.nodeList[2].rule).toStrictEqual(resultB);
405
-
406
- document.setRule(ruleC);
407
- const resultC = {
408
- disabled: false,
409
- reason: undefined,
410
- severity: 'error',
411
- value: 'buz',
412
- options: null,
413
- };
414
- expect(document.nodeList[0].rule).toStrictEqual(resultC);
415
- expect(document.nodeList[1].rule).not.toStrictEqual(resultC);
416
- expect(document.nodeList[2].rule).toStrictEqual(resultC);
417
-
418
- document.setRule(ruleD);
419
- const resultD = {
420
- disabled: true,
421
- reason: undefined,
422
- severity: 'error',
423
- value: 'fuz',
424
- options: null,
425
- };
426
- expect(document.nodeList[0].rule).toStrictEqual(resultD);
427
- expect(document.nodeList[1].rule).not.toStrictEqual(resultC);
428
- expect(document.nodeList[2].rule).toStrictEqual(resultD);
429
-
430
- document.setRule(ruleE);
431
- const resultE = {
432
- disabled: true,
433
- reason: undefined,
434
- severity: 'error',
435
- value: 'piyo',
436
- options: null,
437
- };
438
- expect(document.nodeList[0].rule).toStrictEqual(resultE);
439
- expect(document.nodeList[1].rule).not.toStrictEqual(resultE);
440
- expect(document.nodeList[2].rule).toStrictEqual(resultE);
441
- });
442
-
443
- test('regexSelector + pug', () => {
444
- const document = createTestDocument(
445
- `section.Card
446
- .Card__inner1
447
- .Card__inner2
448
- if true
449
- .Card__inner3`,
450
- {
451
- config: {
452
- rules: {
453
- ruleA: 'global',
454
- },
455
- childNodeRules: [
456
- {
457
- regexSelector: {
458
- attrName: 'class',
459
- attrValue: '/^(?<BlockName>[A-Z][a-z0-9]+)$/',
460
- },
461
- inheritance: true,
462
- rules: {
463
- ruleA: '{{ BlockName }}',
464
- },
465
- },
466
- ],
467
- },
468
- parser: require('@markuplint/pug-parser'),
469
- },
470
- );
471
- const ruleA = createRule({
472
- name: 'ruleA',
473
- defaultValue: 'foo',
474
- defaultOptions: null,
475
- verify() {
476
- throw new Error();
477
- },
478
- });
479
- document.setRule(ruleA);
480
- expect(document.nodeList[0].rule).toStrictEqual({
481
- disabled: false,
482
- reason: undefined,
483
- severity: 'error',
484
- value: 'global',
485
- options: null,
486
- });
487
- expect(document.nodeList[1].rule).toStrictEqual({
488
- disabled: false,
489
- reason: undefined,
490
- severity: 'error',
491
- value: 'Card',
492
- options: null,
493
- });
494
- expect(document.nodeList[2].rule).toStrictEqual({
495
- disabled: false,
496
- reason: undefined,
497
- severity: 'error',
498
- value: 'Card',
499
- options: null,
500
- });
501
- expect(document.nodeList[4].rule).toStrictEqual({
502
- disabled: false,
503
- reason: undefined,
504
- severity: 'error',
505
- value: 'Card',
506
- options: null,
507
- });
508
- });
509
-
510
- test('regexSelector + jsx', () => {
511
- const document = createTestDocument(
512
- `<section className="Card">
513
- <div className="Card__inner1">
514
- <div className="Card__inner2">
515
- {() => (<div className="Card__inner3" />)}
516
- </div>
517
- </div>
518
- </section>`,
519
- {
520
- config: {
521
- rules: {
522
- ruleA: 'global',
523
- },
524
- childNodeRules: [
525
- {
526
- regexSelector: {
527
- attrName: 'class',
528
- attrValue: '/^(?<BlockName>[A-Z][a-z0-9]+)$/',
529
- },
530
- inheritance: true,
531
- rules: {
532
- ruleA: '{{ BlockName }}',
533
- },
534
- },
535
- ],
536
- },
537
- parser: require('@markuplint/jsx-parser'),
538
- },
539
- );
540
- const ruleA = createRule({
541
- name: 'ruleA',
542
- defaultValue: 'foo',
543
- defaultOptions: null,
544
- verify() {
545
- throw new Error();
546
- },
547
- });
548
- document.setRule(ruleA);
549
- expect(document.nodeList[0].rule).toStrictEqual({
550
- disabled: false,
551
- reason: undefined,
552
- severity: 'error',
553
- value: 'global',
554
- options: null,
555
- });
556
- expect(document.nodeList[2].rule).toStrictEqual({
557
- disabled: false,
558
- reason: undefined,
559
- severity: 'error',
560
- value: 'Card',
561
- options: null,
562
- });
563
- expect(document.nodeList[4].rule).toStrictEqual({
564
- disabled: false,
565
- reason: undefined,
566
- severity: 'error',
567
- value: 'Card',
568
- options: null,
569
- });
570
- expect(document.nodeList[7].rule).toStrictEqual({
571
- disabled: false,
572
- reason: undefined,
573
- severity: 'error',
574
- value: 'Card',
575
- options: null,
576
- });
577
- });
578
-
579
- test('Rule Mapping', () => {
580
- const config = {
581
- rules: {
582
- ruleA: 'global',
583
- },
584
- childNodeRules: [
585
- {
586
- regexSelector: {
587
- nodeName: '/^x-(?<name>[a-c])/',
588
- },
589
- inheritance: true,
590
- rules: {
591
- ruleA: '{{ name }}',
592
- },
593
- },
594
- ],
595
- };
596
-
597
- const html = createTestDocument('<x-a><x-b><x-c></x-c></x-b></x-a>', {
598
- config,
599
- });
600
- const htmlRules = html.nodeList.map(node => node.nodeName.toLowerCase() + ':' + node.rules['ruleA']);
601
- expect(htmlRules).toStrictEqual(['x-a:global', 'x-b:a', 'x-c:b']);
602
-
603
- const pug = createTestDocument('x-a: x-b: x-c', {
604
- config,
605
- parser: require('@markuplint/pug-parser'),
606
- });
607
- const pugRules = pug.nodeList.map(node => node.nodeName.toLowerCase() + ':' + node.rules['ruleA']);
608
- expect(pugRules).toStrictEqual(['x-a:global', 'x-b:a', 'x-c:b']);
609
- });
610
- });
611
-
612
- describe('Issues', () => {
613
- test('#607', () => {
614
- const dom = createTestDocument('<% %><div></div>', {
615
- config: {
616
- nodeRules: [{ selector: '* ~ div', rules: {} }],
617
- },
618
- parser: require('@markuplint/ejs-parser'),
619
- });
620
- expect(dom.nodeList[0].nodeName).toBe('#ml-block');
621
- });
622
-
623
- test('#641', () => {
624
- const dom = createTestDocument('<p>{array.map(_ => <></>)}</p>', {
625
- parser: require('@markuplint/jsx-parser'),
626
- });
627
- expect(dom.nodeList[0].raw).toBe('<p>');
628
- expect(dom.nodeList[1].raw).toBe('{array.map(_ => <></>)}');
629
- expect(dom.nodeList[2].raw).toBe('<>');
630
- expect(dom.nodeList[3]).toBeUndefined();
631
- expect(dom.nodeList[0].childNodes[0].raw).toBe('{array.map(_ => <></>)}');
632
- expect(dom.nodeList[0].childNodes[0].childNodes[0].raw).toBe('<>');
633
- const elements = dom.querySelectorAll('*');
634
- expect(elements.length).toBe(2);
635
- });
636
-
637
- test('#698', () => {
638
- const dom = createTestDocument(
639
- `<ul>
640
- {#if cond === valueA}
641
- <li>A</li>
642
- {:else if cond === valueB}
643
- <li>B</li>
644
- {/if}
645
- </ul>`,
646
- { parser: require('@markuplint/svelte-parser') },
647
- );
648
-
649
- // 💡 This calling is a test that checks it
650
- // doesn't throw an error when it referrers a DOM object.
651
- dom.querySelectorAll('*');
652
-
653
- const map = dom.debugMap();
654
- expect(map).toStrictEqual([
655
- '[1:1]>[1:5](0,4)UL: <ul>',
656
- ' namespaceURI: true',
657
- ' elementType: html',
658
- ' isInFragmentDocument: true',
659
- ' isForeignElement: false',
660
- '[1:5]>[2:2](4,6)#text: ⏎→',
661
- '[2:2]>[3:3](6,30)#ml-block: {#if␣cond␣===␣valueA}⏎→→',
662
- '[3:3]>[3:7](30,34)LI: <li>',
663
- ' namespaceURI: true',
664
- ' elementType: html',
665
- ' isInFragmentDocument: true',
666
- ' isForeignElement: false',
667
- '[3:7]>[3:8](34,35)#text: A',
668
- '[3:13]>[5:3](40,71)#ml-block: ⏎→{:else␣if␣cond␣===␣valueB}⏎→→',
669
- '[5:3]>[5:7](71,75)LI: <li>',
670
- ' namespaceURI: true',
671
- ' elementType: html',
672
- ' isInFragmentDocument: true',
673
- ' isForeignElement: false',
674
- '[5:7]>[5:8](75,76)#text: B',
675
- '[5:13]>[6:2](81,83)#text: ⏎→',
676
- '[6:2]>[6:7](83,88)#ml-block: {/if}',
677
- '[6:7]>[7:1](88,89)#text: ⏎',
678
- ]);
679
- });
680
- });