1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package io.earcam.instrumental.archive.jpms;
20
21 import static io.earcam.instrumental.archive.Archive.archive;
22 import static io.earcam.instrumental.archive.jpms.AsJpmsModule.asJpmsModule;
23 import static io.earcam.instrumental.module.jpms.ExportModifier.MANDATED;
24 import static java.nio.charset.StandardCharsets.UTF_8;
25 import static org.hamcrest.MatcherAssert.assertThat;
26 import static org.hamcrest.Matchers.aMapWithSize;
27 import static org.hamcrest.Matchers.allOf;
28 import static org.hamcrest.Matchers.anEmptyMap;
29 import static org.hamcrest.Matchers.arrayContaining;
30 import static org.hamcrest.Matchers.contains;
31 import static org.hamcrest.Matchers.containsInAnyOrder;
32 import static org.hamcrest.Matchers.empty;
33 import static org.hamcrest.Matchers.equalTo;
34 import static org.hamcrest.Matchers.hasEntry;
35 import static org.hamcrest.Matchers.is;
36 import static org.hamcrest.Matchers.nullValue;
37
38 import java.util.Comparator;
39 import java.util.function.Predicate;
40
41 import org.junit.jupiter.api.Test;
42
43 import com.acme.DummyIntComparator;
44 import com.acme.DummyMain;
45 import com.acme.ext.Ext;
46 import com.acme.internal.DummyInternal;
47
48 import io.earcam.instrumental.archive.Archive;
49 import io.earcam.instrumental.archive.ArchiveResource;
50 import io.earcam.instrumental.module.jpms.Export;
51 import io.earcam.instrumental.module.jpms.ModuleInfo;
52 import io.earcam.instrumental.module.jpms.Require;
53 import io.earcam.instrumental.module.jpms.RequireModifier;
54
55 public class AsJpmsModuleTest {
56
57 @Test
58 void emptyModule()
59 {
60 Archive archive = archive()
61 .configured(asJpmsModule()
62 .named("foo")
63 .versioned("0.42.1"))
64 .toObjectModel();
65
66 ModuleInfo moduleInfo = moduleInfoFrom(archive);
67
68 assertThat(moduleInfo.name(), is("foo"));
69 assertThat(moduleInfo.version(), is("0.42.1"));
70
71 assertThat(moduleInfo.mainClass(), is(nullValue()));
72 assertThat(moduleInfo.packages(), is(empty()));
73 assertThat(moduleInfo.exports(), is(empty()));
74 assertThat(moduleInfo.opens(), is(empty()));
75 assertThat(moduleInfo.uses(), is(empty()));
76 assertThat(moduleInfo.requires(), is(empty()));
77 assertThat(moduleInfo.provides(), is(anEmptyMap()));
78 }
79
80
81 @Test
82 void mainClass()
83 {
84 Archive archive = archive()
85 .configured(asJpmsModule()
86 .named("foo")
87 .launching(DummyMain.class))
88 .toObjectModel();
89
90 ModuleInfo moduleInfo = moduleInfoFrom(archive);
91
92 assertThat(moduleInfo.mainClass(), is(equalTo(DummyMain.class.getCanonicalName())));
93 }
94
95
96 private ModuleInfo moduleInfoFrom(Archive archive)
97 {
98 ModuleInfo moduleInfo = archive
99 .content("module-info.class")
100 .map(ArchiveResource::bytes)
101 .map(ModuleInfo::read)
102 .orElseThrow(AssertionError::new);
103 return moduleInfo;
104 }
105
106
107 @Test
108 void provides()
109 {
110 Archive archive = archive()
111 .configured(asJpmsModule()
112 .named("foo")
113 .providing(Comparator.class, DummyIntComparator.class))
114 .toObjectModel();
115
116 ModuleInfo moduleInfo = moduleInfoFrom(archive);
117
118 assertThat(moduleInfo.provides(), hasEntry(
119 equalTo(cn(Comparator.class)),
120 arrayContaining(cn(DummyIntComparator.class))));
121 }
122
123
124 private static String cn(Class<?> type)
125 {
126 return type.getCanonicalName();
127 }
128
129
130 @Test
131 void export()
132 {
133
134 Predicate<String> predicate = e -> !e.contains("internal");
135
136 Archive archive = archive()
137 .configured(asJpmsModule()
138 .named("foo")
139 .exporting(predicate))
140 .with(DummyIntComparator.class)
141 .with(DummyInternal.class)
142 .toObjectModel();
143
144
145 ModuleInfo moduleInfo = moduleInfoFrom(archive);
146
147 Export expectedExport = new Export(pkg(DummyIntComparator.class), MANDATED.access());
148
149 assertThat(moduleInfo.exports(), contains(expectedExport));
150 assertThat(moduleInfo.opens(), is(empty()));
151 }
152
153
154 private static String pkg(Class<?> type)
155 {
156 return type.getPackage().getName();
157 }
158
159
160 @Test
161 void exportsTo()
162 {
163 String packageA = pkg(DummyIntComparator.class);
164 String packageB = pkg(Ext.class);
165 Predicate<String> predicateA = Predicate.isEqual(packageA);
166 Predicate<String> predicateB = Predicate.isEqual(packageB);
167
168 Archive archive = archive()
169 .configured(asJpmsModule()
170 .named("foo")
171 .exporting(predicateA, "a")
172 .exporting(predicateB, "b"))
173 .with(DummyIntComparator.class)
174 .with(DummyInternal.class)
175 .with(Ext.class)
176 .toObjectModel();
177
178 ModuleInfo moduleInfo = moduleInfoFrom(archive);
179
180 Export expectedExportA = new Export(packageA, MANDATED.access(), "a");
181 Export expectedExportB = new Export(packageB, MANDATED.access(), "b");
182
183 assertThat(moduleInfo.exports(), contains(expectedExportA, expectedExportB));
184 assertThat(moduleInfo.opens(), is(empty()));
185 }
186
187
188 @Test
189 void opens()
190 {
191 String packageA = pkg(DummyIntComparator.class);
192 String packageB = pkg(Ext.class);
193 Predicate<String> predicateA = Predicate.isEqual(packageA);
194 Predicate<String> predicateB = Predicate.isEqual(packageB);
195
196 Archive archive = archive()
197 .configured(asJpmsModule()
198 .named("foo")
199 .opening(predicateA, "a")
200 .opening(predicateB))
201 .with(DummyIntComparator.class)
202 .with(DummyInternal.class)
203 .with(Ext.class)
204 .toObjectModel();
205
206 ModuleInfo moduleInfo = moduleInfoFrom(archive);
207
208 Export expectedExportA = new Export(packageA, MANDATED.access(), "a");
209 Export expectedExportB = new Export(packageB, MANDATED.access());
210
211 assertThat(moduleInfo.opens(), contains(expectedExportA, expectedExportB));
212 assertThat(moduleInfo.exports(), is(empty()));
213 }
214
215
216 @Test
217 void requires()
218 {
219 Archive archive = archive()
220 .configured(asJpmsModule()
221 .named("foo")
222 .requiring("bar")
223 .requiring("hum.bug", "1.42.0"))
224 .toObjectModel();
225
226 ModuleInfo moduleInfo = moduleInfoFrom(archive);
227
228 Require expectedRequire1 = new Require("bar", RequireModifier.MANDATED.access(), null);
229 Require expectedRequire2 = new Require("hum.bug", RequireModifier.MANDATED.access(), "1.42.0");
230
231 assertThat(moduleInfo.requires(), containsInAnyOrder(expectedRequire1, expectedRequire2));
232 }
233
234
235 @Test
236 void uses()
237 {
238 Archive archive = archive()
239 .configured(asJpmsModule()
240 .named("foo")
241 .using(Comparator.class)
242 .using(Predicate.class))
243 .toObjectModel();
244
245 ModuleInfo moduleInfo = moduleInfoFrom(archive);
246
247 assertThat(moduleInfo.uses(), containsInAnyOrder(cn(Comparator.class), cn(Predicate.class)));
248 }
249
250
251 @Test
252 void packages()
253 {
254 Archive archive = archive()
255 .configured(asJpmsModule()
256 .named("foo")
257 .listingPackages())
258 .with(DummyIntComparator.class)
259 .with(Ext.class)
260 .toObjectModel();
261
262 ModuleInfo moduleInfo = moduleInfoFrom(archive);
263
264 assertThat(moduleInfo.packages(), containsInAnyOrder(pkg(DummyIntComparator.class), pkg(Ext.class)));
265 }
266
267
268 @Test
269 void providingFromMetaInfServices()
270 {
271 Archive archive = archive()
272 .configured(asJpmsModule()
273 .named("foo")
274 .providingFromMetaInfServices())
275 .with(DummyIntComparator.class)
276 .with("META-INF/services/java.util.Comparator", cn(DummyIntComparator.class).getBytes(UTF_8))
277 .with("META-INF/servicehistory", "one careful owner".getBytes(UTF_8))
278 .toObjectModel();
279
280 ModuleInfo moduleInfo = moduleInfoFrom(archive);
281
282 assertThat(moduleInfo.provides(), allOf(
283 aMapWithSize(1),
284 hasEntry(equalTo("java.util.Comparator"), arrayContaining(cn(DummyIntComparator.class)))));
285 }
286
287
288 @Test
289 void notProvidingFromMetaInfServices()
290 {
291 Archive archive = archive()
292 .configured(asJpmsModule()
293 .named("foo"))
294 .with(DummyIntComparator.class)
295 .with("META-INF/services/java.util.Comparator", cn(DummyIntComparator.class).getBytes(UTF_8))
296 .with("META-INF/servicehistory", "one careful owner".getBytes(UTF_8))
297 .toObjectModel();
298
299 ModuleInfo moduleInfo = moduleInfoFrom(archive);
300
301 assertThat(moduleInfo.provides(), is(anEmptyMap()));
302 }
303 }