Skip to content

Commit 2612b25

Browse files
awilkinsjdneoAdrian Wilkins
authored
feat - Set which encoding your test JVM will start with (#1735)
* Set which encoding your test JVM will start with This patch adds a setting to the `java.test.config` object. ```jsonc { "java.test.config": { "encoding": "ISO-8859-1", }, } ``` The aim here is to be able to seamlessly test code which cares about the launch encoding of the JVM. Yes, such code is not good. But sometimes you don't control your dependencies enough to fix this. Since the debug launcher already cares about the `encoding` member of the config, the only thing required is to add the member, which is missing from the launch configs generated by the test plugin. ```typescript // In `configurationProvider.ts:` (vscode-java-debug) // VS Code internal console uses UTF-8 to display output by default. if (config.console === "internalConsole" && !config.encoding) { config.encoding = "UTF-8"; } ``` Fixes #1641 --------- Co-authored-by: Sheng Chen <sheche@microsoft.com> Co-authored-by: Adrian Wilkins <adrian.wilkins.contractor@dvla.gov.uk>
1 parent d00d92a commit 2612b25

File tree

6 files changed

+113
-56
lines changed

6 files changed

+113
-56
lines changed

package.json

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,18 @@
5555
"main": "./main.js",
5656
"contributes": {
5757
"javaExtensions": [
58-
"./server/junit-jupiter-api_5.10.3.jar",
59-
"./server/junit-jupiter-engine_5.10.3.jar",
60-
"./server/junit-jupiter-migrationsupport_5.10.3.jar",
61-
"./server/junit-jupiter-params_5.10.3.jar",
62-
"./server/junit-platform-commons_1.10.3.jar",
63-
"./server/junit-platform-engine_1.10.3.jar",
64-
"./server/junit-platform-launcher_1.10.3.jar",
65-
"./server/junit-platform-runner_1.10.3.jar",
66-
"./server/junit-platform-suite-api_1.10.3.jar",
67-
"./server/junit-platform-suite-commons_1.10.3.jar",
68-
"./server/junit-platform-suite-engine_1.10.3.jar",
69-
"./server/junit-vintage-engine_5.10.3.jar",
58+
"./server/junit-jupiter-api_5.11.0.jar",
59+
"./server/junit-jupiter-engine_5.11.0.jar",
60+
"./server/junit-jupiter-migrationsupport_5.11.0.jar",
61+
"./server/junit-jupiter-params_5.11.0.jar",
62+
"./server/junit-platform-commons_1.11.0.jar",
63+
"./server/junit-platform-engine_1.11.0.jar",
64+
"./server/junit-platform-launcher_1.11.0.jar",
65+
"./server/junit-platform-runner_1.11.0.jar",
66+
"./server/junit-platform-suite-api_1.11.0.jar",
67+
"./server/junit-platform-suite-commons_1.11.0.jar",
68+
"./server/junit-platform-suite-engine_1.11.0.jar",
69+
"./server/junit-vintage-engine_5.11.0.jar",
7070
"./server/org.apiguardian.api_1.1.2.jar",
7171
"./server/org.eclipse.jdt.junit4.runtime_1.3.100.v20231214-1952.jar",
7272
"./server/org.eclipse.jdt.junit5.runtime_1.1.300.v20231214-1952.jar",
@@ -254,6 +254,11 @@
254254
"markdownDescription": "%configuration.java.test.config.javaExec.description%",
255255
"default": ""
256256
},
257+
"encoding": {
258+
"type": "string",
259+
"description": "%configuration.java.test.config.encoding.description%",
260+
"default": ""
261+
},
257262
"vmArgs": {
258263
"type": "array",
259264
"items": {
@@ -409,7 +414,12 @@
409414
"markdownDescription": "%configuration.java.test.config.javaExec.description%",
410415
"default": ""
411416
},
412-
"vmargs": {
417+
"encoding": {
418+
"type": "string",
419+
"description": "%configuration.java.test.config.encoding.description%",
420+
"default": ""
421+
},
422+
"vmArgs": {
413423
"type": "array",
414424
"items": {
415425
"type": "string"

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"configuration.java.test.config.modulePaths.runtime.description": "The modulepaths within 'runtime' scope of current project.",
2222
"configuration.java.test.config.modulePaths.test.description": "The modulepaths within 'test' scope of current project.",
2323
"configuration.java.test.config.modulePaths.exclude.description": "The path after '!' will be excluded from the modulePaths.",
24+
"configuration.java.test.config.encoding.description": "The 'file.encoding' setting for the test JVM. Only set this if you have to test code that relies on the default encoding being something other than UTF-8.",
2425
"configuration.java.test.config.vmArgs.description": "Specify the extra options and system properties for the JVM.",
2526
"configuration.java.test.config.args.description": "Specify the command line arguments which will be passed to the test runner.",
2627
"configuration.java.test.config.env.description": "Specify the extra environment variables when running the tests.",

src/java-test-runner.api.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,12 @@ export interface IExecutionConfig {
279279
*/
280280
javaExec?: string;
281281

282+
/**
283+
* the default encoding the JVM will start with. If undefined, this will be UTF-8.
284+
* @since 0.43.0
285+
*/
286+
encoding?: string;
287+
282288
/**
283289
* the extra options and system properties for the JVM.
284290
* @since 0.14.0
@@ -353,4 +359,4 @@ export interface IExecutionConfig {
353359
* @since 0.41.0
354360
*/
355361
when?: string
356-
}
362+
}

src/utils/launchUtils.ts

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,68 +18,51 @@ export async function resolveLaunchConfigurationForRunner(runner: BaseRunner, te
1818

1919
if (config && config.vmArgs) {
2020
launchArguments.vmArguments.push(...config.vmArgs.filter(Boolean));
21-
} else if (config && (config as any).vmargs) { // to support the deprecated property name.
22-
launchArguments.vmArguments.push(...(config as any).vmargs.filter(Boolean));
23-
sendInfo('', {'deprecatedPropertyUsed': 'vmargs'});
2421
}
2522

26-
let debugConfiguration: DebugConfiguration;
23+
let debugConfiguration: DebugConfiguration = {
24+
name: `Launch Java Tests - ${testContext.testItems[0].label}`,
25+
type: 'java',
26+
request: 'launch',
27+
projectName: launchArguments.projectName,
28+
cwd: config && config.workingDirectory ? config.workingDirectory : launchArguments.workingDirectory,
29+
modulePaths: [
30+
...config?.modulePaths || [],
31+
...launchArguments.modulepath || [],
32+
],
33+
encoding: config?.encoding,
34+
vmArgs: launchArguments.vmArguments,
35+
env: config?.env,
36+
envFile: config?.envFile,
37+
noDebug: !testContext.isDebug,
38+
sourcePaths: config?.sourcePaths,
39+
preLaunchTask: config?.preLaunchTask,
40+
postDebugTask: config?.postDebugTask,
41+
javaExec: config?.javaExec,
42+
};
43+
2744
if (testContext.kind === TestKind.TestNG) {
28-
debugConfiguration = {
29-
name: `Launch Java Tests - ${testContext.testItems[0].label}`,
30-
type: 'java',
31-
request: 'launch',
45+
debugConfiguration = Object.assign(debugConfiguration, {
3246
mainClass: 'com.microsoft.java.test.runner.Launcher',
33-
projectName: launchArguments.projectName,
34-
cwd: config && config.workingDirectory ? config.workingDirectory : launchArguments.workingDirectory,
3547
classPaths: [
3648
...config?.classPaths || [],
3749
...launchArguments.classpath || [],
3850
path.join(extensionContext.extensionPath, 'server', 'com.microsoft.java.test.runner-jar-with-dependencies.jar'),
3951
],
40-
modulePaths: [
41-
...config?.modulePaths || [],
42-
...launchArguments.modulepath || [],
43-
],
4452
args: runner.getApplicationArgs(config),
45-
vmArgs: launchArguments.vmArguments,
46-
env: config?.env,
47-
envFile: config?.envFile,
48-
noDebug: !testContext.isDebug,
49-
sourcePaths: config?.sourcePaths,
50-
preLaunchTask: config?.preLaunchTask,
51-
postDebugTask: config?.postDebugTask,
52-
javaExec: config?.javaExec,
53-
};
53+
});
5454
} else {
55-
debugConfiguration = {
56-
name: `Launch Java Tests - ${testContext.testItems[0].label}`,
57-
type: 'java',
58-
request: 'launch',
55+
debugConfiguration = Object.assign(debugConfiguration, {
5956
mainClass: launchArguments.mainClass,
60-
projectName: launchArguments.projectName,
61-
cwd: config && config.workingDirectory ? config.workingDirectory : launchArguments.workingDirectory,
6257
classPaths: [
6358
...config?.classPaths || [],
6459
...launchArguments.classpath || [],
6560
],
66-
modulePaths: [
67-
...config?.modulePaths || [],
68-
...launchArguments.modulepath || [],
69-
],
7061
args: [
7162
...launchArguments.programArguments,
7263
...(testContext.kind === TestKind.JUnit5 ? parseTags(config) : [])
7364
],
74-
vmArgs: launchArguments.vmArguments,
75-
env: config?.env,
76-
envFile: config?.envFile,
77-
noDebug: !testContext.isDebug,
78-
sourcePaths: config?.sourcePaths,
79-
preLaunchTask: config?.preLaunchTask,
80-
postDebugTask: config?.postDebugTask,
81-
javaExec: config?.javaExec,
82-
};
65+
});
8366
}
8467

8568
if (testContext.profile?.kind === TestRunProfileKind.Coverage) {

test/suite/config.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
'use strict';
55

66
import * as assert from 'assert';
7+
78
import { TestController, TestRunRequest, tests, workspace } from 'vscode';
89
import { JUnitRunner } from '../../src/runners/junitRunner/JunitRunner';
910
import { resolveLaunchConfigurationForRunner } from '../../src/utils/launchUtils';
@@ -70,4 +71,40 @@ suite('JUnit Runner Analyzer Tests', () => {
7071
assert.strictEqual(configuration.classPaths[1], "/foo/bar.jar");
7172
assert.strictEqual(configuration.javaExec, "/usr/bin/java");
7273
});
74+
75+
test("test launch encoding", async() => {
76+
const testItem = generateTestItem(testController, 'junit@junit4.TestEncoding#latin1IsSet', TestKind.JUnit, undefined, '=junit/src\\/test\\/java=/optional=/true=/=/maven.pomderived=/true=/=/test=/true=/<junit4{TestAnnotation.java[TestEncoding~latin1IsSet');
77+
const testRunRequest = new TestRunRequest([testItem], []);
78+
const testRun = testController.createTestRun(testRunRequest);
79+
const runnerContext: IRunTestContext = {
80+
isDebug: false,
81+
kind: TestKind.JUnit,
82+
projectName: 'junit',
83+
testItems: [testItem],
84+
testRun: testRun,
85+
workspaceFolder: workspace.workspaceFolders?.[0]!,
86+
};
87+
const junitRunner = new JUnitRunner(runnerContext);
88+
const configuration = await resolveLaunchConfigurationForRunner(junitRunner, runnerContext, {
89+
classPaths: [
90+
"/a/b/c.jar",
91+
"/foo/bar.jar"
92+
],
93+
env: {
94+
test: "test",
95+
},
96+
envFile: "${workspaceFolder}/.env",
97+
encoding: "ISO-8859-1",
98+
javaExec: "/usr/bin/java",
99+
modulePaths: [
100+
"/test/module.jar",
101+
],
102+
postDebugTask: "test",
103+
preLaunchTask: "test",
104+
sourcePaths: [
105+
"/a/b/c.jar"
106+
]
107+
});
108+
assert.strictEqual(configuration.encoding, "ISO-8859-1");
109+
});
73110
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package junit4;
2+
3+
import org.junit.Test;
4+
5+
import static org.junit.Assert.assertEquals;
6+
7+
import java.nio.charset.Charset;
8+
9+
/**
10+
* The test case in this class will fail unless you set `java.test.config : encoding` to ISO-8859-1
11+
*/
12+
public class TestEncoding {
13+
@Test
14+
public void latin1IsSet() {
15+
assertEquals(
16+
"ISO-8859-1",
17+
Charset.defaultCharset().name()
18+
);
19+
}
20+
}

0 commit comments

Comments
 (0)