@grafana/openapi-to-k6 0.2.5 → 0.2.6
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/.github/workflows/tests.yaml +1 -0
- package/README.md +6 -4
- package/dist/cli.js +27 -12
- package/dist/errors.js +10 -0
- package/dist/generator/index.js +50 -3
- package/dist/helper.js +32 -0
- package/examples/basic_schema/single/simpleAPI.ts +1 -1
- package/examples/basic_schema/split/simpleAPI.schemas.ts +1 -1
- package/examples/basic_schema/split/simpleAPI.ts +1 -1
- package/examples/basic_schema/tags/default.ts +1 -1
- package/examples/basic_schema/tags/simpleAPI.schemas.ts +1 -1
- package/examples/form_data_schema/single/formDataAPI.ts +1 -1
- package/examples/form_data_schema/split/formDataAPI.schemas.ts +1 -1
- package/examples/form_data_schema/split/formDataAPI.ts +1 -1
- package/examples/form_data_schema/tags/default.ts +1 -1
- package/examples/form_data_schema/tags/formDataAPI.schemas.ts +1 -1
- package/examples/form_url_encoded_data_schema/single/formURLEncodedAPI.ts +1 -1
- package/examples/form_url_encoded_data_schema/split/formURLEncodedAPI.schemas.ts +1 -1
- package/examples/form_url_encoded_data_schema/split/formURLEncodedAPI.ts +1 -1
- package/examples/form_url_encoded_data_schema/tags/default.ts +1 -1
- package/examples/form_url_encoded_data_schema/tags/formURLEncodedAPI.schemas.ts +1 -1
- package/examples/form_url_encoded_data_with_query_params_schema/single/formURLEncodedAPIWithQueryParameters.ts +1 -1
- package/examples/form_url_encoded_data_with_query_params_schema/split/formURLEncodedAPIWithQueryParameters.schemas.ts +1 -1
- package/examples/form_url_encoded_data_with_query_params_schema/split/formURLEncodedAPIWithQueryParameters.ts +1 -1
- package/examples/form_url_encoded_data_with_query_params_schema/tags/default.ts +1 -1
- package/examples/form_url_encoded_data_with_query_params_schema/tags/formURLEncodedAPIWithQueryParameters.schemas.ts +1 -1
- package/examples/get_request_with_path_parameters_schema/single/simpleAPI.ts +1 -1
- package/examples/get_request_with_path_parameters_schema/split/simpleAPI.schemas.ts +1 -1
- package/examples/get_request_with_path_parameters_schema/split/simpleAPI.ts +1 -1
- package/examples/get_request_with_path_parameters_schema/tags/default.ts +1 -1
- package/examples/get_request_with_path_parameters_schema/tags/simpleAPI.schemas.ts +1 -1
- package/examples/headers_schema/single/headerDemoAPI.ts +1 -1
- package/examples/headers_schema/split/headerDemoAPI.schemas.ts +1 -1
- package/examples/headers_schema/split/headerDemoAPI.ts +1 -1
- package/examples/headers_schema/tags/default.ts +1 -1
- package/examples/headers_schema/tags/headerDemoAPI.schemas.ts +1 -1
- package/examples/no_title_schema/single/k6Client.ts +1 -1
- package/examples/no_title_schema/split/k6Client.schemas.ts +1 -1
- package/examples/no_title_schema/split/k6Client.ts +1 -1
- package/examples/no_title_schema/tags/default.ts +1 -1
- package/examples/no_title_schema/tags/k6Client.schemas.ts +1 -1
- package/examples/post_request_with_query_params/single/exampleAPI.ts +1 -1
- package/examples/post_request_with_query_params/split/exampleAPI.schemas.ts +1 -1
- package/examples/post_request_with_query_params/split/exampleAPI.ts +1 -1
- package/examples/post_request_with_query_params/tags/default.ts +1 -1
- package/examples/post_request_with_query_params/tags/exampleAPI.schemas.ts +1 -1
- package/examples/query_params_schema/single/exampleAPI.ts +1 -1
- package/examples/query_params_schema/split/exampleAPI.schemas.ts +1 -1
- package/examples/query_params_schema/split/exampleAPI.ts +1 -1
- package/examples/query_params_schema/tags/default.ts +1 -1
- package/examples/query_params_schema/tags/exampleAPI.schemas.ts +1 -1
- package/examples/simple_post_request_schema/single/exampleAPI.ts +1 -1
- package/examples/simple_post_request_schema/split/exampleAPI.schemas.ts +1 -1
- package/examples/simple_post_request_schema/split/exampleAPI.ts +1 -1
- package/examples/simple_post_request_schema/tags/default.ts +1 -1
- package/examples/simple_post_request_schema/tags/exampleAPI.schemas.ts +1 -1
- package/package.json +1 -1
- package/src/cli.ts +32 -14
- package/src/errors.ts +6 -0
- package/src/generator/index.ts +67 -2
- package/src/helper.ts +40 -0
- package/src/type.d.ts +1 -0
- package/tests/e2e/schema.json +1 -0
- package/tests/e2e/single-tag-filter/k6Script.ts +50 -0
- package/tests/e2e/tags/k6Script.ts +3 -3
- package/tests/functional-tests/fixtures/tags_filtering.json +141 -0
- package/tests/functional-tests/generator.test.ts +159 -3
- package/tests/helper.test.ts +59 -0
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
it,
|
|
13
13
|
} from 'vitest'
|
|
14
14
|
import { Mode } from '../../src/constants'
|
|
15
|
+
import { NoFilesGeneratedError } from '../../src/errors'
|
|
15
16
|
import generator from '../../src/generator'
|
|
16
17
|
|
|
17
18
|
const writeFile = promisify(fs.writeFile)
|
|
@@ -19,7 +20,7 @@ const readFile = promisify(fs.readFile)
|
|
|
19
20
|
const mkdtemp = promisify(fs.mkdtemp)
|
|
20
21
|
const rmdir = promisify(fs.rmdir)
|
|
21
22
|
|
|
22
|
-
const fixturesDir = path.join(__dirname, 'fixtures'
|
|
23
|
+
const fixturesDir = path.join(__dirname, 'fixtures')
|
|
23
24
|
|
|
24
25
|
const loadFixture = (filename: string) => {
|
|
25
26
|
const filePath = path.join(fixturesDir, filename)
|
|
@@ -44,7 +45,7 @@ function replaceSpacesAndNewLineToSingleSpace(input: string): string {
|
|
|
44
45
|
|
|
45
46
|
describe('generator', () => {
|
|
46
47
|
let tempDir: string, schemaDirectory: string
|
|
47
|
-
const allFixtures = fs.readdirSync(fixturesDir)
|
|
48
|
+
const allFixtures = fs.readdirSync(path.join(fixturesDir, 'schemas'))
|
|
48
49
|
|
|
49
50
|
beforeAll(async () => {
|
|
50
51
|
tempDir = await mkdtemp(path.join(os.tmpdir(), 'sdk-generator-'))
|
|
@@ -57,7 +58,7 @@ describe('generator', () => {
|
|
|
57
58
|
for (const fixtureName of allFixtures) {
|
|
58
59
|
describe(`test ${fixtureName} OpenAPI schema`, () => {
|
|
59
60
|
let openApiPath: string, generatedSchemaPath: string
|
|
60
|
-
const fixture = loadFixture(fixtureName)
|
|
61
|
+
const fixture = loadFixture(path.join('schemas', fixtureName))
|
|
61
62
|
|
|
62
63
|
beforeEach(async () => {
|
|
63
64
|
schemaDirectory = await mkdtemp(
|
|
@@ -160,4 +161,159 @@ describe('generator', () => {
|
|
|
160
161
|
})
|
|
161
162
|
})
|
|
162
163
|
}
|
|
164
|
+
|
|
165
|
+
describe('validate tags filtering', () => {
|
|
166
|
+
let tempDir: string, openApiPath: string
|
|
167
|
+
const tagsFilteringSchema = loadFixture('tags_filtering.json')
|
|
168
|
+
|
|
169
|
+
beforeAll(async () => {
|
|
170
|
+
tempDir = await mkdtemp(path.join(os.tmpdir(), 'tags-filtering-test-'))
|
|
171
|
+
openApiPath = path.join(tempDir, 'openapi-schema.json')
|
|
172
|
+
await writeFile(openApiPath, JSON.stringify(tagsFilteringSchema))
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
afterAll(async () => {
|
|
176
|
+
await rmdir(tempDir, { recursive: true })
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
const generateAndTest = async (
|
|
180
|
+
mode: Mode,
|
|
181
|
+
tags: string[],
|
|
182
|
+
expectedFiles: string[],
|
|
183
|
+
expectedContents: string[],
|
|
184
|
+
unexpectedContents: string[]
|
|
185
|
+
) => {
|
|
186
|
+
const generatedSchemaPath = path.join(
|
|
187
|
+
tempDir,
|
|
188
|
+
`generated-schema-${mode}-${tags.join('-')}`
|
|
189
|
+
)
|
|
190
|
+
await generator({
|
|
191
|
+
openApiPath,
|
|
192
|
+
outputDir: generatedSchemaPath,
|
|
193
|
+
tags,
|
|
194
|
+
mode,
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
const generatedFiles = fs.readdirSync(generatedSchemaPath)
|
|
198
|
+
expect(generatedFiles).to.have.members(expectedFiles)
|
|
199
|
+
|
|
200
|
+
for (const file of expectedFiles) {
|
|
201
|
+
if (file.includes('.schemas.ts')) {
|
|
202
|
+
// Skip schemas file
|
|
203
|
+
continue
|
|
204
|
+
}
|
|
205
|
+
const generatedFilePath = path.join(generatedSchemaPath, file)
|
|
206
|
+
const generatedContent = await readFile(generatedFilePath, 'utf-8')
|
|
207
|
+
|
|
208
|
+
for (const content of expectedContents) {
|
|
209
|
+
expect(generatedContent).to.contain(content)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
for (const content of unexpectedContents) {
|
|
213
|
+
expect(generatedContent).not.to.contain(content)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
it('should generate only endpoints with specified tags in single mode', async () => {
|
|
219
|
+
await generateAndTest(
|
|
220
|
+
Mode.SINGLE,
|
|
221
|
+
['users'],
|
|
222
|
+
['sampleAPI.ts'],
|
|
223
|
+
['/users'],
|
|
224
|
+
['/user-profiles', '/pets', '/auth']
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
await generateAndTest(
|
|
228
|
+
Mode.SINGLE,
|
|
229
|
+
['users', 'userProfiles'],
|
|
230
|
+
['sampleAPI.ts'],
|
|
231
|
+
['/users', '/user-profiles'],
|
|
232
|
+
['/pets', '/auth']
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
// Invalid tag should not generate any endpoints
|
|
236
|
+
await generateAndTest(
|
|
237
|
+
Mode.SINGLE,
|
|
238
|
+
['invalid-tag'],
|
|
239
|
+
['sampleAPI.ts'],
|
|
240
|
+
[],
|
|
241
|
+
['/users', '/user-profiles', '/pets', '/auth']
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
// Empty tags should generate all endpoints
|
|
245
|
+
await generateAndTest(
|
|
246
|
+
Mode.SINGLE,
|
|
247
|
+
[],
|
|
248
|
+
['sampleAPI.ts'],
|
|
249
|
+
['/users', '/user-profiles', '/pets', '/auth'],
|
|
250
|
+
[]
|
|
251
|
+
)
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
it('should generate only endpoints with specified tags in split mode', async () => {
|
|
255
|
+
await generateAndTest(
|
|
256
|
+
Mode.SPLIT,
|
|
257
|
+
['users'],
|
|
258
|
+
['sampleAPI.ts', 'sampleAPI.schemas.ts'],
|
|
259
|
+
['/users'],
|
|
260
|
+
['/user-profiles', '/pets', '/auth']
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
// Test empty tags
|
|
264
|
+
await generateAndTest(
|
|
265
|
+
Mode.SPLIT,
|
|
266
|
+
[],
|
|
267
|
+
['sampleAPI.ts', 'sampleAPI.schemas.ts'],
|
|
268
|
+
['/users', '/user-profiles', '/pets', '/auth'],
|
|
269
|
+
[]
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
// Invalid tag should not generate any endpoints
|
|
273
|
+
// In the single mode it will create the client file which will have only the schemas
|
|
274
|
+
await expect(
|
|
275
|
+
generateAndTest(
|
|
276
|
+
Mode.SPLIT,
|
|
277
|
+
['invalid-tag'],
|
|
278
|
+
[],
|
|
279
|
+
[],
|
|
280
|
+
['/users', '/user-profiles', '/pets', '/auth']
|
|
281
|
+
)
|
|
282
|
+
).rejects.toThrow(NoFilesGeneratedError)
|
|
283
|
+
|
|
284
|
+
// Empty tags should generate all endpoints
|
|
285
|
+
await generateAndTest(
|
|
286
|
+
Mode.SPLIT,
|
|
287
|
+
[],
|
|
288
|
+
['sampleAPI.ts', 'sampleAPI.schemas.ts'],
|
|
289
|
+
['/users', '/user-profiles', '/pets', '/auth'],
|
|
290
|
+
[]
|
|
291
|
+
)
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
it('should generate only endpoints with specified tags in tags mode', async () => {
|
|
295
|
+
await generateAndTest(
|
|
296
|
+
Mode.TAGS,
|
|
297
|
+
['users'],
|
|
298
|
+
['users.ts', 'sampleAPI.schemas.ts'],
|
|
299
|
+
['/users'],
|
|
300
|
+
['/user-profiles', '/pets', '/auth']
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
// Empty tags should generate all endpoints
|
|
304
|
+
await generateAndTest(
|
|
305
|
+
Mode.TAGS,
|
|
306
|
+
[],
|
|
307
|
+
[
|
|
308
|
+
'users.ts',
|
|
309
|
+
'sampleAPI.schemas.ts',
|
|
310
|
+
'auth.ts',
|
|
311
|
+
'pets.ts',
|
|
312
|
+
'user-profiles.ts',
|
|
313
|
+
],
|
|
314
|
+
[], // Skipping test for content
|
|
315
|
+
[]
|
|
316
|
+
)
|
|
317
|
+
})
|
|
318
|
+
})
|
|
163
319
|
})
|
package/tests/helper.test.ts
CHANGED
|
@@ -157,3 +157,62 @@ describe('getDirectoryForPath', () => {
|
|
|
157
157
|
expect(directory).toEqual(expectedDirectory)
|
|
158
158
|
})
|
|
159
159
|
})
|
|
160
|
+
|
|
161
|
+
describe('hasOnlyComments', () => {
|
|
162
|
+
it('should return true if the file has only comments', () => {
|
|
163
|
+
const expectedResultsAndData = [
|
|
164
|
+
{
|
|
165
|
+
fileContent: '// This is a comment',
|
|
166
|
+
expectedResult: true,
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
fileContent: '/* This is a comment */',
|
|
170
|
+
expectedResult: true,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
fileContent: '// This is a comment\nconst x = 1',
|
|
174
|
+
expectedResult: false,
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
fileContent: '/* This is a comment */\nconst x = 1',
|
|
178
|
+
expectedResult: false,
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
fileContent: 'const x = 1',
|
|
182
|
+
expectedResult: false,
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
fileContent: '',
|
|
186
|
+
expectedResult: true,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
fileContent: '// This is a comment\n// This is another comment',
|
|
190
|
+
expectedResult: true,
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
fileContent: '/* This is a comment */\n/* This is another comment */',
|
|
194
|
+
expectedResult: true,
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
fileContent: '// This is a comment\n/* This is another comment */',
|
|
198
|
+
expectedResult: true,
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
fileContent: `/**
|
|
202
|
+
* This is a comment
|
|
203
|
+
*/
|
|
204
|
+
`,
|
|
205
|
+
expectedResult: true,
|
|
206
|
+
},
|
|
207
|
+
]
|
|
208
|
+
for (const { fileContent, expectedResult } of expectedResultsAndData) {
|
|
209
|
+
const result = helper.hasOnlyComments(fileContent)
|
|
210
|
+
try {
|
|
211
|
+
expect(result).toBe(expectedResult)
|
|
212
|
+
} catch (error) {
|
|
213
|
+
console.log(`Expected ${expectedResult} for content:\n${fileContent}`)
|
|
214
|
+
throw error
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
})
|