Files
portal/app/vite-plugins/dev-indices/__tests__/integration.test.ts
T
2026-05-12 11:50:15 +03:00

74 lines
3.1 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdtempSync, readFileSync, rmSync, copyFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import { devIndicesPlugin } from '../index';
const FIXTURE = resolve(__dirname, 'fixtures/sample.vue');
function runTransform(filePath: string, manifestPath: string) {
const plugin = devIndicesPlugin({
manifestPath,
appRoot: resolve(__dirname, '..', '..', '..'),
enabled: true,
});
// buildStart loads existing manifest (or createEmpty() if missing)
if (typeof plugin.buildStart === 'function') (plugin.buildStart as Function).call({});
const source = readFileSync(filePath, 'utf8');
const result = (plugin.transform as Function).call({}, source, filePath);
// buildEnd flushes manifest to disk
if (typeof plugin.buildEnd === 'function') (plugin.buildEnd as Function).call({});
return result?.code ?? result;
}
describe('vite-plugin-dev-indices integration', () => {
let dir: string;
let manifestPath: string;
let workingFixture: string;
beforeEach(() => {
dir = mkdtempSync(join(tmpdir(), 'dx-int-'));
manifestPath = join(dir, 'dev-indices.json');
workingFixture = join(dir, 'sample.vue');
copyFileSync(FIXTURE, workingFixture);
});
afterEach(() => rmSync(dir, { recursive: true, force: true }));
it('injects data-dx attributes into every element', () => {
const code = runTransform(workingFixture, manifestPath);
expect(code).toMatch(/<div class="root" data-dx="\d+">/);
expect(code).toMatch(/<v-btn icon="plus" data-dx="\d+">/);
expect(code).toMatch(/<v-btn icon="user" data-dx="\d+">/);
expect(code).toMatch(/<v-list data-dx="\d+">/);
expect(code).toMatch(/<v-list-item v-for="i in 3" :key="i" data-dx="\d+">/);
});
it('writes manifest with one entry per element', () => {
runTransform(workingFixture, manifestPath);
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
// 5 elements in fixture (div, 2 v-btn, v-list, v-list-item)
expect(Object.keys(manifest.entries)).toHaveLength(5);
expect(manifest.lastId).toBe(5);
});
it('second run on unchanged file produces identical IDs', () => {
const code1 = runTransform(workingFixture, manifestPath);
const code2 = runTransform(workingFixture, manifestPath);
expect(code1).toBe(code2);
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
expect(manifest.lastId).toBe(5);
});
it('returns null for non-.vue files', () => {
const plugin = devIndicesPlugin({ manifestPath, appRoot: dir, enabled: true });
expect((plugin.transform as Function).call({}, '// js', '/foo/bar.ts')).toBeNull();
});
it('returns null when disabled', () => {
const plugin = devIndicesPlugin({ manifestPath, appRoot: dir, enabled: false });
const source = readFileSync(workingFixture, 'utf8');
expect((plugin.transform as Function).call({}, source, workingFixture)).toBeNull();
});
});