Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 1 | // Copyright 2017 The Bazel Authors. All rights reserved. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | package com.google.devtools.build.android; |
| 15 | |
| 16 | import static com.google.common.truth.Truth.assertAbout; |
| 17 | import static com.google.common.truth.Truth.assertThat; |
| 18 | |
| 19 | import com.android.ide.common.internal.PngCruncher; |
| 20 | import com.android.ide.common.internal.PngException; |
| 21 | import com.google.common.collect.ImmutableMap; |
| 22 | import com.google.common.jimfs.Jimfs; |
Googler | 694105d | 2017-11-10 19:40:08 +0100 | [diff] [blame^] | 23 | import com.google.common.truth.Subject; |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 24 | import com.google.common.util.concurrent.MoreExecutors; |
| 25 | import java.io.File; |
| 26 | import java.io.IOException; |
| 27 | import java.nio.file.FileSystem; |
| 28 | import java.nio.file.Files; |
| 29 | import java.nio.file.Path; |
| 30 | import org.junit.Before; |
| 31 | import org.junit.Test; |
| 32 | import org.junit.runner.RunWith; |
| 33 | import org.junit.runners.JUnit4; |
| 34 | |
| 35 | /** Tests for the AndroidDataWriter. */ |
| 36 | @RunWith(JUnit4.class) |
| 37 | public class AndroidDataWriterTest { |
| 38 | |
| 39 | private static final String START_RESOURCES = |
| 40 | new String(AndroidDataWriter.PRELUDE) + "<resources"; |
| 41 | private static final String END_RESOURCES = new String(AndroidDataWriter.END_RESOURCES); |
| 42 | |
| 43 | private FileSystem fs; |
| 44 | |
| 45 | @Before |
| 46 | public void createCleanEnvironment() { |
| 47 | fs = Jimfs.newFileSystem(); |
| 48 | } |
| 49 | |
| 50 | @Test |
| 51 | public void writeResourceFile() throws Exception { |
| 52 | Path target = fs.getPath("target"); |
| 53 | Path source = fs.getPath("source"); |
| 54 | AndroidDataWriter mergedDataWriter = AndroidDataWriter.createWithDefaults(target); |
| 55 | String drawable = "drawable/menu.gif"; |
| 56 | String layout = "layout/foo.xml"; |
| 57 | ParsedAndroidData direct = |
| 58 | AndroidDataBuilder.of(source) |
| 59 | .addResource(layout, AndroidDataBuilder.ResourceType.LAYOUT, "") |
| 60 | .addResourceBinary(drawable, Files.createFile(fs.getPath("menu.gif"))) |
| 61 | .createManifest("AndroidManifest.xml", "com.carroll.lewis", "") |
| 62 | .buildParsed(); |
| 63 | MergedAndroidData actual = |
| 64 | UnwrittenMergedAndroidData.of( |
| 65 | source.resolve("AndroidManifest.xml"), direct, ParsedAndroidDataBuilder.empty()) |
| 66 | .write(mergedDataWriter); |
| 67 | |
| 68 | assertAbout(paths).that(actual.getManifest()).exists(); |
| 69 | assertAbout(paths).that(actual.getResourceDir().resolve(drawable)).exists(); |
| 70 | assertAbout(paths).that(actual.getResourceDir().resolve(layout)).exists(); |
| 71 | } |
| 72 | |
| 73 | @Test |
| 74 | public void writePngInRawAndNotInRaw() throws Exception { |
| 75 | Path tmpDir = Files.createTempDirectory(this.toString()); |
| 76 | final Path target = tmpDir.resolve("target"); |
| 77 | final Path source = tmpDir.resolve("source"); |
| 78 | final String drawable = "drawable/crunch.png"; |
| 79 | final String raw = "raw/nocrunch.png"; |
| 80 | final String layout = "layout/foo.xml"; |
| 81 | AndroidDataWriter mergedDataWriter = |
| 82 | AndroidDataWriter.createWith( |
| 83 | target, |
| 84 | target.resolve("res"), |
| 85 | target.resolve("assets"), |
| 86 | new PngCruncher() { |
| 87 | @Override |
| 88 | public int start() { |
| 89 | return 0; |
| 90 | } |
| 91 | |
| 92 | @Override |
| 93 | public void end(int key) throws InterruptedException { |
| 94 | } |
| 95 | |
| 96 | @Override |
| 97 | public void crunchPng(int key, File from, File to) |
| 98 | throws PngException { |
| 99 | assertThat(from.toString()).doesNotContain(raw); |
| 100 | try { |
| 101 | Files.copy(from.toPath(), to.toPath()); |
| 102 | } catch (IOException e) { |
| 103 | throw new PngException(e); |
| 104 | } |
| 105 | } |
| 106 | }, |
| 107 | MoreExecutors.newDirectExecutorService()); |
| 108 | ParsedAndroidData direct = |
| 109 | AndroidDataBuilder.of(source) |
| 110 | .addResource(layout, AndroidDataBuilder.ResourceType.LAYOUT, "") |
| 111 | .addResourceBinary(drawable, Files.createFile(tmpDir.resolve("crunch.png"))) |
| 112 | .addResourceBinary(raw, Files.createFile(tmpDir.resolve("nocrunch.png"))) |
| 113 | .createManifest("AndroidManifest.xml", "com.carroll.lewis", "") |
| 114 | .buildParsed(); |
| 115 | MergedAndroidData actual = |
| 116 | UnwrittenMergedAndroidData.of( |
| 117 | source.resolve("AndroidManifest.xml"), direct, ParsedAndroidDataBuilder.empty()) |
| 118 | .write(mergedDataWriter); |
| 119 | |
| 120 | assertAbout(paths).that(actual.getManifest()).exists(); |
| 121 | assertAbout(paths).that(actual.getResourceDir().resolve(drawable)).exists(); |
| 122 | assertAbout(paths).that(actual.getResourceDir().resolve(raw)).exists(); |
| 123 | assertAbout(paths).that(actual.getResourceDir().resolve(layout)).exists(); |
| 124 | } |
| 125 | |
| 126 | @Test |
| 127 | public void writeNinepatchResourceFile() throws Exception { |
| 128 | Path tmpDir = Files.createTempDirectory(this.toString()); |
| 129 | Path target = tmpDir.resolve("target"); |
| 130 | Path source = tmpDir.resolve("source"); |
| 131 | AndroidDataWriter mergedDataWriter = AndroidDataWriter.createWithDefaults(target); |
| 132 | String drawable = "drawable-hdpi-v4/seven_eight.9.png"; |
| 133 | ParsedAndroidData direct = |
| 134 | AndroidDataBuilder.of(source) |
| 135 | .addResourceBinary(drawable, Files.createFile(fs.getPath("seven_eight.9.png"))) |
| 136 | .createManifest("AndroidManifest.xml", "com.carroll.lewis", "") |
| 137 | .buildParsed(); |
| 138 | MergedAndroidData actual = |
| 139 | UnwrittenMergedAndroidData.of( |
| 140 | source.resolve("AndroidManifest.xml"), direct, ParsedAndroidDataBuilder.empty()) |
| 141 | .write(mergedDataWriter); |
| 142 | |
| 143 | assertAbout(paths).that(actual.getManifest()).exists(); |
| 144 | assertAbout(paths).that(actual.getResourceDir().resolve(drawable)).exists(); |
| 145 | } |
| 146 | |
| 147 | @Test |
| 148 | public void writeResourceXml() throws Exception { |
| 149 | Path target = fs.getPath("target"); |
| 150 | Path source = fs.getPath("source"); |
| 151 | AndroidDataWriter mergedDataWriter = AndroidDataWriter.createWithDefaults(target); |
| 152 | ParsedAndroidData direct = |
| 153 | AndroidDataBuilder.of(source) |
| 154 | .addResource( |
| 155 | "values/ids.xml", |
| 156 | AndroidDataBuilder.ResourceType.VALUE, |
| 157 | "<item name=\"id1\" type=\"id\"/>", |
| 158 | "<item name=\"id\" type=\"id\"/>") |
| 159 | .addResource( |
| 160 | "values/stubs.xml", |
| 161 | AndroidDataBuilder.ResourceType.VALUE, |
| 162 | "<item name=\"walrus\" type=\"drawable\"/>") |
| 163 | .createManifest("AndroidManifest.xml", "com.carroll.lewis", "") |
| 164 | .buildParsed(); |
| 165 | MergedAndroidData actual = |
| 166 | UnwrittenMergedAndroidData.of( |
| 167 | source.resolve("AndroidManifest.xml"), direct, ParsedAndroidDataBuilder.empty()) |
| 168 | .write(mergedDataWriter); |
| 169 | |
| 170 | assertAbout(paths).that(actual.getManifest()).exists(); |
| 171 | assertAbout(paths).that(actual.getResourceDir().resolve("values/values.xml")).exists(); |
| 172 | assertAbout(paths) |
| 173 | .that(actual.getResourceDir().resolve("values/values.xml")) |
| 174 | .xmlContentsIsEqualTo( |
| 175 | START_RESOURCES + ">", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 176 | "<!-- " + fs.getPath("source/res/values/stubs.xml") + " --><eat-comment/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 177 | "<item name='walrus' type='drawable'/>", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 178 | "<!-- " + fs.getPath("source/res/values/ids.xml") + " --><eat-comment/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 179 | "<item name='id' type='id'/>", |
| 180 | "<item name='id1' type='id'/>", |
| 181 | END_RESOURCES); |
| 182 | } |
| 183 | |
| 184 | @Test |
| 185 | public void writeResourceXmlWithQualfiers() throws Exception { |
| 186 | Path target = fs.getPath("target"); |
| 187 | Path source = fs.getPath("source"); |
| 188 | AndroidDataWriter mergedDataWriter = AndroidDataWriter.createWithDefaults(target); |
| 189 | ParsedAndroidData direct = |
| 190 | AndroidDataBuilder.of(source) |
| 191 | .addResource( |
| 192 | "values/ids.xml", |
| 193 | AndroidDataBuilder.ResourceType.VALUE, |
| 194 | "<item name=\"id1\" type=\"id\"/>") |
| 195 | .addResource( |
| 196 | "values-en/ids.xml", |
| 197 | AndroidDataBuilder.ResourceType.VALUE, |
| 198 | "<item name=\"id1\" type=\"id\"/>") |
| 199 | .createManifest("AndroidManifest.xml", "com.carroll.lewis", "") |
| 200 | .buildParsed(); |
| 201 | MergedAndroidData actual = |
| 202 | UnwrittenMergedAndroidData.of( |
| 203 | source.resolve("AndroidManifest.xml"), direct, ParsedAndroidDataBuilder.empty()) |
| 204 | .write(mergedDataWriter); |
| 205 | |
| 206 | assertAbout(paths).that(actual.getManifest()).exists(); |
| 207 | assertAbout(paths).that(actual.getResourceDir().resolve("values/values.xml")).exists(); |
| 208 | assertAbout(paths) |
| 209 | .that(actual.getResourceDir().resolve("values/values.xml")) |
| 210 | .xmlContentsIsEqualTo( |
| 211 | START_RESOURCES + ">", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 212 | "<!-- " |
| 213 | + fs.getPath("source/res/values/ids.xml") |
| 214 | + " --><eat-comment/><item name='id1' type='id'/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 215 | END_RESOURCES); |
| 216 | assertAbout(paths).that(actual.getResourceDir().resolve("values-en/values.xml")).exists(); |
| 217 | assertAbout(paths) |
| 218 | .that(actual.getResourceDir().resolve("values-en/values.xml")) |
| 219 | .xmlContentsIsEqualTo( |
| 220 | START_RESOURCES + ">", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 221 | "<!-- " |
| 222 | + fs.getPath("source/res/values-en/ids.xml") |
| 223 | + " --><eat-comment/><item name='id1' type='id'/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 224 | END_RESOURCES); |
| 225 | } |
| 226 | |
| 227 | @Test |
| 228 | public void writePublicResourceSameNameDifferentType() throws Exception { |
| 229 | Path target = fs.getPath("target"); |
| 230 | Path source = fs.getPath("source"); |
| 231 | AndroidDataWriter mergedDataWriter = AndroidDataWriter.createWithDefaults(target); |
| 232 | ParsedAndroidData direct = |
| 233 | AndroidDataBuilder.of(source) |
| 234 | .addResource( |
| 235 | "values/integers.xml", |
| 236 | AndroidDataBuilder.ResourceType.VALUE, |
| 237 | "<integer name=\"foo\">12345</integer>", |
| 238 | "<public name=\"foo\" type=\"integer\" id=\"0x7f040000\"/>", |
| 239 | "<integer name=\"zoo\">54321</integer>", |
| 240 | "<public name=\"zoo\" type=\"integer\" />") |
| 241 | .addResource( |
| 242 | "values/strings.xml", |
| 243 | AndroidDataBuilder.ResourceType.VALUE, |
| 244 | "<string name=\"foo\">meow</string>", |
| 245 | "<public name=\"foo\" type=\"string\" id=\"0x7f050000\"/>") |
| 246 | .createManifest("AndroidManifest.xml", "com.carroll.lewis", "") |
| 247 | .buildParsed(); |
| 248 | MergedAndroidData actual = |
| 249 | UnwrittenMergedAndroidData.of( |
| 250 | source.resolve("AndroidManifest.xml"), direct, ParsedAndroidDataBuilder.empty()) |
| 251 | .write(mergedDataWriter); |
| 252 | |
| 253 | assertAbout(paths).that(actual.getManifest()).exists(); |
| 254 | assertAbout(paths).that(actual.getResourceDir().resolve("values/values.xml")).exists(); |
| 255 | assertAbout(paths) |
| 256 | .that(actual.getResourceDir().resolve("values/values.xml")) |
| 257 | .xmlContentsIsEqualTo( |
| 258 | START_RESOURCES + ">", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 259 | "<!-- " + fs.getPath("source/res/values/integers.xml") + " --><eat-comment/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 260 | "<integer name='foo'>12345</integer>", |
| 261 | "<integer name='zoo'>54321</integer>", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 262 | "<!-- " + fs.getPath("source/res/values/strings.xml") + " --><eat-comment/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 263 | "<string name='foo'>meow</string>", |
corysmith | c28b4ce | 2017-11-03 21:04:40 +0100 | [diff] [blame] | 264 | "<!-- " + fs.getPath("source/res/values/integers.xml") + " --><eat-comment/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 265 | "<public name='foo' type='integer' id='0x7f040000'/>", |
| 266 | "<public name='foo' type='string' id='0x7f050000'/>", |
| 267 | "<public name='zoo' type='integer' />", |
| 268 | END_RESOURCES); |
| 269 | } |
| 270 | |
| 271 | @Test |
| 272 | public void writeWithIDDuplicates() throws Exception { |
| 273 | // We parse IDs from layout, etc. XML. We can include it in the merged values.xml redundantly |
| 274 | // (redundant because we also give aapt the original layout xml, which it can parse for IDs |
| 275 | // too), but make sure we don't accidentally put multiple copies in the merged values.xml file. |
| 276 | // Otherwise, aapt will throw an error if there are duplicates in the same values.xml file. |
| 277 | Path target = fs.getPath("target"); |
| 278 | Path source = fs.getPath("source"); |
| 279 | AndroidDataWriter mergedDataWriter = AndroidDataWriter.createWithDefaults(target); |
| 280 | ParsedAndroidData direct = |
| 281 | AndroidDataBuilder.of(source) |
| 282 | .addResource( |
| 283 | "layout/some_layout.xml", |
| 284 | AndroidDataBuilder.ResourceType.LAYOUT, |
| 285 | "<TextView android:id=\"@+id/MyTextView\"", |
| 286 | " android:text=\"@string/walrus\"", |
| 287 | " android:layout_above=\"@+id/AnotherTextView\"", |
| 288 | " android:layout_width=\"wrap_content\"", |
| 289 | " android:layout_height=\"wrap_content\" />", |
| 290 | // Test redundantly having a "+id/MyTextView" in a different attribute. |
| 291 | "<TextView android:id=\"@id/AnotherTextView\"", |
| 292 | " android:text=\"@string/walrus\"", |
| 293 | " android:layout_below=\"@+id/MyTextView\"", |
| 294 | " android:layout_width=\"wrap_content\"", |
| 295 | " android:layout_height=\"wrap_content\" />") |
| 296 | // Test what happens if a user accidentally uses the same ID in multiple layouts too. |
| 297 | .addResource( |
| 298 | "layout/another_layout.xml", |
| 299 | AndroidDataBuilder.ResourceType.LAYOUT, |
| 300 | "<TextView android:id=\"@+id/MyTextView\"", |
| 301 | " android:text=\"@string/walrus\"", |
| 302 | " android:layout_width=\"wrap_content\"", |
| 303 | " android:layout_height=\"wrap_content\" />") |
| 304 | // Also check what happens if a value XML file also contains the same ID. |
| 305 | .addResource( |
| 306 | "values/ids.xml", |
| 307 | AndroidDataBuilder.ResourceType.VALUE, |
| 308 | "<item name=\"MyTextView\" type=\"id\"/>", |
| 309 | "<item name=\"OtherId\" type=\"id\"/>") |
| 310 | .addResource( |
| 311 | "values/strings.xml", |
| 312 | AndroidDataBuilder.ResourceType.VALUE, |
| 313 | "<string name=\"walrus\">I has a bucket</string>") |
| 314 | .createManifest("AndroidManifest.xml", "com.carroll.lewis", "") |
| 315 | .buildParsed(); |
| 316 | MergedAndroidData actual = |
| 317 | UnwrittenMergedAndroidData.of( |
| 318 | source.resolve("AndroidManifest.xml"), direct, ParsedAndroidDataBuilder.empty()) |
| 319 | .write(mergedDataWriter); |
| 320 | |
| 321 | assertAbout(paths).that(actual.getManifest()).exists(); |
| 322 | assertAbout(paths).that(actual.getResourceDir().resolve("layout/some_layout.xml")).exists(); |
| 323 | assertAbout(paths).that(actual.getResourceDir().resolve("values/values.xml")).exists(); |
| 324 | assertAbout(paths) |
| 325 | .that(actual.getResourceDir().resolve("values/values.xml")) |
| 326 | .xmlContentsIsEqualTo( |
| 327 | START_RESOURCES + ">", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 328 | "<!-- " + fs.getPath("source/res/values/ids.xml") + " --><eat-comment/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 329 | "<item name='MyTextView' type='id'/>", |
| 330 | "<item name='OtherId' type='id'/>", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 331 | "<!-- " + fs.getPath("source/res/values/strings.xml") + " --><eat-comment/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 332 | "<string name='walrus'>I has a bucket</string>", |
| 333 | END_RESOURCES); |
| 334 | } |
| 335 | |
| 336 | @Test |
| 337 | public void writeResourceXmlWithAttributes() throws Exception { |
| 338 | Path target = fs.getPath("target"); |
| 339 | Path source = fs.getPath("source"); |
| 340 | AndroidDataWriter mergedDataWriter = AndroidDataWriter.createWithDefaults(target); |
| 341 | ParsedAndroidData direct = |
| 342 | AndroidDataBuilder.of(source) |
| 343 | .addValuesWithAttributes( |
| 344 | "values/ids.xml", |
| 345 | ImmutableMap.of("foo", "fooVal", "bar", "barVal"), |
| 346 | "<item name=\"id1\" type=\"id\"/>", |
| 347 | "<item name=\"id\" type=\"id\"/>") |
| 348 | .addValuesWithAttributes( |
| 349 | "values/stubs.xml", |
| 350 | ImmutableMap.of("baz", "bazVal"), |
| 351 | "<item name=\"walrus\" type=\"drawable\"/>") |
| 352 | .createManifest("AndroidManifest.xml", "com.carroll.lewis", "") |
| 353 | .buildParsed(); |
| 354 | MergedAndroidData actual = |
| 355 | UnwrittenMergedAndroidData.of( |
| 356 | source.resolve("AndroidManifest.xml"), direct, ParsedAndroidDataBuilder.empty()) |
| 357 | .write(mergedDataWriter); |
| 358 | |
| 359 | assertAbout(paths).that(actual.getManifest()).exists(); |
| 360 | assertAbout(paths).that(actual.getResourceDir().resolve("values/values.xml")).exists(); |
| 361 | assertAbout(paths) |
| 362 | .that(actual.getResourceDir().resolve("values/values.xml")) |
| 363 | .xmlContentsIsEqualTo( |
| 364 | START_RESOURCES + " foo=\"fooVal\" bar=\"barVal\" baz=\"bazVal\">", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 365 | "<!-- " + fs.getPath("source/res/values/stubs.xml") + " --><eat-comment/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 366 | "<item name='walrus' type='drawable'/>", |
Laszlo Csomor | 9cce261b | 2017-07-10 12:17:22 +0200 | [diff] [blame] | 367 | "<!-- " + fs.getPath("source/res/values/ids.xml") + " --><eat-comment/>", |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 368 | "<item name='id' type='id'/>", |
| 369 | "<item name='id1' type='id'/>", |
| 370 | END_RESOURCES); |
| 371 | } |
| 372 | |
| 373 | @Test |
| 374 | public void writeAssetFile() throws Exception { |
| 375 | Path target = fs.getPath("target"); |
| 376 | Path source = fs.getPath("source"); |
| 377 | AndroidDataWriter mergedDataWriter = AndroidDataWriter.createWithDefaults(target); |
| 378 | String asset = "hunting/of/the/boojum"; |
| 379 | ParsedAndroidData direct = |
| 380 | AndroidDataBuilder.of(source) |
| 381 | .addAsset(asset, "not a snark!") |
| 382 | .createManifest("AndroidManifest.xml", "com.carroll.lewis", "") |
| 383 | .buildParsed(); |
| 384 | MergedAndroidData actual = |
| 385 | UnwrittenMergedAndroidData.of( |
| 386 | source.resolve("AndroidManifest.xml"), direct, ParsedAndroidDataBuilder.empty()) |
| 387 | .write(mergedDataWriter); |
| 388 | |
| 389 | assertAbout(paths).that(actual.getManifest()).exists(); |
| 390 | assertAbout(paths).that(actual.getAssetDir().resolve(asset)).exists(); |
| 391 | } |
| 392 | |
Googler | 694105d | 2017-11-10 19:40:08 +0100 | [diff] [blame^] | 393 | private static final Subject.Factory<PathsSubject, Path> paths = PathsSubject::new; |
Adam Michael | 2587a6d | 2017-03-22 15:33:40 +0000 | [diff] [blame] | 394 | } |