5180 fichiers 38.5 Mo 0 téléchargements 133 vues mis à jour il y a 4 heures ui
nitro-v36-with-renderer-v36 / src / hooks / stateUpdaterSideEffects.test.ts
stateUpdaterSideEffects.test.ts 2 Ko Télécharger le fichier
import { readdirSync, readFileSync, statSync } from 'node:fs';
import { join, relative } from 'node:path';
import { describe, expect, it } from 'vitest';

/**
 * A state updater must be pure: React may run it twice (StrictMode in development) or later than the call. Packets
 * sent from inside one went out twice, and a value copied out of one could be stale. This scans the client for an
 * updater (`setX((prev) => { ... })`) whose body sends a packet.
 */
const SOURCE = join(process.cwd(), 'src');
const UPDATER = /\bset[A-Z]\w*\(\s*\(?\s*\w+\s*(?::[^)=]*)?\)?\s*=>\s*\{/g;
// Packets, and the room-placement and link side effects the inventory used to run from its updaters.
const SENDS = /SendMessageComposer\(|\.connection\.send\(|\bsendActiveBadges\(|\bcancelRoomObjectPlacement\(|\battemptItemPlacement\(|\bCreateLinkEvent\(/;

const sourceFiles = (directory: string): string[] =>
    readdirSync(directory).flatMap((name) => {
        const path = join(directory, name);
        if (statSync(path).isDirectory()) return sourceFiles(path);
        return /\.tsx?$/.test(name) && !/\.test\.tsx?$/.test(name) ? [path] : [];
    });

const updaterBody = (source: string, start: number): string => {
    let depth = 1;
    let index = start;
    while (depth > 0 && index < source.length) {
        if (source[index] === '{') depth++;
        else if (source[index] === '}') depth--;
        index++;
    }
    return source.slice(start, index);
};

describe('state updaters', () => {
    it('never send a packet', () => {
        const offenders: string[] = [];

        for (const file of sourceFiles(SOURCE)) {
            const source = readFileSync(file, 'utf8');

            for (const match of source.matchAll(UPDATER)) {
                if (SENDS.test(updaterBody(source, match.index + match[0].length))) {
                    const line = source.slice(0, match.index).split('\n').length;
                    offenders.push(`${relative(process.cwd(), file).replace(/\\/g, '/')}:${line}`);
                }
            }
        }

        expect(offenders).toEqual([]);
    });
});
15Sujets
1Dépôts
20Membres
7En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser