f27ccc0081
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
74 lines
3.1 KiB
TypeScript
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();
|
|
});
|
|
});
|