Skip to content

Commit 95c9bf1

Browse files
committed
feat(framework): add framework detection and shim functionality for Vue and Astro in migration tests
1 parent 7b8f9ae commit 95c9bf1

1 file changed

Lines changed: 115 additions & 0 deletions

File tree

packages/cli/src/migration/__tests__/migrator.spec.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import path from 'node:path';
55
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
66

77
import { PackageManager } from '../../types/index.js';
8+
import { createMigrationReport } from '../report.js';
89

910
// Mock VITE_PLUS_VERSION to a stable value for snapshot tests.
1011
// When tests run via `vp test`, the env var is injected with the actual version,
@@ -21,6 +22,9 @@ const {
2122
parseNvmrcVersion,
2223
detectNodeVersionManagerFile,
2324
migrateNodeVersionManagerFile,
25+
detectFramework,
26+
hasFrameworkShim,
27+
addFrameworkShim,
2428
} = await import('../migrator.js');
2529

2630
describe('rewritePackageJson', () => {
@@ -304,6 +308,7 @@ describe('migrateNodeVersionManagerFile', () => {
304308
prettierMigrated: false,
305309
nodeVersionFileMigrated: false,
306310
gitHooksConfigured: false,
311+
frameworkShimAdded: false,
307312
warnings: [],
308313
manualSteps: [],
309314
};
@@ -334,6 +339,7 @@ describe('migrateNodeVersionManagerFile', () => {
334339
prettierMigrated: false,
335340
nodeVersionFileMigrated: false,
336341
gitHooksConfigured: false,
342+
frameworkShimAdded: false,
337343
warnings: [],
338344
manualSteps: [],
339345
};
@@ -366,6 +372,7 @@ describe('migrateNodeVersionManagerFile', () => {
366372
prettierMigrated: false,
367373
nodeVersionFileMigrated: false,
368374
gitHooksConfigured: false,
375+
frameworkShimAdded: false,
369376
warnings: [],
370377
manualSteps: [],
371378
};
@@ -401,6 +408,7 @@ describe('migrateNodeVersionManagerFile', () => {
401408
prettierMigrated: false,
402409
nodeVersionFileMigrated: false,
403410
gitHooksConfigured: false,
411+
frameworkShimAdded: false,
404412
warnings: [],
405413
manualSteps: [],
406414
};
@@ -638,3 +646,110 @@ describe('rewriteMonorepo bun catalog', () => {
638646
expect(workspaces.packages).toEqual(['packages/*']);
639647
});
640648
});
649+
650+
describe('framework shim', () => {
651+
let tmpDir: string;
652+
653+
beforeEach(() => {
654+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vp-test-'));
655+
});
656+
657+
afterEach(() => {
658+
fs.rmSync(tmpDir, { recursive: true, force: true });
659+
});
660+
661+
describe('detectFramework', () => {
662+
it('returns vue when vue is in devDependencies', () => {
663+
fs.writeFileSync(
664+
path.join(tmpDir, 'package.json'),
665+
JSON.stringify({ devDependencies: { vue: '^3.0.0' } }),
666+
);
667+
expect(detectFramework(tmpDir)).toBe('vue');
668+
});
669+
670+
it('returns astro when astro is in devDependencies', () => {
671+
fs.writeFileSync(
672+
path.join(tmpDir, 'package.json'),
673+
JSON.stringify({ devDependencies: { astro: '^4.0.0' } }),
674+
);
675+
expect(detectFramework(tmpDir)).toBe('astro');
676+
});
677+
678+
it('returns null when no framework dependency is present', () => {
679+
fs.writeFileSync(
680+
path.join(tmpDir, 'package.json'),
681+
JSON.stringify({ devDependencies: { vite: '^7.0.0' } }),
682+
);
683+
expect(detectFramework(tmpDir)).toBeNull();
684+
});
685+
686+
it('returns null when package.json does not exist', () => {
687+
expect(detectFramework(tmpDir)).toBeNull();
688+
});
689+
});
690+
691+
describe('hasFrameworkShim', () => {
692+
it('returns true when src/env.d.ts contains vue shim', () => {
693+
const srcDir = path.join(tmpDir, 'src');
694+
fs.mkdirSync(srcDir);
695+
fs.writeFileSync(
696+
path.join(srcDir, 'env.d.ts'),
697+
"declare module '*.vue' { export default {} }\n",
698+
);
699+
expect(hasFrameworkShim(tmpDir, 'vue')).toBe(true);
700+
});
701+
702+
it('returns false when src/env.d.ts does not contain vue shim', () => {
703+
const srcDir = path.join(tmpDir, 'src');
704+
fs.mkdirSync(srcDir);
705+
fs.writeFileSync(path.join(srcDir, 'env.d.ts'), '/// <reference types="vite-plus/client" />\n');
706+
expect(hasFrameworkShim(tmpDir, 'vue')).toBe(false);
707+
});
708+
709+
it('returns false when env.d.ts does not exist', () => {
710+
expect(hasFrameworkShim(tmpDir, 'vue')).toBe(false);
711+
});
712+
713+
it('returns true when root env.d.ts contains astro/client reference', () => {
714+
fs.writeFileSync(
715+
path.join(tmpDir, 'env.d.ts'),
716+
'/// <reference types="astro/client" />\n',
717+
);
718+
expect(hasFrameworkShim(tmpDir, 'astro')).toBe(true);
719+
});
720+
});
721+
722+
describe('addFrameworkShim', () => {
723+
it('creates src/env.d.ts with vue shim when src/ exists and no env.d.ts', () => {
724+
fs.mkdirSync(path.join(tmpDir, 'src'));
725+
addFrameworkShim(tmpDir, 'vue');
726+
const content = fs.readFileSync(path.join(tmpDir, 'src', 'env.d.ts'), 'utf-8');
727+
expect(content).toContain("declare module '*.vue'");
728+
expect(content).toContain('DefineComponent');
729+
});
730+
731+
it('creates root env.d.ts with vue shim when no src/ dir', () => {
732+
addFrameworkShim(tmpDir, 'vue');
733+
const content = fs.readFileSync(path.join(tmpDir, 'env.d.ts'), 'utf-8');
734+
expect(content).toContain("declare module '*.vue'");
735+
});
736+
737+
it('appends vue shim to existing src/env.d.ts', () => {
738+
const srcDir = path.join(tmpDir, 'src');
739+
fs.mkdirSync(srcDir);
740+
const existing = '/// <reference types="vite-plus/client" />\n';
741+
fs.writeFileSync(path.join(srcDir, 'env.d.ts'), existing);
742+
addFrameworkShim(tmpDir, 'vue');
743+
const content = fs.readFileSync(path.join(srcDir, 'env.d.ts'), 'utf-8');
744+
expect(content).toContain('/// <reference types="vite-plus/client" />');
745+
expect(content).toContain("declare module '*.vue'");
746+
});
747+
748+
it('sets frameworkShimAdded on report', () => {
749+
fs.mkdirSync(path.join(tmpDir, 'src'));
750+
const report = createMigrationReport();
751+
addFrameworkShim(tmpDir, 'vue', report);
752+
expect(report.frameworkShimAdded).toBe(true);
753+
});
754+
});
755+
});

0 commit comments

Comments
 (0)