Skip to content

Commit fed0989

Browse files
committed
update tests
1 parent b446896 commit fed0989

1 file changed

Lines changed: 207 additions & 27 deletions

File tree

src/testResultsSummary.unit.test.ts

Lines changed: 207 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as path from "path";
55
import * as os from "os";
66
import * as nodeFs from "fs";
77
import { JSDOM } from "jsdom";
8-
import type { TestResultsData, MatlabTestFile, TestStatistics } from "./testResultsSummary.js";
8+
import type { TestResultsData, MatlabTestFile, TestStatistics, TestSession } from "./testResultsSummary.js";
99

1010
// Mock @actions/core
1111
jest.unstable_mockModule("@actions/core", () => ({
@@ -22,6 +22,7 @@ jest.unstable_mockModule("fs", () => ({
2222
existsSync: nodeFs.existsSync,
2323
writeFileSync: nodeFs.writeFileSync,
2424
copyFileSync: nodeFs.copyFileSync,
25+
readdirSync: nodeFs.readdirSync,
2526
unlinkSync: mockUnlinkSync,
2627
}));
2728

@@ -34,8 +35,8 @@ const { MatlabTestStatus } = testResultsSummary;
3435
describe("Artifact Processing Tests", () => {
3536
// Shared test data
3637
let testResultsData: TestResultsData | null;
37-
let testResults: MatlabTestFile[][];
38-
let stats: TestStatistics;
38+
let testSessions: TestSession[];
39+
let overallStats: TestStatistics;
3940

4041
beforeAll(() => {
4142
const runnerTemp = path.join(import.meta.dirname, "..");
@@ -48,8 +49,8 @@ describe("Artifact Processing Tests", () => {
4849

4950
testResultsData = testResultsSummary.getTestResults(runnerTemp, runId, workspace);
5051
if (testResultsData) {
51-
testResults = testResultsData.TestResults;
52-
stats = testResultsData.Stats;
52+
testSessions = testResultsData.TestSessions;
53+
overallStats = testResultsData.OverallStats;
5354
}
5455
});
5556

@@ -78,7 +79,7 @@ describe("Artifact Processing Tests", () => {
7879
osName,
7980
"matlabTestResults.json",
8081
);
81-
const destinationFilePath = path.join(runnerTemp, "matlabTestResults" + runId + ".json");
82+
const destinationFilePath = path.join(runnerTemp, "matlabTestResults_20250101_120000_000.json");
8283

8384
try {
8485
fs.copyFileSync(sourceFilePath, destinationFilePath);
@@ -87,26 +88,48 @@ describe("Artifact Processing Tests", () => {
8788
}
8889
}
8990

91+
it("should return correct test results data structure", () => {
92+
expect(testResultsData).toBeDefined();
93+
expect(testSessions).toBeDefined();
94+
expect(overallStats).toBeDefined();
95+
expect(testSessions.length).toBe(1);
96+
expect(testSessions[0].FileName).toBe("matlabTestResults_20250101_120000_000.json");
97+
expect(testSessions[0].TestResults.length).toBe(2);
98+
expect(testSessions[0].TestResults[0].length).toBe(1);
99+
expect(testSessions[0].TestResults[1].length).toBe(1);
100+
});
101+
90102
it("should return correct test results data for valid JSON", () => {
103+
const testResults = testSessions[0].TestResults;
91104
expect(testResults).toBeDefined();
92-
expect(stats).toBeDefined();
93105
expect(testResults.length).toBe(2);
94106
expect(testResults[0].length).toBe(1);
95107
expect(testResults[1].length).toBe(1);
96108
expect(testResults[0][0].TestCases.length).toBe(9);
97109
expect(testResults[1][0].TestCases.length).toBe(1);
98110
});
99111

100-
it("should return correct test stats for valid JSON", () => {
101-
expect(stats.Total).toBe(10);
102-
expect(stats.Passed).toBe(4);
103-
expect(stats.Failed).toBe(3);
104-
expect(stats.Incomplete).toBe(2);
105-
expect(stats.NotRun).toBe(1);
106-
expect(stats.Duration).toBeCloseTo(1.83);
112+
it("should return correct overall stats for valid JSON", () => {
113+
expect(overallStats.Total).toBe(10);
114+
expect(overallStats.Passed).toBe(4);
115+
expect(overallStats.Failed).toBe(3);
116+
expect(overallStats.Incomplete).toBe(2);
117+
expect(overallStats.NotRun).toBe(1);
118+
expect(overallStats.Duration).toBeCloseTo(1.83);
119+
});
120+
121+
it("should return correct session stats for valid JSON", () => {
122+
const sessionStats = testSessions[0].Stats;
123+
expect(sessionStats.Total).toBe(10);
124+
expect(sessionStats.Passed).toBe(4);
125+
expect(sessionStats.Failed).toBe(3);
126+
expect(sessionStats.Incomplete).toBe(2);
127+
expect(sessionStats.NotRun).toBe(1);
128+
expect(sessionStats.Duration).toBeCloseTo(1.83);
107129
});
108130

109131
it("should return correct test files data for valid JSON", () => {
132+
const testResults = testSessions[0].TestResults;
110133
expect(testResults[0][0].Path).toBe(path.join("visualization", "tests", "TestExamples1"));
111134
expect(testResults[1][0].Path).toBe(
112135
path.join("visualization", "duplicate_tests", "TestExamples2"),
@@ -120,6 +143,7 @@ describe("Artifact Processing Tests", () => {
120143
});
121144

122145
it("should return correct test cases data for valid JSON", () => {
146+
const testResults = testSessions[0].TestResults;
123147
expect(testResults[0][0].TestCases[0].Name).toBe("testNonLeapYear");
124148
expect(testResults[0][0].TestCases[4].Name).toBe("testLeapYear");
125149
expect(testResults[0][0].TestCases[7].Name).toBe("testValidDateFormat");
@@ -148,12 +172,100 @@ describe("Artifact Processing Tests", () => {
148172
);
149173
});
150174

175+
it("should handle test results with undefined Details property", () => {
176+
const runnerTemp = path.join(import.meta.dirname, "..");
177+
const testFilePath = path.join(runnerTemp, "matlabTestResults_undefined_details.json");
178+
179+
// Create test data with undefined Details
180+
const testData = [[
181+
{
182+
BaseFolder: "/workspace/tests",
183+
TestResult: {
184+
Name: "TestFile/testCase1",
185+
Duration: 0.5,
186+
Failed: false,
187+
Incomplete: false,
188+
Passed: true,
189+
// Details property is intentionally omitted
190+
}
191+
}
192+
]];
193+
194+
try {
195+
fs.writeFileSync(testFilePath, JSON.stringify(testData));
196+
197+
const result = testResultsSummary.getTestResults(runnerTemp, "123", "/workspace");
198+
199+
expect(result).not.toBeNull();
200+
if (result) {
201+
expect(result.TestSessions.length).toBeGreaterThan(0);
202+
const session = result.TestSessions.find(s => s.FileName === "matlabTestResults_undefined_details.json");
203+
expect(session).toBeDefined();
204+
if (session) {
205+
expect(session.TestResults.length).toBeGreaterThan(0);
206+
const testFile = session.TestResults[0][0];
207+
expect(testFile.TestCases.length).toBe(1);
208+
expect(testFile.TestCases[0].Diagnostics).toEqual([]);
209+
}
210+
}
211+
} finally {
212+
if (nodeFs.existsSync(testFilePath)) {
213+
nodeFs.unlinkSync(testFilePath);
214+
}
215+
}
216+
});
217+
218+
it("should handle test results with Details but no DiagnosticRecord", () => {
219+
const runnerTemp = path.join(import.meta.dirname, "..");
220+
const testFilePath = path.join(runnerTemp, "matlabTestResults_no_diagnostics.json");
221+
222+
// Create test data with Details but no DiagnosticRecord
223+
const testData = [[
224+
{
225+
BaseFolder: "/workspace/tests",
226+
TestResult: {
227+
Name: "TestFile/testCase1",
228+
Duration: 0.5,
229+
Failed: false,
230+
Incomplete: false,
231+
Passed: true,
232+
Details: {}
233+
}
234+
}
235+
]];
236+
237+
try {
238+
fs.writeFileSync(testFilePath, JSON.stringify(testData));
239+
240+
const result = testResultsSummary.getTestResults(runnerTemp, "123", "/workspace");
241+
242+
expect(result).not.toBeNull();
243+
if (result) {
244+
expect(result.TestSessions.length).toBeGreaterThan(0);
245+
const session = result.TestSessions.find(s => s.FileName === "matlabTestResults_no_diagnostics.json");
246+
expect(session).toBeDefined();
247+
if (session) {
248+
expect(session.TestResults.length).toBeGreaterThan(0);
249+
const testFile = session.TestResults[0][0];
250+
expect(testFile.TestCases.length).toBe(1);
251+
expect(testFile.TestCases[0].Diagnostics).toEqual([]);
252+
}
253+
}
254+
} finally {
255+
if (nodeFs.existsSync(testFilePath)) {
256+
nodeFs.unlinkSync(testFilePath);
257+
}
258+
}
259+
});
260+
151261
it("should write test results data to the GitHub job summary", () => {
152262
if (testResultsData) {
153-
const actionName = process.env.GITHUB_ACTION || "";
154263
testResultsSummary.addSummary(testResultsData, null);
155264

265+
// Should have: 1 main heading + 1 session heading = 2 total
156266
expect(core.summary.addHeading).toHaveBeenCalledTimes(2);
267+
268+
// First heading: overall results
157269
expect(core.summary.addHeading).toHaveBeenNthCalledWith(
158270
1,
159271
expect.stringContaining("MATLAB Test Results "),
@@ -172,9 +284,47 @@ describe("Artifact Processing Tests", () => {
172284
1,
173285
expect.stringContaining("ℹ️</a>"),
174286
);
175-
expect(core.summary.addHeading).toHaveBeenNthCalledWith(2, "All tests", 3);
287+
288+
// Second heading: session (no session number for single session)
289+
expect(core.summary.addHeading).toHaveBeenNthCalledWith(2, "Test Session", 3);
176290

177-
expect(core.summary.addRaw).toHaveBeenCalledTimes(2);
291+
// Should have: 1 overall header + 1 session header + 1 detailed results = 3 total
292+
expect(core.summary.addRaw).toHaveBeenCalledTimes(3);
293+
}
294+
});
295+
296+
it("should show session numbers when multiple sessions exist", () => {
297+
if (testResultsData) {
298+
// Create a mock with multiple sessions
299+
const multiSessionData: TestResultsData = {
300+
TestSessions: [
301+
testResultsData.TestSessions[0],
302+
{
303+
FileName: "matlabTestResults_20250101_120001_000.json",
304+
TestResults: testResultsData.TestSessions[0].TestResults,
305+
Stats: testResultsData.TestSessions[0].Stats,
306+
},
307+
],
308+
OverallStats: {
309+
Total: testResultsData.OverallStats.Total * 2,
310+
Passed: testResultsData.OverallStats.Passed * 2,
311+
Failed: testResultsData.OverallStats.Failed * 2,
312+
Incomplete: testResultsData.OverallStats.Incomplete * 2,
313+
NotRun: testResultsData.OverallStats.NotRun * 2,
314+
Duration: testResultsData.OverallStats.Duration * 2,
315+
},
316+
};
317+
318+
// Clear previous mock calls
319+
(core.summary.addHeading as jest.Mock).mockClear();
320+
(core.summary.addRaw as jest.Mock).mockClear();
321+
322+
testResultsSummary.addSummary(multiSessionData, null);
323+
324+
// Should have: 1 main heading + 2 session headings = 3 total
325+
expect(core.summary.addHeading).toHaveBeenCalledTimes(3);
326+
expect(core.summary.addHeading).toHaveBeenNthCalledWith(2, "Test Session (Session 1)", 3);
327+
expect(core.summary.addHeading).toHaveBeenNthCalledWith(3, "Test Session (Session 2)", 3);
178328
}
179329
});
180330
});
@@ -347,10 +497,14 @@ describe("Error Handling Tests", () => {
347497
NotRun: 0,
348498
Duration: 0.5,
349499
};
350-
const mockTestResults: MatlabTestFile[][] = [];
500+
const mockTestResults: MatlabTestFile[] = [];
351501
const mockTestResultsData: TestResultsData = {
352-
TestResults: mockTestResults,
353-
Stats: mockStats,
502+
TestSessions: [{
503+
FileName: "test.json",
504+
TestResults: [mockTestResults],
505+
Stats: mockStats,
506+
}],
507+
OverallStats: mockStats,
354508
};
355509

356510
// This should not throw, but should log the error
@@ -376,7 +530,7 @@ describe("Error Handling Tests", () => {
376530
process.env.GITHUB_ACTION = "run-tests";
377531

378532
// Create a file with invalid JSON
379-
const invalidJsonPath = path.join(process.env.RUNNER_TEMP, "matlabTestResults123.json");
533+
const invalidJsonPath = path.join(process.env.RUNNER_TEMP, "matlabTestResults_invalid.json");
380534
fs.writeFileSync(invalidJsonPath, "{ invalid json content");
381535

382536
try {
@@ -385,7 +539,12 @@ describe("Error Handling Tests", () => {
385539
process.env.GITHUB_RUN_ID,
386540
"",
387541
);
388-
expect(result).toBeNull();
542+
543+
// Should return data but skip the invalid file
544+
if (result) {
545+
// The invalid file should be skipped, so we might have 0 sessions
546+
expect(result.TestSessions).toBeDefined();
547+
}
389548

390549
// Verify error was logged
391550
expect(consoleSpy).toHaveBeenCalledWith(
@@ -417,8 +576,8 @@ describe("Error Handling Tests", () => {
417576
process.env.GITHUB_ACTION = "run-tests";
418577

419578
// Create a valid JSON file
420-
const validJsonPath = path.join(process.env.RUNNER_TEMP, "matlabTestResults123.json");
421-
fs.writeFileSync(validJsonPath, "[]"); // Empty array - valid JSON
579+
const validJsonPath = path.join(process.env.RUNNER_TEMP, "matlabTestResults_delete_test.json");
580+
fs.writeFileSync(validJsonPath, "[[]]"); // Empty array - valid JSON
422581

423582
try {
424583
const result = testResultsSummary.getTestResults(
@@ -427,10 +586,10 @@ describe("Error Handling Tests", () => {
427586
"",
428587
);
429588

589+
// Should still return results even if deletion fails
590+
expect(result).toBeDefined();
430591
if (result) {
431-
// Should still return results even if deletion fails
432-
expect(result).toBeDefined();
433-
expect(result.TestResults).toEqual([]);
592+
expect(result.TestSessions.length).toBeGreaterThanOrEqual(0);
434593
}
435594

436595
// Verify deletion error was logged
@@ -456,4 +615,25 @@ describe("Error Handling Tests", () => {
456615
}
457616
}
458617
});
618+
619+
it("should handle directory read errors gracefully", () => {
620+
const consoleSpy = jest.spyOn(console, "error").mockImplementation(() => {});
621+
622+
// Use a non-existent directory
623+
const nonExistentDir = path.join(import.meta.dirname, "non_existent_directory_12345");
624+
625+
const result = testResultsSummary.getTestResults(
626+
nonExistentDir,
627+
"123",
628+
"",
629+
);
630+
631+
expect(result).toBeNull();
632+
expect(consoleSpy).toHaveBeenCalledWith(
633+
expect.stringContaining(`An error occurred while reading directory ${nonExistentDir}`),
634+
expect.any(Error),
635+
);
636+
637+
consoleSpy.mockRestore();
638+
});
459639
});

0 commit comments

Comments
 (0)