Skip to content

Commit 53b5fb2

Browse files
committed
Add tests for new and existing features
1 parent 06a2537 commit 53b5fb2

File tree

5 files changed

+374
-2
lines changed

5 files changed

+374
-2
lines changed
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/*
2+
* Copyright the GradleX team.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.gradlex.javamodule.packaging.test;
18+
19+
import org.gradlex.javamodule.packaging.test.fixture.GradleBuild;
20+
import org.junit.jupiter.api.BeforeEach;
21+
import org.junit.jupiter.api.Test;
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
25+
/**
26+
* Tests for setting various options for jpackage or the underlying jlink.
27+
* The tests are OS-dependent and should run on each operating system once.
28+
*/
29+
class JavaModulePackagingOptionsTest {
30+
31+
GradleBuild build = new GradleBuild();
32+
33+
@BeforeEach
34+
void setup() {
35+
var macosArch = System.getProperty("os.arch").contains("aarch") ? "aarch64" : "x86-64";
36+
build.appBuildFile.appendText("""
37+
version = "1.0"
38+
javaModulePackaging {
39+
target("macos") {
40+
operatingSystem.set("macos")
41+
architecture.set("%s")
42+
packageTypes.set(listOf("dmg"))
43+
}
44+
target("ubuntu") {
45+
operatingSystem.set("linux")
46+
architecture.set("x86-64")
47+
packageTypes.set(listOf("deb"))
48+
}
49+
target("windows") {
50+
operatingSystem.set("windows")
51+
architecture.set("x86-64")
52+
packageTypes.set(listOf("exe"))
53+
}
54+
}
55+
""".formatted(macosArch));
56+
build.appModuleInfoFile.writeText("""
57+
module org.example.app {
58+
}
59+
""");
60+
61+
}
62+
63+
@Test
64+
void can_configure_jlink_options() {
65+
build.appBuildFile.appendText("""
66+
javaModulePackaging {
67+
jlinkOptions.addAll(
68+
"--ignore-signing-information",
69+
"--compress", "zip-6",
70+
"--no-header-files",
71+
"--no-man-pages",
72+
"--bind-services",
73+
"--unsupported-option"
74+
)
75+
}
76+
""");
77+
78+
var result = build.fail(":app:jpackage");
79+
80+
// The error shows that all options before '--unsupported-option' are passed through to jlink
81+
assertThat(result.getOutput()).contains("jlink failed with: Error: unknown option: --unsupported-option");
82+
}
83+
84+
@Test
85+
void can_configure_java_options() {
86+
build.appBuildFile.appendText("""
87+
application {
88+
applicationDefaultJvmArgs = listOf(
89+
"-XX:+UnlockExperimentalVMOptions",
90+
"-XX:+UseCompactObjectHeaders",
91+
"-Xmx1g",
92+
"-Dsome.prop=some.val"
93+
)
94+
}
95+
""");
96+
97+
build.build(":app:jpackage");
98+
99+
assertThat(build.file("app/build/packages/macos/app.app/Contents/app/app.cfg").getAsPath()).hasContent("""
100+
[Application]
101+
app.mainmodule=org.example.app/org.example.app.Main
102+
103+
[JavaOptions]
104+
java-options=-Djpackage.app-version=1.0
105+
java-options=-XX:+UnlockExperimentalVMOptions
106+
java-options=-XX:+UseCompactObjectHeaders
107+
java-options=-Xmx1g
108+
java-options=-Dsome.prop=some.val
109+
""");
110+
}
111+
112+
@Test
113+
void can_configure_add_modules() {
114+
build.appBuildFile.appendText("""
115+
javaModulePackaging {
116+
addModules.addAll("com.acme.boo")
117+
}
118+
""");
119+
120+
var result = build.fail(":app:jpackage");
121+
122+
// The error shows that the option is passed on to jlink
123+
assertThat(result.getOutput()).contains("jlink failed with: Error: Module com.acme.boo not found");
124+
}
125+
126+
@Test
127+
void can_set_verbose_option() {
128+
build.appBuildFile.appendText("""
129+
javaModulePackaging {
130+
verbose.set(true)
131+
}
132+
""");
133+
134+
var result = build.build(":app:jpackage");
135+
136+
assertThat(result.getOutput()).contains("Creating app package: app.app in");
137+
}
138+
139+
@Test
140+
void can_set_target_specific_option() {
141+
build.appBuildFile.appendText("""
142+
javaModulePackaging {
143+
targetsWithOs("windows") {
144+
singleStepPackaging.set(true)
145+
options.addAll("--dummy")
146+
appImageOptions.addAll("--dummyimg") // no effect due to single-step
147+
}
148+
targetsWithOs("linux") {
149+
singleStepPackaging.set(true)
150+
options.addAll("--dummy")
151+
appImageOptions.addAll("--dummyimg") // no effect due to single-step
152+
}
153+
targetsWithOs("macos") {
154+
singleStepPackaging.set(true)
155+
options.addAll("--dummy")
156+
appImageOptions.addAll("--dummyimg") // no effect due to single-step
157+
}
158+
}
159+
""");
160+
161+
var result = build.fail(":app:jpackage");
162+
163+
assertThat(result.getOutput()).contains("Error: Invalid Option: [--dummy]");
164+
}
165+
166+
@Test
167+
void can_set_target_specific_option_for_app_image() {
168+
build.appBuildFile.appendText("""
169+
javaModulePackaging {
170+
targetsWithOs("windows") {
171+
options.addAll("--dummy") // no effect as app-image fails first
172+
appImageOptions.addAll("--dummyimg")
173+
}
174+
targetsWithOs("linux") {
175+
options.addAll("--dummy") // no effect as app-image fails first
176+
appImageOptions.addAll("--dummyimg")
177+
}
178+
targetsWithOs("macos") {
179+
options.addAll("--dummy") // no effect as app-image fails first
180+
appImageOptions.addAll("--dummyimg")
181+
}
182+
}
183+
""");
184+
185+
var result = build.fail(":app:jpackage");
186+
187+
assertThat(result.getOutput()).contains("Error: Invalid Option: [--dummyimg]");
188+
}
189+
190+
@Test
191+
void can_build_package_in_one_step() {
192+
build.appBuildFile.appendText("""
193+
javaModulePackaging {
194+
targetsWithOs("windows") { singleStepPackaging.set(true) }
195+
targetsWithOs("linux") { singleStepPackaging.set(true) }
196+
targetsWithOs("macos") { singleStepPackaging.set(true) }
197+
}
198+
""");
199+
200+
build.build(":app:jpackage");
201+
202+
assertThat(build.file("app/build/packages/macos/app-1.0.dmg").getAsPath()).exists();
203+
assertThat(build.file("app/build/packages/macos/app-1.0.dmg.sha256").getAsPath()).exists();
204+
assertThat(build.projectDir.dir("app/build/packages/macos").getAsPath()).isDirectoryNotContaining(
205+
f -> f.toFile().isDirectory());
206+
}
207+
}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* Copyright the GradleX team.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.gradlex.javamodule.packaging.test;
18+
19+
import org.gradlex.javamodule.packaging.test.fixture.GradleBuild;
20+
import org.junit.jupiter.api.BeforeEach;
21+
import org.junit.jupiter.api.Test;
22+
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
25+
/**
26+
* Tests for adding custom resources to the image/package.
27+
* The tests are OS-dependent and should run on each operating system once.
28+
*/
29+
class JavaModulePackagingResourcesTest {
30+
31+
GradleBuild build = new GradleBuild();
32+
33+
@BeforeEach
34+
void setup() {
35+
var macosArch = System.getProperty("os.arch").contains("aarch") ? "aarch64" : "x86-64";
36+
build.appBuildFile.appendText("""
37+
version = "1.0"
38+
javaModulePackaging {
39+
target("macos") {
40+
operatingSystem.set("macos")
41+
architecture.set("%s")
42+
}
43+
target("ubuntu") {
44+
operatingSystem.set("linux")
45+
architecture.set("x86-64")
46+
}
47+
target("windows") {
48+
operatingSystem.set("windows")
49+
architecture.set("x86-64")
50+
}
51+
}
52+
""".formatted(macosArch));
53+
build.appModuleInfoFile.writeText("""
54+
module org.example.app {
55+
}
56+
""");
57+
58+
}
59+
60+
@Test
61+
void can_configure_jlink_options() {
62+
build.appBuildFile.appendText("""
63+
javaModulePackaging {
64+
jlinkOptions.addAll(
65+
"--ignore-signing-information",
66+
"--compress", "zip-6",
67+
"--no-header-files",
68+
"--no-man-pages",
69+
"--bind-services",
70+
"--unsupported-option"
71+
)
72+
}
73+
""");
74+
75+
// The error shows that all options before '--unsupported-option' are passed through to jlink
76+
var result = build.fail(":app:jpackage");
77+
assertThat(result.getOutput()).contains(
78+
"jlink failed with: Error: unknown option: --unsupported-option");
79+
}
80+
81+
@Test
82+
void can_configure_add_modules() {
83+
build.appBuildFile.appendText("""
84+
javaModulePackaging {
85+
addModules.addAll("com.acme.boo")
86+
}
87+
""");
88+
89+
// The error shows that the option is passed on to jlink
90+
var result = build.fail(":app:jpackage");
91+
assertThat(result.getOutput()).contains(
92+
"jlink failed with: Error: Module com.acme.boo not found");
93+
}
94+
95+
@Test
96+
void can_add_resources_for_jpackage() {
97+
// Use 'src/main/resourcesPackage', which is the convention
98+
99+
// resources that are not known - will be ignored
100+
build.projectDir.file("app/src/main/resourcesPackage/windows/dummy.txt").writeText("");
101+
build.projectDir.file("app/src/main/resourcesPackage/macos/dummy.txt").writeText("");
102+
build.projectDir.file("app/src/main/resourcesPackage/linux/dummy.txt").writeText("");
103+
104+
// icons will be used
105+
build.projectDir.file("app/src/main/resourcesPackage/windows/icon.png").create();
106+
build.projectDir.file("app/src/main/resourcesPackage/macos/icon.icns").create();
107+
build.projectDir.file("app/src/main/resourcesPackage/linux/icon.ico").create();
108+
109+
build.build(":app:jpackage");
110+
111+
// Intermediate location to collect files
112+
assertThat(build.file("app/build/tmp/jpackage/macos/jpackage-resources/dummy.txt").getAsPath()).exists();
113+
assertThat(build.file("app/build/tmp/jpackage/macos/jpackage-resources/app.icns").getAsPath()).exists();
114+
115+
// Icons end up in Resources
116+
assertThat(build.file("app/build/packages/macos/app.app/Contents/Resources/app.icns").getAsPath()).hasSize(0);
117+
}
118+
119+
@Test
120+
void can_add_resources_for_app_folder() {
121+
build.appBuildFile.appendText("""
122+
javaModulePackaging {
123+
// resource is added to the os-specific 'app' folder inside the image
124+
resources.from("res")
125+
}
126+
""");
127+
128+
// resources that are not known - will be ignored
129+
build.projectDir.file("app/res/dummy.txt").writeText("");
130+
131+
build.build(":app:jpackage");
132+
133+
// Icons end up in Resources
134+
assertThat(build.file("app/build/packages/macos/app.app/Contents/app/dummy.txt").getAsPath()).exists();
135+
}
136+
137+
@Test
138+
void can_add_resources_to_image_root() {
139+
// Resource is added to the root of the image.
140+
// This is a target-specific setting as it usually needs to be placed in a place that
141+
// makes sense in the corresponding package structure.
142+
build.appBuildFile.appendText("""
143+
javaModulePackaging {
144+
targetsWithOs("windows") { targetResources.from("res") }
145+
targetsWithOs("linux") { targetResources.from("res") }
146+
targetsWithOs("macos") { targetResources.from("res") }
147+
}
148+
""");
149+
150+
// resources that are not known - will be ignored
151+
build.projectDir.file("app/res/customFolder/dummy.txt").writeText("");
152+
153+
build.build(":app:jpackage");
154+
155+
// Icons end up in Resources
156+
assertThat(build.file("app/build/packages/macos/app.app/Contents/customFolder/dummy.txt").getAsPath()).exists();
157+
}
158+
}

src/test/java/org/gradlex/javamodule/packaging/test/JavaModulePackagingTest.java renamed to src/test/java/org/gradlex/javamodule/packaging/test/JavaModulePackagingSmokeTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@
3232
import static org.gradlex.javamodule.packaging.test.fixture.GradleBuild.runsOnMacos;
3333
import static org.gradlex.javamodule.packaging.test.fixture.GradleBuild.runsOnWindows;
3434

35-
class JavaModulePackagingTest {
35+
/**
36+
* Tests that run on all operating systems and assert success or failure depending on the system they run on.
37+
*/
38+
class JavaModulePackagingSmokeTest {
3639

3740
GradleBuild build = new GradleBuild();
3841

src/test/java/org/gradlex/javamodule/packaging/test/fixture/GradleBuild.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public GradleBuild(Path dir) {
5353
this.libBuildFile = file("lib/build.gradle.kts");
5454
this.libModuleInfoFile = file("lib/src/main/java/module-info.java");
5555

56-
// TODO remove, should work with empty dir
56+
// https://github.com/gradlex-org/java-module-packaging/issues/56 ?
5757
projectDir.dir("app/src/main/resourcesPackage/windows");
5858
projectDir.dir("app/src/main/resourcesPackage/macos");
5959
projectDir.dir("app/src/main/resourcesPackage/linux");

src/test/java/org/gradlex/javamodule/packaging/test/fixture/WritableFile.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public WritableFile appendText(String text) {
4343
return this;
4444
}
4545

46+
public void create() {
47+
Io.unchecked(() -> Files.createFile(file));
48+
}
49+
4650
public WritableFile delete() {
4751
Io.unchecked(file, Files::delete);
4852
return this;

0 commit comments

Comments
 (0)