diff --git a/src/language-tools/java.ts b/src/language-tools/java.ts index b17ea05..eb48758 100644 --- a/src/language-tools/java.ts +++ b/src/language-tools/java.ts @@ -20,7 +20,10 @@ export class JavaLanguageTools implements LanguageTools { * @returns Lookup key to find this test case in the TestRunTracker. */ mapTestFinishDataToLookupKey(testFinishData: TestFinish): string | undefined { - if (testFinishData.dataKind === TestFinishDataKind.JUnitStyleTestCaseData) { + if ( + testFinishData.dataKind === TestFinishDataKind.JUnitStyleTestCaseData && + testFinishData.data + ) { const testCaseData = testFinishData.data as JUnitStyleTestCaseData if (testCaseData.className !== undefined) { let testCaseName = testFinishData.displayName @@ -31,7 +34,10 @@ export class JavaLanguageTools implements LanguageTools { testCaseName = match.groups.lookupKey } - return `${testCaseData.className}.${testCaseName}` + // Use the class name as the base, and append the test case name if available. + let result = testCaseData.className + if (testCaseName.length > 0) result += `.${testCaseName}` + return result } else { return testFinishData.displayName } diff --git a/src/language-tools/python.ts b/src/language-tools/python.ts index 2879bb5..f71feac 100644 --- a/src/language-tools/python.ts +++ b/src/language-tools/python.ts @@ -22,7 +22,10 @@ export class PythonLanguageTools * @returns Lookup key to find this test case in the TestRunTracker. */ mapTestFinishDataToLookupKey(testFinishData: TestFinish): string | undefined { - if (testFinishData.dataKind === TestFinishDataKind.JUnitStyleTestCaseData) { + if ( + testFinishData.dataKind === TestFinishDataKind.JUnitStyleTestCaseData && + testFinishData.data + ) { const testCaseData = testFinishData.data as JUnitStyleTestCaseData let testCaseName = testFinishData.displayName @@ -32,7 +35,10 @@ export class PythonLanguageTools testCaseName = match.groups.lookupKey } - return `${testCaseData.className}.${testCaseName}` + // Use the class name as the base, and append the test case name if available. + let result = testCaseData.className + if (testCaseName.length > 0) result += `.${testCaseName}` + return result } return undefined } diff --git a/src/test/suite/language-tools/java.test.ts b/src/test/suite/language-tools/java.test.ts index 524eb3c..1b29cb1 100644 --- a/src/test/suite/language-tools/java.test.ts +++ b/src/test/suite/language-tools/java.test.ts @@ -99,45 +99,149 @@ suite('Java Language Tools', () => { assert.strictEqual(result.testCases.length, 0) }) - test('map test finish data to lookup key', async () => { - let result = languageTools.mapTestFinishDataToLookupKey({ - displayName: 'myTest', - status: TestStatus.Failed, - dataKind: TestFinishDataKind.JUnitStyleTestCaseData, - data: { - time: 0, - className: 'com.example.ClassName', + const testCases = [ + { + description: 'test method within a class', + input: { + displayName: 'myTest', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'com.example.ClassName', + }, }, - }) - assert.strictEqual(result, 'com.example.ClassName.myTest') - - result = languageTools.mapTestFinishDataToLookupKey({ - displayName: 'com.example.MySuite', - status: TestStatus.Failed, - dataKind: TestFinishDataKind.JUnitStyleTestCaseData, - data: { - time: 0, + expected: 'com.example.ClassName.myTest', + }, + { + description: 'suite level test case', + input: { + displayName: 'com.example.MySuite', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + }, }, - }) - assert.strictEqual(result, 'com.example.MySuite') - - result = languageTools.mapTestFinishDataToLookupKey({ - displayName: 'com.example.MySuite', - status: TestStatus.Failed, - }) - assert.strictEqual(result, undefined) - - result = languageTools.mapTestFinishDataToLookupKey({ - displayName: 'myTest[example1]', - status: TestStatus.Failed, - dataKind: TestFinishDataKind.JUnitStyleTestCaseData, - data: { - time: 0, - className: 'com.example.ClassName', + expected: 'com.example.MySuite', + }, + { + description: 'no dataKind provided', + input: { + displayName: 'com.example.MySuite', + status: TestStatus.Failed, + }, + expected: undefined, + }, + { + description: 'parameterized test cases', + input: { + displayName: 'myTest[example1]', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'com.example.ClassName', + }, + }, + expected: 'com.example.ClassName.myTest', + }, + { + description: 'successful tests with data', + input: { + displayName: 'mySuccessfulTest', + status: TestStatus.Passed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 1, + className: 'com.example.SuccessClass', + }, }, + expected: 'com.example.SuccessClass.mySuccessfulTest', + }, + { + description: 'tests with no className', + input: { + displayName: 'myTestWithoutClass', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 2, + }, + }, + expected: 'myTestWithoutClass', + }, + { + description: 'unknown dataKind', + input: { + displayName: 'unknownTest', + status: TestStatus.Failed, + dataKind: 'UnknownDataKind', + data: { + time: 0, + className: 'com.example.UnknownClass', + }, + }, + expected: undefined, + }, + // Remaining scenarios are unexpected, but should still return results. + { + description: 'null data gracefully', + input: { + displayName: 'nullDataTest', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: null, + }, + expected: undefined, + }, + { + description: 'numeric displayName', + input: { + displayName: '123456', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'com.example.ClassName', + }, + }, + expected: 'com.example.ClassName.123456', + }, + { + description: 'special characters in displayName', + input: { + displayName: '!@#$%^&*()', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'com.example.ClassName', + }, + }, + expected: 'com.example.ClassName.!@#$%^&*()', + }, + { + description: 'empty string as displayName', + input: { + displayName: '', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'com.example.ClassName', + }, + }, + expected: 'com.example.ClassName', + }, + ] + + for (const testCase of testCases) { + test(`map test finish data to lookup key: ${testCase.description}`, async () => { + const result = languageTools.mapTestFinishDataToLookupKey(testCase.input) + assert.strictEqual(result, testCase.expected) }) - assert.strictEqual(result, 'com.example.ClassName.myTest') - }) + } test('map test case info to lookup key', async () => { let testInfo = testController.createTestItem('test1', 'test1') diff --git a/src/test/suite/language-tools/python.test.ts b/src/test/suite/language-tools/python.test.ts index f025c7d..3c4cc9d 100644 --- a/src/test/suite/language-tools/python.test.ts +++ b/src/test/suite/language-tools/python.test.ts @@ -88,49 +88,139 @@ suite('Python Language Tools', () => { assert.ok(executeCommandStub.notCalled) }) - test('map test finish data to lookup key', async () => { - let result = languageTools.mapTestFinishDataToLookupKey({ - displayName: 'test_method', - status: TestStatus.Failed, - dataKind: TestFinishDataKind.JUnitStyleTestCaseData, - data: { - time: 0, - className: 'my.example.test_example.TestMyClass', + const testCases = [ + { + description: 'method within a class', + input: { + displayName: 'test_method', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'my.example.test_example.TestMyClass', + }, }, - }) - assert.strictEqual( - result, - 'my.example.test_example.TestMyClass.test_method' - ) - - result = languageTools.mapTestFinishDataToLookupKey({ - displayName: 'test_method', - status: TestStatus.Failed, - dataKind: TestFinishDataKind.JUnitStyleTestCaseData, - data: { - time: 0, - className: 'my.example.test_example', + expected: 'my.example.test_example.TestMyClass.test_method', + }, + { + description: 'standalone method', + input: { + displayName: 'test_method', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'my.example.test_example', + }, }, - }) - assert.strictEqual(result, 'my.example.test_example.test_method') - - result = languageTools.mapTestFinishDataToLookupKey({ - displayName: 'test_method[example1]', - status: TestStatus.Failed, - dataKind: TestFinishDataKind.JUnitStyleTestCaseData, - data: { - time: 0, - className: 'my.example.test_example', + expected: 'my.example.test_example.test_method', + }, + { + description: 'parameterized test result', + input: { + displayName: 'test_method[example1]', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'my.example.test_example', + }, }, - }) - assert.strictEqual(result, 'my.example.test_example.test_method') + expected: 'my.example.test_example.test_method', + }, + { + description: 'result with no data', + input: { + displayName: 'pytest', + status: TestStatus.Failed, + }, + expected: undefined, + }, + { + description: 'successful test case', + input: { + displayName: 'test_successful_method', + status: TestStatus.Passed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 1, + className: 'my.example.test_example.TestMyClass', + }, + }, + expected: 'my.example.test_example.TestMyClass.test_successful_method', + }, + { + description: 'unknown dataKind', + input: { + displayName: 'unknown_test', + status: TestStatus.Failed, + dataKind: 'UnknownDataKind', + data: { + time: 0, + className: 'my.example.test_example.UnknownClass', + }, + }, + expected: undefined, + }, + // Remaining scenarios are unexpected, but should still return results. + { + description: 'method with special characters', + input: { + displayName: 'test_method_with_special_chars!@#', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'my.example.test_example.TestMyClass', + }, + }, + expected: + 'my.example.test_example.TestMyClass.test_method_with_special_chars!@#', + }, + { + description: 'method with numeric displayName', + input: { + displayName: '123456', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'my.example.test_example.TestMyClass', + }, + }, + expected: 'my.example.test_example.TestMyClass.123456', + }, + { + description: 'empty string as displayName', + input: { + displayName: '', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: { + time: 0, + className: 'my.example.test_example.TestMyClass', + }, + }, + expected: 'my.example.test_example.TestMyClass', + }, + { + description: 'null data gracefully', + input: { + displayName: 'null_data_test', + status: TestStatus.Failed, + dataKind: TestFinishDataKind.JUnitStyleTestCaseData, + data: null, + }, + expected: undefined, + }, + ] - result = languageTools.mapTestFinishDataToLookupKey({ - displayName: 'pytest', - status: TestStatus.Failed, + for (const testCase of testCases) { + test(`map test finish data to lookup key: ${testCase.description}`, async () => { + const result = languageTools.mapTestFinishDataToLookupKey(testCase.input) + assert.strictEqual(result, testCase.expected) }) - assert.strictEqual(result, undefined) - }) + } test('map test case info to lookup key', async () => { let testInfo = testController.createTestItem('test1', 'test1')