inula/packages/inula-reactive/tests/reactive.test.ts

192 lines
4.2 KiB
TypeScript

import { reactive, computed, watch } from '../src';
describe('test reactive', () => {
it('computation should work with two reactive', () => {
const a = reactive(7);
const b = reactive(1);
let callCount = 0;
const product = computed(() => {
callCount++;
return { value: a.get() * b.get() };
});
// computed should be lazy
expect(callCount).toBe(0);
expect(a.read()).toBe(7);
a.set(2);
expect(product.value.read()).toBe(2);
b.set(3);
expect(product.value.get()).toBe(6);
expect(callCount).toBe(2);
product.read();
// computed function should not be invoked
expect(callCount).toBe(2);
});
it('computations should be triggered when source is same reactive', () => {
const pos = reactive({ x: 0, y: 0 });
let xCalledTimes = 0;
let yCalledTimes = 0;
const x = computed(() => {
xCalledTimes++;
return pos.x.get();
});
const y = computed(() => {
yCalledTimes++;
return pos.y.get();
});
expect(x.read()).toBe(0);
expect(y.read()).toBe(0);
expect(xCalledTimes).toBe(1);
expect(yCalledTimes).toBe(1);
// when pos.x changed, x should be triggered and y should not
pos.x.set(1);
expect(x.read()).toBe(1);
expect(y.read()).toBe(0);
expect(xCalledTimes).toBe(2);
expect(yCalledTimes).toBe(1);
// when pos.y changed, y should be triggered and x should not
pos.y.set(1);
expect(x.read()).toBe(1);
expect(y.read()).toBe(1);
expect(xCalledTimes).toBe(2);
expect(yCalledTimes).toBe(2);
});
it('overwrite object reactive should keep reactive', () => {
const pos = reactive({ x: 0, y: 0 });
const xWatch = jest.fn();
watch(() => {
xWatch(pos.x.get());
});
const yWatch = jest.fn();
watch(() => {
yWatch(pos.y.get());
});
expect(xWatch).toBeCalledTimes(1);
expect(yWatch).toBeCalledTimes(1);
pos.set({x: 1, y: 1});
expect(xWatch).toBeCalledTimes(2);
expect(yWatch).toBeCalledTimes(2);
pos.set({x: 2, y: 1});
expect(xWatch).toBeCalledTimes(3);
expect(yWatch).toBeCalledTimes(2);
pos.set({x: 2, y: 2});
expect(xWatch).toBeCalledTimes(3);
expect(yWatch).toBeCalledTimes(3);
});
it('overwrite array reactive should keep reactive', () => {
const pos = reactive([0, 0]);
const xWatch = jest.fn();
watch(() => {
xWatch(pos[0].get());
});
const yWatch = jest.fn();
watch(() => {
yWatch(pos[1].get());
});
expect(xWatch).toBeCalledTimes(1);
expect(yWatch).toBeCalledTimes(1);
pos.set([1, 1]);
expect(xWatch).toBeCalledTimes(2);
expect(yWatch).toBeCalledTimes(2);
pos.set([2, 1]);
expect(xWatch).toBeCalledTimes(3);
expect(yWatch).toBeCalledTimes(2);
pos.set([2, 2]);
expect(xWatch).toBeCalledTimes(3);
expect(yWatch).toBeCalledTimes(3);
});
it('reactive is a obj', () => {
const rObj = reactive({ count: 1 });
const double = computed(() => {
return 2 * rObj.count.get();
});
watch(() => {
console.log('count: ', rObj.count.get(), 'double: ', double.get());
});
expect(double.read()).toBe(2);
rObj.count.set(2);
expect(rObj.count.read()).toBe(2);
expect(double.read()).toBe(4);
});
it('reactive is a array', () => {
const rObj = reactive({
items: [
{ name: 'p1', id: 1 },
{ name: 'p2', id: 2 },
],
});
const doubleId = computed(() => {
return 2 * rObj.items[0].id.get();
});
expect(doubleId.get()).toBe(2);
rObj.items.set([{ name: 'p11', id: 11 }]);
expect(doubleId.get()).toBe(22);
});
it('return obj computed', () => {
const a = reactive(7);
const c = computed(() => {
return { a: a.get() };
});
a.set(2);
expect(c.a.read()).toBe(2);
});
it('reactive is a array, watch', () => {
const rObj = reactive({
items: [
{ name: 'p1', id: 1 },
{ name: 'p2', id: 2 },
],
});
watch(() => {
console.log(rObj.items[0].id.get());
});
rObj.items.set([
{ name: 'p1', id: 1 },
{ name: 'p2', id: 2 },
]);
rObj.items.set([{ name: 'p11', id: 11 }]);
rObj.items[0].id.set(111);
});
});