@form8ion/javascript 15.5.0 → 15.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/lib/index.js +2 -2
  2. package/lib/index.js.map +1 -1
  3. package/package.json +4 -3
  4. package/src/code-style/index.js +3 -0
  5. package/src/code-style/lifter.js +6 -0
  6. package/src/code-style/lifter.test.js +25 -0
  7. package/src/code-style/remark/index.js +3 -0
  8. package/src/code-style/remark/lifter.js +10 -0
  9. package/src/code-style/remark/lifter.test.js +28 -0
  10. package/src/code-style/remark/scaffolder.js +38 -0
  11. package/src/code-style/remark/scaffolder.test.js +102 -0
  12. package/src/code-style/remark/tester.js +11 -0
  13. package/src/code-style/remark/tester.test.js +46 -0
  14. package/src/code-style/scaffolder.js +26 -0
  15. package/src/code-style/scaffolder.test.js +87 -0
  16. package/src/code-style/tester.js +5 -0
  17. package/src/code-style/tester.test.js +23 -0
  18. package/src/corepack/index.js +1 -0
  19. package/src/corepack/lifter.js +5 -0
  20. package/src/corepack/lifter.test.js +22 -0
  21. package/src/coverage/index.js +3 -0
  22. package/src/coverage/lifter.js +31 -0
  23. package/src/coverage/lifter.test.js +58 -0
  24. package/src/coverage/nyc/index.js +2 -0
  25. package/src/coverage/nyc/remover.js +16 -0
  26. package/src/coverage/nyc/remover.test.js +24 -0
  27. package/src/coverage/nyc/tester.js +5 -0
  28. package/src/coverage/nyc/tester.test.js +29 -0
  29. package/src/coverage/scaffolder.js +7 -0
  30. package/src/coverage/scaffolder.test.js +32 -0
  31. package/src/coverage/tester.js +10 -0
  32. package/src/coverage/tester.test.js +50 -0
  33. package/src/dependencies/index.js +3 -0
  34. package/src/dependencies/installer.js +25 -0
  35. package/src/dependencies/installer.test.js +77 -0
  36. package/src/dependencies/package-managers.js +32 -0
  37. package/src/dependencies/package-managers.test.js +46 -0
  38. package/src/dependencies/processor.js +30 -0
  39. package/src/dependencies/processor.test.js +75 -0
  40. package/src/dependencies/remover.js +10 -0
  41. package/src/dependencies/remover.test.js +28 -0
  42. package/src/dialects/babel/config/ignore-adder.js +10 -0
  43. package/src/dialects/babel/config/ignore-adder.test.js +33 -0
  44. package/src/dialects/babel/config/index.js +3 -0
  45. package/src/dialects/babel/config/loader.js +5 -0
  46. package/src/dialects/babel/config/loader.test.js +21 -0
  47. package/src/dialects/babel/config/writer.js +6 -0
  48. package/src/dialects/babel/config/writer.test.js +20 -0
  49. package/src/dialects/babel/index.js +3 -0
  50. package/src/dialects/babel/lifter.js +7 -0
  51. package/src/dialects/babel/lifter.test.js +17 -0
  52. package/src/dialects/babel/predicate.js +5 -0
  53. package/src/dialects/babel/predicate.test.js +25 -0
  54. package/src/dialects/babel/scaffolder.js +14 -0
  55. package/src/dialects/babel/scaffolder.test.js +28 -0
  56. package/src/dialects/index.js +2 -0
  57. package/src/dialects/prompt-choices.js +10 -0
  58. package/src/dialects/prompt-choices.test.js +28 -0
  59. package/src/dialects/scaffolder.js +15 -0
  60. package/src/dialects/scaffolder.test.js +49 -0
  61. package/src/dialects/typescript/index.js +1 -0
  62. package/src/dialects/typescript/scaffolder.js +31 -0
  63. package/src/dialects/typescript/scaffolder.test.js +95 -0
  64. package/src/documentation/generation-command.js +11 -0
  65. package/src/documentation/generation-command.test.js +25 -0
  66. package/src/documentation/index.js +1 -0
  67. package/src/documentation/scaffolder.js +20 -0
  68. package/src/documentation/scaffolder.test.js +49 -0
  69. package/src/engines/index.js +2 -0
  70. package/src/engines/lifter.js +7 -0
  71. package/src/engines/lifter.test.js +18 -0
  72. package/src/engines/tester.js +7 -0
  73. package/src/engines/tester.test.js +37 -0
  74. package/src/index.js +9 -0
  75. package/src/lifter.js +55 -0
  76. package/src/lifter.test.js +96 -0
  77. package/src/linting/index.js +1 -0
  78. package/src/linting/scaffolder.js +5 -0
  79. package/src/linting/scaffolder.test.js +31 -0
  80. package/src/lockfile-lint/allowed-hosts-builder.js +6 -0
  81. package/src/lockfile-lint/allowed-hosts-builder.test.js +35 -0
  82. package/src/lockfile-lint/config.js +12 -0
  83. package/src/lockfile-lint/config.test.js +37 -0
  84. package/src/lockfile-lint/index.js +3 -0
  85. package/src/lockfile-lint/scaffolder.js +38 -0
  86. package/src/lockfile-lint/scaffolder.test.js +85 -0
  87. package/src/lockfile-lint/tester.js +5 -0
  88. package/src/lockfile-lint/tester.test.js +25 -0
  89. package/src/node-version/index.js +2 -0
  90. package/src/node-version/scaffolder.js +19 -0
  91. package/src/node-version/scaffolder.test.js +33 -0
  92. package/src/node-version/tasks.js +25 -0
  93. package/src/node-version/tasks.test.js +43 -0
  94. package/src/node-version/tester.js +5 -0
  95. package/src/node-version/tester.test.js +29 -0
  96. package/src/npm-config/index.js +5 -0
  97. package/src/npm-config/lifter.js +14 -0
  98. package/src/npm-config/lifter.test.js +23 -0
  99. package/src/npm-config/reader.js +11 -0
  100. package/src/npm-config/reader.test.js +33 -0
  101. package/src/npm-config/scaffolder.js +16 -0
  102. package/src/npm-config/scaffolder.test.js +54 -0
  103. package/src/npm-config/tester.js +5 -0
  104. package/src/npm-config/tester.test.js +29 -0
  105. package/src/npm-config/writer.js +6 -0
  106. package/src/npm-config/writer.test.js +24 -0
  107. package/src/options/schemas.js +14 -0
  108. package/src/options/schemas.test.js +147 -0
  109. package/src/options/validator.js +45 -0
  110. package/src/options/validator.test.js +79 -0
  111. package/src/package/details.js +18 -0
  112. package/src/package/details.test.js +51 -0
  113. package/src/package/index.js +2 -0
  114. package/src/package/lifter.js +47 -0
  115. package/src/package/lifter.test.js +100 -0
  116. package/src/package/package-name.js +13 -0
  117. package/src/package/package-name.test.js +52 -0
  118. package/src/package/property-sorter.js +38 -0
  119. package/src/package/property-sorter.test.js +56 -0
  120. package/src/package/scaffolder.js +32 -0
  121. package/src/package/scaffolder.test.js +46 -0
  122. package/src/package/scripts/index.js +1 -0
  123. package/src/package/scripts/lifter.js +14 -0
  124. package/src/package/scripts/lifter.test.js +31 -0
  125. package/src/package/scripts/script-comparator.js +46 -0
  126. package/src/package/scripts/script-comparator.test.js +119 -0
  127. package/src/package/scripts/scripts-sorter.js +7 -0
  128. package/src/package/scripts/scripts-sorter.test.js +20 -0
  129. package/src/package/scripts/test-script-updater.js +15 -0
  130. package/src/package/scripts/test-script-updater.test.js +32 -0
  131. package/src/package/vcs-host-details.js +12 -0
  132. package/src/package/vcs-host-details.test.js +16 -0
  133. package/src/package-managers/current-manager-resolver.js +21 -0
  134. package/src/package-managers/current-manager-resolver.test.js +51 -0
  135. package/src/package-managers/index.js +5 -0
  136. package/src/package-managers/lifter.js +7 -0
  137. package/src/package-managers/lifter.test.js +18 -0
  138. package/src/package-managers/lockfile-path-resolver.js +10 -0
  139. package/src/package-managers/lockfile-path-resolver.test.js +15 -0
  140. package/src/package-managers/npm/index.js +2 -0
  141. package/src/package-managers/npm/scaffolder.js +19 -0
  142. package/src/package-managers/npm/scaffolder.test.js +33 -0
  143. package/src/package-managers/npm/tester.js +11 -0
  144. package/src/package-managers/npm/tester.test.js +33 -0
  145. package/src/package-managers/scaffolder.js +11 -0
  146. package/src/package-managers/scaffolder.test.js +27 -0
  147. package/src/package-managers/tester.js +11 -0
  148. package/src/package-managers/tester.test.js +33 -0
  149. package/src/package-managers/yarn/index.js +2 -0
  150. package/src/package-managers/yarn/scaffolder.js +19 -0
  151. package/src/package-managers/yarn/scaffolder.test.js +33 -0
  152. package/src/package-managers/yarn/tester.js +11 -0
  153. package/src/package-managers/yarn/tester.test.js +33 -0
  154. package/src/plugins-schemas.js +4 -0
  155. package/src/plugins-schemas.test.js +28 -0
  156. package/src/project-type/application/index.js +2 -0
  157. package/src/project-type/application/predicate.js +3 -0
  158. package/src/project-type/application/predicate.test.js +14 -0
  159. package/src/project-type/application/scaffolder.js +24 -0
  160. package/src/project-type/application/scaffolder.test.js +35 -0
  161. package/src/project-type/cli/index.js +3 -0
  162. package/src/project-type/cli/lifter.js +5 -0
  163. package/src/project-type/cli/lifter.test.js +20 -0
  164. package/src/project-type/cli/scaffolder.js +52 -0
  165. package/src/project-type/cli/scaffolder.test.js +103 -0
  166. package/src/project-type/cli/tester.js +3 -0
  167. package/src/project-type/cli/tester.test.js +14 -0
  168. package/src/project-type/index.js +3 -0
  169. package/src/project-type/lifter.js +23 -0
  170. package/src/project-type/lifter.test.js +69 -0
  171. package/src/project-type/monorepo/index.js +1 -0
  172. package/src/project-type/monorepo/scaffolder.js +16 -0
  173. package/src/project-type/monorepo/scaffolder.test.js +27 -0
  174. package/src/project-type/package/build-details.js +56 -0
  175. package/src/project-type/package/build-details.test.js +111 -0
  176. package/src/project-type/package/documentation.js +34 -0
  177. package/src/project-type/package/documentation.test.js +106 -0
  178. package/src/project-type/package/index.js +3 -0
  179. package/src/project-type/package/lifter.js +5 -0
  180. package/src/project-type/package/lifter.test.js +20 -0
  181. package/src/project-type/package/scaffolder.js +84 -0
  182. package/src/project-type/package/scaffolder.test.js +267 -0
  183. package/src/project-type/package/tester.js +5 -0
  184. package/src/project-type/package/tester.test.js +28 -0
  185. package/src/project-type/publishable/access-level.js +3 -0
  186. package/src/project-type/publishable/access-level.test.js +13 -0
  187. package/src/project-type/publishable/badges.js +20 -0
  188. package/src/project-type/publishable/badges.test.js +29 -0
  189. package/src/project-type/publishable/bundler/index.js +1 -0
  190. package/src/project-type/publishable/bundler/prompt.js +16 -0
  191. package/src/project-type/publishable/bundler/prompt.test.js +35 -0
  192. package/src/project-type/publishable/bundler/scaffolder.js +8 -0
  193. package/src/project-type/publishable/bundler/scaffolder.test.js +33 -0
  194. package/src/project-type/publishable/index.js +2 -0
  195. package/src/project-type/publishable/lifter.js +24 -0
  196. package/src/project-type/publishable/lifter.test.js +49 -0
  197. package/src/project-type/publishable/provenance/index.js +1 -0
  198. package/src/project-type/publishable/provenance/lifter.js +15 -0
  199. package/src/project-type/publishable/provenance/lifter.test.js +56 -0
  200. package/src/project-type/publishable/provenance/slsa.js +17 -0
  201. package/src/project-type/publishable/provenance/slsa.test.js +21 -0
  202. package/src/project-type/publishable/registry-resolver.js +15 -0
  203. package/src/project-type/publishable/registry-resolver.test.js +60 -0
  204. package/src/project-type/publishable/scaffolder.js +7 -0
  205. package/src/project-type/publishable/scaffolder.test.js +23 -0
  206. package/src/project-type/scaffolder.js +56 -0
  207. package/src/project-type/scaffolder.test.js +115 -0
  208. package/src/project-type/tester.js +9 -0
  209. package/src/project-type/tester.test.js +51 -0
  210. package/src/project-type-plugin/index.js +1 -0
  211. package/src/project-type-plugin/prompt.js +16 -0
  212. package/src/project-type-plugin/prompt.test.js +39 -0
  213. package/src/project-type-plugin/scaffolder.js +28 -0
  214. package/src/project-type-plugin/scaffolder.test.js +70 -0
  215. package/src/prompts/conditionals.js +39 -0
  216. package/src/prompts/conditionals.test.js +95 -0
  217. package/src/prompts/question-names.js +17 -0
  218. package/src/prompts/questions.js +158 -0
  219. package/src/prompts/questions.test.js +247 -0
  220. package/src/prompts/validators.js +9 -0
  221. package/src/prompts/validators.test.js +19 -0
  222. package/src/registries/index.js +2 -0
  223. package/src/registries/lifter.js +43 -0
  224. package/src/registries/lifter.test.js +63 -0
  225. package/src/registries/npm-config/list-builder.js +9 -0
  226. package/src/registries/npm-config/list-builder.test.js +43 -0
  227. package/src/registries/tester.js +3 -0
  228. package/src/registries/tester.test.js +9 -0
  229. package/src/runkit/badge/index.js +1 -0
  230. package/src/runkit/badge/scaffolder.js +13 -0
  231. package/src/runkit/badge/scaffolder.test.js +22 -0
  232. package/src/runkit/index.js +4 -0
  233. package/src/runkit/lifter.js +5 -0
  234. package/src/runkit/lifter.test.js +17 -0
  235. package/src/runkit/remover.js +3 -0
  236. package/src/runkit/remover.test.js +9 -0
  237. package/src/runkit/scaffolder.js +11 -0
  238. package/src/runkit/scaffolder.test.js +35 -0
  239. package/src/runkit/tester.js +3 -0
  240. package/src/runkit/tester.test.js +16 -0
  241. package/src/scaffolder.js +155 -0
  242. package/src/scaffolder.test.js +239 -0
  243. package/src/tester.js +17 -0
  244. package/src/tester.test.js +37 -0
  245. package/src/testing/index.js +1 -0
  246. package/src/testing/scaffolder.js +31 -0
  247. package/src/testing/scaffolder.test.js +63 -0
  248. package/src/testing/unit/index.js +1 -0
  249. package/src/testing/unit/prompt.js +15 -0
  250. package/src/testing/unit/prompt.test.js +33 -0
  251. package/src/testing/unit/scaffolder.js +30 -0
  252. package/src/testing/unit/scaffolder.test.js +54 -0
  253. package/src/vcs/ignore-lists-builder.js +6 -0
  254. package/src/vcs/ignore-lists-builder.test.js +25 -0
  255. package/src/vcs/schema.js +7 -0
  256. package/src/vcs/schema.test.js +40 -0
  257. package/src/verification/index.js +1 -0
  258. package/src/verification/scaffolder.js +35 -0
  259. package/src/verification/scaffolder.test.js +56 -0
@@ -0,0 +1,155 @@
1
+ import deepmerge from 'deepmerge';
2
+ import {info} from '@travi/cli-messages';
3
+ import {projectTypes, scaffoldChoice} from '@form8ion/javascript-core';
4
+ import {scaffold as scaffoldCommitConvention} from '@form8ion/commit-convention';
5
+
6
+ import {validate} from './options/validator.js';
7
+ import {prompt} from './prompts/questions.js';
8
+ import {scaffold as scaffoldDialect} from './dialects/index.js';
9
+ import {scaffold as scaffoldNpmConfig} from './npm-config/index.js';
10
+ import {scaffold as scaffoldPackageManager} from './package-managers/index.js';
11
+ import scaffoldDocumentation from './documentation/index.js';
12
+ import {scaffold as scaffoldNodeVersion} from './node-version/index.js';
13
+ import buildVcsIgnoreLists from './vcs/ignore-lists-builder.js';
14
+ import {scaffold as scaffoldPackage} from './package/index.js';
15
+ import {scaffold as scaffoldProjectType} from './project-type/index.js';
16
+ import {scaffold as scaffoldProjectTypePlugin} from './project-type-plugin/index.js';
17
+ import buildDocumentationCommand from './documentation/generation-command.js';
18
+ import {scaffold as scaffoldVerification} from './verification/index.js';
19
+ import {scaffold as scaffoldCodeStyle} from './code-style/index.js';
20
+
21
+ export default async function scaffoldJavascript(options) {
22
+ info('Initializing JavaScript project');
23
+
24
+ const {
25
+ projectRoot,
26
+ projectName,
27
+ visibility,
28
+ license,
29
+ vcs,
30
+ description,
31
+ configs,
32
+ decisions,
33
+ pathWithinParent,
34
+ plugins: {
35
+ applicationTypes,
36
+ packageTypes,
37
+ monorepoTypes,
38
+ packageBundlers,
39
+ unitTestFrameworks,
40
+ hosts,
41
+ ciServices
42
+ }
43
+ } = validate(options);
44
+
45
+ const {
46
+ tests,
47
+ projectType,
48
+ ci,
49
+ chosenHost,
50
+ scope,
51
+ nodeVersionCategory,
52
+ author,
53
+ configureLinting,
54
+ provideExample,
55
+ packageManager,
56
+ dialect
57
+ } = await prompt(ciServices, hosts, visibility, vcs, decisions, configs, pathWithinParent);
58
+
59
+ info('Writing project files', {level: 'secondary'});
60
+
61
+ const {packageName} = await scaffoldPackage({
62
+ projectRoot,
63
+ projectName,
64
+ scope,
65
+ dialect,
66
+ license,
67
+ author,
68
+ description
69
+ });
70
+ const projectTypeResults = await scaffoldProjectType({
71
+ projectType,
72
+ projectRoot,
73
+ projectName,
74
+ packageName,
75
+ packageManager,
76
+ visibility,
77
+ applicationTypes,
78
+ packageTypes,
79
+ monorepoTypes,
80
+ packageBundlers,
81
+ scope,
82
+ tests,
83
+ vcs,
84
+ decisions,
85
+ dialect,
86
+ provideExample,
87
+ publishRegistry: configs.registries.publish
88
+ });
89
+ const verificationResults = await scaffoldVerification({
90
+ projectRoot,
91
+ dialect,
92
+ visibility,
93
+ packageManager,
94
+ vcs,
95
+ registries: configs.registries,
96
+ tests,
97
+ unitTestFrameworks,
98
+ decisions,
99
+ pathWithinParent
100
+ });
101
+ const [nodeVersion, npmResults, dialectResults, codeStyleResults] = await Promise.all([
102
+ scaffoldNodeVersion({projectRoot, nodeVersionCategory}),
103
+ scaffoldNpmConfig({projectType, projectRoot}),
104
+ scaffoldDialect({
105
+ dialect,
106
+ configs,
107
+ projectRoot,
108
+ projectType,
109
+ testFilenamePattern: verificationResults.testFilenamePattern
110
+ }),
111
+ scaffoldCodeStyle({projectRoot, projectType, configs, vcs, configureLinting}),
112
+ scaffoldPackageManager({projectRoot, packageManager})
113
+ ]);
114
+ const projectTypePluginResults = await scaffoldProjectTypePlugin({
115
+ projectRoot,
116
+ projectType,
117
+ projectName,
118
+ packageName,
119
+ packageManager,
120
+ scope,
121
+ dialect,
122
+ tests,
123
+ decisions,
124
+ plugins: {
125
+ [projectTypes.PACKAGE]: packageTypes,
126
+ [projectTypes.APPLICATION]: applicationTypes,
127
+ [projectTypes.MONOREPO]: monorepoTypes
128
+ }
129
+ });
130
+ const mergedContributions = deepmerge.all([
131
+ ...(await Promise.all([
132
+ scaffoldChoice(
133
+ hosts,
134
+ chosenHost,
135
+ {buildDirectory: `./${projectTypeResults.buildDirectory}`, projectRoot, projectName, nodeVersion}
136
+ ),
137
+ scaffoldChoice(ciServices, ci, {projectRoot, vcs, visibility, projectType, projectName, nodeVersion, tests}),
138
+ scaffoldCommitConvention({projectRoot, projectType, configs, pathWithinParent})
139
+ ])),
140
+ projectTypeResults,
141
+ verificationResults,
142
+ codeStyleResults,
143
+ npmResults,
144
+ dialectResults,
145
+ projectTypePluginResults
146
+ ]);
147
+
148
+ return {
149
+ ...mergedContributions,
150
+ documentation: scaffoldDocumentation({projectTypeResults, packageManager}),
151
+ tags: projectTypeResults.tags,
152
+ vcsIgnore: buildVcsIgnoreLists(mergedContributions.vcsIgnore),
153
+ verificationCommand: `${buildDocumentationCommand(packageManager)} && ${packageManager} test`
154
+ };
155
+ }
@@ -0,0 +1,239 @@
1
+ import deepmerge from 'deepmerge';
2
+ import {projectTypes, scaffoldChoice} from '@form8ion/javascript-core';
3
+ import {scaffold as scaffoldCommitConvention} from '@form8ion/commit-convention';
4
+
5
+ import {beforeEach, describe, expect, it, vi} from 'vitest';
6
+ import {when} from 'vitest-when';
7
+ import any from '@travi/any';
8
+
9
+ import {scaffold as scaffoldPackage} from './package/index.js';
10
+ import {scaffold as scaffoldVerification} from './verification/index.js';
11
+ import {scaffold as scaffoldCodeStyle} from './code-style/index.js';
12
+ import {scaffold as scaffoldDialect} from './dialects/index.js';
13
+ import {scaffold as scaffoldNpmConfig} from './npm-config/index.js';
14
+ import {scaffold as scaffoldPackageManager} from './package-managers/index.js';
15
+ import {scaffold as scaffoldNodeVersion} from './node-version/index.js';
16
+ import {scaffold as scaffoldProjectTypePlugin} from './project-type-plugin/index.js';
17
+ import buildVcsIgnoreLists from './vcs/ignore-lists-builder.js';
18
+ import {scaffold as scaffoldProjectType} from './project-type/index.js';
19
+ import buildDocumentationCommand from './documentation/generation-command.js';
20
+ import scaffoldDocumentation from './documentation/index.js';
21
+ import {validate} from './options/validator.js';
22
+ import {prompt} from './prompts/questions.js';
23
+ import scaffold from './scaffolder.js';
24
+
25
+ vi.mock('deepmerge');
26
+ vi.mock('@form8ion/javascript-core');
27
+ vi.mock('@form8ion/commit-convention');
28
+ vi.mock('./package/index.js');
29
+ vi.mock('./code-style/index.js');
30
+ vi.mock('./dialects/index.js');
31
+ vi.mock('./npm-config/index.js');
32
+ vi.mock('./package-managers/index.js');
33
+ vi.mock('./node-version/index.js');
34
+ vi.mock('./project-type-plugin/index.js');
35
+ vi.mock('./vcs/ignore-lists-builder.js');
36
+ vi.mock('./project-type/index.js');
37
+ vi.mock('./documentation/generation-command.js');
38
+ vi.mock('./documentation/index.js');
39
+ vi.mock('./options/validator.js');
40
+ vi.mock('./prompts/questions.js');
41
+ vi.mock('./documentation/badges.js');
42
+ vi.mock('./verification/index.js');
43
+
44
+ describe('javascript project scaffolder', () => {
45
+ const options = any.simpleObject();
46
+ const projectRoot = any.string();
47
+ const vcs = any.simpleObject();
48
+ const pathWithinParent = any.string();
49
+ const publishRegistry = any.url();
50
+ const registries = {...any.simpleObject(), publish: publishRegistry};
51
+ const configs = {...any.simpleObject(), registries};
52
+ const packageManager = any.word();
53
+ const visibility = any.word();
54
+ const decisions = any.simpleObject();
55
+ const documentationCommand = any.string();
56
+ const documentation = any.string();
57
+ const tags = any.listOf(any.word);
58
+ const dialect = any.word();
59
+ const provideExample = any.boolean();
60
+ const scope = any.word();
61
+ const vcsIgnore = any.simpleObject();
62
+ const mergedVcsIgnore = any.simpleObject();
63
+ const mergedNextSteps = any.listOf(any.simpleObject);
64
+ const mergedResults = {...any.simpleObject(), vcsIgnore: mergedVcsIgnore, nextSteps: mergedNextSteps};
65
+
66
+ beforeEach(() => {
67
+ const projectName = any.word();
68
+ const packageName = any.string();
69
+ const description = any.sentence();
70
+ const projectType = any.word();
71
+ const ciChoice = any.word();
72
+ const hostChoice = any.word();
73
+ const license = any.word();
74
+ const nodeVersionCategory = any.word();
75
+ const author = any.simpleObject();
76
+ const configureLinting = any.boolean();
77
+ const tests = any.simpleObject();
78
+ const ciServices = any.simpleObject();
79
+ const hosts = any.simpleObject();
80
+ const applicationTypes = any.simpleObject();
81
+ const packageTypes = any.simpleObject();
82
+ const monorepoTypes = any.simpleObject();
83
+ const packageBundlers = any.simpleObject();
84
+ const unitTestFrameworks = any.simpleObject();
85
+ const testFilenamePattern = any.string();
86
+ const buildDirectory = any.string();
87
+ const packageResults = {...any.simpleObject(), packageName};
88
+ const projectTypeResults = {...any.simpleObject(), tags, buildDirectory};
89
+ const projectTypePluginResults = any.simpleObject();
90
+ const nodeVersionResults = any.simpleObject();
91
+ const ciServiceResults = any.simpleObject();
92
+ const npmConfigResults = any.simpleObject();
93
+ const dialectResults = any.simpleObject();
94
+ const commitConventionResults = any.simpleObject();
95
+ const codeStyleResults = any.simpleObject();
96
+ const hostResults = any.simpleObject();
97
+ const verificationResults = {...any.simpleObject(), testFilenamePattern};
98
+
99
+ when(validate)
100
+ .calledWith(options)
101
+ .thenReturn({
102
+ projectRoot,
103
+ projectName,
104
+ description,
105
+ vcs,
106
+ pathWithinParent,
107
+ configs,
108
+ visibility,
109
+ license,
110
+ decisions,
111
+ plugins: {ciServices, hosts, applicationTypes, packageTypes, monorepoTypes, packageBundlers, unitTestFrameworks}
112
+ });
113
+ when(prompt)
114
+ .calledWith(ciServices, hosts, visibility, vcs, decisions, configs, pathWithinParent)
115
+ .thenResolve({
116
+ packageManager,
117
+ dialect,
118
+ scope,
119
+ author,
120
+ provideExample,
121
+ projectType,
122
+ tests,
123
+ ci: ciChoice,
124
+ chosenHost: hostChoice,
125
+ nodeVersionCategory,
126
+ configureLinting
127
+ });
128
+ when(scaffoldDocumentation).calledWith({packageManager, projectTypeResults}).thenReturn(documentation);
129
+ when(buildDocumentationCommand).calledWith(packageManager).thenReturn(documentationCommand);
130
+ when(scaffoldPackage)
131
+ .calledWith({projectRoot, projectName, scope, dialect, license, author, description})
132
+ .thenResolve(packageResults);
133
+ when(scaffoldProjectType)
134
+ .calledWith({
135
+ projectRoot,
136
+ projectName,
137
+ packageName,
138
+ projectType,
139
+ packageManager,
140
+ visibility,
141
+ vcs,
142
+ decisions,
143
+ applicationTypes,
144
+ packageTypes,
145
+ monorepoTypes,
146
+ packageBundlers,
147
+ dialect,
148
+ provideExample,
149
+ scope,
150
+ tests,
151
+ publishRegistry
152
+ })
153
+ .thenResolve(projectTypeResults);
154
+ when(scaffoldVerification)
155
+ .calledWith({
156
+ projectRoot,
157
+ dialect,
158
+ visibility,
159
+ packageManager,
160
+ vcs,
161
+ registries,
162
+ tests,
163
+ decisions,
164
+ pathWithinParent,
165
+ unitTestFrameworks
166
+ })
167
+ .thenResolve(verificationResults);
168
+ when(scaffoldNodeVersion).calledWith({projectRoot, nodeVersionCategory}).thenResolve(nodeVersionResults);
169
+ when(scaffoldDialect)
170
+ .calledWith({dialect, configs, projectRoot, projectType, testFilenamePattern})
171
+ .thenResolve(dialectResults);
172
+ when(scaffoldNpmConfig).calledWith({projectType, projectRoot}).thenResolve(npmConfigResults);
173
+ when(scaffoldCodeStyle)
174
+ .calledWith({projectRoot, projectType, configs, vcs, configureLinting})
175
+ .thenResolve(codeStyleResults);
176
+ when(scaffoldChoice)
177
+ .calledWith(
178
+ ciServices,
179
+ ciChoice,
180
+ {projectRoot, vcs, visibility, projectType, projectName, nodeVersion: nodeVersionResults, tests}
181
+ )
182
+ .thenResolve(ciServiceResults);
183
+ when(scaffoldChoice)
184
+ .calledWith(
185
+ hosts,
186
+ hostChoice,
187
+ {projectRoot, projectName, nodeVersion: nodeVersionResults, buildDirectory: `./${buildDirectory}`}
188
+ )
189
+ .thenResolve(hostResults);
190
+ when(scaffoldCommitConvention)
191
+ .calledWith({projectRoot, projectType, configs, pathWithinParent})
192
+ .thenResolve(commitConventionResults);
193
+ when(scaffoldProjectTypePlugin)
194
+ .calledWith({
195
+ projectRoot,
196
+ projectType,
197
+ projectName,
198
+ packageName,
199
+ packageManager,
200
+ scope,
201
+ dialect,
202
+ tests,
203
+ decisions,
204
+ plugins: {
205
+ [projectTypes.PACKAGE]: packageTypes,
206
+ [projectTypes.APPLICATION]: applicationTypes,
207
+ [projectTypes.MONOREPO]: monorepoTypes
208
+ }
209
+ })
210
+ .thenResolve(projectTypePluginResults);
211
+ when(buildVcsIgnoreLists).calledWith(mergedVcsIgnore).thenReturn(vcsIgnore);
212
+ when(deepmerge.all)
213
+ .calledWith([
214
+ hostResults,
215
+ ciServiceResults,
216
+ commitConventionResults,
217
+ projectTypeResults,
218
+ verificationResults,
219
+ codeStyleResults,
220
+ npmConfigResults,
221
+ dialectResults,
222
+ projectTypePluginResults
223
+ ])
224
+ .thenReturn(mergedResults);
225
+ });
226
+
227
+ it('should scaffold the javascript details', async () => {
228
+ const results = await scaffold(options);
229
+
230
+ expect(scaffoldPackageManager).toHaveBeenCalledWith({projectRoot, packageManager});
231
+ expect(results).toEqual({
232
+ ...mergedResults,
233
+ documentation,
234
+ tags,
235
+ vcsIgnore,
236
+ verificationCommand: `${documentationCommand} && ${packageManager} test`
237
+ });
238
+ });
239
+ });
package/src/tester.js ADDED
@@ -0,0 +1,17 @@
1
+ import {info} from '@travi/cli-messages';
2
+
3
+ import {test as nvmIsUsed} from './node-version/index.js';
4
+ import {test as jsPackageManagerIsUsed} from './package-managers/index.js';
5
+
6
+ export default async function projectUsesJavaScript({projectRoot}) {
7
+ const [nvmFound, jsPackageManagerFound] = await Promise.all([
8
+ nvmIsUsed({projectRoot}),
9
+ jsPackageManagerIsUsed({projectRoot})
10
+ ]);
11
+
12
+ const jsProjectFound = nvmFound || jsPackageManagerFound;
13
+
14
+ if (jsProjectFound) info('JavaScript Project Detected');
15
+
16
+ return jsProjectFound;
17
+ }
@@ -0,0 +1,37 @@
1
+ import {vi, it, describe, afterEach, expect} from 'vitest';
2
+ import any from '@travi/any';
3
+ import {when} from 'vitest-when';
4
+
5
+ import {test as nvmIsUsed} from './node-version/index.js';
6
+ import {test as jsPackageManagerIsUsed} from './package-managers/index.js';
7
+ import testApplicability from './tester.js';
8
+
9
+ vi.mock('./node-version/index.js');
10
+ vi.mock('./package-managers/index.js');
11
+
12
+ describe('javascript predicate', () => {
13
+ const projectRoot = any.string();
14
+
15
+ afterEach(() => {
16
+ vi.clearAllMocks();
17
+ });
18
+
19
+ it('should return `true` if nvm is detected', async () => {
20
+ when(nvmIsUsed).calledWith({projectRoot}).thenResolve(true);
21
+
22
+ expect(await testApplicability({projectRoot})).toBe(true);
23
+ });
24
+
25
+ it('should return `true` if a javascript package manager is detected', async () => {
26
+ when(jsPackageManagerIsUsed).calledWith({projectRoot}).thenResolve(true);
27
+
28
+ expect(await testApplicability({projectRoot})).toBe(true);
29
+ });
30
+
31
+ it('should return `false` if neither nvm nor a js package manager is found', async () => {
32
+ when(nvmIsUsed).calledWith({projectRoot}).thenResolve(false);
33
+ when(jsPackageManagerIsUsed).calledWith({projectRoot}).thenResolve(false);
34
+
35
+ expect(await testApplicability({projectRoot})).toBe(false);
36
+ });
37
+ });
@@ -0,0 +1 @@
1
+ export {default as scaffold} from './scaffolder.js';
@@ -0,0 +1,31 @@
1
+ import deepmerge from 'deepmerge';
2
+
3
+ import {scaffold as scaffoldUnitTesting} from './unit/index.js';
4
+
5
+ export default async function scaffoldTesting({
6
+ projectRoot,
7
+ visibility,
8
+ tests: {unit, integration},
9
+ vcs,
10
+ unitTestFrameworks,
11
+ decisions,
12
+ dialect,
13
+ pathWithinParent
14
+ }) {
15
+ const unitResults = unit
16
+ ? await scaffoldUnitTesting({
17
+ projectRoot,
18
+ visibility,
19
+ vcs,
20
+ frameworks: unitTestFrameworks,
21
+ decisions,
22
+ dialect,
23
+ pathWithinParent
24
+ })
25
+ : {};
26
+
27
+ return deepmerge(
28
+ {dependencies: {javascript: {development: [...(unit || integration) ? ['@travi/any'] : []]}}, eslint: {}},
29
+ unitResults
30
+ );
31
+ }
@@ -0,0 +1,63 @@
1
+ import any from '@travi/any';
2
+ import {it, expect, describe, vi, beforeEach} from 'vitest';
3
+ import {when} from 'vitest-when';
4
+
5
+ import {scaffold as scaffoldUnitTesting} from './unit/index.js';
6
+ import scaffoldTesting from './scaffolder.js';
7
+
8
+ vi.mock('./unit/index.js');
9
+
10
+ describe('testing scaffolder', () => {
11
+ const projectRoot = any.string();
12
+ const visibility = any.word();
13
+ const dialect = any.word();
14
+ const unitTestingDevDependencies = any.listOf(any.string);
15
+ const unitTestNextSteps = any.listOf(any.simpleObject);
16
+ const unitTestScripts = any.simpleObject();
17
+ const unitTestFilesToIgnoreFromVcs = any.listOf(any.string);
18
+ const unitTestDirectoriesToIgnoreFromVcs = any.listOf(any.string);
19
+ const vcs = any.simpleObject();
20
+ const unitTestFrameworks = any.simpleObject();
21
+ const decisions = any.simpleObject();
22
+ const pathWithinParent = any.string();
23
+
24
+ beforeEach(() => {
25
+ when(scaffoldUnitTesting)
26
+ .calledWith({projectRoot, visibility, vcs, frameworks: unitTestFrameworks, decisions, dialect, pathWithinParent})
27
+ .thenResolve({
28
+ dependencies: {javascript: {development: unitTestingDevDependencies}},
29
+ scripts: unitTestScripts,
30
+ vcsIgnore: {files: unitTestFilesToIgnoreFromVcs, directories: unitTestDirectoriesToIgnoreFromVcs},
31
+ nextSteps: unitTestNextSteps
32
+ });
33
+ });
34
+
35
+ it('should scaffold unit testing if the project will be unit test', async () => {
36
+ expect(await scaffoldTesting({
37
+ projectRoot,
38
+ visibility,
39
+ tests: {unit: true},
40
+ vcs,
41
+ unitTestFrameworks,
42
+ decisions,
43
+ dialect,
44
+ pathWithinParent
45
+ })).toEqual({
46
+ dependencies: {javascript: {development: ['@travi/any', ...unitTestingDevDependencies]}},
47
+ scripts: unitTestScripts,
48
+ vcsIgnore: {files: unitTestFilesToIgnoreFromVcs, directories: unitTestDirectoriesToIgnoreFromVcs},
49
+ eslint: {},
50
+ nextSteps: unitTestNextSteps
51
+ });
52
+ });
53
+
54
+ it('should not scaffold unit testing if the project will not be unit tested', async () => {
55
+ expect(await scaffoldTesting({projectRoot, visibility, tests: {unit: false, integration: true}, pathWithinParent}))
56
+ .toEqual({dependencies: {javascript: {development: ['@travi/any']}}, eslint: {}});
57
+ });
58
+
59
+ it('should not scaffold testing if the project will not be tested', async () => {
60
+ expect(await scaffoldTesting({projectRoot, visibility, tests: {unit: false, integration: false}, pathWithinParent}))
61
+ .toEqual({dependencies: {javascript: {development: []}}, eslint: {}});
62
+ });
63
+ });
@@ -0,0 +1 @@
1
+ export {default as scaffold} from './scaffolder.js';
@@ -0,0 +1,15 @@
1
+ import {prompt} from '@form8ion/overridable-prompts';
2
+ import {questionNames} from '../../prompts/question-names.js';
3
+
4
+ export default async function gatherUnitTestingInput({frameworks, decisions}) {
5
+ if (!Object.keys(frameworks).length) return 'Other';
6
+
7
+ const answers = await prompt([{
8
+ name: questionNames.UNIT_TEST_FRAMEWORK,
9
+ type: 'list',
10
+ message: 'Which type of unit testing framework should be used?',
11
+ choices: [...Object.keys(frameworks), 'Other']
12
+ }], decisions);
13
+
14
+ return answers[questionNames.UNIT_TEST_FRAMEWORK];
15
+ }
@@ -0,0 +1,33 @@
1
+ import * as prompts from '@form8ion/overridable-prompts';
2
+
3
+ import any from '@travi/any';
4
+ import {when} from 'vitest-when';
5
+ import {describe, expect, it, vi} from 'vitest';
6
+
7
+ import {questionNames} from '../../prompts/question-names.js';
8
+ import prompt from './prompt.js';
9
+
10
+ vi.mock('@form8ion/overridable-prompts');
11
+
12
+ describe('project-type prompts', () => {
13
+ it('should preset the choice of application-type', async () => {
14
+ const chosenType = any.word();
15
+ const decisions = any.simpleObject();
16
+ const answers = {...any.simpleObject(), [questionNames.UNIT_TEST_FRAMEWORK]: chosenType};
17
+ const frameworks = any.simpleObject();
18
+ when(prompts.prompt)
19
+ .calledWith([{
20
+ name: questionNames.UNIT_TEST_FRAMEWORK,
21
+ type: 'list',
22
+ message: 'Which type of unit testing framework should be used?',
23
+ choices: [...Object.keys(frameworks), 'Other']
24
+ }], decisions)
25
+ .thenResolve(answers);
26
+
27
+ expect(await prompt({frameworks, decisions})).toEqual(chosenType);
28
+ });
29
+
30
+ it('should skip the prompt and return `Other` when no options are provided', async () => {
31
+ expect(await prompt({frameworks: {}})).toEqual('Other');
32
+ });
33
+ });
@@ -0,0 +1,30 @@
1
+ import deepmerge from 'deepmerge';
2
+ import {validateOptions} from '@form8ion/core';
3
+ import {scaffoldChoice as scaffoldFrameworkChoice} from '@form8ion/javascript-core';
4
+
5
+ import {scaffold as scaffoldCoverage} from '../../coverage/index.js';
6
+ import chooseFramework from './prompt.js';
7
+ import {pluginsSchema} from '../../plugins-schemas.js';
8
+
9
+ export default async function scaffoldUnitTesting({
10
+ projectRoot,
11
+ frameworks,
12
+ decisions,
13
+ visibility,
14
+ vcs,
15
+ pathWithinParent,
16
+ dialect
17
+ }) {
18
+ const validatedFrameworks = validateOptions(pluginsSchema, frameworks);
19
+ const [framework, coverage] = await Promise.all([
20
+ chooseFramework({frameworks: validatedFrameworks, decisions})
21
+ .then(chosenFramework => scaffoldFrameworkChoice(validatedFrameworks, chosenFramework, {projectRoot, dialect})),
22
+ scaffoldCoverage({projectRoot, vcs, visibility, pathWithinParent})
23
+ ]);
24
+
25
+ return deepmerge.all([
26
+ {scripts: {'test:unit': 'cross-env NODE_ENV=test c8 run-s test:unit:base'}},
27
+ framework,
28
+ coverage
29
+ ]);
30
+ }
@@ -0,0 +1,54 @@
1
+ import {validateOptions} from '@form8ion/core';
2
+ import {scaffoldChoice} from '@form8ion/javascript-core';
3
+ import deepmerge from 'deepmerge';
4
+
5
+ import {describe, expect, it, vi} from 'vitest';
6
+ import any from '@travi/any';
7
+ import {when} from 'vitest-when';
8
+
9
+ import scaffoldCoverage from '../../coverage/scaffolder.js';
10
+ import prompt from './prompt.js';
11
+ import scaffoldUnitTesting from './scaffolder.js';
12
+ import {pluginsSchema} from '../../plugins-schemas.js';
13
+
14
+ vi.mock('deepmerge');
15
+ vi.mock('@form8ion/core');
16
+ vi.mock('@form8ion/javascript-core');
17
+ vi.mock('../../coverage/scaffolder.js');
18
+ vi.mock('./prompt.js');
19
+
20
+ describe('unit testing scaffolder', () => {
21
+ const projectRoot = any.string();
22
+ const vcs = any.simpleObject();
23
+ const frameworks = any.simpleObject();
24
+ const decisions = any.simpleObject();
25
+ const chosenFramework = any.word();
26
+ const dialect = any.word();
27
+ const pathWithinParent = any.string();
28
+ const coverageResults = any.simpleObject();
29
+ const unitTestFrameworkResults = any.simpleObject();
30
+ const mergedResults = any.simpleObject();
31
+
32
+ it('should scaffold the chosen framework', async () => {
33
+ const visibility = any.word();
34
+ const validatedFrameworks = any.simpleObject();
35
+ when(validateOptions).calledWith(pluginsSchema, frameworks).thenReturn(validatedFrameworks);
36
+ when(prompt).calledWith({frameworks: validatedFrameworks, decisions}).thenResolve(chosenFramework);
37
+ when(scaffoldChoice)
38
+ .calledWith(validatedFrameworks, chosenFramework, {projectRoot, dialect})
39
+ .thenResolve(unitTestFrameworkResults);
40
+ when(scaffoldCoverage)
41
+ .calledWith({projectRoot, vcs, visibility, pathWithinParent})
42
+ .thenResolve(coverageResults);
43
+ when(deepmerge.all)
44
+ .calledWith([
45
+ {scripts: {'test:unit': 'cross-env NODE_ENV=test c8 run-s test:unit:base'}},
46
+ unitTestFrameworkResults,
47
+ coverageResults
48
+ ])
49
+ .thenReturn(mergedResults);
50
+
51
+ expect(await scaffoldUnitTesting({projectRoot, frameworks, decisions, vcs, visibility, pathWithinParent, dialect}))
52
+ .toEqual(mergedResults);
53
+ });
54
+ });