Skip to content

Commit a29c4d5

Browse files
authored
chore: check if generated CTS match committed CTS (#107)
1 parent e3b7ed8 commit a29c4d5

File tree

10 files changed

+96
-114
lines changed

10 files changed

+96
-114
lines changed

.github/workflows/check.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,5 +158,8 @@ jobs:
158158
- name: Generate CTS
159159
run: yarn cts:generate
160160

161+
- name: Check diff with pushed CTS
162+
run: exit $(git status --porcelain ./tests/output | wc -l)
163+
161164
- name: Run CTS
162165
run: yarn cts:test

tests/CTS/config.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"javascript": {
3+
"extension": "test.ts",
4+
"outputFolder": "tests"
5+
},
6+
"java": {
7+
"extension": "test.java",
8+
"outputFolder": "src/test/java/com/algolia"
9+
}
10+
}

tests/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
],
77
"scripts": {
88
"build": "tsc",
9-
"generate": "yarn generate:methods:requets ${0:-javascript} ${1:-search} && yarn generate:client ${0:-javascript} ${1:-search} && yarn format ${0:-javascript}",
9+
"generate": "yarn generate:methods:requets ${0:-javascript} ${1:-search} && yarn generate:client ${0:-javascript} ${1:-search}",
1010
"generate:methods:requets": "node dist/tests/src/methods/requests/main.js ${0:-javascript} ${1:-search}",
1111
"generate:client": "node dist/tests/src/client/main.js ${0:-javascript} ${1:-search}",
1212
"format": "../scripts/formatter.sh ${0:-javascript} tests/output/${0:-javascript} && yarn lint",

tests/src/client/generate.ts

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ import Mustache from 'mustache';
55
import openapitools from '../../../openapitools.json';
66
import {
77
walk,
8-
extensionForLanguage,
98
packageNames,
109
createClientName,
1110
exists,
11+
createOutputDir,
12+
getOutputPath,
13+
loadTemplates,
1214
} from '../utils';
1315

1416
import type { TestsBlock, Test, ModifiedStepForMustache } from './types';
1517

18+
const testPath = 'client';
19+
1620
async function loadTests(client: string): Promise<TestsBlock[]> {
1721
const testsBlocks: TestsBlock[] = [];
1822
const clientPath = `./CTS/client/${client}`;
@@ -53,28 +57,6 @@ async function loadTests(client: string): Promise<TestsBlock[]> {
5357
return testsBlocks;
5458
}
5559

56-
async function loadTemplates(
57-
language: string
58-
): Promise<Record<string, string>> {
59-
const templates: Record<string, string> = {};
60-
const templatePath = `./CTS/client/templates/${language}`;
61-
62-
await exists(`./CTS/client/templates/javascript`);
63-
if (!(await exists(templatePath))) {
64-
return {};
65-
}
66-
67-
for await (const file of walk(templatePath)) {
68-
if (!file.name.endsWith('.mustache')) {
69-
continue;
70-
}
71-
const type = file.name.replace('.mustache', '');
72-
const fileContent = (await fsp.readFile(file.path)).toString();
73-
templates[type] = fileContent;
74-
}
75-
return templates;
76-
}
77-
7860
export async function generateTests(
7961
language: string,
8062
client: string
@@ -89,11 +71,12 @@ export async function generateTests(
8971
return;
9072
}
9173

92-
const outputPath = `output/${language}/tests/client/`;
93-
await fsp.mkdir(outputPath, { recursive: true });
94-
const { suite: template, ...partialTemplates } = await loadTemplates(
95-
language
96-
);
74+
await createOutputDir({ language, testPath });
75+
76+
const { suite: template, ...partialTemplates } = await loadTemplates({
77+
language,
78+
testPath,
79+
});
9780

9881
if (!template) {
9982
// eslint-disable-next-line no-console
@@ -117,10 +100,7 @@ export async function generateTests(
117100
},
118101
partialTemplates
119102
);
120-
await fsp.writeFile(
121-
`${outputPath}/${client}.${extensionForLanguage[language]}`,
122-
code
123-
);
103+
await fsp.writeFile(getOutputPath({ language, client, testPath }), code);
124104
}
125105

126106
function serializeParameters(parameters: any): string {

tests/src/methods/requests/generate.ts

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,27 @@ import openapitools from '../../../../openapitools.json';
66
import {
77
createClientName,
88
packageNames,
9-
extensionForLanguage,
10-
sourcePathForLanguage,
119
capitalize,
10+
getOutputPath,
11+
createOutputDir,
12+
loadTemplates,
1213
} from '../../utils';
1314

1415
import { loadCTS } from './cts';
15-
import { loadPartials, loadRequestsTemplate } from './templates';
16-
import type { CTSBlock } from './types';
1716

18-
async function createOutputDir(language: string): Promise<void> {
19-
await fsp.mkdir(`output/${language}/${sourcePathForLanguage[language]}`, {
20-
recursive: true,
21-
});
22-
}
17+
const testPath = 'methods/requests';
2318

24-
async function generateRequestsTests(
25-
cts: CTSBlock[],
26-
template: string,
19+
export async function generateTests(
2720
language: string,
28-
client: string,
29-
partials: Record<string, string>
21+
client: string
3022
): Promise<void> {
23+
const { requests: template, ...partialTemplates } = await loadTemplates({
24+
language,
25+
testPath,
26+
});
27+
const cts = (await loadCTS(client)).requests;
28+
await createOutputDir({ language, testPath });
29+
3130
if (cts.length === 0) {
3231
return;
3332
}
@@ -54,30 +53,8 @@ async function generateRequestsTests(
5453
};
5554
},
5655
},
57-
partials
56+
partialTemplates
5857
);
5958

60-
await fsp.writeFile(
61-
`output/${language}/${sourcePathForLanguage[language]}/${client}.${extensionForLanguage[language]}`,
62-
code
63-
);
64-
}
65-
66-
export async function generateTests(
67-
language: string,
68-
client: string
69-
): Promise<void> {
70-
const template = await loadRequestsTemplate(language);
71-
const cts = await loadCTS(client);
72-
const partials = await loadPartials(language);
73-
74-
await createOutputDir(language);
75-
76-
await generateRequestsTests(
77-
cts.requests,
78-
template,
79-
language,
80-
client,
81-
partials
82-
);
59+
await fsp.writeFile(getOutputPath({ language, client, testPath }), code);
8360
}

tests/src/methods/requests/templates.ts

Lines changed: 0 additions & 30 deletions
This file was deleted.

tests/src/utils.ts

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fsp from 'fs/promises';
22
import path from 'path';
33

44
import openapitools from '../../openapitools.json';
5+
import ctsConfig from '../CTS/config.json';
56

67
// For each generator, we map the packageName with the language and client
78
export const packageNames: Record<
@@ -90,19 +91,8 @@ export function removeEnumType(obj: any): any {
9091
return obj;
9192
}
9293

93-
// All those language dependents object should be defined in the CTS itself
94-
export const extensionForLanguage: Record<string, string> = {
95-
javascript: 'test.ts',
96-
java: 'test.java',
97-
};
98-
99-
export const sourcePathForLanguage: Record<string, string> = {
100-
javascript: 'tests/methods/requests',
101-
java: 'src/test/java/com/algolia',
102-
};
103-
104-
/* eslint-disable no-console */
10594
function printUsage(commandName: string): void {
95+
/* eslint-disable no-console */
10696
console.log(`usage: ${commandName} language client`);
10797
// eslint-disable-next-line no-process-exit
10898
process.exit(1);
@@ -130,10 +120,62 @@ export function parseCLI(
130120
// eslint-disable-next-line no-process-exit
131121
process.exit(1);
132122
}
123+
/* eslint-enable no-console */
133124

134125
return {
135126
lang,
136127
client,
137128
};
138129
}
139-
/* eslint-enable no-console */
130+
131+
export async function createOutputDir({
132+
language,
133+
testPath,
134+
}: {
135+
language: string;
136+
testPath: string;
137+
}): Promise<void> {
138+
await fsp.mkdir(
139+
`output/${language}/${ctsConfig[language].outputFolder}/${testPath}`,
140+
{
141+
recursive: true,
142+
}
143+
);
144+
}
145+
146+
export function getOutputPath({
147+
language,
148+
client,
149+
testPath,
150+
}: {
151+
language: string;
152+
client: string;
153+
testPath: string;
154+
}): string {
155+
return `output/${language}/${ctsConfig[language].outputFolder}/${testPath}/${client}.${ctsConfig[language].extension}`;
156+
}
157+
158+
export async function loadTemplates({
159+
language,
160+
testPath,
161+
}: {
162+
language: string;
163+
testPath: string;
164+
}): Promise<Record<string, string>> {
165+
const templates: Record<string, string> = {};
166+
const templatePath = `./CTS/${testPath}/templates/${language}`;
167+
168+
if (!(await exists(templatePath))) {
169+
return {};
170+
}
171+
172+
for await (const file of walk(templatePath)) {
173+
if (!file.name.endsWith('.mustache')) {
174+
continue;
175+
}
176+
const name = file.name.replace('.mustache', '');
177+
const fileContent = (await fsp.readFile(file.path)).toString();
178+
templates[name] = fileContent;
179+
}
180+
return templates;
181+
}

0 commit comments

Comments
 (0)