feat(plugin-typescript): add setup wizard binding · code-pushup/cli@32f3e51
1+import { vol } from 'memfs';
2+import type { PluginAnswer } from '@code-pushup/models';
3+import { MEMFS_VOLUME } from '@code-pushup/test-utils';
4+import { typescriptSetupBinding as binding } from './binding.js';
5+6+const defaultAnswers: Record<string, PluginAnswer> = {
7+'typescript.tsconfig': 'tsconfig.json',
8+'typescript.categories': true,
9+};
10+11+describe('typescriptSetupBinding', () => {
12+beforeEach(() => {
13+vol.fromJSON({ '.gitkeep': '' }, MEMFS_VOLUME);
14+});
15+16+describe('isRecommended', () => {
17+it('should recommend when tsconfig.json exists', async () => {
18+vol.fromJSON({ 'tsconfig.json': '{}' }, MEMFS_VOLUME);
19+20+await expect(binding.isRecommended(MEMFS_VOLUME)).resolves.toBeTrue();
21+});
22+23+it('should recommend when tsconfig.base.json exists', async () => {
24+vol.fromJSON({ 'tsconfig.base.json': '{}' }, MEMFS_VOLUME);
25+26+await expect(binding.isRecommended(MEMFS_VOLUME)).resolves.toBeTrue();
27+});
28+29+it('should not recommend when no tsconfig found', async () => {
30+await expect(binding.isRecommended(MEMFS_VOLUME)).resolves.toBeFalse();
31+});
32+});
33+34+describe('prompts', () => {
35+it('should detect tsconfig.json as default', async () => {
36+vol.fromJSON({ 'tsconfig.json': '{}' }, MEMFS_VOLUME);
37+38+await expect(
39+binding.prompts(MEMFS_VOLUME),
40+).resolves.toIncludeAllPartialMembers([
41+{ key: 'typescript.tsconfig', default: 'tsconfig.json' },
42+]);
43+});
44+45+it('should detect tsconfig.base.json when present', async () => {
46+vol.fromJSON({ 'tsconfig.base.json': '{}' }, MEMFS_VOLUME);
47+48+await expect(
49+binding.prompts(MEMFS_VOLUME),
50+).resolves.toIncludeAllPartialMembers([
51+{ key: 'typescript.tsconfig', default: 'tsconfig.base.json' },
52+]);
53+});
54+55+it('should detect tsconfig.app.json when present', async () => {
56+vol.fromJSON({ 'tsconfig.app.json': '{}' }, MEMFS_VOLUME);
57+58+await expect(
59+binding.prompts(MEMFS_VOLUME),
60+).resolves.toIncludeAllPartialMembers([
61+{ key: 'typescript.tsconfig', default: 'tsconfig.app.json' },
62+]);
63+});
64+65+it('should default to tsconfig.json when no tsconfig found', async () => {
66+await expect(
67+binding.prompts(MEMFS_VOLUME),
68+).resolves.toIncludeAllPartialMembers([
69+{ key: 'typescript.tsconfig', default: 'tsconfig.json' },
70+]);
71+});
72+73+it('should default categories confirmation to true', async () => {
74+await expect(
75+binding.prompts(MEMFS_VOLUME),
76+).resolves.toIncludeAllPartialMembers([
77+{ key: 'typescript.categories', type: 'confirm', default: true },
78+]);
79+});
80+});
81+82+describe('generateConfig', () => {
83+it('should omit tsconfig option when using default tsconfig.json', () => {
84+expect(binding.generateConfig(defaultAnswers).pluginInit).toEqual([
85+'typescriptPlugin(),',
86+]);
87+});
88+89+it('should include tsconfig when non-default path provided', () => {
90+expect(
91+binding.generateConfig({
92+ ...defaultAnswers,
93+'typescript.tsconfig': 'tsconfig.base.json',
94+}).pluginInit,
95+).toEqual([
96+'typescriptPlugin({',
97+" tsconfig: 'tsconfig.base.json',",
98+'}),',
99+]);
100+});
101+102+it('should generate bug-prevention category from problems group when confirmed', () => {
103+expect(binding.generateConfig(defaultAnswers).categories).toEqual([
104+expect.objectContaining({
105+slug: 'bug-prevention',
106+refs: [
107+expect.objectContaining({
108+type: 'group',
109+plugin: 'typescript',
110+slug: 'problems',
111+}),
112+],
113+}),
114+]);
115+});
116+117+it('should omit categories when declined', () => {
118+expect(
119+binding.generateConfig({
120+ ...defaultAnswers,
121+'typescript.categories': false,
122+}).categories,
123+).toBeUndefined();
124+});
125+126+it('should import from @code-pushup/typescript-plugin', () => {
127+expect(binding.generateConfig(defaultAnswers).imports).toEqual([
128+{
129+moduleSpecifier: '@code-pushup/typescript-plugin',
130+defaultImport: 'typescriptPlugin',
131+},
132+]);
133+});
134+});
135+});