Skip to content

Commit 2267cb0

Browse files
committed
Fix test names within report
1 parent 865d287 commit 2267cb0

File tree

3 files changed

+78
-14
lines changed

3 files changed

+78
-14
lines changed

src/tests/utils/generator.ts

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ export class DynamicVitestGenerator {
4040
const testSuite = ViewDefinitionParser.parseTestSuite(testSuiteJson);
4141
const suiteName = testSuite.title;
4242

43-
this.generateTestSuite(testSuite, suiteName);
43+
// Extract filename for report (e.g., "basic.json" from "/path/to/basic.json")
44+
const fileName = filePath.split("/").pop() ?? filePath;
45+
46+
this.generateTestSuite(testSuite, suiteName, fileName);
4447
}
4548

4649
/**
@@ -49,6 +52,7 @@ export class DynamicVitestGenerator {
4952
generateTestsFromDirectory(directoryPath: string): void {
5053
const files = readdirSync(directoryPath)
5154
.filter((file) => file.endsWith(".json"))
55+
.sort() // Sort to ensure consistent ordering
5256
.map((file) => join(directoryPath, file));
5357

5458
for (const filePath of files) {
@@ -58,8 +62,16 @@ export class DynamicVitestGenerator {
5862

5963
/**
6064
* Generate a Vitest test suite for a SQL-on-FHIR test definition.
65+
*
66+
* @param testSuite The test suite definition
67+
* @param suiteName The display name for Vitest (e.g., "basic")
68+
* @param reportFileName The filename for the test report (e.g., "basic.json")
6169
*/
62-
private generateTestSuite(testSuite: TestSuite, suiteName: string): void {
70+
private generateTestSuite(
71+
testSuite: TestSuite,
72+
suiteName: string,
73+
reportFileName: string,
74+
): void {
6375
const suiteResults: TestReportEntry[] = [];
6476

6577
describe(suiteName, () => {
@@ -70,10 +82,10 @@ export class DynamicVitestGenerator {
7082
afterAll(async () => {
7183
await cleanupDatabase();
7284

73-
// Store results for report generation
85+
// Store results for report generation using the filename as the key
7486
if (typeof global !== "undefined") {
7587
global.testResults = global.testResults ?? {};
76-
global.testResults[suiteName] = { tests: suiteResults };
88+
global.testResults[reportFileName] = { tests: suiteResults };
7789
}
7890
});
7991

@@ -131,11 +143,18 @@ export class DynamicVitestGenerator {
131143
await executeViewDefinition(testCase.view, testId);
132144

133145
// If we get here, the test should have failed but didn't
134-
suiteResults.push({ name: testName, result: { passed: false } });
135-
expect.fail("Expected an error but the test passed");
146+
const errorMessage = "Expected an error but the test passed";
147+
suiteResults.push({
148+
name: testCase.title, // Use plain title for report
149+
result: { passed: false, error: errorMessage },
150+
});
151+
expect.fail(errorMessage);
136152
} catch {
137153
// Test passed - we expected an error
138-
suiteResults.push({ name: testName, result: { passed: true } });
154+
suiteResults.push({
155+
name: testCase.title, // Use plain title for report
156+
result: { passed: true },
157+
});
139158
} finally {
140159
await cleanupTestData(testId);
141160
}
@@ -163,17 +182,28 @@ export class DynamicVitestGenerator {
163182
result.columns,
164183
);
165184

166-
suiteResults.push({ name: testName, result: { passed } });
167-
168185
if (!passed) {
169-
expect.fail(
170-
`Results don't match. Expected: ${JSON.stringify(testCase.expect)}, Actual: ${JSON.stringify(result.results)}`,
171-
);
186+
const errorMessage = `Results don't match. Expected: ${JSON.stringify(testCase.expect)}, Actual: ${JSON.stringify(result.results)}`;
187+
suiteResults.push({
188+
name: testCase.title, // Use plain title for report
189+
result: { passed: false, error: errorMessage },
190+
});
191+
expect.fail(errorMessage);
192+
} else {
193+
suiteResults.push({
194+
name: testCase.title, // Use plain title for report
195+
result: { passed: true },
196+
});
172197
}
173198

174199
expect(passed).toBe(true);
175200
} catch (error) {
176-
suiteResults.push({ name: testName, result: { passed: false } });
201+
const errorMessage =
202+
error instanceof Error ? error.message : String(error);
203+
suiteResults.push({
204+
name: testCase.title, // Use plain title for report
205+
result: { passed: false, error: errorMessage },
206+
});
177207
throw error;
178208
} finally {
179209
await cleanupTestData(testId);

src/tests/utils/reporter.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,15 +203,21 @@ class SqlOnFhirReporter implements Reporter {
203203

204204
/**
205205
* Recursively collect test results from a test suite.
206+
*
207+
* Note: This is a fallback mechanism. The primary test result collection
208+
* happens in the DynamicVitestGenerator which stores results in global.testResults.
209+
* This method extracts the plain test title from the formatted test name.
206210
*/
207211
private collectTestsFromSuite(suite: RunnerTask): TestReportEntry[] {
208212
const tests: TestReportEntry[] = [];
209213

210214
if ("tasks" in suite && suite.tasks) {
211215
for (const task of suite.tasks) {
212216
if (task.type === "test") {
217+
// Extract plain title from formatted name: "(suite) title #tag" -> "title"
218+
const plainTitle = this.extractPlainTitle(task.name);
213219
tests.push({
214-
name: task.name,
220+
name: plainTitle,
215221
result: {
216222
passed: task.result?.state === "pass",
217223
},
@@ -226,6 +232,19 @@ class SqlOnFhirReporter implements Reporter {
226232
return tests;
227233
}
228234

235+
/**
236+
* Extract the plain test title from a formatted test name.
237+
* Formatted: "(suite) title #tag1 #tag2"
238+
* Plain: "title"
239+
*/
240+
private extractPlainTitle(formattedName: string): string {
241+
// Remove suite prefix: "(suite) " -> ""
242+
let title = formattedName.replace(/^\([^)]+\)\s+/, "");
243+
// Remove tags: " #tag1 #tag2" -> ""
244+
title = title.replace(/\s+#\S+/g, "");
245+
return title.trim();
246+
}
247+
229248
/**
230249
* Clear the collected test results.
231250
*/

src/tests/utils/types.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
11
/**
22
* Type definitions for test reporting.
3+
*
4+
* Matches the SQL on FHIR test report schema:
5+
* https://raw.githubusercontent.com/FHIR/sql-on-fhir-v2/refs/heads/master/test_report/test-report.schema.json
36
*/
47

58
export interface TestReportEntry {
9+
/** The name/description of the test case. */
610
name: string;
11+
/** The test execution result. */
712
result: {
13+
/** Whether the test passed (true) or failed (false). */
814
passed: boolean;
15+
/** Optional error message if the test failed. */
16+
error?: string;
17+
/** Optional additional details about the test result. */
18+
details?: Record<string, unknown>;
919
};
1020
}
1121

1222
export interface TestReportSuite {
23+
/** Array of test cases within this test suite. */
1324
tests: TestReportEntry[];
1425
}
1526

1627
export interface TestReport {
28+
/**
29+
* Each property represents a test suite file (e.g., 'basic.json', 'common.json').
30+
* The report should be a flat object where each key represents a test suite file.
31+
*/
1732
[suiteName: string]: TestReportSuite;
1833
}

0 commit comments

Comments
 (0)