1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package io.earcam.instrumental.module.manifest;
20
21 import static io.earcam.instrumental.module.manifest.ManifestInfoBuilder.attribute;
22 import static io.earcam.instrumental.module.manifest.ManifestInfoBuilder.ManifestNamedEntry.entry;
23 import static java.util.jar.Attributes.Name.IMPLEMENTATION_TITLE;
24 import static org.hamcrest.MatcherAssert.assertThat;
25 import static org.hamcrest.Matchers.*;
26 import static org.hamcrest.Matchers.is;
27 import static org.hamcrest.Matchers.not;
28 import static org.junit.jupiter.api.Assertions.*;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.io.IOException;
33 import java.util.jar.Attributes;
34 import java.util.jar.Manifest;
35
36 import org.junit.jupiter.api.Nested;
37 import org.junit.jupiter.api.Test;
38
39 import io.earcam.unexceptional.Closing;
40
41 public class AbstractManifestBuilderTest {
42
43 static final class TestManifestBuilder extends AbstractManifestBuilder<TestManifestBuilder> {
44
45 public boolean hookWasInvoked;
46
47
48 @Override
49 protected TestManifestBuilder self()
50 {
51 return this;
52 }
53
54
55 @Override
56 protected void preBuildHook()
57 {
58 hookWasInvoked = true;
59 }
60
61
62 @Override
63 public boolean equals(AbstractManifestBuilder<?> that)
64 {
65 return same(that);
66 }
67 }
68
69 @Nested
70 class Equality {
71
72 private TestManifestBuilder a = new TestManifestBuilder()
73 .manifestMain(attribute(IMPLEMENTATION_TITLE, "Imps"))
74 .manifestNamed(entry("com.acme.SomeThing").attribute("XYZ-Digest", "xyz=="));
75
76
77 @Test
78 void equal()
79 {
80 ManifestInfo b = new TestManifestBuilder()
81 .manifestMain(attribute(IMPLEMENTATION_TITLE, "Imps"))
82 .manifestNamed(entry("com.acme.SomeThing").attribute("XYZ-Digest", "xyz=="));
83
84 assertThat(a, is(equalTo(b)));
85 assertThat(a.hashCode(), is(equalTo(b.hashCode())));
86 }
87
88
89 @Test
90 void notEqualWhenMainAttributesDiffer()
91 {
92 ManifestInfo b = new TestManifestBuilder()
93 .manifestMain(attribute(IMPLEMENTATION_TITLE, "Something completely different"))
94 .manifestNamed(entry("com.acme.SomeThing").attribute("XYZ-Digest", "xyz=="));
95
96 assertThat(a, is(not(equalTo(b))));
97 }
98
99
100 @Test
101 void notEqualWhenNamedEntriesDiffer()
102 {
103 ManifestInfo b = new TestManifestBuilder()
104 .manifestMain(attribute(IMPLEMENTATION_TITLE, "Imps"))
105 .manifestNamed(entry("com.acme.SomeThing").attribute("XYZ-Digest", "ABC=="));
106
107 assertThat(a, is(not(equalTo(b))));
108 }
109
110
111 @Test
112 void notEqualToNull()
113 {
114 TestManifestBuilder b = null;
115 assertFalse(a.equals(b));
116 }
117
118
119 @Test
120 void notEqualToNullObject()
121 {
122 Object b = null;
123 assertFalse(a.equals(b));
124 }
125
126
127 @Test
128 void notSameAsNullObject()
129 {
130 TestManifestBuilder b = null;
131 assertFalse(a.same(b));
132 }
133 }
134
135 @Nested
136 class Properties {
137
138 @Test
139 void mainAttribute()
140 {
141
142 ManifestInfo info = new TestManifestBuilder()
143 .manifestMain(attribute(IMPLEMENTATION_TITLE, "Imps"));
144
145 assertThat(info.mainAttribute(IMPLEMENTATION_TITLE.toString()), is(equalTo("Imps")));
146 }
147
148
149 @Test
150 void namedEntry()
151 {
152
153 ManifestInfo info = new TestManifestBuilder()
154 .manifestNamed(entry("com.acme.SomeThing").attribute("XYZ-Digest", "xyz=="));
155
156 assertThat(info.namedEntry("com.acme.SomeThing"), hasEntry(new Attributes.Name("XYZ-Digest"), "xyz=="));
157 }
158 }
159
160
161 @Test
162 void hookInvokedWhenToManifest()
163 {
164 TestManifestBuilder builder = new TestManifestBuilder();
165
166 builder.mergeFrom(createManifest()).toManifest();
167
168 assertThat(builder.hookWasInvoked, is(true));
169 }
170
171
172 @Test
173 void hookInvokedWhenToOutputStream()
174 {
175 TestManifestBuilder builder = new TestManifestBuilder();
176
177 builder.mergeFrom(createManifest()).to(new ByteArrayOutputStream());
178
179 assertThat(builder.hookWasInvoked, is(true));
180 }
181
182
183 @Test
184 void symmetricFromTo()
185 {
186 Manifest manifest = createManifest();
187
188 TestManifestBuilder builder = new TestManifestBuilder();
189
190 Manifest rehydrated = builder.mergeFrom(manifest).toManifest();
191
192 assertThat(rehydrated, is(equalTo(manifest)));
193 }
194
195
196 private Manifest createManifest()
197 {
198 Manifest manifest = new Manifest();
199 Attributes main = manifest.getMainAttributes();
200 main.put(Attributes.Name.IMPLEMENTATION_TITLE, "A test");
201 main.put(Attributes.Name.MANIFEST_VERSION, "1.0");
202 Attributes attributes = new Attributes();
203 attributes.putValue("aka", "anon");
204 manifest.getEntries().put("nom.de.plume", attributes);
205 return manifest;
206 }
207
208
209 @Test
210 void symmetricFromToOutputStream()
211 {
212 Manifest manifest = createManifest();
213
214 TestManifestBuilder builder = new TestManifestBuilder();
215
216 ByteArrayOutputStream noCloseOut = new ByteArrayOutputStream() {
217 @Override
218 public void close() throws IOException
219 {
220 throw new IOException("open 24/7, 365");
221 }
222 };
223 builder.mergeFrom(manifest).to(noCloseOut);
224
225 ByteArrayInputStream in = new ByteArrayInputStream(noCloseOut.toByteArray());
226 Manifest rehydrated = Closing.closeAfterApplying(in, Manifest::new);
227
228 assertThat(rehydrated, is(equalTo(manifest)));
229 }
230
231
232 @Test
233 void unhook()
234 {
235 Manifest manifest = createManifest();
236
237 TestManifestBuilder builder = new TestManifestBuilder();
238 builder.mergeFrom(manifest).to(new ByteArrayOutputStream());
239
240 assertThat(builder.hooked, is(true));
241 builder.unhook();
242 assertThat(builder.hooked, is(false));
243 }
244 }