1
1
package xyz.poeschl.roborush.service
2
2
3
+ import org.apache.commons.imaging.Imaging
4
+ import org.apache.commons.imaging.formats.png.PngImagingParameters
5
+ import org.apache.commons.imaging.formats.png.PngWriter
6
+ import org.apache.xmlgraphics.xmp.XMPParser
3
7
import org.assertj.core.api.Assertions.assertThat
4
8
import org.assertj.core.api.Assertions.assertThatThrownBy
5
9
import org.junit.jupiter.api.Test
6
10
import org.junit.jupiter.params.ParameterizedTest
7
11
import org.junit.jupiter.params.provider.Arguments
8
12
import org.junit.jupiter.params.provider.MethodSource
13
+ import org.springframework.core.io.ByteArrayResource
9
14
import org.springframework.core.io.ClassPathResource
10
15
import xyz.poeschl.roborush.exceptions.NoStartingPosition
11
16
import xyz.poeschl.roborush.exceptions.NoTargetPosition
@@ -19,10 +24,14 @@ import xyz.poeschl.roborush.test.utils.builder.GameLogicBuilder.Companion.`$Map`
19
24
import xyz.poeschl.roborush.test.utils.builder.GameLogicBuilder.Companion .`$Position `
20
25
import xyz.poeschl.roborush.test.utils.builder.GameLogicBuilder.Companion .`$Size `
21
26
import xyz.poeschl.roborush.test.utils.builder.GameLogicBuilder.Companion .`$Tile `
27
+ import xyz.poeschl.roborush.test.utils.builder.NativeTypes.Companion .`$Double `
28
+ import xyz.poeschl.roborush.test.utils.builder.NativeTypes.Companion .`$Int `
22
29
import xyz.poeschl.roborush.test.utils.builder.NativeTypes.Companion .`$String `
23
30
import java.io.ByteArrayInputStream
31
+ import java.io.ByteArrayOutputStream
24
32
import java.util.stream.Stream
25
33
import javax.imageio.ImageIO
34
+ import javax.xml.transform.stream.StreamSource
26
35
27
36
class MapImportExportServiceTest {
28
37
@@ -34,6 +43,17 @@ class MapImportExportServiceTest {
34
43
Arguments .of(TileType .FUEL_TILE , 1 , Color (1 , 1 , 255 )),
35
44
Arguments .of(TileType .DEFAULT_TILE , 100 , Color (100 , 100 , 100 ))
36
45
)
46
+
47
+ private val XMP_META_TEMPLATE = """
48
+ <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/">
49
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
50
+ <rdf:Description xmlns:rr="https://github.com/Poeschl/RoboRush" rdf:about="">
51
+ <rr:solarChargeRate>%s</rr:solarChargeRate>
52
+ <rr:maxRobotFuel>%s</rr:maxRobotFuel>
53
+ </rdf:Description>
54
+ </rdf:RDF>
55
+ </x:xmpmeta>
56
+ """ .trimIndent()
37
57
}
38
58
39
59
private val importExportService = MapImportExportService ()
@@ -75,6 +95,30 @@ class MapImportExportServiceTest {
75
95
assertThat(Color .fromColorInt(resultImage.getRGB(0 , 0 ))).isEqualTo(expectedColor)
76
96
}
77
97
98
+ @Test
99
+ fun exportMap_metadata () {
100
+ // WHEN
101
+ val expectedMaxRobotFuel = a(`$Int `(10 , 500 ))
102
+ val expectedSolarChargeRate = a(`$Double `(.1 , 1.0 ))
103
+ val map = a(
104
+ `$Map `()
105
+ .withMaxRobotFuel(expectedMaxRobotFuel)
106
+ .withSolarChargeRate(expectedSolarChargeRate)
107
+ )
108
+ map.addTile(a(`$Tile `()))
109
+
110
+ // THEN
111
+ val byteResult = importExportService.exportMap(map)
112
+
113
+ // VERIFY
114
+ val xmpMetadataString = Imaging .getXmpXml(byteResult)
115
+ val xmpMetadata = XMPParser .parseXMP(StreamSource (xmpMetadataString.byteInputStream().buffered()))
116
+ assertThat(xmpMetadata.getProperty(" https://github.com/Poeschl/RoboRush" , " rr:solarChargeRate" ).value)
117
+ .isEqualTo(expectedSolarChargeRate.toString())
118
+ assertThat(xmpMetadata.getProperty(" https://github.com/Poeschl/RoboRush" , " rr:maxRobotFuel" ).value)
119
+ .isEqualTo(expectedMaxRobotFuel.toString())
120
+ }
121
+
78
122
@Test
79
123
fun importMap_correct () {
80
124
// WHEN
@@ -196,4 +240,33 @@ class MapImportExportServiceTest {
196
240
)
197
241
)
198
242
}
243
+
244
+ @Test
245
+ fun importMap_readMetadata () {
246
+ // WHEN
247
+ val inputImage = ClassPathResource (" /maps/with-fuel.png" )
248
+ val expectedMaxRobotFuel = a(`$Int `(10 , 500 ))
249
+ val expectedSolarChargeRate = a(`$Double `(.1 , 1.0 ))
250
+ val xmpString = XMP_META_TEMPLATE .format(expectedSolarChargeRate, expectedMaxRobotFuel)
251
+ val name = a(`$String `(" name" ))
252
+
253
+ // Put metadata in image, since the png optimizer removes it from the file
254
+ val imageWithMetadata = ByteArrayResource (
255
+ ByteArrayOutputStream ().use {
256
+ val pngParams = PngImagingParameters ()
257
+ pngParams.isForceTrueColor = true
258
+ pngParams.xmpXml = xmpString
259
+ PngWriter ().writeImage(ImageIO .read(inputImage.inputStream.buffered()), it, pngParams, null )
260
+ return @use it.toByteArray()
261
+ }
262
+ )
263
+
264
+ // THEN
265
+ val genResult = importExportService.importMap(name, imageWithMetadata)
266
+
267
+ // VERIFY
268
+ assertThat(genResult.errors).isEmpty()
269
+ assertThat(genResult.map.solarChargeRate).isEqualTo(expectedSolarChargeRate)
270
+ assertThat(genResult.map.maxRobotFuel).isEqualTo(expectedMaxRobotFuel)
271
+ }
199
272
}
0 commit comments