@asyncapi/generator 2.0.3 → 2.1.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.
- package/.dockerignore +2 -0
- package/CHANGELOG.md +15 -0
- package/docs/configuration-file.md +2 -2
- package/docs/nunjucks-render-engine.md +2 -1
- package/jest.config.js +9 -0
- package/lib/__mocks__/filtersRegistry.js +3 -0
- package/lib/__mocks__/hooksRegistry.js +3 -0
- package/lib/__mocks__/templateConfigValidator.js +3 -0
- package/lib/__mocks__/utils.js +25 -0
- package/lib/filtersRegistry.js +14 -10
- package/package.json +9 -9
- package/test/__mocks__/@npmcli/arborist.js +11 -0
- package/test/__mocks__/@npmcli/config.js +3 -0
- package/test/__mocks__/fs.extra.js +3 -0
- package/test/__mocks__/loglevel.js +3 -0
- package/test/__mocks__/resolve-from.js +8 -0
- package/test/__mocks__/resolve-pkg.js +8 -0
- package/test/__snapshots__/integration.test.js.snap +25 -0
- package/test/docs/apiwithref.json +41 -0
- package/test/docs/dummy.yml +390 -0
- package/test/docs/dummyV3.yml +31 -0
- package/test/docs/shared.json +27 -0
- package/test/docs/ws.yml +36 -0
- package/test/generator.test.js +626 -0
- package/test/integration.test.js +58 -0
- package/test/parser.test.js +107 -0
- package/test/renderer.test.js +62 -0
- package/test/templateConfigValidator.test.js +277 -0
- package/test/test-project/.yarncr.yml +3 -0
- package/test/test-project/README.md +4 -0
- package/test/test-project/docker-compose.yml +24 -0
- package/test/test-project/package.json +25 -0
- package/test/test-project/test-entrypoint.sh +12 -0
- package/test/test-project/test-global.test.js +37 -0
- package/test/test-project/test-project.test.js +98 -0
- package/test/test-project/test-registry.test.js +55 -0
- package/test/test-project/test.sh +99 -0
- package/test/test-project/verdaccio/config.yaml +16 -0
- package/test/test-project/verdaccio/htpasswd +1 -0
- package/test/test-templates/nunjucks-template/package-lock.json +4143 -0
- package/test/test-templates/nunjucks-template/package.json +21 -0
- package/test/test-templates/nunjucks-template/template/test-file.md +5 -0
- package/test/test-templates/react-template/__transpiled/test-file.md.js +24 -0
- package/test/test-templates/react-template/__transpiled/test-file.md.js.map +1 -0
- package/test/test-templates/react-template/package-lock.json +4143 -0
- package/test/test-templates/react-template/package.json +23 -0
- package/test/test-templates/react-template/template/test-file.md.js +11 -0
- package/test/utils.test.js +76 -0
- package/.eslintignore +0 -5
- package/.eslintrc +0 -113
- package/.npmrc.template +0 -1
- package/.releaserc +0 -24
- package/.sonarcloud.properties +0 -2
- package/CODEOWNERS +0 -12
- package/CODE_OF_CONDUCT.md +0 -46
- package/CONTRIBUTING.md +0 -79
- package/LICENSE +0 -201
- package/README.md +0 -98
- package/assets/readme-banner.png +0 -0
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
/* eslint-disable sonarjs/no-duplicate-string */
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const Generator = require('../lib/generator');
|
|
5
|
+
const log = require('loglevel');
|
|
6
|
+
const unixify = require('unixify');
|
|
7
|
+
const dummyYAML = fs.readFileSync(path.resolve(__dirname, './docs/dummy.yml'), 'utf8');
|
|
8
|
+
|
|
9
|
+
const logMessage = require('./../lib/logMessages.js');
|
|
10
|
+
|
|
11
|
+
jest.mock('../lib/utils');
|
|
12
|
+
jest.mock('../lib/filtersRegistry');
|
|
13
|
+
jest.mock('../lib/hooksRegistry');
|
|
14
|
+
jest.mock('../lib/templateConfigValidator');
|
|
15
|
+
|
|
16
|
+
describe('Generator', () => {
|
|
17
|
+
describe('constructor', () => {
|
|
18
|
+
it('works with minimum amount of params', () => {
|
|
19
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
20
|
+
expect(gen.templateName).toStrictEqual('testTemplate');
|
|
21
|
+
expect(gen.targetDir).toStrictEqual(__dirname);
|
|
22
|
+
expect(gen.entrypoint).toStrictEqual(undefined);
|
|
23
|
+
expect(gen.noOverwriteGlobs).toStrictEqual([]);
|
|
24
|
+
expect(gen.disabledHooks).toStrictEqual({});
|
|
25
|
+
expect(gen.output).toStrictEqual('fs');
|
|
26
|
+
expect(gen.forceWrite).toStrictEqual(false);
|
|
27
|
+
expect(gen.install).toStrictEqual(false);
|
|
28
|
+
expect(gen.templateParams).toStrictEqual({});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('works with all the params', () => {
|
|
32
|
+
const gen = new Generator('testTemplate', __dirname, {
|
|
33
|
+
entrypoint: 'test-entrypoint',
|
|
34
|
+
noOverwriteGlobs: ['test-globs'],
|
|
35
|
+
disabledHooks: { 'test-hooks': true, 'generate:after': ['foo', 'bar'], foo: 'bar' },
|
|
36
|
+
output: 'string',
|
|
37
|
+
forceWrite: true,
|
|
38
|
+
install: true,
|
|
39
|
+
templateParams: {
|
|
40
|
+
test: true,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
expect(gen.templateName).toStrictEqual('testTemplate');
|
|
44
|
+
expect(gen.targetDir).toStrictEqual(__dirname);
|
|
45
|
+
expect(gen.entrypoint).toStrictEqual('test-entrypoint');
|
|
46
|
+
expect(gen.noOverwriteGlobs).toStrictEqual(['test-globs']);
|
|
47
|
+
expect(gen.disabledHooks).toStrictEqual({ 'test-hooks': true, 'generate:after': ['foo', 'bar'], foo: 'bar' });
|
|
48
|
+
expect(gen.output).toStrictEqual('string');
|
|
49
|
+
expect(gen.forceWrite).toStrictEqual(true);
|
|
50
|
+
expect(gen.install).toStrictEqual(true);
|
|
51
|
+
expect(() => gen.templateParams.test).toThrow('Template parameter "test" has not been defined in the package.json file under generator property. Please make sure it\'s listed there before you use it in your template.');
|
|
52
|
+
|
|
53
|
+
// Mock params on templateConfig so it doesn't fail.
|
|
54
|
+
gen.templateConfig.parameters = { test: {} };
|
|
55
|
+
|
|
56
|
+
expect(gen.templateParams.test).toStrictEqual(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('throws an error indicating an unexpected param was given', () => {
|
|
60
|
+
const t = () => new Generator('testTemplate', __dirname, {
|
|
61
|
+
entrypoint: 'test-entrypoint',
|
|
62
|
+
noOverwriteGlobs: ['test-globs'],
|
|
63
|
+
disabledHooks: { 'test-hooks': true },
|
|
64
|
+
output: 'string',
|
|
65
|
+
forceWrite: true,
|
|
66
|
+
forceInstall: true,
|
|
67
|
+
templateParams: {
|
|
68
|
+
test: true,
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
expect(t).toThrow('These options are not supported by the generator: forceInstall');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('throws an error indicating multiple unexpected params were given', () => {
|
|
75
|
+
const t = () => new Generator('testTemplate', __dirname, {
|
|
76
|
+
entrypoint: 'test-entrypoint',
|
|
77
|
+
noOverwriteGlobs: ['test-globs'],
|
|
78
|
+
disabledHooks: { 'test-hooks': true },
|
|
79
|
+
output: 'string',
|
|
80
|
+
write: true,
|
|
81
|
+
forceInstall: true,
|
|
82
|
+
templateParams: {
|
|
83
|
+
test: true,
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
expect(t).toThrow('These options are not supported by the generator: write, forceInstall');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('fails if no templateName is given', () => {
|
|
90
|
+
const t = () => new Generator();
|
|
91
|
+
expect(t).toThrow('No template name has been specified.');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('fails if no targetDir is given', () => {
|
|
95
|
+
const t = () => new Generator('testTemplate');
|
|
96
|
+
expect(t).toThrow('No target directory has been specified.');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('fails if output is given and is different than "fs" and "string"', () => {
|
|
100
|
+
const t = () => new Generator('testTemplate', __dirname, { output: 'fail' });
|
|
101
|
+
expect(t).toThrow('Invalid output type fail. Valid values are \'fs\' and \'string\'.');
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe('#generate', () => {
|
|
106
|
+
let asyncApiDocumentMock;
|
|
107
|
+
let xfsMock;
|
|
108
|
+
let util;
|
|
109
|
+
let filtersRegistry;
|
|
110
|
+
let hooksRegistry;
|
|
111
|
+
let templateConfigValidator;
|
|
112
|
+
|
|
113
|
+
const mockMethods = (gen) => {
|
|
114
|
+
gen.verifyTargetDir = jest.fn();
|
|
115
|
+
gen.installTemplate = jest.fn().mockResolvedValue({ name: 'nameOfTestTemplate', path: '/path/to/template/nameOfTestTemplate' });
|
|
116
|
+
gen.configureTemplate = jest.fn();
|
|
117
|
+
gen.loadTemplateConfig = jest.fn();
|
|
118
|
+
gen.registerHooks = jest.fn();
|
|
119
|
+
gen.registerFilters = jest.fn();
|
|
120
|
+
gen.validateTemplateConfig = jest.fn();
|
|
121
|
+
gen.generateDirectoryStructure = jest.fn();
|
|
122
|
+
gen.launchHook = jest.fn();
|
|
123
|
+
gen.generateFile = jest.fn();
|
|
124
|
+
gen.renderString = jest.fn();
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
beforeAll(() => {
|
|
128
|
+
util = require('../lib/utils');
|
|
129
|
+
filtersRegistry = require('../lib/filtersRegistry');
|
|
130
|
+
hooksRegistry = require('../lib/hooksRegistry');
|
|
131
|
+
templateConfigValidator = require('../lib/templateConfigValidator');
|
|
132
|
+
xfsMock = require('fs.extra');
|
|
133
|
+
const { AsyncAPIDocument } = require('@asyncapi/parser/cjs/models/v2/asyncapi');
|
|
134
|
+
asyncApiDocumentMock = new AsyncAPIDocument({ 'x-parser-api-version': 0 });
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('works with output=fs, forceWrite=false, install=false', async () => {
|
|
138
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
139
|
+
mockMethods(gen);
|
|
140
|
+
await gen.generate(asyncApiDocumentMock);
|
|
141
|
+
|
|
142
|
+
expect(xfsMock.mkdirpSync).toHaveBeenCalledWith(__dirname);
|
|
143
|
+
expect(gen.verifyTargetDir).toHaveBeenCalledWith(__dirname);
|
|
144
|
+
expect(gen.installTemplate).toHaveBeenCalledWith(false);
|
|
145
|
+
expect(gen.loadTemplateConfig).toHaveBeenCalled();
|
|
146
|
+
expect(gen.configureTemplate).toHaveBeenCalled();
|
|
147
|
+
expect(hooksRegistry.registerHooks).toHaveBeenCalled();
|
|
148
|
+
expect(filtersRegistry.registerFilters).toHaveBeenCalled();
|
|
149
|
+
expect(templateConfigValidator.validateTemplateConfig).toHaveBeenCalled();
|
|
150
|
+
expect(gen.generateDirectoryStructure).toHaveBeenCalledWith(asyncApiDocumentMock);
|
|
151
|
+
expect(gen.launchHook).toHaveBeenCalledWith('generate:after');
|
|
152
|
+
|
|
153
|
+
expect(util.exists).toHaveBeenCalledTimes(0);
|
|
154
|
+
expect(util.readFile).toHaveBeenCalledTimes(0);
|
|
155
|
+
expect(gen.generateFile).toHaveBeenCalledTimes(0);
|
|
156
|
+
expect(gen.renderString).toHaveBeenCalledTimes(0);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('works with output=fs, forceWrite=false, install=true', async () => {
|
|
160
|
+
const gen = new Generator('testTemplate', __dirname, { install: true });
|
|
161
|
+
mockMethods(gen);
|
|
162
|
+
await gen.generate(asyncApiDocumentMock);
|
|
163
|
+
|
|
164
|
+
expect(xfsMock.mkdirpSync).toHaveBeenCalledWith(__dirname);
|
|
165
|
+
expect(gen.verifyTargetDir).toHaveBeenCalledWith(__dirname);
|
|
166
|
+
expect(gen.installTemplate).toHaveBeenCalledWith(true);
|
|
167
|
+
expect(gen.loadTemplateConfig).toHaveBeenCalled();
|
|
168
|
+
expect(gen.configureTemplate).toHaveBeenCalled();
|
|
169
|
+
expect(hooksRegistry.registerHooks).toHaveBeenCalled();
|
|
170
|
+
expect(filtersRegistry.registerFilters).toHaveBeenCalled();
|
|
171
|
+
expect(templateConfigValidator.validateTemplateConfig).toHaveBeenCalled();
|
|
172
|
+
expect(gen.generateDirectoryStructure).toHaveBeenCalledWith(asyncApiDocumentMock);
|
|
173
|
+
expect(gen.launchHook).toHaveBeenCalledWith('generate:after');
|
|
174
|
+
|
|
175
|
+
expect(util.exists).toHaveBeenCalledTimes(0);
|
|
176
|
+
expect(util.readFile).toHaveBeenCalledTimes(0);
|
|
177
|
+
expect(gen.generateFile).toHaveBeenCalledTimes(0);
|
|
178
|
+
expect(gen.renderString).toHaveBeenCalledTimes(0);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('works with output=fs, forceWrite=true, install=false', async () => {
|
|
182
|
+
const gen = new Generator('testTemplate', __dirname, { forceWrite: true });
|
|
183
|
+
mockMethods(gen);
|
|
184
|
+
await gen.generate(asyncApiDocumentMock);
|
|
185
|
+
|
|
186
|
+
expect(xfsMock.mkdirpSync).toHaveBeenCalledWith(__dirname);
|
|
187
|
+
expect(gen.installTemplate).toHaveBeenCalledWith(false);
|
|
188
|
+
expect(gen.configureTemplate).toHaveBeenCalled();
|
|
189
|
+
expect(hooksRegistry.registerHooks).toHaveBeenCalled();
|
|
190
|
+
expect(filtersRegistry.registerFilters).toHaveBeenCalled();
|
|
191
|
+
expect(templateConfigValidator.validateTemplateConfig).toHaveBeenCalled();
|
|
192
|
+
expect(gen.generateDirectoryStructure).toHaveBeenCalledWith(asyncApiDocumentMock);
|
|
193
|
+
expect(gen.launchHook).toHaveBeenCalledWith('generate:after');
|
|
194
|
+
|
|
195
|
+
expect(util.exists).toHaveBeenCalledTimes(0);
|
|
196
|
+
expect(util.readFile).toHaveBeenCalledTimes(0);
|
|
197
|
+
expect(gen.verifyTargetDir).toHaveBeenCalledTimes(0);
|
|
198
|
+
expect(gen.generateFile).toHaveBeenCalledTimes(0);
|
|
199
|
+
expect(gen.renderString).toHaveBeenCalledTimes(0);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('works with output=fs, forceWrite=true, install=true', async () => {
|
|
203
|
+
const gen = new Generator('testTemplate', __dirname, { forceWrite: true, install: true });
|
|
204
|
+
mockMethods(gen);
|
|
205
|
+
await gen.generate(asyncApiDocumentMock);
|
|
206
|
+
|
|
207
|
+
expect(xfsMock.mkdirpSync).toHaveBeenCalledWith(__dirname);
|
|
208
|
+
expect(gen.installTemplate).toHaveBeenCalledWith(true);
|
|
209
|
+
expect(gen.loadTemplateConfig).toHaveBeenCalled();
|
|
210
|
+
expect(gen.loadTemplateConfig).toHaveBeenCalled();
|
|
211
|
+
expect(hooksRegistry.registerHooks).toHaveBeenCalled();
|
|
212
|
+
expect(filtersRegistry.registerFilters).toHaveBeenCalled();
|
|
213
|
+
expect(templateConfigValidator.validateTemplateConfig).toHaveBeenCalled();
|
|
214
|
+
expect(gen.generateDirectoryStructure).toHaveBeenCalledWith(asyncApiDocumentMock);
|
|
215
|
+
expect(gen.launchHook).toHaveBeenCalledWith('generate:after');
|
|
216
|
+
|
|
217
|
+
expect(util.exists).toHaveBeenCalledTimes(0);
|
|
218
|
+
expect(util.readFile).toHaveBeenCalledTimes(0);
|
|
219
|
+
expect(gen.verifyTargetDir).toHaveBeenCalledTimes(0);
|
|
220
|
+
expect(gen.generateFile).toHaveBeenCalledTimes(0);
|
|
221
|
+
expect(gen.renderString).toHaveBeenCalledTimes(0);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('works with output=fs, forceWrite=false, install=false, entrypoint=set', async () => {
|
|
225
|
+
const gen = new Generator('testTemplate', __dirname, { entrypoint: 'file.js' });
|
|
226
|
+
mockMethods(gen);
|
|
227
|
+
util.exists.mockResolvedValue(true);
|
|
228
|
+
await gen.generate(asyncApiDocumentMock);
|
|
229
|
+
|
|
230
|
+
expect(xfsMock.mkdirpSync).toHaveBeenCalledWith(__dirname);
|
|
231
|
+
expect(gen.verifyTargetDir).toHaveBeenCalledWith(__dirname);
|
|
232
|
+
expect(gen.installTemplate).toHaveBeenCalledWith(false);
|
|
233
|
+
expect(gen.loadTemplateConfig).toHaveBeenCalled();
|
|
234
|
+
expect(gen.loadTemplateConfig).toHaveBeenCalled();
|
|
235
|
+
expect(hooksRegistry.registerHooks).toHaveBeenCalled();
|
|
236
|
+
expect(filtersRegistry.registerFilters).toHaveBeenCalled();
|
|
237
|
+
expect(templateConfigValidator.validateTemplateConfig).toHaveBeenCalled();
|
|
238
|
+
expect(gen.launchHook).toHaveBeenCalledWith('generate:after');
|
|
239
|
+
expect(unixify(util.exists.mock.calls[0][0])).toEqual('/path/to/template/nameOfTestTemplate/template/file.js');
|
|
240
|
+
expect(gen.generateFile.mock.calls[0][0]).toEqual(asyncApiDocumentMock);
|
|
241
|
+
expect(gen.generateFile.mock.calls[0][1]).toEqual('file.js');
|
|
242
|
+
expect(unixify(gen.generateFile.mock.calls[0][2])).toEqual('/path/to/template/nameOfTestTemplate/template');
|
|
243
|
+
expect(util.readFile).toHaveBeenCalledTimes(0);
|
|
244
|
+
expect(gen.renderString).toHaveBeenCalledTimes(0);
|
|
245
|
+
expect(gen.generateDirectoryStructure).toHaveBeenCalledTimes(0);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('should be able to generate with string inputs', async () => {
|
|
249
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
250
|
+
|
|
251
|
+
mockMethods(gen);
|
|
252
|
+
await gen.generate(dummyYAML);
|
|
253
|
+
|
|
254
|
+
expect(xfsMock.mkdirpSync).toHaveBeenCalledWith(__dirname);
|
|
255
|
+
expect(gen.installTemplate).toHaveBeenCalledWith(false);
|
|
256
|
+
expect(gen.configureTemplate).toHaveBeenCalled();
|
|
257
|
+
expect(hooksRegistry.registerHooks).toHaveBeenCalled();
|
|
258
|
+
expect(filtersRegistry.registerFilters).toHaveBeenCalled();
|
|
259
|
+
expect(templateConfigValidator.validateTemplateConfig).toHaveBeenCalled();
|
|
260
|
+
expect(gen.launchHook).toHaveBeenCalledWith('generate:after');
|
|
261
|
+
expect(gen.originalAsyncAPI).toBe(dummyYAML);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('fails if input is not a string nor a parsed AsyncAPI document', async () => {
|
|
265
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
266
|
+
expect(() => gen.generate(1)).rejects.toThrow('Parameter "asyncapiDocument" must be a non-empty string or an already parsed AsyncAPI document');
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
describe('#generateFromString', () => {
|
|
271
|
+
let generateMock;
|
|
272
|
+
|
|
273
|
+
beforeAll(() => {
|
|
274
|
+
generateMock = jest.fn().mockResolvedValue();
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('calls this.generate', async () => {
|
|
278
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
279
|
+
gen.generate = generateMock;
|
|
280
|
+
await gen.generateFromString(dummyYAML);
|
|
281
|
+
|
|
282
|
+
expect(generateMock).toHaveBeenCalled();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('fails if asyncapiString is not provided', async () => {
|
|
286
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
287
|
+
gen.generate = generateMock;
|
|
288
|
+
expect(() => gen.generateFromString()).rejects.toThrow('Parameter "asyncapiString" must be a non-empty string.');
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('fails if asyncapiString is not a string', async () => {
|
|
292
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
293
|
+
gen.generate = generateMock;
|
|
294
|
+
expect(() => gen.generateFromString(1)).rejects.toThrow('Parameter "asyncapiString" must be a non-empty string.');
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
describe('#generateFromFile', () => {
|
|
299
|
+
it('calls readFile and generateFromString with the right params', async () => {
|
|
300
|
+
const utils = require('../lib/utils');
|
|
301
|
+
const filePath = 'fake-asyncapi.yml';
|
|
302
|
+
utils.__files = {
|
|
303
|
+
[filePath]: 'test content',
|
|
304
|
+
};
|
|
305
|
+
const generateMock = jest.fn().mockResolvedValue();
|
|
306
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
307
|
+
gen.generate = generateMock;
|
|
308
|
+
await gen.generateFromFile(filePath);
|
|
309
|
+
expect(utils.readFile).toHaveBeenCalled();
|
|
310
|
+
expect(utils.readFile.mock.calls[0][0]).toBe(filePath);
|
|
311
|
+
expect(utils.readFile.mock.calls[0][1]).toStrictEqual({ encoding: 'utf8' });
|
|
312
|
+
expect(generateMock.mock.calls[0][0]).toBe('test content');
|
|
313
|
+
expect(generateMock.mock.calls[0][1]).toStrictEqual({ path: filePath });
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
describe('#generateFromURL', () => {
|
|
318
|
+
it('calls fetch and generateFromString with the right params', async () => {
|
|
319
|
+
const utils = require('../lib/utils');
|
|
320
|
+
const asyncapiURL = 'http://example.com/fake-asyncapi.yml';
|
|
321
|
+
utils.__contentOfFetchedFile = 'fake text';
|
|
322
|
+
|
|
323
|
+
const generateMock = jest.fn().mockResolvedValue();
|
|
324
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
325
|
+
gen.generate = generateMock;
|
|
326
|
+
await gen.generateFromURL(asyncapiURL);
|
|
327
|
+
expect(utils.fetchSpec).toHaveBeenCalled();
|
|
328
|
+
expect(utils.fetchSpec.mock.calls[0][0]).toBe(asyncapiURL);
|
|
329
|
+
expect(generateMock.mock.calls[0][0]).toBe('fake text');
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
describe('#installTemplate', () => {
|
|
334
|
+
let ArboristMock;
|
|
335
|
+
let arboristMock;
|
|
336
|
+
let utils;
|
|
337
|
+
|
|
338
|
+
beforeEach(() => {
|
|
339
|
+
ArboristMock = require('@npmcli/arborist');
|
|
340
|
+
arboristMock = new ArboristMock();
|
|
341
|
+
utils = require('../lib/utils');
|
|
342
|
+
jest.mock(path.resolve('./testTemplate', 'package.json'), () => ({ name: 'nameOfTestTemplate' }), { virtual: true });
|
|
343
|
+
jest.mock(path.resolve(Generator.DEFAULT_TEMPLATES_DIR, 'nameOfTestTemplate', 'package.json'), () => ({ name: 'nameOfTestTemplate' }), { virtual: true });
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
it('works with a file system path', async () => {
|
|
347
|
+
log.debug = jest.fn();
|
|
348
|
+
utils.__getTemplateDetails = { pkgPath: '/path', name: 'test-template' };
|
|
349
|
+
const templatePath = './testTemplate';
|
|
350
|
+
const gen = new Generator(templatePath, __dirname);
|
|
351
|
+
await gen.installTemplate();
|
|
352
|
+
setTimeout(() => { // This puts the call at the end of the Node.js event loop queue.
|
|
353
|
+
expect(arboristMock.reify).toHaveBeenCalledTimes(0);
|
|
354
|
+
}, 0);
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it('works with a file system path and force = true', async () => {
|
|
358
|
+
log.debug = jest.fn();
|
|
359
|
+
const gen = new Generator('./testTemplate', __dirname);
|
|
360
|
+
await gen.installTemplate(true);
|
|
361
|
+
//TODO: this test is disabled until we find a solution how to fix jest config in monorepo so it recognize arborist mock
|
|
362
|
+
// setTimeout(() => { // This puts the call at the end of the Node.js event loop queue.
|
|
363
|
+
// expect(arboristMock.reify).toHaveBeenCalledTimes(1);
|
|
364
|
+
// expect(arboristMock.reify.mock.calls[0][0]).toStrictEqual({
|
|
365
|
+
// add: ['./testTemplate'],
|
|
366
|
+
// saveType: 'prod',
|
|
367
|
+
// save: false
|
|
368
|
+
// });
|
|
369
|
+
// }, 0);
|
|
370
|
+
expect(log.debug).toHaveBeenCalledWith(logMessage.installationDebugMessage(logMessage.TEMPLATE_INSTALL_FLAG_MSG));
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it('works with an npm package', async () => {
|
|
374
|
+
utils.__isFileSystemPathValue = false;
|
|
375
|
+
const gen = new Generator('nameOfTestTemplate', __dirname);
|
|
376
|
+
await gen.installTemplate();
|
|
377
|
+
setTimeout(() => { // This puts the call at the end of the Node.js event loop queue.
|
|
378
|
+
expect(arboristMock.reify).toHaveBeenCalledTimes(0);
|
|
379
|
+
}, 0);
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('works with an npm package that is installed for the first time', async () => {
|
|
383
|
+
log.debug = jest.fn();
|
|
384
|
+
utils.__getTemplateDetails = undefined;
|
|
385
|
+
const gen = new Generator('nameOfTestTemplate', __dirname, {debug: true});
|
|
386
|
+
await gen.installTemplate();
|
|
387
|
+
//TODO: this test is disabled until we find a solution how to fix jest config in monorepo so it recognize arborist mock
|
|
388
|
+
// setTimeout(() => { // This puts the call at the end of the Node.js event loop queue.
|
|
389
|
+
// expect(arboristMock.reify).toHaveBeenCalledTimes(1);
|
|
390
|
+
// }, 0);
|
|
391
|
+
expect(log.debug).toHaveBeenCalledWith(logMessage.installationDebugMessage(logMessage.TEMPLATE_INSTALL_DISK_MSG));
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
it('works with an npm package and force = true', async () => {
|
|
395
|
+
log.debug = jest.fn();
|
|
396
|
+
utils.__isFileSystemPathValue = false;
|
|
397
|
+
const gen = new Generator('nameOfTestTemplate', __dirname);
|
|
398
|
+
await gen.installTemplate(true);
|
|
399
|
+
//TODO: this test is disabled until we find a solution how to fix jest config in monorepo so it recognize arborist mock
|
|
400
|
+
// setTimeout(() => { // This puts the call at the end of the Node.js event loop queue.
|
|
401
|
+
// expect(arboristMock.reify).toHaveBeenCalledTimes(1);
|
|
402
|
+
// }, 0);
|
|
403
|
+
expect(log.debug).toHaveBeenCalledWith(logMessage.installationDebugMessage(logMessage.TEMPLATE_INSTALL_FLAG_MSG));
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
it('works with a url', async () => {
|
|
407
|
+
utils.__isFileSystemPathValue = false;
|
|
408
|
+
utils.__getTemplateDetails = undefined;
|
|
409
|
+
const gen = new Generator('https://my-test-template.com', __dirname);
|
|
410
|
+
await gen.installTemplate();
|
|
411
|
+
//TODO: this test is disabled until we find a solution how to fix jest config in monorepo so it recognize arborist mock
|
|
412
|
+
// setTimeout(() => { // This puts the call at the end of the Node.js event loop queue.
|
|
413
|
+
// expect(arboristMock.reify).toHaveBeenCalledTimes(1);
|
|
414
|
+
// }, 0);
|
|
415
|
+
expect(log.debug).toHaveBeenCalledWith(logMessage.installationDebugMessage(logMessage.TEMPLATE_INSTALL_DISK_MSG));
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('works with a url and force = true', async () => {
|
|
419
|
+
const gen = new Generator('https://my-test-template.com', __dirname);
|
|
420
|
+
await gen.installTemplate(true);
|
|
421
|
+
//TODO: this test is disabled until we find a solution how to fix jest config in monorepo so it recognize arborist mock
|
|
422
|
+
// setTimeout(() => { // This puts the call at the end of the Node.js event loop queue.
|
|
423
|
+
// expect(arboristMock.reify).toHaveBeenCalledTimes(1);
|
|
424
|
+
// }, 0);
|
|
425
|
+
expect(log.debug).toHaveBeenCalledWith(logMessage.installationDebugMessage(logMessage.TEMPLATE_INSTALL_FLAG_MSG));
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it('works with a path to registry', async () => {
|
|
429
|
+
log.debug = jest.fn();
|
|
430
|
+
const gen = new Generator('nameOfTestTemplate', __dirname, {debug: true, registry: {url: 'some.registry.com', authorizationName: 'sdfsf'}});
|
|
431
|
+
await gen.installTemplate();
|
|
432
|
+
//TODO: this test is disabled until we find a solution how to fix jest config in monorepo so it recognize arborist mock
|
|
433
|
+
// setTimeout(() => { // This puts the call at the end of the Node.js event loop queue.
|
|
434
|
+
// expect(arboristMock.reify).toHaveBeenCalledTimes(1);
|
|
435
|
+
// });
|
|
436
|
+
expect(log.debug).toHaveBeenCalledWith(logMessage.installationDebugMessage(logMessage.TEMPLATE_INSTALL_DISK_MSG));
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
it('throws an error indicating an unexpected param was given for registry configuration', () => {
|
|
440
|
+
const t = () => new Generator('testTemplate', __dirname, {
|
|
441
|
+
url: 'some.url.com',
|
|
442
|
+
privateKey: 'some.key'
|
|
443
|
+
|
|
444
|
+
});
|
|
445
|
+
expect(t).toThrow('These options are not supported by the generator: privateKey');
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
describe('.getTemplateFile', () => {
|
|
450
|
+
it('retrieves the content of a template file', async () => {
|
|
451
|
+
const utils = require('../lib/utils');
|
|
452
|
+
const filePath = path.resolve(Generator.DEFAULT_TEMPLATES_DIR, 'simple', 'template/static.md');
|
|
453
|
+
utils.__files = {
|
|
454
|
+
[filePath]: 'test content',
|
|
455
|
+
};
|
|
456
|
+
const content = await Generator.getTemplateFile('simple', 'template/static.md');
|
|
457
|
+
expect(utils.readFile).toHaveBeenCalled();
|
|
458
|
+
expect(utils.readFile.mock.calls[0][0]).toBe(filePath);
|
|
459
|
+
expect(content).toBe(utils.__files[filePath]);
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
it('retrieves the content of a template file overriding the default template dir', async () => {
|
|
463
|
+
const utils = require('../lib/utils');
|
|
464
|
+
const filePath = path.resolve('~', 'templates', 'simple', 'template/static.md');
|
|
465
|
+
utils.__files = {
|
|
466
|
+
[filePath]: 'test content',
|
|
467
|
+
};
|
|
468
|
+
const content = await Generator.getTemplateFile('simple', 'template/static.md', path.resolve('~', 'templates'));
|
|
469
|
+
expect(utils.readFile).toHaveBeenCalled();
|
|
470
|
+
expect(utils.readFile.mock.calls[0][0]).toBe(filePath);
|
|
471
|
+
expect(content).toBe(utils.__files[filePath]);
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
describe('#loadDefaultValues', () => {
|
|
476
|
+
it('default value of parameter is set', async () => {
|
|
477
|
+
const gen = new Generator('testTemplate', __dirname, {
|
|
478
|
+
templateParams: {
|
|
479
|
+
test: true
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
gen.templateConfig = {
|
|
483
|
+
parameters: {
|
|
484
|
+
paramWithDefault: {
|
|
485
|
+
description: 'Parameter with default value',
|
|
486
|
+
default: 'default',
|
|
487
|
+
required: false
|
|
488
|
+
},
|
|
489
|
+
paramWithoutDefault: {
|
|
490
|
+
description: 'Parameter without default value',
|
|
491
|
+
required: false
|
|
492
|
+
},
|
|
493
|
+
test: {
|
|
494
|
+
description: 'test',
|
|
495
|
+
required: false
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
await gen.loadDefaultValues();
|
|
501
|
+
|
|
502
|
+
expect(gen.templateParams).toStrictEqual({
|
|
503
|
+
test: true,
|
|
504
|
+
paramWithDefault: 'default'
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it('default value of parameter is not override user value', async () => {
|
|
509
|
+
const gen = new Generator('testTemplate', __dirname, {
|
|
510
|
+
templateParams: {
|
|
511
|
+
test: true
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
gen.templateConfig = {
|
|
515
|
+
parameters: {
|
|
516
|
+
test: {
|
|
517
|
+
description: 'Parameter with default value',
|
|
518
|
+
default: false,
|
|
519
|
+
required: false
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
await gen.loadDefaultValues();
|
|
525
|
+
|
|
526
|
+
expect(gen.templateParams).toStrictEqual({
|
|
527
|
+
test: true
|
|
528
|
+
});
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
it('no default values', async () => {
|
|
532
|
+
const gen = new Generator('testTemplate', __dirname, {
|
|
533
|
+
templateParams: {
|
|
534
|
+
test: true
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
gen.templateConfig = {
|
|
538
|
+
parameters: {
|
|
539
|
+
test: {
|
|
540
|
+
description: 'Parameter with default value',
|
|
541
|
+
required: false
|
|
542
|
+
},
|
|
543
|
+
anotherParam: {
|
|
544
|
+
description: 'Yeat another param',
|
|
545
|
+
required: false
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
await gen.loadDefaultValues();
|
|
551
|
+
|
|
552
|
+
expect(gen.templateParams).toStrictEqual({
|
|
553
|
+
test: true
|
|
554
|
+
});
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
describe('#launchHook', () => {
|
|
559
|
+
it('launch given hook', async () => {
|
|
560
|
+
let iteration = 0;
|
|
561
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
562
|
+
gen.hooks = { 'test-hooks': [function a() { iteration++; }, function b() { iteration++; }] };
|
|
563
|
+
await gen.launchHook('test-hooks');
|
|
564
|
+
expect(iteration).toStrictEqual(2);
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
it('launch given hook which is disabled', async () => {
|
|
568
|
+
let iteration = 0;
|
|
569
|
+
const gen = new Generator('testTemplate', __dirname, { disabledHooks: { 'test-hooks': true } });
|
|
570
|
+
gen.hooks = { 'test-hooks': [function a() { iteration++; }, function b() { iteration++; }] };
|
|
571
|
+
await gen.launchHook('test-hooks');
|
|
572
|
+
expect(iteration).toStrictEqual(0);
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
it('launch given hook where disabledHooks key has array format for given hook type', async () => {
|
|
576
|
+
let iteration = 0;
|
|
577
|
+
const gen = new Generator('testTemplate', __dirname, { disabledHooks: { 'test-hooks': ['a', 'b'] } });
|
|
578
|
+
gen.hooks = { 'test-hooks': [function a() { iteration++; }, function b() { iteration++; }, function c() { iteration++; }] };
|
|
579
|
+
await gen.launchHook('test-hooks');
|
|
580
|
+
expect(iteration).toStrictEqual(1);
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
it('launch given hook where disabledHooks key has array format for given hook type', async () => {
|
|
584
|
+
let iteration = 0;
|
|
585
|
+
const gen = new Generator('testTemplate', __dirname, { disabledHooks: { 'test-hooks': 'c' } });
|
|
586
|
+
gen.hooks = { 'test-hooks': [function a() { iteration++; }, function b() { iteration++; }, function c() { iteration++; }] };
|
|
587
|
+
await gen.launchHook('test-hooks');
|
|
588
|
+
expect(iteration).toStrictEqual(2);
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
describe('#isHookAvailable', () => {
|
|
593
|
+
it('given hook type not exist or has empty array', async () => {
|
|
594
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
595
|
+
gen.hooks = { 'test-hooks': [] };
|
|
596
|
+
expect(gen.isHookAvailable('foo-bar')).toStrictEqual(false);
|
|
597
|
+
expect(gen.isHookAvailable('test-hooks')).toStrictEqual(false);
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
it('given hook type exist and has hooks', async () => {
|
|
601
|
+
const gen = new Generator('testTemplate', __dirname);
|
|
602
|
+
gen.hooks = { 'test-hooks': ['foo-bar'] };
|
|
603
|
+
expect(gen.isHookAvailable('test-hooks')).toStrictEqual(true);
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
it('given hook type is disabled', async () => {
|
|
607
|
+
const gen = new Generator('testTemplate', __dirname, { disabledHooks: { 'test-hooks': true } });
|
|
608
|
+
gen.hooks = { 'test-hooks': ['foo-bar'] };
|
|
609
|
+
expect(gen.isHookAvailable('test-hooks')).toStrictEqual(false);
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
it('for given hook type only some hooks are disabled', async () => {
|
|
613
|
+
const gen = new Generator('testTemplate', __dirname, { disabledHooks: { 'test-hooks': ['fooBar'], 'string-test-hooks': 'fooBar' } });
|
|
614
|
+
gen.hooks = { 'test-hooks': [function fooBar() {}, function barFoo() {}], 'string-test-hooks': [function fooBar() {}, function barFoo() {}] };
|
|
615
|
+
expect(gen.isHookAvailable('test-hooks')).toStrictEqual(true);
|
|
616
|
+
expect(gen.isHookAvailable('string-test-hooks')).toStrictEqual(true);
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
it('for given hook type whole hooks are disabled', async () => {
|
|
620
|
+
const gen = new Generator('testTemplate', __dirname, { disabledHooks: { 'test-hooks': ['fooBar', 'barFoo'], 'string-test-hooks': 'fooBar' } });
|
|
621
|
+
gen.hooks = { 'test-hooks': [function fooBar() {}, function barFoo() {}], 'string-test-hooks': [function fooBar() {}] };
|
|
622
|
+
expect(gen.isHookAvailable('test-hooks')).toStrictEqual(false);
|
|
623
|
+
expect(gen.isHookAvailable('string-test-hooks')).toStrictEqual(false);
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment node
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { readFile } = require('fs').promises;
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const Generator = require('../lib/generator');
|
|
8
|
+
const dummySpecPath = path.resolve(__dirname, './docs/dummy.yml');
|
|
9
|
+
const refSpecPath = path.resolve(__dirname, './docs/apiwithref.json');
|
|
10
|
+
const refSpecFolder = path.resolve(__dirname, './docs/');
|
|
11
|
+
const crypto = require('crypto');
|
|
12
|
+
const mainTestResultPath = 'test/temp/integrationTestResult';
|
|
13
|
+
const reactTemplate = 'test/test-templates/react-template';
|
|
14
|
+
const nunjucksTemplate = 'test/test-templates/nunjucks-template';
|
|
15
|
+
|
|
16
|
+
describe('Integration testing generateFromFile() to make sure the result of the generation is not changend comparing to snapshot', () => {
|
|
17
|
+
const generateFolderName = () => {
|
|
18
|
+
//you always want to generate to new directory to make sure test runs in clear environment
|
|
19
|
+
return path.resolve(mainTestResultPath, crypto.randomBytes(4).toString('hex'));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
jest.setTimeout(60000);
|
|
23
|
+
const testOutputFile = 'test-file.md';
|
|
24
|
+
|
|
25
|
+
it('generated using Nunjucks template', async () => {
|
|
26
|
+
const outputDir = generateFolderName();
|
|
27
|
+
const generator = new Generator(nunjucksTemplate, outputDir, {
|
|
28
|
+
forceWrite: true,
|
|
29
|
+
templateParams: { version: 'v1', mode: 'production' }
|
|
30
|
+
});
|
|
31
|
+
await generator.generateFromFile(dummySpecPath);
|
|
32
|
+
const file = await readFile(path.join(outputDir, testOutputFile), 'utf8');
|
|
33
|
+
expect(file).toMatchSnapshot();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('generate using React template', async () => {
|
|
37
|
+
const outputDir = generateFolderName();
|
|
38
|
+
const generator = new Generator(reactTemplate, outputDir, {
|
|
39
|
+
forceWrite: true ,
|
|
40
|
+
templateParams: { version: 'v1', mode: 'production' }
|
|
41
|
+
});
|
|
42
|
+
await generator.generateFromFile(dummySpecPath);
|
|
43
|
+
const file = await readFile(path.join(outputDir, testOutputFile), 'utf8');
|
|
44
|
+
expect(file).toMatchSnapshot();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('generate json based api with referenced JSON Schema', async () => {
|
|
48
|
+
const outputDir = generateFolderName();
|
|
49
|
+
const generator = new Generator(reactTemplate, outputDir, {
|
|
50
|
+
mapBaseUrlToFolder: { url: 'https://schema.example.com/crm/', folder: `${refSpecFolder}/`},
|
|
51
|
+
forceWrite: true,
|
|
52
|
+
templateParams: { version: 'v1', mode: 'production' }
|
|
53
|
+
});
|
|
54
|
+
await generator.generateFromFile(refSpecPath);
|
|
55
|
+
const file = await readFile(path.join(outputDir, testOutputFile), 'utf8');
|
|
56
|
+
expect(file).toMatchSnapshot();
|
|
57
|
+
});
|
|
58
|
+
});
|