zero-query 0.9.8 → 1.0.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.
Files changed (99) hide show
  1. package/README.md +55 -31
  2. package/cli/args.js +1 -1
  3. package/cli/commands/build.js +2 -2
  4. package/cli/commands/bundle.js +15 -15
  5. package/cli/commands/create.js +41 -7
  6. package/cli/commands/dev/devtools/index.js +1 -1
  7. package/cli/commands/dev/devtools/js/core.js +14 -14
  8. package/cli/commands/dev/devtools/js/elements.js +4 -4
  9. package/cli/commands/dev/devtools/js/stats.js +1 -1
  10. package/cli/commands/dev/devtools/styles.css +2 -2
  11. package/cli/commands/dev/index.js +2 -2
  12. package/cli/commands/dev/logger.js +1 -1
  13. package/cli/commands/dev/overlay.js +21 -14
  14. package/cli/commands/dev/server.js +5 -5
  15. package/cli/commands/dev/validator.js +7 -7
  16. package/cli/commands/dev/watcher.js +6 -6
  17. package/cli/help.js +4 -2
  18. package/cli/index.js +2 -2
  19. package/cli/scaffold/default/app/app.js +17 -18
  20. package/cli/scaffold/default/app/components/about.js +9 -9
  21. package/cli/scaffold/default/app/components/api-demo.js +6 -6
  22. package/cli/scaffold/default/app/components/contact-card.js +4 -4
  23. package/cli/scaffold/default/app/components/contacts/contacts.css +2 -2
  24. package/cli/scaffold/default/app/components/contacts/contacts.html +3 -3
  25. package/cli/scaffold/default/app/components/contacts/contacts.js +11 -11
  26. package/cli/scaffold/default/app/components/counter.js +8 -8
  27. package/cli/scaffold/default/app/components/home.js +13 -13
  28. package/cli/scaffold/default/app/components/not-found.js +1 -1
  29. package/cli/scaffold/default/app/components/playground/playground.css +1 -1
  30. package/cli/scaffold/default/app/components/playground/playground.html +11 -11
  31. package/cli/scaffold/default/app/components/playground/playground.js +11 -11
  32. package/cli/scaffold/default/app/components/todos.js +8 -8
  33. package/cli/scaffold/default/app/components/toolkit/toolkit.css +1 -1
  34. package/cli/scaffold/default/app/components/toolkit/toolkit.html +4 -4
  35. package/cli/scaffold/default/app/components/toolkit/toolkit.js +7 -7
  36. package/cli/scaffold/default/app/routes.js +1 -1
  37. package/cli/scaffold/default/app/store.js +1 -1
  38. package/cli/scaffold/default/global.css +2 -2
  39. package/cli/scaffold/default/index.html +2 -2
  40. package/cli/scaffold/minimal/app/app.js +6 -7
  41. package/cli/scaffold/minimal/app/components/about.js +5 -5
  42. package/cli/scaffold/minimal/app/components/counter.js +6 -6
  43. package/cli/scaffold/minimal/app/components/home.js +8 -8
  44. package/cli/scaffold/minimal/app/components/not-found.js +1 -1
  45. package/cli/scaffold/minimal/app/routes.js +1 -1
  46. package/cli/scaffold/minimal/app/store.js +1 -1
  47. package/cli/scaffold/minimal/global.css +2 -2
  48. package/cli/scaffold/minimal/index.html +1 -1
  49. package/cli/scaffold/ssr/app/app.js +29 -0
  50. package/cli/scaffold/ssr/app/components/about.js +28 -0
  51. package/cli/scaffold/ssr/app/components/home.js +37 -0
  52. package/cli/scaffold/ssr/app/components/not-found.js +15 -0
  53. package/cli/scaffold/ssr/app/routes.js +6 -0
  54. package/cli/scaffold/ssr/global.css +113 -0
  55. package/cli/scaffold/ssr/index.html +31 -0
  56. package/cli/scaffold/ssr/package.json +8 -0
  57. package/cli/scaffold/ssr/server/index.js +118 -0
  58. package/cli/utils.js +6 -6
  59. package/dist/zquery.dist.zip +0 -0
  60. package/dist/zquery.js +565 -228
  61. package/dist/zquery.min.js +2 -2
  62. package/index.d.ts +25 -12
  63. package/index.js +11 -7
  64. package/package.json +9 -3
  65. package/src/component.js +64 -63
  66. package/src/core.js +15 -15
  67. package/src/diff.js +38 -38
  68. package/src/errors.js +72 -18
  69. package/src/expression.js +15 -17
  70. package/src/http.js +4 -4
  71. package/src/package.json +1 -0
  72. package/src/reactive.js +75 -9
  73. package/src/router.js +104 -24
  74. package/src/ssr.js +133 -39
  75. package/src/store.js +103 -21
  76. package/src/utils.js +64 -12
  77. package/tests/audit.test.js +143 -15
  78. package/tests/cli.test.js +20 -20
  79. package/tests/component.test.js +121 -121
  80. package/tests/core.test.js +56 -56
  81. package/tests/diff.test.js +42 -42
  82. package/tests/errors.test.js +425 -147
  83. package/tests/expression.test.js +58 -53
  84. package/tests/http.test.js +20 -20
  85. package/tests/reactive.test.js +185 -24
  86. package/tests/router.test.js +501 -74
  87. package/tests/ssr.test.js +444 -10
  88. package/tests/store.test.js +264 -23
  89. package/tests/utils.test.js +163 -26
  90. package/types/collection.d.ts +2 -2
  91. package/types/component.d.ts +5 -5
  92. package/types/errors.d.ts +36 -4
  93. package/types/http.d.ts +3 -3
  94. package/types/misc.d.ts +9 -9
  95. package/types/reactive.d.ts +25 -3
  96. package/types/router.d.ts +10 -6
  97. package/types/ssr.d.ts +22 -2
  98. package/types/store.d.ts +40 -5
  99. package/types/utils.d.ts +1 -1
@@ -25,7 +25,7 @@ beforeEach(() => {
25
25
 
26
26
 
27
27
  // ---------------------------------------------------------------------------
28
- // query() single selector
28
+ // query() - single selector
29
29
  // ---------------------------------------------------------------------------
30
30
 
31
31
  describe('query()', () => {
@@ -79,7 +79,7 @@ describe('query()', () => {
79
79
 
80
80
 
81
81
  // ---------------------------------------------------------------------------
82
- // queryAll() collection selector
82
+ // queryAll() - collection selector
83
83
  // ---------------------------------------------------------------------------
84
84
 
85
85
  describe('queryAll()', () => {
@@ -362,7 +362,7 @@ describe('ZQueryCollection', () => {
362
362
  const ref = main.children[0]; // grab DOM reference
363
363
  const col = queryAll('#main');
364
364
  col.html('<p id="preserved">new text</p>');
365
- // Same DOM node preserved morph, not innerHTML replace
365
+ // Same DOM node preserved - morph, not innerHTML replace
366
366
  expect(main.children[0]).toBe(ref);
367
367
  expect(main.children[0].textContent).toBe('new text');
368
368
  });
@@ -381,7 +381,7 @@ describe('ZQueryCollection', () => {
381
381
  const ref = main.children[0];
382
382
  const col = queryAll('#main');
383
383
  col.empty().html('<p id="old">replaced</p>');
384
- // NOT the same node empty() cleared children, so html() used innerHTML
384
+ // NOT the same node - empty() cleared children, so html() used innerHTML
385
385
  expect(main.children[0]).not.toBe(ref);
386
386
  expect(main.children[0].textContent).toBe('replaced');
387
387
  });
@@ -547,7 +547,7 @@ describe('query quick refs', () => {
547
547
  expect(el.textContent).toBe('text');
548
548
  });
549
549
 
550
- // qs / qsa raw DOM shortcuts
550
+ // qs / qsa - raw DOM shortcuts
551
551
  it('$.qs() returns raw element by CSS selector', () => {
552
552
  const el = query.qs('#main');
553
553
  expect(el).toBe(document.getElementById('main'));
@@ -792,7 +792,7 @@ describe('CSS dimension methods', () => {
792
792
  // prop() method
793
793
  // ---------------------------------------------------------------------------
794
794
 
795
- describe('ZQueryCollection prop()', () => {
795
+ describe('ZQueryCollection - prop()', () => {
796
796
  it('gets a DOM property', () => {
797
797
  document.body.innerHTML = '<input type="checkbox" checked>';
798
798
  const col = queryAll('input');
@@ -821,7 +821,7 @@ describe('ZQueryCollection — prop()', () => {
821
821
  // css() method
822
822
  // ---------------------------------------------------------------------------
823
823
 
824
- describe('ZQueryCollection css()', () => {
824
+ describe('ZQueryCollection - css()', () => {
825
825
  beforeEach(() => {
826
826
  document.body.innerHTML = '<div id="styled">test</div>';
827
827
  });
@@ -843,7 +843,7 @@ describe('ZQueryCollection — css()', () => {
843
843
  // val() method
844
844
  // ---------------------------------------------------------------------------
845
845
 
846
- describe('ZQueryCollection val()', () => {
846
+ describe('ZQueryCollection - val()', () => {
847
847
  it('gets input value', () => {
848
848
  document.body.innerHTML = '<input value="test">';
849
849
  expect(queryAll('input').val()).toBe('test');
@@ -871,7 +871,7 @@ describe('ZQueryCollection — val()', () => {
871
871
  // after(), before() methods
872
872
  // ---------------------------------------------------------------------------
873
873
 
874
- describe('ZQueryCollection after() / before()', () => {
874
+ describe('ZQueryCollection - after() / before()', () => {
875
875
  beforeEach(() => {
876
876
  document.body.innerHTML = '<div id="container"><p id="target">target</p></div>';
877
877
  });
@@ -894,7 +894,7 @@ describe('ZQueryCollection — after() / before()', () => {
894
894
  // wrap() method
895
895
  // ---------------------------------------------------------------------------
896
896
 
897
- describe('ZQueryCollection wrap()', () => {
897
+ describe('ZQueryCollection - wrap()', () => {
898
898
  it('wraps element in new parent', () => {
899
899
  document.body.innerHTML = '<div id="container"><p id="target">text</p></div>';
900
900
  queryAll('#target').wrap('<div class="wrapper"></div>');
@@ -909,7 +909,7 @@ describe('ZQueryCollection — wrap()', () => {
909
909
  // replaceWith() method
910
910
  // ---------------------------------------------------------------------------
911
911
 
912
- describe('ZQueryCollection replaceWith()', () => {
912
+ describe('ZQueryCollection - replaceWith()', () => {
913
913
  it('replaces element with new content', () => {
914
914
  document.body.innerHTML = '<div id="container"><p id="old">old</p></div>';
915
915
  queryAll('#old').replaceWith('<span id="new">new</span>');
@@ -921,7 +921,7 @@ describe('ZQueryCollection — replaceWith()', () => {
921
921
  document.body.innerHTML = '<div id="container"><p id="target" class="old">old text</p></div>';
922
922
  const target = document.querySelector('#target');
923
923
  queryAll('#target').replaceWith('<p id="target" class="new">new text</p>');
924
- // Same DOM node morphed, not replaced
924
+ // Same DOM node - morphed, not replaced
925
925
  expect(document.querySelector('#target')).toBe(target);
926
926
  expect(target.className).toBe('new');
927
927
  expect(target.textContent).toBe('new text');
@@ -941,7 +941,7 @@ describe('ZQueryCollection — replaceWith()', () => {
941
941
  // offset() and position()
942
942
  // ---------------------------------------------------------------------------
943
943
 
944
- describe('ZQueryCollection offset() / position()', () => {
944
+ describe('ZQueryCollection - offset() / position()', () => {
945
945
  it('offset() returns object with top and left', () => {
946
946
  document.body.innerHTML = '<div id="box">box</div>';
947
947
  const off = queryAll('#box').offset();
@@ -963,7 +963,7 @@ describe('ZQueryCollection — offset() / position()', () => {
963
963
  // width() and height()
964
964
  // ---------------------------------------------------------------------------
965
965
 
966
- describe('ZQueryCollection width() / height()', () => {
966
+ describe('ZQueryCollection - width() / height()', () => {
967
967
  it('width() returns a number', () => {
968
968
  document.body.innerHTML = '<div id="box" style="width:100px">box</div>';
969
969
  const val = queryAll('#box').width();
@@ -982,7 +982,7 @@ describe('ZQueryCollection — width() / height()', () => {
982
982
  // animate()
983
983
  // ---------------------------------------------------------------------------
984
984
 
985
- describe('ZQueryCollection animate()', () => {
985
+ describe('ZQueryCollection - animate()', () => {
986
986
  it('returns a promise', () => {
987
987
  document.body.innerHTML = '<div id="box">box</div>';
988
988
  const result = queryAll('#box').animate({ opacity: 0 }, 100);
@@ -1019,10 +1019,10 @@ describe('hover()', () => {
1019
1019
 
1020
1020
 
1021
1021
  // ---------------------------------------------------------------------------
1022
- // ZQueryCollection empty collection safety
1022
+ // ZQueryCollection - empty collection safety
1023
1023
  // ---------------------------------------------------------------------------
1024
1024
 
1025
- describe('ZQueryCollection empty collection operations', () => {
1025
+ describe('ZQueryCollection - empty collection operations', () => {
1026
1026
  it('first() returns null on empty', () => {
1027
1027
  expect(queryAll('.nonexistent').first()).toBeNull();
1028
1028
  });
@@ -1076,7 +1076,7 @@ describe('ZQueryCollection — empty collection operations', () => {
1076
1076
  // Collection wrapping edge cases
1077
1077
  // ---------------------------------------------------------------------------
1078
1078
 
1079
- describe('query wrapping edge cases', () => {
1079
+ describe('query - wrapping edge cases', () => {
1080
1080
  it('wraps an HTMLCollection', () => {
1081
1081
  const col = queryAll(document.getElementsByClassName('text'));
1082
1082
  expect(col).toBeInstanceOf(ZQueryCollection);
@@ -1115,7 +1115,7 @@ describe('query — wrapping edge cases', () => {
1115
1115
  // html() morphing advanced
1116
1116
  // ---------------------------------------------------------------------------
1117
1117
 
1118
- describe('ZQueryCollection html() morphing advanced', () => {
1118
+ describe('ZQueryCollection - html() morphing advanced', () => {
1119
1119
  it('morphs complex nested structure', () => {
1120
1120
  document.body.innerHTML = '<div id="m"><ul><li id="i1">old1</li><li id="i2">old2</li></ul></div>';
1121
1121
  const li1 = document.getElementById('i1');
@@ -1139,7 +1139,7 @@ describe('ZQueryCollection — html() morphing advanced', () => {
1139
1139
  // Event delegation
1140
1140
  // ---------------------------------------------------------------------------
1141
1141
 
1142
- describe('ZQueryCollection event delegation', () => {
1142
+ describe('ZQueryCollection - event delegation', () => {
1143
1143
  it('on() with selector delegates to matching children', () => {
1144
1144
  let clicked = null;
1145
1145
  queryAll('#nav').on('click', '.nav-item', function() { clicked = this.textContent; });
@@ -1160,7 +1160,7 @@ describe('ZQueryCollection — event delegation', () => {
1160
1160
  // Multiple class operations
1161
1161
  // ---------------------------------------------------------------------------
1162
1162
 
1163
- describe('ZQueryCollection multiple class operations', () => {
1163
+ describe('ZQueryCollection - multiple class operations', () => {
1164
1164
  it('addClass with space-separated classes', () => {
1165
1165
  const col = queryAll('#main');
1166
1166
  col.addClass('a', 'b', 'c');
@@ -1184,7 +1184,7 @@ describe('ZQueryCollection — multiple class operations', () => {
1184
1184
  // Traversal edge cases
1185
1185
  // ---------------------------------------------------------------------------
1186
1186
 
1187
- describe('ZQueryCollection traversal edge cases', () => {
1187
+ describe('ZQueryCollection - traversal edge cases', () => {
1188
1188
  it('find() returns empty when no descendants match', () => {
1189
1189
  expect(queryAll('#main').find('.nonexistent').length).toBe(0);
1190
1190
  });
@@ -1230,7 +1230,7 @@ describe('ZQueryCollection — traversal edge cases', () => {
1230
1230
  // DOM manipulation edge cases
1231
1231
  // ---------------------------------------------------------------------------
1232
1232
 
1233
- describe('ZQueryCollection DOM manipulation edge cases', () => {
1233
+ describe('ZQueryCollection - DOM manipulation edge cases', () => {
1234
1234
  it('append with element node', () => {
1235
1235
  const newEl = document.createElement('div');
1236
1236
  newEl.id = 'appended-el';
@@ -1272,7 +1272,7 @@ describe('ZQueryCollection — DOM manipulation edge cases', () => {
1272
1272
  // Attribute edge cases
1273
1273
  // ---------------------------------------------------------------------------
1274
1274
 
1275
- describe('ZQueryCollection attribute edge cases', () => {
1275
+ describe('ZQueryCollection - attribute edge cases', () => {
1276
1276
  it('attr() set with sequential calls sets multiple attributes', () => {
1277
1277
  document.body.innerHTML = '<div id="a"></div>';
1278
1278
  queryAll('#a').attr('data-x', '1').attr('data-y', '2').attr('title', 'test');
@@ -1296,7 +1296,7 @@ describe('ZQueryCollection — attribute edge cases', () => {
1296
1296
  // css() advanced
1297
1297
  // ---------------------------------------------------------------------------
1298
1298
 
1299
- describe('ZQueryCollection css() advanced', () => {
1299
+ describe('ZQueryCollection - css() advanced', () => {
1300
1300
  it('sets a single style property via object', () => {
1301
1301
  document.body.innerHTML = '<div id="s">test</div>';
1302
1302
  queryAll('#s').css({ color: 'green' });
@@ -1317,7 +1317,7 @@ describe('ZQueryCollection — css() advanced', () => {
1317
1317
  // $.create advanced
1318
1318
  // ---------------------------------------------------------------------------
1319
1319
 
1320
- describe('query.create advanced', () => {
1320
+ describe('query.create - advanced', () => {
1321
1321
  it('creates element with no attributes', () => {
1322
1322
  const col = query.create('span');
1323
1323
  expect(col.length).toBe(1);
@@ -1345,7 +1345,7 @@ describe('query.create — advanced', () => {
1345
1345
  // Prop edge cases
1346
1346
  // ---------------------------------------------------------------------------
1347
1347
 
1348
- describe('ZQueryCollection prop() edge cases', () => {
1348
+ describe('ZQueryCollection - prop() edge cases', () => {
1349
1349
  it('gets defaultValue property', () => {
1350
1350
  document.body.innerHTML = '<input value="initial">';
1351
1351
  const col = queryAll('input');
@@ -1367,7 +1367,7 @@ describe('ZQueryCollection — prop() edge cases', () => {
1367
1367
  // BUG FIX: siblings() with selector filtering + null parent guard
1368
1368
  // ---------------------------------------------------------------------------
1369
1369
 
1370
- describe('ZQueryCollection siblings() fixes', () => {
1370
+ describe('ZQueryCollection - siblings() fixes', () => {
1371
1371
  it('filters siblings by selector', () => {
1372
1372
  document.body.innerHTML = '<div><p class="a">1</p><p class="b">2</p><p class="a">3</p></div>';
1373
1373
  const sibs = queryAll('.b').siblings('.a');
@@ -1393,7 +1393,7 @@ describe('ZQueryCollection — siblings() fixes', () => {
1393
1393
  // BUG FIX: ZQueryCollection constructor null safety
1394
1394
  // ---------------------------------------------------------------------------
1395
1395
 
1396
- describe('ZQueryCollection constructor null/undefined safety', () => {
1396
+ describe('ZQueryCollection - constructor null/undefined safety', () => {
1397
1397
  it('creates empty collection from null', () => {
1398
1398
  const col = new ZQueryCollection(null);
1399
1399
  expect(col.length).toBe(0);
@@ -1417,7 +1417,7 @@ describe('ZQueryCollection — constructor null/undefined safety', () => {
1417
1417
  // BUG FIX: attr() with object syntax
1418
1418
  // ---------------------------------------------------------------------------
1419
1419
 
1420
- describe('ZQueryCollection attr() object set', () => {
1420
+ describe('ZQueryCollection - attr() object set', () => {
1421
1421
  it('sets multiple attributes with object', () => {
1422
1422
  document.body.innerHTML = '<div id="at"></div>';
1423
1423
  queryAll('#at').attr({ 'data-x': '1', 'data-y': '2', title: 'hello' });
@@ -1433,7 +1433,7 @@ describe('ZQueryCollection — attr() object set', () => {
1433
1433
  // BUG FIX: css() two-argument setter
1434
1434
  // ---------------------------------------------------------------------------
1435
1435
 
1436
- describe('ZQueryCollection css() two-argument setter', () => {
1436
+ describe('ZQueryCollection - css() two-argument setter', () => {
1437
1437
  it('sets a CSS property with key-value arguments', () => {
1438
1438
  document.body.innerHTML = '<div id="cs">text</div>';
1439
1439
  queryAll('#cs').css('color', 'green');
@@ -1460,7 +1460,7 @@ describe('ZQueryCollection — css() two-argument setter', () => {
1460
1460
  // BUG FIX: wrap() does not crash on empty/invalid wrapper
1461
1461
  // ---------------------------------------------------------------------------
1462
1462
 
1463
- describe('ZQueryCollection wrap() safety', () => {
1463
+ describe('ZQueryCollection - wrap() safety', () => {
1464
1464
  it('does not crash if wrapper string is empty', () => {
1465
1465
  document.body.innerHTML = '<div id="w"><p>inside</p></div>';
1466
1466
  expect(() => queryAll('#w p').wrap('')).not.toThrow();
@@ -1478,7 +1478,7 @@ describe('ZQueryCollection — wrap() safety', () => {
1478
1478
  // BUG FIX: index() does not crash on detached element
1479
1479
  // ---------------------------------------------------------------------------
1480
1480
 
1481
- describe('ZQueryCollection index() null parent safety', () => {
1481
+ describe('ZQueryCollection - index() null parent safety', () => {
1482
1482
  it('returns -1 for detached element', () => {
1483
1483
  const detached = document.createElement('div');
1484
1484
  const col = new ZQueryCollection([detached]);
@@ -1491,7 +1491,7 @@ describe('ZQueryCollection — index() null parent safety', () => {
1491
1491
  // BUG FIX: delegated on() / off() handler removal
1492
1492
  // ---------------------------------------------------------------------------
1493
1493
 
1494
- describe('ZQueryCollection delegated on/off', () => {
1494
+ describe('ZQueryCollection - delegated on/off', () => {
1495
1495
  it('off() removes delegated event handlers', () => {
1496
1496
  document.body.innerHTML = '<div id="parent"><button class="btn">click</button></div>';
1497
1497
  const parent = new ZQueryCollection([document.getElementById('parent')]);
@@ -1513,7 +1513,7 @@ describe('ZQueryCollection — delegated on/off', () => {
1513
1513
  // BUG FIX: animate() resolves immediately on empty collection
1514
1514
  // ---------------------------------------------------------------------------
1515
1515
 
1516
- describe('ZQueryCollection animate() empty collection', () => {
1516
+ describe('ZQueryCollection - animate() empty collection', () => {
1517
1517
  it('resolves immediately when collection is empty', async () => {
1518
1518
  const col = new ZQueryCollection([]);
1519
1519
  const result = await col.animate({ opacity: '0' }, 50);
@@ -1523,10 +1523,10 @@ describe('ZQueryCollection — animate() empty collection', () => {
1523
1523
 
1524
1524
 
1525
1525
  // ===========================================================================
1526
- // one() single-fire event listener
1526
+ // one() - single-fire event listener
1527
1527
  // ===========================================================================
1528
1528
 
1529
- describe('ZQueryCollection one()', () => {
1529
+ describe('ZQueryCollection - one()', () => {
1530
1530
  it('fires handler only once', () => {
1531
1531
  const handler = vi.fn();
1532
1532
  document.body.innerHTML = '<button id="one-btn">click</button>';
@@ -1540,10 +1540,10 @@ describe('ZQueryCollection — one()', () => {
1540
1540
 
1541
1541
 
1542
1542
  // ===========================================================================
1543
- // toggle() show/hide toggle
1543
+ // toggle() - show/hide toggle
1544
1544
  // ===========================================================================
1545
1545
 
1546
- describe('ZQueryCollection toggle()', () => {
1546
+ describe('ZQueryCollection - toggle()', () => {
1547
1547
  it('hides a visible element', () => {
1548
1548
  const el = document.querySelector('#main');
1549
1549
  el.style.display = '';
@@ -1574,7 +1574,7 @@ describe('ZQueryCollection — toggle()', () => {
1574
1574
  // serialize() and serializeObject()
1575
1575
  // ===========================================================================
1576
1576
 
1577
- describe('ZQueryCollection serialize()', () => {
1577
+ describe('ZQueryCollection - serialize()', () => {
1578
1578
  it('serializes form inputs to URL-encoded string', () => {
1579
1579
  document.body.innerHTML = '<form id="f"><input name="user" value="Alice"><input name="age" value="30"></form>';
1580
1580
  const result = query('#f').serialize();
@@ -1587,7 +1587,7 @@ describe('ZQueryCollection — serialize()', () => {
1587
1587
  });
1588
1588
  });
1589
1589
 
1590
- describe('ZQueryCollection serializeObject()', () => {
1590
+ describe('ZQueryCollection - serializeObject()', () => {
1591
1591
  it('builds an object from form fields', () => {
1592
1592
  document.body.innerHTML = '<form id="f"><input name="user" value="Alice"><input name="age" value="30"></form>';
1593
1593
  expect(query('#f').serializeObject()).toEqual({ user: 'Alice', age: '30' });
@@ -1681,10 +1681,10 @@ describe('$.create', () => {
1681
1681
 
1682
1682
 
1683
1683
  // ===========================================================================
1684
- // data() no key returns full dataset
1684
+ // data() - no key returns full dataset
1685
1685
  // ===========================================================================
1686
1686
 
1687
- describe('ZQueryCollection data() full dataset', () => {
1687
+ describe('ZQueryCollection - data() full dataset', () => {
1688
1688
  it('returns the full dataset when no key is given', () => {
1689
1689
  document.body.innerHTML = '<div id="d" data-x="1" data-y="2"></div>';
1690
1690
  const ds = query('#d').data();
@@ -1698,7 +1698,7 @@ describe('ZQueryCollection — data() full dataset', () => {
1698
1698
  // css() getter on empty collection
1699
1699
  // ===========================================================================
1700
1700
 
1701
- describe('ZQueryCollection css() empty collection', () => {
1701
+ describe('ZQueryCollection - css() empty collection', () => {
1702
1702
  it('returns undefined when collection is empty', () => {
1703
1703
  const col = new ZQueryCollection([]);
1704
1704
  expect(col.css('color')).toBeUndefined();
@@ -1710,7 +1710,7 @@ describe('ZQueryCollection — css() empty collection', () => {
1710
1710
  // append/prepend/after/before with Node
1711
1711
  // ===========================================================================
1712
1712
 
1713
- describe('ZQueryCollection append/prepend with Node', () => {
1713
+ describe('ZQueryCollection - append/prepend with Node', () => {
1714
1714
  it('appends a Node element', () => {
1715
1715
  document.body.innerHTML = '<div id="container"><p>existing</p></div>';
1716
1716
  const newNode = document.createElement('span');
@@ -1736,7 +1736,7 @@ describe('ZQueryCollection — append/prepend with Node', () => {
1736
1736
  });
1737
1737
  });
1738
1738
 
1739
- describe('ZQueryCollection after/before with Node', () => {
1739
+ describe('ZQueryCollection - after/before with Node', () => {
1740
1740
  it('inserts Node after element', () => {
1741
1741
  document.body.innerHTML = '<div id="anchor"></div>';
1742
1742
  const newNode = document.createElement('span');
@@ -1759,7 +1759,7 @@ describe('ZQueryCollection — after/before with Node', () => {
1759
1759
  // replaceWith using Node
1760
1760
  // ===========================================================================
1761
1761
 
1762
- describe('ZQueryCollection replaceWith(Node)', () => {
1762
+ describe('ZQueryCollection - replaceWith(Node)', () => {
1763
1763
  it('replaces element with a Node', () => {
1764
1764
  document.body.innerHTML = '<div id="old">old</div>';
1765
1765
  const newNode = document.createElement('span');
@@ -1776,7 +1776,7 @@ describe('ZQueryCollection — replaceWith(Node)', () => {
1776
1776
  // nextUntil/prevUntil/parentsUntil with filter
1777
1777
  // ===========================================================================
1778
1778
 
1779
- describe('ZQueryCollection nextUntil with filter', () => {
1779
+ describe('ZQueryCollection - nextUntil with filter', () => {
1780
1780
  it('collects siblings until stop selector, applying filter', () => {
1781
1781
  document.body.innerHTML = '<div id="start"></div><span class="a">A</span><p>P</p><span class="a">A2</span><div id="stop"></div>';
1782
1782
  const result = query('#start').nextUntil('#stop', 'span');
@@ -1784,7 +1784,7 @@ describe('ZQueryCollection — nextUntil with filter', () => {
1784
1784
  });
1785
1785
  });
1786
1786
 
1787
- describe('ZQueryCollection prevUntil with filter', () => {
1787
+ describe('ZQueryCollection - prevUntil with filter', () => {
1788
1788
  it('collects previous siblings until stop selector, applying filter', () => {
1789
1789
  document.body.innerHTML = '<div id="stop"></div><span>A</span><p>P</p><span>B</span><div id="end"></div>';
1790
1790
  const result = query('#end').prevUntil('#stop', 'span');
@@ -1792,7 +1792,7 @@ describe('ZQueryCollection — prevUntil with filter', () => {
1792
1792
  });
1793
1793
  });
1794
1794
 
1795
- describe('ZQueryCollection parentsUntil with filter', () => {
1795
+ describe('ZQueryCollection - parentsUntil with filter', () => {
1796
1796
  it('collects parent elements until stop selector, applying filter', () => {
1797
1797
  document.body.innerHTML = '<section><article><div><span id="target"></span></div></article></section>';
1798
1798
  const result = query('#target').parentsUntil('section', 'div');
@@ -1806,7 +1806,7 @@ describe('ZQueryCollection — parentsUntil with filter', () => {
1806
1806
  // delegated on() at document level
1807
1807
  // ===========================================================================
1808
1808
 
1809
- describe('ZQueryCollection delegated on()', () => {
1809
+ describe('ZQueryCollection - delegated on()', () => {
1810
1810
  it('delegates event to matching child selector', () => {
1811
1811
  document.body.innerHTML = '<div id="container"><button class="action">click</button></div>';
1812
1812
  const handler = vi.fn();
@@ -1829,7 +1829,7 @@ describe('ZQueryCollection — delegated on()', () => {
1829
1829
  // Multi-event on/off
1830
1830
  // ===========================================================================
1831
1831
 
1832
- describe('ZQueryCollection multi-event on()', () => {
1832
+ describe('ZQueryCollection - multi-event on()', () => {
1833
1833
  it('binds handler to multiple space-separated events', () => {
1834
1834
  document.body.innerHTML = '<input id="inp" type="text">';
1835
1835
  const handler = vi.fn();
@@ -1845,7 +1845,7 @@ describe('ZQueryCollection — multi-event on()', () => {
1845
1845
  // scrollTop/scrollLeft getters
1846
1846
  // ===========================================================================
1847
1847
 
1848
- describe('ZQueryCollection scrollTop/scrollLeft', () => {
1848
+ describe('ZQueryCollection - scrollTop/scrollLeft', () => {
1849
1849
  it('gets and sets scrollTop', () => {
1850
1850
  document.body.innerHTML = '<div id="scr" style="overflow:auto; height: 50px;"><div style="height:200px;">x</div></div>';
1851
1851
  const el = document.querySelector('#scr');
@@ -1865,7 +1865,7 @@ describe('ZQueryCollection — scrollTop/scrollLeft', () => {
1865
1865
  // slideDown/slideUp set styles
1866
1866
  // ===========================================================================
1867
1867
 
1868
- describe('ZQueryCollection slideDown/slideUp', () => {
1868
+ describe('ZQueryCollection - slideDown/slideUp', () => {
1869
1869
  it('slideDown sets overflow hidden and maxHeight initially', () => {
1870
1870
  vi.useFakeTimers();
1871
1871
  document.body.innerHTML = '<div id="slide" style="display:none;">content</div>';
@@ -1893,7 +1893,7 @@ describe('ZQueryCollection — slideDown/slideUp', () => {
1893
1893
  // fadeIn/fadeOut set opacity
1894
1894
  // ===========================================================================
1895
1895
 
1896
- describe('ZQueryCollection fadeIn/fadeOut', () => {
1896
+ describe('ZQueryCollection - fadeIn/fadeOut', () => {
1897
1897
  it('fadeIn sets initial opacity to 0', () => {
1898
1898
  document.body.innerHTML = '<div id="fade" style="display:none;">content</div>';
1899
1899
  query('#fade').fadeIn(100);
@@ -1904,7 +1904,7 @@ describe('ZQueryCollection — fadeIn/fadeOut', () => {
1904
1904
  it('fadeTo animates to specified opacity', () => {
1905
1905
  document.body.innerHTML = '<div id="fade">content</div>';
1906
1906
  query('#fade').fadeTo(100, 0.5);
1907
- // Animation starts just verify no throw
1907
+ // Animation starts - just verify no throw
1908
1908
  expect(document.querySelector('#fade')).not.toBeNull();
1909
1909
  });
1910
1910
  });