|
|
@ -1,14 +1,28 @@
|
|
|
|
import { describe, assert, it } from 'vitest';
|
|
|
|
import { describe, assert, it } from 'vitest';
|
|
|
|
import * as $ from '../../src/internal/client/runtime';
|
|
|
|
import * as $ from '../../src/internal/client/runtime';
|
|
|
|
|
|
|
|
|
|
|
|
function run_test(runes: boolean, fn: () => void) {
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @param runes runes mode
|
|
|
|
|
|
|
|
* @param fn A function that returns a function because we first need to setup all the signals
|
|
|
|
|
|
|
|
* and then execute the test in order to simulate a real component
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function run_test(runes: boolean, fn: () => () => void) {
|
|
|
|
return () => {
|
|
|
|
return () => {
|
|
|
|
// Create a component context to test runes vs legacy mode
|
|
|
|
// Create a component context to test runes vs legacy mode
|
|
|
|
$.push({}, runes);
|
|
|
|
$.push({}, runes);
|
|
|
|
// Create a render context so that effect validations etc don't fail
|
|
|
|
// Create a render context so that effect validations etc don't fail
|
|
|
|
const signal = $.render_effect(fn, null, true, true);
|
|
|
|
let execute: any;
|
|
|
|
$.destroy_signal(signal);
|
|
|
|
const signal = $.render_effect(
|
|
|
|
|
|
|
|
() => {
|
|
|
|
|
|
|
|
execute = fn();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
null,
|
|
|
|
|
|
|
|
true,
|
|
|
|
|
|
|
|
true
|
|
|
|
|
|
|
|
);
|
|
|
|
$.pop();
|
|
|
|
$.pop();
|
|
|
|
|
|
|
|
execute();
|
|
|
|
|
|
|
|
$.destroy_signal(signal);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -23,14 +37,16 @@ describe('signals', () => {
|
|
|
|
|
|
|
|
|
|
|
|
let count = $.source(0);
|
|
|
|
let count = $.source(0);
|
|
|
|
let double = $.derived(() => $.get(count) * 2);
|
|
|
|
let double = $.derived(() => $.get(count) * 2);
|
|
|
|
|
|
|
|
|
|
|
|
$.effect(() => {
|
|
|
|
$.effect(() => {
|
|
|
|
log.push(`${$.get(count)}:${$.get(double)}`);
|
|
|
|
log.push(`${$.get(count)}:${$.get(double)}`);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert.deepEqual(log, ['0:0', '1:2', '2:4']);
|
|
|
|
return () => {
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert.deepEqual(log, ['0:0', '1:2', '2:4']);
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('multiple effects with state and derived in it#1', () => {
|
|
|
|
test('multiple effects with state and derived in it#1', () => {
|
|
|
@ -46,10 +62,12 @@ describe('signals', () => {
|
|
|
|
log.push(`B:${$.get(double)}`);
|
|
|
|
log.push(`B:${$.get(double)}`);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
return () => {
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
|
|
|
|
|
|
|
|
assert.deepEqual(log, ['A:0:0', 'B:0', 'A:1:2', 'B:2', 'A:2:4', 'B:4']);
|
|
|
|
assert.deepEqual(log, ['A:0:0', 'B:0', 'A:1:2', 'B:2', 'A:2:4', 'B:4']);
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('multiple effects with state and derived in it#2', () => {
|
|
|
|
test('multiple effects with state and derived in it#2', () => {
|
|
|
@ -65,10 +83,12 @@ describe('signals', () => {
|
|
|
|
log.push(`B:${$.get(count)}:${$.get(double)}`);
|
|
|
|
log.push(`B:${$.get(count)}:${$.get(double)}`);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
return () => {
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
|
|
|
|
|
|
|
|
assert.deepEqual(log, ['A:0', 'B:0:0', 'A:2', 'B:1:2', 'A:4', 'B:2:4']);
|
|
|
|
assert.deepEqual(log, ['A:0', 'B:0:0', 'A:2', 'B:1:2', 'A:4', 'B:2:4']);
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('derived from state', () => {
|
|
|
|
test('derived from state', () => {
|
|
|
@ -80,10 +100,13 @@ describe('signals', () => {
|
|
|
|
$.effect(() => {
|
|
|
|
$.effect(() => {
|
|
|
|
log.push($.get(double));
|
|
|
|
log.push($.get(double));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert.deepEqual(log, [0, 2, 4]);
|
|
|
|
return () => {
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert.deepEqual(log, [0, 2, 4]);
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('derived from derived', () => {
|
|
|
|
test('derived from derived', () => {
|
|
|
@ -96,10 +119,13 @@ describe('signals', () => {
|
|
|
|
$.effect(() => {
|
|
|
|
$.effect(() => {
|
|
|
|
log.push($.get(quadruple));
|
|
|
|
log.push($.get(quadruple));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert.deepEqual(log, [0, 4, 8]);
|
|
|
|
return () => {
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 1));
|
|
|
|
|
|
|
|
$.flushSync(() => $.set(count, 2));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert.deepEqual(log, [0, 4, 8]);
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('https://perf.js.hyoo.ru/#!bench=9h2as6_u0mfnn', () => {
|
|
|
|
test('https://perf.js.hyoo.ru/#!bench=9h2as6_u0mfnn', () => {
|
|
|
@ -116,31 +142,33 @@ describe('signals', () => {
|
|
|
|
const E = $.derived(() => hard($.get(C) + $.get(A) + $.get(D)[0]!, 'E'));
|
|
|
|
const E = $.derived(() => hard($.get(C) + $.get(A) + $.get(D)[0]!, 'E'));
|
|
|
|
const F = $.derived(() => hard($.get(D)[0]! && $.get(B), 'F'));
|
|
|
|
const F = $.derived(() => hard($.get(D)[0]! && $.get(B), 'F'));
|
|
|
|
const G = $.derived(() => $.get(C) + ($.get(C) || $.get(E) % 2) + $.get(D)[0]! + $.get(F));
|
|
|
|
const G = $.derived(() => $.get(C) + ($.get(C) || $.get(E) % 2) + $.get(D)[0]! + $.get(F));
|
|
|
|
let H = $.effect(() => {
|
|
|
|
$.effect(() => {
|
|
|
|
res.push(hard($.get(G), 'H'));
|
|
|
|
res.push(hard($.get(G), 'H'));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
let I = $.effect(() => {
|
|
|
|
$.effect(() => {
|
|
|
|
res.push($.get(G));
|
|
|
|
res.push($.get(G));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
let J = $.effect(() => {
|
|
|
|
$.effect(() => {
|
|
|
|
res.push(hard($.get(F), 'J'));
|
|
|
|
res.push(hard($.get(F), 'J'));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
$.flushSync();
|
|
|
|
return () => {
|
|
|
|
|
|
|
|
|
|
|
|
let i = 2;
|
|
|
|
|
|
|
|
while (--i) {
|
|
|
|
|
|
|
|
res.length = 0;
|
|
|
|
|
|
|
|
$.set(B, 1);
|
|
|
|
|
|
|
|
$.set(A, 1 + i * 2);
|
|
|
|
|
|
|
|
$.flushSync();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$.set(A, 2 + i * 2);
|
|
|
|
|
|
|
|
$.set(B, 2);
|
|
|
|
|
|
|
|
$.flushSync();
|
|
|
|
$.flushSync();
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(res.length, 4);
|
|
|
|
let i = 2;
|
|
|
|
assert.deepEqual(res, [3198, 1601, 3195, 1598]);
|
|
|
|
while (--i) {
|
|
|
|
}
|
|
|
|
res.length = 0;
|
|
|
|
|
|
|
|
$.set(B, 1);
|
|
|
|
|
|
|
|
$.set(A, 1 + i * 2);
|
|
|
|
|
|
|
|
$.flushSync();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$.set(A, 2 + i * 2);
|
|
|
|
|
|
|
|
$.set(B, 2);
|
|
|
|
|
|
|
|
$.flushSync();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert.equal(res.length, 4);
|
|
|
|
|
|
|
|
assert.deepEqual(res, [3198, 1601, 3195, 1598]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|