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+

});