// @vitest-environment jsdom
import { act, cleanup, render } from '@testing-library/react';
import React from 'react';
import { describe, expect, test, afterEach } from 'vitest';
import { manage } from '../src';
import { auto, Component } from '../src/react';
let id = 0;
class Bullet {
public id: number;
public speed = 10;
public constructor() {
this.id = id++;
}
}
class Store {
public bullets: { [key: number]: Bullet } = {};
}
let bulletCount = 0;
const BulletComponent = auto((props: { bullet: Bullet }) => {
bulletCount += 1;
const { bullet } = props;
return bullet.speed;
});
// Functional App component
const FunctionalApp = auto((props: { store: Store }) => {
const { store } = props;
return Object.values(store.bullets).map((bullet) => (
));
});
// Class App component
class ClassApp extends Component<{ store: Store }> {
render() {
const { store } = this.props;
return Object.values(store.bullets).map((bullet) => (
));
}
}
const store = manage(new Store());
describe('React re-render', () => {
const testCases = [
{ name: 'Functional component', App: FunctionalApp },
{ name: 'Class component', App: ClassApp },
];
afterEach(() => {
cleanup();
bulletCount = 0;
store.bullets = {};
});
testCases.forEach(({ name, App }) => {
test(`Update children props - ${ name }`, async () => {
store.bullets[0] = new Bullet();
render(
);
expect(bulletCount).toBe(1);
act(() => {
store.bullets[0].speed = 20;
});
expect(bulletCount).toBe(2);
act(() => {
store.bullets[0].speed = 30;
});
expect(bulletCount).toBe(3);
act(() => {
store.bullets[1] = new Bullet();
});
expect(bulletCount).toBe(4);
});
});
testCases.forEach(({ name, App }) => {
test(`Add new child - ${ name }`, async () => {
render(
);
expect(bulletCount).toBe(0);
act(() => {
store.bullets[0] = new Bullet();
});
expect(bulletCount).toBe(1);
act(() => {
store.bullets[1] = new Bullet();
});
expect(bulletCount).toBe(2);
act(() => {
store.bullets[2] = new Bullet();
});
expect(bulletCount).toBe(3);
});
});
});