ripple 0.2.44 → 0.2.46

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.
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
2
  import { mount, flushSync, effect, untrack, RippleArray } from 'ripple';
3
- import { ARRAY_SET_INDEX_AT } from '../src/runtime/internal/client/constants.js';
3
+ import { ARRAY_SET_INDEX_AT, MAX_ARRAY_LENGTH } from '../src/runtime/internal/client/constants.js';
4
4
 
5
5
  describe('RippleArray', () => {
6
6
  let container;
@@ -1244,37 +1244,34 @@ describe('RippleArray', () => {
1244
1244
  expect(container.querySelector('pre').textContent).toBe('Cannot set length on RippleArray, use $length instead');
1245
1245
  });
1246
1246
 
1247
- ('fromAsync' in Array.prototype ? describe : describe.skip)('RippleArray fromAsync', () => {
1247
+ ('fromAsync' in Array.prototype ? describe : describe.skip)('RippleArray fromAsync', async () => {
1248
1248
  it('handles static fromAsync method with reactivity', async () => {
1249
- component ArrayTest() {
1250
- let itemsPromise = RippleArray.fromAsync(Promise.resolve([1, 2, 3]));
1251
- let items = null;
1252
- let error = null;
1253
-
1249
+ component Parent() {
1254
1250
  try {
1255
- items = await itemsPromise;
1256
- } catch (e) {
1257
- error = e.message;
1251
+ <ArrayTest />
1252
+ } async {
1253
+ <div>{'Loading placeholder...'}</div>
1258
1254
  }
1255
+ }
1256
+
1257
+ component ArrayTest() {
1258
+ let items = await RippleArray.fromAsync([1, 2, 3]);
1259
1259
 
1260
1260
  <button onClick={() => {
1261
- if (items) items.push(4);
1261
+ if (items) items.push(4);
1262
1262
  }}>{'add item'}</button>
1263
- <pre>{error ? 'Error: ' + error : 'Loaded'}</pre>
1264
- <pre>{items ? JSON.stringify(items) : 'Loading...'}</pre>
1263
+
1264
+ <pre>{JSON.stringify(items)}</pre>
1265
1265
  }
1266
1266
 
1267
- render(ArrayTest);
1267
+ render(Parent);
1268
1268
 
1269
- // Wait for promise to resolve
1270
- await new Promise(resolve => setTimeout(resolve, 50));
1269
+ await new Promise(resolve => setTimeout(resolve, 0));
1271
1270
  flushSync();
1272
1271
 
1273
1272
  const addButton = container.querySelector('button');
1274
1273
 
1275
- // Check that the promise resolved correctly
1276
- expect(container.querySelectorAll('pre')[0].textContent).toBe('Loaded');
1277
- expect(container.querySelectorAll('pre')[1].textContent).toBe('[1,2,3]');
1274
+ expect(container.querySelectorAll('pre')[0].textContent).toBe('[1,2,3]');
1278
1275
 
1279
1276
  // Test adding an item to the async-created array
1280
1277
  addButton.click();
@@ -1284,33 +1281,35 @@ describe('RippleArray', () => {
1284
1281
  });
1285
1282
 
1286
1283
  it('handles static fromAsync method with mapping function', async () => {
1284
+ component Parent() {
1285
+ try {
1286
+ <ArrayTest />
1287
+ } async {
1288
+ <div>{'Loading placeholder...'}</div>
1289
+ }
1290
+ }
1291
+
1287
1292
  component ArrayTest() {
1288
- let itemsPromise = RippleArray.fromAsync(
1289
- Promise.resolve([1, 2, 3]),
1290
- x => x * 2
1293
+ let items = await RippleArray.fromAsync(
1294
+ [1, 2, 3],
1295
+ x => x * 2
1291
1296
  );
1292
- let items = null;
1293
-
1294
- items = await itemsPromise;
1295
1297
 
1296
1298
  <button onClick={() => {
1297
- if (items) items.push(8);
1299
+ if (items) items.push(8);
1298
1300
  }}>{'add item'}</button>
1299
1301
  <pre>{items ? JSON.stringify(items) : 'Loading...'}</pre>
1300
1302
  }
1301
1303
 
1302
- render(ArrayTest);
1304
+ render(Parent);
1303
1305
 
1304
- // Wait for promise to resolve
1305
- await new Promise(resolve => setTimeout(resolve, 50));
1306
+ await new Promise(resolve => setTimeout(resolve, 0));
1306
1307
  flushSync();
1307
1308
 
1308
1309
  const addButton = container.querySelector('button');
1309
1310
 
1310
- // Check that the promise resolved correctly with mapping applied
1311
1311
  expect(container.querySelector('pre').textContent).toBe('[2,4,6]');
1312
1312
 
1313
- // Test adding an item to the async-created array
1314
1313
  addButton.click();
1315
1314
  flushSync();
1316
1315
 
@@ -1318,13 +1317,20 @@ describe('RippleArray', () => {
1318
1317
  });
1319
1318
 
1320
1319
  it('handles error in fromAsync method', async () => {
1320
+ component Parent() {
1321
+ try {
1322
+ <ArrayTest />
1323
+ } async {
1324
+ <div>{'Loading placeholder...'}</div>
1325
+ }
1326
+ }
1327
+
1321
1328
  component ArrayTest() {
1322
- let itemsPromise = RippleArray.fromAsync(Promise.reject(new Error('Async error')));
1323
1329
  let items = null;
1324
1330
  let error = null;
1325
1331
 
1326
1332
  try {
1327
- items = await itemsPromise;
1333
+ items = await RippleArray.fromAsync(Promise.reject(new Error('Async error')));
1328
1334
  } catch (e) {
1329
1335
  error = e.message;
1330
1336
  }
@@ -1333,13 +1339,11 @@ describe('RippleArray', () => {
1333
1339
  <pre>{items ? JSON.stringify(items) : 'No items'}</pre>
1334
1340
  }
1335
1341
 
1336
- render(ArrayTest);
1342
+ render(Parent);
1337
1343
 
1338
- // Wait for promise to reject
1339
- await new Promise(resolve => setTimeout(resolve, 50));
1344
+ await new Promise(resolve => setTimeout(resolve, 0));
1340
1345
  flushSync();
1341
1346
 
1342
- // Check that the error was caught correctly
1343
1347
  expect(container.querySelectorAll('pre')[0].textContent).toBe('Error: Async error');
1344
1348
  expect(container.querySelectorAll('pre')[1].textContent).toBe('No items');
1345
1349
  });
@@ -1463,6 +1467,90 @@ describe('RippleArray', () => {
1463
1467
  expect(container.querySelectorAll('pre')[5].textContent).toBe('items[4]: 4');
1464
1468
  });
1465
1469
  });
1470
+
1471
+ describe('Creates RippleArray with a single element', () => {
1472
+ it('specifies int', () => {
1473
+ component ArrayTest() {
1474
+ let items = new RippleArray(3);
1475
+ <pre>{JSON.stringify(items)}</pre>
1476
+ <pre>{items.$length}</pre>
1477
+ }
1478
+
1479
+ render(ArrayTest);
1480
+
1481
+ expect(container.querySelectorAll('pre')[0].textContent).toBe('[null,null,null]');
1482
+ expect(container.querySelectorAll('pre')[1].textContent).toBe('3');
1483
+ });
1484
+
1485
+ it('errors on exceeding max array size', () => {
1486
+ component ArrayTest() {
1487
+ let error = null;
1488
+
1489
+ try {
1490
+ new RippleArray(MAX_ARRAY_LENGTH + 1);
1491
+ } catch (e) {
1492
+ error = e.message;
1493
+ }
1494
+
1495
+ <pre>{error}</pre>
1496
+ }
1497
+
1498
+ render(ArrayTest);
1499
+
1500
+ expect(container.querySelector('pre').textContent).toBe('Invalid array length');
1501
+ });
1502
+
1503
+ it('specifies int using static from method', () => {
1504
+ component ArrayTest() {
1505
+ let items = RippleArray.from([4]);
1506
+ <pre>{JSON.stringify(items)}</pre>
1507
+ <pre>{items.$length}</pre>
1508
+ }
1509
+
1510
+ render(ArrayTest);
1511
+
1512
+ expect(container.querySelectorAll('pre')[0].textContent).toBe('[4]');
1513
+ // expect(container.querySelectorAll('pre')[1].textContent).toBe('1');
1514
+ });
1515
+
1516
+ it('specifies int using static of method', () => {
1517
+ component ArrayTest() {
1518
+ let items = RippleArray.of(5);
1519
+ <pre>{JSON.stringify(items)}</pre>
1520
+ <pre>{items.$length}</pre>
1521
+ }
1522
+
1523
+ render(ArrayTest);
1524
+
1525
+ expect(container.querySelectorAll('pre')[0].textContent).toBe('[5]');
1526
+ expect(container.querySelectorAll('pre')[1].textContent).toBe('1');
1527
+ });
1528
+
1529
+ ('fromAsync' in Array.prototype ? it : it.skip)('specifies int using static fromAsync method', async () => {
1530
+ component Parent() {
1531
+ try {
1532
+ <ArrayTest />
1533
+ } async {
1534
+ <div>{'Loading placeholder...'}</div>
1535
+ }
1536
+ }
1537
+
1538
+ component ArrayTest() {
1539
+ const items = await RippleArray.fromAsync([6]);
1540
+
1541
+ <pre>{items ? JSON.stringify(items) : 'Loading...'}</pre>
1542
+ <pre>{items ? items.$length : ''}</pre>
1543
+ }
1544
+
1545
+ render(Parent);
1546
+
1547
+ await new Promise(resolve => setTimeout(resolve, 0));
1548
+ flushSync();
1549
+
1550
+ expect(container.querySelectorAll('pre')[0].textContent).toBe('[6]');
1551
+ expect(container.querySelectorAll('pre')[1].textContent).toBe('1');
1552
+ });
1553
+ });
1466
1554
  });
1467
1555
 
1468
1556
 
@@ -115,6 +115,12 @@ describe('basic', () => {
115
115
 
116
116
  <button onClick={() => $active = !$active}>{'Toggle'}</button>
117
117
  <div $class={$active ? 'active' : 'inactive'}>{'Dynamic Class'}</div>
118
+
119
+ <style>
120
+ .active {
121
+ color: green;
122
+ }
123
+ </style>
118
124
  }
119
125
 
120
126
  render(Basic);
@@ -122,17 +128,17 @@ describe('basic', () => {
122
128
  const button = container.querySelector('button');
123
129
  const div = container.querySelector('div');
124
130
 
125
- expect(div.className).toBe('inactive');
126
-
131
+ expect(Array.from(div.classList).some(className => className.startsWith('ripple-'))).toBe(true);
132
+ expect(div.classList.contains('inactive')).toBe(true);
133
+
127
134
  button.click();
128
135
  flushSync();
129
-
130
- expect(div.className).toBe('active');
136
+ expect(div.classList.contains('active')).toBe(true);
131
137
 
132
138
  button.click();
133
139
  flushSync();
134
140
 
135
- expect(div.className).toBe('inactive');
141
+ expect(div.classList.contains('inactive')).toBe(true);
136
142
  });
137
143
 
138
144
  it('render dynamic id attribute', () => {