Update versions, refactor, cleanup.
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									4291b422bf
								
							
						
					
					
						commit
						874d4208ef
					
				
					 19 changed files with 478 additions and 429 deletions
				
			
		
							
								
								
									
										18
									
								
								.drone.yml
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								.drone.yml
									
										
									
									
									
								
							|  | @ -1,12 +1,20 @@ | ||||||
| kind: pipeline | kind: pipeline | ||||||
| type: docker | type: docker | ||||||
| name: default | name: default | ||||||
| 
 |  | ||||||
| steps: | steps: | ||||||
|   - name: test |   - name: build | ||||||
|     image: maven:3.6-jdk-11 |     image: maven:3.8-openjdk-18-slim | ||||||
|     commands: |     commands: | ||||||
|       - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -B -V |       - mvn clean install -DskipTests=true -Dmaven.javadoc.skip=true -B -V | ||||||
|  |     when: | ||||||
|  |       ref: | ||||||
|  |         include: | ||||||
|  |           - refs/head/master | ||||||
|  |           - refs/head/feature/** | ||||||
|  |           - refs/tags/** | ||||||
|  |   - name: test | ||||||
|  |     image: maven:3.8-openjdk-18-slim | ||||||
|  |     commands: | ||||||
|       - mvn test -B |       - mvn test -B | ||||||
|     when: |     when: | ||||||
|       branch: |       branch: | ||||||
|  | @ -14,13 +22,13 @@ steps: | ||||||
|           - master |           - master | ||||||
|           - feature/* |           - feature/* | ||||||
|   - name: deploy |   - name: deploy | ||||||
|     image: maven:3.6-jdk-11 |     image: maven:3.8-openjdk-18-slim | ||||||
|     environment: |     environment: | ||||||
|       REPO_TOKEN: |       REPO_TOKEN: | ||||||
|         from_secret: repo-token |         from_secret: repo-token | ||||||
|     commands: |     commands: | ||||||
|       - mvn -s maven-settings.xml deploy -DskipTests=true |       - mvn -s maven-settings.xml deploy -DskipTests=true | ||||||
|     trigger: |     when: | ||||||
|       branch: |       branch: | ||||||
|         - master |         - master | ||||||
|       event: |       event: | ||||||
|  |  | ||||||
|  | @ -1,27 +0,0 @@ | ||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> |  | ||||||
|   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_11"> |  | ||||||
|     <output url="file://$MODULE_DIR$/target/classes" /> |  | ||||||
|     <output-test url="file://$MODULE_DIR$/target/test-classes" /> |  | ||||||
|     <content url="file://$MODULE_DIR$"> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" /> |  | ||||||
|       <excludeFolder url="file://$MODULE_DIR$/target" /> |  | ||||||
|     </content> |  | ||||||
|     <orderEntry type="inheritedJdk" /> |  | ||||||
|     <orderEntry type="sourceFolder" forTests="false" /> |  | ||||||
|     <orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.12" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.jetbrains:annotations:19.0.0" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: io.vavr:vavr:0.10.2" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: io.vavr:vavr-match:0.10.2" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.pdfbox:pdfbox:2.0.25" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.pdfbox:fontbox:2.0.25" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" /> |  | ||||||
|     <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.6.1" level="project" /> |  | ||||||
|     <orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" /> |  | ||||||
|     <orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" /> |  | ||||||
|     <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.6.1" level="project" /> |  | ||||||
|   </component> |  | ||||||
| </module> |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" | <settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
| 		  xmlns="http://maven.apache.org/SETTINGS/1.1.0" |           xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" | ||||||
| 		  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |           xmlns="http://maven.apache.org/SETTINGS/1.1.0"> | ||||||
|     <servers> |     <servers> | ||||||
|         <server> |         <server> | ||||||
|             <id>repo.gittr.ch</id> |             <id>repo.gittr.ch</id> | ||||||
|  |  | ||||||
							
								
								
									
										58
									
								
								pom.xml
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								pom.xml
									
										
									
									
									
								
							|  | @ -1,5 +1,6 @@ | ||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" | ||||||
|  |          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|     <modelVersion>4.0.0</modelVersion> |     <modelVersion>4.0.0</modelVersion> | ||||||
| 
 | 
 | ||||||
|     <parent> |     <parent> | ||||||
|  | @ -11,13 +12,36 @@ | ||||||
|     <groupId>ch.fritteli.labyrinth</groupId> |     <groupId>ch.fritteli.labyrinth</groupId> | ||||||
|     <artifactId>labyrinth-generator</artifactId> |     <artifactId>labyrinth-generator</artifactId> | ||||||
|     <version>0.0.3-SNAPSHOT</version> |     <version>0.0.3-SNAPSHOT</version> | ||||||
|  |     <description>The Labyrinth generator, a library for generating Labyrinths in various output formats.</description> | ||||||
|  |     <url>https://manuel.friedli.info/labyrinth.html</url> | ||||||
| 
 | 
 | ||||||
|     <properties> |     <properties> | ||||||
| 		<logback.version>1.2.10</logback.version> |         <java.source.version>17</java.source.version> | ||||||
| 		<pdfbox.version>2.0.25</pdfbox.version> |         <java.target.version>17</java.target.version> | ||||||
| 		<slf4j.version>1.7.35</slf4j.version> |         <jetbrains-annotations.version>24.0.1</jetbrains-annotations.version> | ||||||
|  |         <junit-jupiter.version>5.9.2</junit-jupiter.version> | ||||||
|  |         <logback.version>1.4.6</logback.version> | ||||||
|  |         <lombok.version>1.18.26</lombok.version> | ||||||
|  |         <pdfbox.version>2.0.27</pdfbox.version> | ||||||
|  |         <slf4j.version>2.0.7</slf4j.version> | ||||||
|  |         <vavr.version>0.10.4</vavr.version> | ||||||
|     </properties> |     </properties> | ||||||
| 
 | 
 | ||||||
|  |     <developers> | ||||||
|  |         <developer> | ||||||
|  |             <name>Manuel Friedli</name> | ||||||
|  |             <id>manuel</id> | ||||||
|  |             <url>https://www.fritteli.ch/</url> | ||||||
|  |             <email>manuel@fritteli.ch</email> | ||||||
|  |             <timezone>Europe/Zurich</timezone> | ||||||
|  |             <roles> | ||||||
|  |                 <role>Project Lead</role> | ||||||
|  |                 <role>Software Architect</role> | ||||||
|  |                 <role>Software Engineer</role> | ||||||
|  |             </roles> | ||||||
|  |         </developer> | ||||||
|  |     </developers> | ||||||
|  | 
 | ||||||
|     <dependencies> |     <dependencies> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.projectlombok</groupId> |             <groupId>org.projectlombok</groupId> | ||||||
|  | @ -50,6 +74,12 @@ | ||||||
|             <groupId>org.junit.jupiter</groupId> |             <groupId>org.junit.jupiter</groupId> | ||||||
|             <artifactId>junit-jupiter-api</artifactId> |             <artifactId>junit-jupiter-api</artifactId> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.assertj</groupId> | ||||||
|  |             <artifactId>assertj-core</artifactId> | ||||||
|  |             <version>3.24.2</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|     </dependencies> |     </dependencies> | ||||||
|     <build> |     <build> | ||||||
|         <plugins> |         <plugins> | ||||||
|  | @ -75,10 +105,28 @@ | ||||||
|                     </execution> |                     </execution> | ||||||
|                 </executions> |                 </executions> | ||||||
|             </plugin> |             </plugin> | ||||||
|  |             <plugin> | ||||||
|  |                 <groupId>org.apache.maven.plugins</groupId> | ||||||
|  |                 <artifactId>maven-source-plugin</artifactId> | ||||||
|  |                 <executions> | ||||||
|  |                     <execution> | ||||||
|  |                         <id>attach-sources</id> | ||||||
|  |                         <phase>verify</phase> | ||||||
|  |                         <goals> | ||||||
|  |                             <goal>jar-no-fork</goal> | ||||||
|  |                         </goals> | ||||||
|  |                     </execution> | ||||||
|  |                 </executions> | ||||||
|  |             </plugin> | ||||||
|  |             <plugin> | ||||||
|  |                 <groupId>org.apache.maven.plugins</groupId> | ||||||
|  |                 <artifactId>maven-site-plugin</artifactId> | ||||||
|  |                 <version>4.0.0-M6</version> | ||||||
|  |             </plugin> | ||||||
|         </plugins> |         </plugins> | ||||||
|     </build> |     </build> | ||||||
|     <scm> |     <scm> | ||||||
| 		<connection>scm:git:git://gittr.ch/java/labyrinth-generator.git</connection> |         <connection>scm:git:https://gittr.ch/java/labyrinth-generator.git</connection> | ||||||
|         <developerConnection>scm:git:ssh://git@gittr.ch/java/labyrinth-generator.git</developerConnection> |         <developerConnection>scm:git:ssh://git@gittr.ch/java/labyrinth-generator.git</developerConnection> | ||||||
|         <url>https://gittr.ch/java/labyrinth-generator</url> |         <url>https://gittr.ch/java/labyrinth-generator</url> | ||||||
|         <tag>HEAD</tag> |         <tag>HEAD</tag> | ||||||
|  |  | ||||||
|  | @ -15,8 +15,8 @@ import java.nio.file.Paths; | ||||||
| @Slf4j | @Slf4j | ||||||
| public class Main { | public class Main { | ||||||
|     public static void main(@NonNull final String[] args) { |     public static void main(@NonNull final String[] args) { | ||||||
|         int width = 100; |         final int width = 20; | ||||||
|         int height = 100; |         final int height = 30; | ||||||
|         final Labyrinth labyrinth = new Labyrinth(width, height/*, 0*/); |         final Labyrinth labyrinth = new Labyrinth(width, height/*, 0*/); | ||||||
|         final TextRenderer textRenderer = TextRenderer.newInstance(); |         final TextRenderer textRenderer = TextRenderer.newInstance(); | ||||||
|         final HTMLRenderer htmlRenderer = HTMLRenderer.newInstance(); |         final HTMLRenderer htmlRenderer = HTMLRenderer.newInstance(); | ||||||
|  |  | ||||||
|  | @ -2,11 +2,7 @@ package ch.fritteli.labyrinth.generator.model; | ||||||
| 
 | 
 | ||||||
| import io.vavr.collection.Stream; | import io.vavr.collection.Stream; | ||||||
| import io.vavr.control.Option; | import io.vavr.control.Option; | ||||||
| import lombok.AccessLevel; | import lombok.*; | ||||||
| import lombok.EqualsAndHashCode; |  | ||||||
| import lombok.Getter; |  | ||||||
| import lombok.NonNull; |  | ||||||
| import lombok.ToString; |  | ||||||
| import lombok.experimental.FieldDefaults; | import lombok.experimental.FieldDefaults; | ||||||
| 
 | 
 | ||||||
| import java.util.EnumSet; | import java.util.EnumSet; | ||||||
|  |  | ||||||
|  | @ -5,11 +5,7 @@ import lombok.EqualsAndHashCode; | ||||||
| import lombok.NonNull; | import lombok.NonNull; | ||||||
| import lombok.ToString; | import lombok.ToString; | ||||||
| 
 | 
 | ||||||
| import java.util.EnumSet; | import java.util.*; | ||||||
| import java.util.HashSet; |  | ||||||
| import java.util.Set; |  | ||||||
| import java.util.SortedSet; |  | ||||||
| import java.util.TreeSet; |  | ||||||
| 
 | 
 | ||||||
| @EqualsAndHashCode | @EqualsAndHashCode | ||||||
| @ToString | @ToString | ||||||
|  |  | ||||||
|  | @ -33,7 +33,8 @@ class Generator { | ||||||
| 
 | 
 | ||||||
|         final PDDocument pdDocument = new PDDocument(); |         final PDDocument pdDocument = new PDDocument(); | ||||||
|         final PDDocumentInformation info = new PDDocumentInformation(); |         final PDDocumentInformation info = new PDDocumentInformation(); | ||||||
|         info.setTitle("Labyrinth " + this.labyrinth.getWidth() + "x" + this.labyrinth.getHeight() + ", ID " + this.labyrinth.getRandomSeed()); |         info.setTitle("Labyrinth " + this.labyrinth.getWidth() + "x" + this.labyrinth.getHeight() + ", ID " + | ||||||
|  |                 this.labyrinth.getRandomSeed()); | ||||||
|         pdDocument.setDocumentInformation(info); |         pdDocument.setDocumentInformation(info); | ||||||
|         final PDPage puzzlePage = new PDPage(new PDRectangle(pageWidth, pageHeight)); |         final PDPage puzzlePage = new PDPage(new PDRectangle(pageWidth, pageHeight)); | ||||||
|         final PDPage solutionPage = new PDPage(new PDRectangle(pageWidth, pageHeight)); |         final PDPage solutionPage = new PDPage(new PDRectangle(pageWidth, pageHeight)); | ||||||
|  | @ -68,7 +69,8 @@ class Generator { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void drawHorizontalLines(@NonNull final PDPageContentStream... contentStreams) throws IOException { |     private void drawHorizontalLines(@NonNull final PDPageContentStream... contentStreams) throws IOException { | ||||||
|         // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required. |         // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is | ||||||
|  |         // required. | ||||||
|         Coordinate coordinate = new Coordinate(0f, 0f); |         Coordinate coordinate = new Coordinate(0f, 0f); | ||||||
|         // Draw the TOP borders of all tiles. |         // Draw the TOP borders of all tiles. | ||||||
|         for (int y = 0; y < this.labyrinth.getHeight(); y++) { |         for (int y = 0; y < this.labyrinth.getHeight(); y++) { | ||||||
|  | @ -136,7 +138,8 @@ class Generator { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void drawVerticalLines(@NonNull final PDPageContentStream... contentStreams) throws IOException { |     private void drawVerticalLines(@NonNull final PDPageContentStream... contentStreams) throws IOException { | ||||||
|         // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required. |         // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is | ||||||
|  |         // required. | ||||||
|         Coordinate coordinate = new Coordinate(0f, 0f); |         Coordinate coordinate = new Coordinate(0f, 0f); | ||||||
|         // Draw the LEFT borders of all tiles. |         // Draw the LEFT borders of all tiles. | ||||||
|         for (int x = 0; x < this.labyrinth.getWidth(); x++) { |         for (int x = 0; x < this.labyrinth.getWidth(); x++) { | ||||||
|  | @ -206,7 +209,8 @@ class Generator { | ||||||
|     private void drawSolution(@NonNull final PDPageContentStream pageContentStream) throws IOException { |     private void drawSolution(@NonNull final PDPageContentStream pageContentStream) throws IOException { | ||||||
|         // Draw the solution in red |         // Draw the solution in red | ||||||
|         pageContentStream.setStrokingColor(Color.RED); |         pageContentStream.setStrokingColor(Color.RED); | ||||||
|         // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required. |         // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is | ||||||
|  |         // required. | ||||||
|         final Position end = this.labyrinth.getEnd(); |         final Position end = this.labyrinth.getEnd(); | ||||||
|         Position currentPosition = this.labyrinth.getStart(); |         Position currentPosition = this.labyrinth.getStart(); | ||||||
|         Position previousPosition = null; |         Position previousPosition = null; | ||||||
|  | @ -223,7 +227,8 @@ class Generator { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @NonNull |     @NonNull | ||||||
|     private Position findNextSolutionPosition(@Nullable final Position previousPosition, @NonNull final Position currentPosition) { |     private Position findNextSolutionPosition(@Nullable final Position previousPosition, | ||||||
|  |                                               @NonNull final Position currentPosition) { | ||||||
|         final Tile currentTile = this.labyrinth.getTileAt(currentPosition).get(); |         final Tile currentTile = this.labyrinth.getTileAt(currentPosition).get(); | ||||||
|         for (final Direction direction : Direction.values()) { |         for (final Direction direction : Direction.values()) { | ||||||
|             if (!currentTile.hasWallAt(direction)) { |             if (!currentTile.hasWallAt(direction)) { | ||||||
|  | @ -250,21 +255,21 @@ class Generator { | ||||||
|             this.y = y; |             this.y = y; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private float calcX(final int x) { |  | ||||||
|             return x * PDFRenderer.SCALE + PDFRenderer.MARGIN; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private float calcY(final int y) { |  | ||||||
|             return (Generator.this.labyrinth.getHeight() - y) * PDFRenderer.SCALE + PDFRenderer.MARGIN; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public Coordinate withX(final int x) { |         public Coordinate withX(final int x) { | ||||||
|             return new Coordinate(calcX(x), this.y); |             return new Coordinate(calcX(x), this.y); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         private float calcX(final int x) { | ||||||
|  |             return x * PDFRenderer.SCALE + PDFRenderer.MARGIN; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         public Coordinate withY(final int y) { |         public Coordinate withY(final int y) { | ||||||
|             return new Coordinate(this.x, calcY(y)); |             return new Coordinate(this.x, calcY(y)); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         private float calcY(final int y) { | ||||||
|  |             return (Generator.this.labyrinth.getHeight() - y) * PDFRenderer.SCALE + PDFRenderer.MARGIN; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Value |     @Value | ||||||
|  | @ -282,7 +287,8 @@ class Generator { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private float calcY(final int y) { |         private float calcY(final int y) { | ||||||
|             return (Generator.this.labyrinth.getHeight() - y) * PDFRenderer.SCALE - PDFRenderer.SCALE / 2 + PDFRenderer.MARGIN; |             return (Generator.this.labyrinth.getHeight() - y) * PDFRenderer.SCALE - PDFRenderer.SCALE / 2 + | ||||||
|  |                     PDFRenderer.MARGIN; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,21 +1,23 @@ | ||||||
| package ch.fritteli.labyrinth.generator.serialization; | package ch.fritteli.labyrinth.generator.serialization; | ||||||
| 
 | 
 | ||||||
|  | import ch.fritteli.labyrinth.generator.model.Labyrinth; | ||||||
|  | import ch.fritteli.labyrinth.generator.model.Tile; | ||||||
| import lombok.NonNull; | import lombok.NonNull; | ||||||
| 
 | 
 | ||||||
| import java.io.ByteArrayInputStream; | import java.io.ByteArrayInputStream; | ||||||
| 
 | 
 | ||||||
|  | import static ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer.*; | ||||||
|  | 
 | ||||||
| public class LabyrinthInputStream extends ByteArrayInputStream { | public class LabyrinthInputStream extends ByteArrayInputStream { | ||||||
|     public LabyrinthInputStream(@NonNull final byte[] buf) { |     public LabyrinthInputStream(@NonNull final byte[] buf) { | ||||||
|         super(buf); |         super(buf); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public byte readByte() { |     public long readLong() { | ||||||
|         final int read = this.read(); |         long result = 0; | ||||||
|         if (read == -1) { |         result |= ((long) this.readInt()) << 32; | ||||||
|             // end of stream reached |         result |= 0xffffffffL & this.readInt(); | ||||||
|             throw new ArrayIndexOutOfBoundsException("End of stream reached. Cannot read more bytes."); |         return result; | ||||||
|         } |  | ||||||
|         return (byte) read; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public int readInt() { |     public int readInt() { | ||||||
|  | @ -27,10 +29,48 @@ public class LabyrinthInputStream extends ByteArrayInputStream { | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public long readLong() { |     public void checkHeader() { | ||||||
|         long result = 0; |         final byte magic1 = this.readByte(); | ||||||
|         result |= ((long) this.readInt()) << 32; |         if (magic1 != MAGIC_BYTE_1) { | ||||||
|         result |= 0xffffffffL & this.readInt(); |             throw new IllegalArgumentException("Invalid labyrinth data."); | ||||||
|         return result; |         } | ||||||
|  |         final byte magic2 = this.readByte(); | ||||||
|  |         if (magic2 != MAGIC_BYTE_2) { | ||||||
|  |             throw new IllegalArgumentException("Invalid labyrinth data."); | ||||||
|  |         } | ||||||
|  |         final int version = this.readByte(); | ||||||
|  |         if (version != VERSION_BYTE) { | ||||||
|  |             throw new IllegalArgumentException("Unknown Labyrinth data version: " + version); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public byte readByte() { | ||||||
|  |         final int read = this.read(); | ||||||
|  |         if (read == -1) { | ||||||
|  |             // end of stream reached | ||||||
|  |             throw new ArrayIndexOutOfBoundsException("End of stream reached. Cannot read more bytes."); | ||||||
|  |         } | ||||||
|  |         return (byte) read; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @NonNull | ||||||
|  |     public Labyrinth readLabyrinthData() { | ||||||
|  |         final long randomSeed = this.readLong(); | ||||||
|  |         final int width = this.readInt(); | ||||||
|  |         final int height = this.readInt(); | ||||||
|  | 
 | ||||||
|  |         final Tile[][] tiles = new Tile[width][height]; | ||||||
|  |         for (int x = 0; x < width; x++) { | ||||||
|  |             tiles[x] = new Tile[height]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for (int y = 0; y < height; y++) { | ||||||
|  |             for (int x = 0; x < width; x++) { | ||||||
|  |                 final byte bitmask = this.readByte(); | ||||||
|  |                 tiles[x][y] = SerializerDeserializer.getTileForBitmask(bitmask); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return SerializerDeserializer.createLabyrinth(tiles, width, height, randomSeed); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,21 +1,51 @@ | ||||||
| package ch.fritteli.labyrinth.generator.serialization; | package ch.fritteli.labyrinth.generator.serialization; | ||||||
| 
 | 
 | ||||||
|  | import ch.fritteli.labyrinth.generator.model.Labyrinth; | ||||||
|  | import ch.fritteli.labyrinth.generator.model.Tile; | ||||||
|  | import lombok.NonNull; | ||||||
|  | 
 | ||||||
| import java.io.ByteArrayOutputStream; | import java.io.ByteArrayOutputStream; | ||||||
| 
 | 
 | ||||||
|  | import static ch.fritteli.labyrinth.generator.serialization.SerializerDeserializer.*; | ||||||
|  | 
 | ||||||
| public class LabyrinthOutputStream extends ByteArrayOutputStream { | public class LabyrinthOutputStream extends ByteArrayOutputStream { | ||||||
|  |     public void writeHeader() { | ||||||
|  |         this.writeByte(MAGIC_BYTE_1); | ||||||
|  |         this.writeByte(MAGIC_BYTE_2); | ||||||
|  |         this.writeByte(VERSION_BYTE); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public void writeByte(final byte value) { |     public void writeByte(final byte value) { | ||||||
|         this.write(value); |         this.write(value); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void writeLabyrinthData(@NonNull final Labyrinth labyrinth) { | ||||||
|  |         final long randomSeed = labyrinth.getRandomSeed(); | ||||||
|  |         final int width = labyrinth.getWidth(); | ||||||
|  |         final int height = labyrinth.getHeight(); | ||||||
|  |         this.writeLong(randomSeed); | ||||||
|  |         this.writeInt(width); | ||||||
|  |         this.writeInt(height); | ||||||
|  | 
 | ||||||
|  |         for (int y = 0; y < height; y++) { | ||||||
|  |             for (int x = 0; x < width; x++) { | ||||||
|  |                 // We .get() it, because we want to crash hard if it is not available. | ||||||
|  |                 final Tile tile = labyrinth.getTileAt(x, y).get(); | ||||||
|  |                 final byte bitmask = SerializerDeserializer.getBitmaskForTile(tile); | ||||||
|  |                 this.writeByte(bitmask); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void writeLong(final long value) { | ||||||
|  |         this.writeInt((int) (value >> 32)); | ||||||
|  |         this.writeInt((int) value); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public void writeInt(final int value) { |     public void writeInt(final int value) { | ||||||
|         this.write(value >> 24); |         this.write(value >> 24); | ||||||
|         this.write(value >> 16); |         this.write(value >> 16); | ||||||
|         this.write(value >> 8); |         this.write(value >> 8); | ||||||
|         this.write(value); |         this.write(value); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     public void writeLong(final long value) { |  | ||||||
|         this.writeInt((int) (value >> 32)); |  | ||||||
|         this.writeInt((int) value); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -36,19 +36,19 @@ import java.util.EnumSet; | ||||||
|  *   byte  hex meaning |  *   byte  hex meaning | ||||||
|  *     00 0x1a magic |  *     00 0x1a magic | ||||||
|  *     01 0xb1 magic |  *     01 0xb1 magic | ||||||
|  *     02 0x00 version (0x00 -> dev / unstable; will be bumped to 0x01 once stabilized) |  *     02 0x01 version (0x00 -> dev, 0x01 -> stable) | ||||||
|  * 03..06      width (int) |  * 03..06      width (int) | ||||||
|  * 07..10      height (int) |  * 07..10      height (int) | ||||||
|  * 11..18      random seed number (long) |  * 11..18      random seed number (long) | ||||||
|  * 19..        tiles |  * 19..        tiles | ||||||
|  * </pre> |  * </pre> | ||||||
|  * exteaneous space (poss. last nibble) is ignored. |  * Extraneous space (poss. last nibble) is ignored. | ||||||
|  */ |  */ | ||||||
| @UtilityClass | @UtilityClass | ||||||
| public class SerializerDeserializer { | public class SerializerDeserializer { | ||||||
|     private final byte MAGIC_BYTE_1 = 0x1a; |     static final byte MAGIC_BYTE_1 = 0x1a; | ||||||
|     private final byte MAGIC_BYTE_2 = (byte) 0xb1; |     static final byte MAGIC_BYTE_2 = (byte) 0xb1; | ||||||
|     private final byte VERSION_BYTE = 0x01; |     static final byte VERSION_BYTE = 0x01; | ||||||
| 
 | 
 | ||||||
|     private final byte TOP_BIT = 0b0000_0001; |     private final byte TOP_BIT = 0b0000_0001; | ||||||
|     private final byte RIGHT_BIT = 0b0000_0010; |     private final byte RIGHT_BIT = 0b0000_0010; | ||||||
|  | @ -65,8 +65,8 @@ public class SerializerDeserializer { | ||||||
|     @NonNull |     @NonNull | ||||||
|     public byte[] serialize(@NonNull final Labyrinth labyrinth) { |     public byte[] serialize(@NonNull final Labyrinth labyrinth) { | ||||||
|         final LabyrinthOutputStream stream = new LabyrinthOutputStream(); |         final LabyrinthOutputStream stream = new LabyrinthOutputStream(); | ||||||
|         writeHeader(stream); |         stream.writeHeader(); | ||||||
|         writeLabyrinthData(stream, labyrinth); |         stream.writeLabyrinthData(labyrinth); | ||||||
|         return stream.toByteArray(); |         return stream.toByteArray(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -79,79 +79,18 @@ public class SerializerDeserializer { | ||||||
|     @NonNull |     @NonNull | ||||||
|     public Labyrinth deserialize(@NonNull final byte[] bytes) { |     public Labyrinth deserialize(@NonNull final byte[] bytes) { | ||||||
|         final LabyrinthInputStream stream = new LabyrinthInputStream(bytes); |         final LabyrinthInputStream stream = new LabyrinthInputStream(bytes); | ||||||
|         checkHeader(stream); |         stream.checkHeader(); | ||||||
|         return readLabyrinthData(stream); |         return stream.readLabyrinthData(); | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static void writeHeader(@NonNull final LabyrinthOutputStream stream) { |  | ||||||
|         stream.writeByte(MAGIC_BYTE_1); |  | ||||||
|         stream.writeByte(MAGIC_BYTE_2); |  | ||||||
|         stream.writeByte(VERSION_BYTE); |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static void checkHeader(@NonNull final LabyrinthInputStream stream) { |  | ||||||
|         final byte magic1 = stream.readByte(); |  | ||||||
|         if (magic1 != MAGIC_BYTE_1) { |  | ||||||
|             throw new IllegalArgumentException("Invalid labyrinth data."); |  | ||||||
|         } |  | ||||||
|         final byte magic2 = stream.readByte(); |  | ||||||
|         if (magic2 != MAGIC_BYTE_2) { |  | ||||||
|             throw new IllegalArgumentException("Invalid labyrinth data."); |  | ||||||
|         } |  | ||||||
|         final int version = stream.readByte(); |  | ||||||
|         if (version != VERSION_BYTE) { |  | ||||||
|             throw new IllegalArgumentException("Unknown Labyrinth data version: " + version); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static void writeLabyrinthData(@NonNull final LabyrinthOutputStream stream, @NonNull final Labyrinth labyrinth) { |  | ||||||
|         final long randomSeed = labyrinth.getRandomSeed(); |  | ||||||
|         final int width = labyrinth.getWidth(); |  | ||||||
|         final int height = labyrinth.getHeight(); |  | ||||||
|         stream.writeLong(randomSeed); |  | ||||||
|         stream.writeInt(width); |  | ||||||
|         stream.writeInt(height); |  | ||||||
| 
 |  | ||||||
|         for (int y = 0; y < height; y++) { |  | ||||||
|             for (int x = 0; x < width; x++) { |  | ||||||
|                 // We .get() it, because we want to crash hard if it is not available. |  | ||||||
|                 final Tile tile = labyrinth.getTileAt(x, y).get(); |  | ||||||
|                 final byte bitmask = getBitmaskForTile(tile); |  | ||||||
|                 stream.writeByte(bitmask); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @NonNull |     @NonNull | ||||||
|     private static Labyrinth readLabyrinthData(@NonNull final LabyrinthInputStream stream) { |     Labyrinth createLabyrinth(@NonNull final Tile[][] field, final int width, final int height, final long randomSeed) { | ||||||
|         final long randomSeed = stream.readLong(); |  | ||||||
|         final int width = stream.readInt(); |  | ||||||
|         final int height = stream.readInt(); |  | ||||||
| 
 |  | ||||||
|         final Tile[][] tiles = new Tile[width][height]; |  | ||||||
|         for (int x = 0; x < width; x++) { |  | ||||||
|             tiles[x] = new Tile[height]; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         for (int y = 0; y < height; y++) { |  | ||||||
|             for (int x = 0; x < width; x++) { |  | ||||||
|                 final byte bitmask = stream.readByte(); |  | ||||||
|                 tiles[x][y] = getTileForBitmask(bitmask); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return createLabyrinth(tiles, width, height, randomSeed); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @NonNull |  | ||||||
|     private Labyrinth createLabyrinth(@NonNull final Tile[][] field, final int width, final int height, final long randomSeed) { |  | ||||||
|         try { |         try { | ||||||
|             @NonNull final Constructor<Labyrinth> constructor = Labyrinth.class.getDeclaredConstructor(Tile[][].class, Integer.TYPE, Integer.TYPE, Long.TYPE); |             final Constructor<Labyrinth> constructor = Labyrinth.class.getDeclaredConstructor(Tile[][].class, Integer.TYPE, Integer.TYPE, Long.TYPE); | ||||||
|             constructor.setAccessible(true); |             constructor.setAccessible(true); | ||||||
|             return constructor.newInstance(field, width, height, randomSeed); |             return constructor.newInstance(field, width, height, randomSeed); | ||||||
|         } catch (final NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { |         } catch (final NoSuchMethodException | IllegalAccessException | InstantiationException | | ||||||
|  |                        InvocationTargetException e) { | ||||||
|             throw new RuntimeException("Can not deserialize Labyrinth from labyrinth data.", e); |             throw new RuntimeException("Can not deserialize Labyrinth from labyrinth data.", e); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -162,12 +101,13 @@ public class SerializerDeserializer { | ||||||
|             @NonNull final Constructor<Tile> constructor = Tile.class.getDeclaredConstructor(EnumSet.class, Boolean.TYPE); |             @NonNull final Constructor<Tile> constructor = Tile.class.getDeclaredConstructor(EnumSet.class, Boolean.TYPE); | ||||||
|             constructor.setAccessible(true); |             constructor.setAccessible(true); | ||||||
|             return constructor.newInstance(walls, solution); |             return constructor.newInstance(walls, solution); | ||||||
|         } catch (final NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { |         } catch (final NoSuchMethodException | InstantiationException | IllegalAccessException | | ||||||
|  |                        InvocationTargetException e) { | ||||||
|             throw new RuntimeException("Can not deserialize Tile from labyrinth data.", e); |             throw new RuntimeException("Can not deserialize Tile from labyrinth data.", e); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private byte getBitmaskForTile(@NonNull final Tile tile) { |     byte getBitmaskForTile(@NonNull final Tile tile) { | ||||||
|         byte bitmask = 0; |         byte bitmask = 0; | ||||||
|         if (tile.hasWallAt(Direction.TOP)) { |         if (tile.hasWallAt(Direction.TOP)) { | ||||||
|             bitmask |= TOP_BIT; |             bitmask |= TOP_BIT; | ||||||
|  | @ -188,7 +128,7 @@ public class SerializerDeserializer { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @NonNull |     @NonNull | ||||||
|     private Tile getTileForBitmask(final byte bitmask) { |      Tile getTileForBitmask(final byte bitmask) { | ||||||
|         final EnumSet<Direction> walls = EnumSet.noneOf(Direction.class); |         final EnumSet<Direction> walls = EnumSet.noneOf(Direction.class); | ||||||
|         if ((bitmask & TOP_BIT) == TOP_BIT) { |         if ((bitmask & TOP_BIT) == TOP_BIT) { | ||||||
|             walls.add(Direction.TOP); |             walls.add(Direction.TOP); | ||||||
|  |  | ||||||
|  | @ -1,12 +1,12 @@ | ||||||
| <?xml version="1.0" encoding="utf-8" ?> | <?xml version="1.0" encoding="utf-8" ?> | ||||||
| <configuration> | <configuration> | ||||||
|     <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/> |     <shutdownHook class="ch.qos.logback.core.hook.DefaultShutdownHook"/> | ||||||
| 
 | 
 | ||||||
|     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> |     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||||||
|         <!-- encoders are by default assigned the type |         <!-- encoders are by default assigned the type | ||||||
|         ch.qos.logback.classic.encoder.PatternLayoutEncoder --> |         ch.qos.logback.classic.encoder.PatternLayoutEncoder --> | ||||||
|         <encoder> |         <encoder> | ||||||
|             <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> |             <pattern>%d{HH:mm:ss.SSS} %-5level %X{correlationId} [%thread] %logger{36} - %msg%n</pattern> | ||||||
|         </encoder> |         </encoder> | ||||||
|     </appender> |     </appender> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,14 +2,14 @@ package ch.fritteli.labyrinth.generator.model; | ||||||
| 
 | 
 | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
| import static org.junit.jupiter.api.Assertions.*; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| 
 | 
 | ||||||
| class DirectionTest { | class DirectionTest { | ||||||
|     @Test |     @Test | ||||||
|     void invert() { |     void invert() { | ||||||
|         assertEquals(Direction.BOTTOM, Direction.TOP.invert()); |         assertThat(Direction.TOP.invert()).isEqualTo(Direction.BOTTOM); | ||||||
|         assertEquals(Direction.LEFT, Direction.RIGHT.invert()); |         assertThat(Direction.RIGHT.invert()).isEqualTo(Direction.LEFT); | ||||||
|         assertEquals(Direction.TOP, Direction.BOTTOM.invert()); |         assertThat(Direction.BOTTOM.invert()).isEqualTo(Direction.TOP); | ||||||
|         assertEquals(Direction.RIGHT, Direction.LEFT.invert()); |         assertThat(Direction.LEFT.invert()).isEqualTo(Direction.RIGHT); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,25 +2,28 @@ package ch.fritteli.labyrinth.generator.model; | ||||||
| 
 | 
 | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| import static org.junit.jupiter.api.Assertions.assertThrows; | import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||||||
| 
 | 
 | ||||||
| class LabyrinthTest { | class LabyrinthTest { | ||||||
|     @Test |     @Test | ||||||
|     void testConstruct() { |     void testConstruct() { | ||||||
|         // act / assert on simple cases |         // act / assert on simple cases | ||||||
|         assertThrows(IllegalArgumentException.class, () -> new Labyrinth(0, 0)); |         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> new Labyrinth(0, 0)) | ||||||
|         assertThrows(IllegalArgumentException.class, () -> new Labyrinth(0, 0, 0)); |                 .withMessage("width and height must be >1"); | ||||||
|  |         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> new Labyrinth(0, 0, 0)) | ||||||
|  |                 .withMessage("width and height must be >1"); | ||||||
| 
 | 
 | ||||||
|         // now for the real work: |         // now for the real work: | ||||||
|         // arrange |         // arrange | ||||||
|         final Labyrinth sut = new Labyrinth(2, 3, 5); |         final Labyrinth sut = new Labyrinth(2, 3, 5); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertEquals(2, sut.getWidth()); |         assertThat(sut) | ||||||
|         assertEquals(3, sut.getHeight()); |                 .returns(2, Labyrinth::getWidth) | ||||||
|         assertEquals(5, sut.getRandomSeed()); |                 .returns(3, Labyrinth::getHeight) | ||||||
|         assertEquals(new Position(0, 0), sut.getStart()); |                 .returns(5L, Labyrinth::getRandomSeed) | ||||||
|         assertEquals(new Position(1, 2), sut.getEnd()); |                 .returns(new Position(0, 0), Labyrinth::getStart) | ||||||
|  |                 .returns(new Position(1, 2), Labyrinth::getEnd); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ package ch.fritteli.labyrinth.generator.model; | ||||||
| 
 | 
 | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| 
 | 
 | ||||||
| class PositionTest { | class PositionTest { | ||||||
|     @Test |     @Test | ||||||
|  | @ -18,10 +18,10 @@ class PositionTest { | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         // Original is unchanged |         // Original is unchanged | ||||||
|         assertEquals(new Position(0, 0), sut); |         assertThat(sut).isEqualTo(new Position(0, 0)); | ||||||
|         assertEquals(new Position(0, -1), resultTOP); |         assertThat(resultTOP).isEqualTo(new Position(0, -1)); | ||||||
|         assertEquals(new Position(1, 0), resultRIGHT); |         assertThat(resultRIGHT).isEqualTo(new Position(1, 0)); | ||||||
|         assertEquals(new Position(0, 1), resultBOTTOM); |         assertThat(resultBOTTOM).isEqualTo(new Position(0, 1)); | ||||||
|         assertEquals(new Position(-1, 0), resultLEFT); |         assertThat(resultLEFT).isEqualTo(new Position(-1, 0)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,9 +5,7 @@ import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
| 
 | 
 | ||||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| import static org.junit.jupiter.api.Assertions.assertFalse; |  | ||||||
| import static org.junit.jupiter.api.Assertions.assertTrue; |  | ||||||
| 
 | 
 | ||||||
| class TileTest { | class TileTest { | ||||||
|     @Test |     @Test | ||||||
|  | @ -16,11 +14,12 @@ class TileTest { | ||||||
|         final Tile sut = new Tile(); |         final Tile sut = new Tile(); | ||||||
| 
 | 
 | ||||||
|         //assert |         //assert | ||||||
|         assertTrue(sut.hasWallAt(Direction.TOP)); |         assertThat(sut) | ||||||
|         assertTrue(sut.hasWallAt(Direction.RIGHT)); |                 .returns(true, v -> v.hasWallAt(Direction.TOP)) | ||||||
|         assertTrue(sut.hasWallAt(Direction.BOTTOM)); |                 .returns(true, v -> v.hasWallAt(Direction.RIGHT)) | ||||||
|         assertTrue(sut.hasWallAt(Direction.LEFT)); |                 .returns(true, v -> v.hasWallAt(Direction.BOTTOM)) | ||||||
|         assertFalse(sut.isSolution()); |                 .returns(true, v -> v.hasWallAt(Direction.LEFT)) | ||||||
|  |                 .returns(false, Tile::isSolution); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -32,15 +31,15 @@ class TileTest { | ||||||
|         boolean result = sut.digFrom(Direction.TOP); |         boolean result = sut.digFrom(Direction.TOP); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(result); |         assertThat(result).isTrue(); | ||||||
|         assertFalse(sut.hasWallAt(Direction.TOP)); |         assertThat(sut.hasWallAt(Direction.TOP)).isFalse(); | ||||||
| 
 | 
 | ||||||
|         // act: can not dig from when already dug |         // act: can not dig from when already dug | ||||||
|         result = sut.digFrom(Direction.BOTTOM); |         result = sut.digFrom(Direction.BOTTOM); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertFalse(result); |         assertThat(result).isFalse(); | ||||||
|         assertTrue(sut.hasWallAt(Direction.BOTTOM)); |         assertThat(sut.hasWallAt(Direction.BOTTOM)).isTrue(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -49,18 +48,20 @@ class TileTest { | ||||||
|         final Tile sut = new Tile(); |         final Tile sut = new Tile(); | ||||||
| 
 | 
 | ||||||
|         // act / assert |         // act / assert | ||||||
|         assertTrue(sut.digTo(Direction.TOP)); |         assertThat(sut) | ||||||
|         assertTrue(sut.digTo(Direction.RIGHT)); |                 .returns(true, v -> v.digTo(Direction.TOP)) | ||||||
|         assertTrue(sut.digTo(Direction.BOTTOM)); |                 .returns(true, v -> v.digTo(Direction.RIGHT)) | ||||||
|         assertTrue(sut.digTo(Direction.LEFT)); |                 .returns(true, v -> v.digTo(Direction.BOTTOM)) | ||||||
|  |                 .returns(true, v -> v.digTo(Direction.LEFT)) | ||||||
|                 // digging a second time does not succeed |                 // digging a second time does not succeed | ||||||
|         assertFalse(sut.digTo(Direction.LEFT)); |                 .returns(false, v -> v.digTo(Direction.LEFT)); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertFalse(sut.hasWallAt(Direction.TOP)); |         assertThat(sut) | ||||||
|         assertFalse(sut.hasWallAt(Direction.RIGHT)); |                 .returns(false, v -> v.hasWallAt(Direction.TOP)) | ||||||
|         assertFalse(sut.hasWallAt(Direction.BOTTOM)); |                 .returns(false, v -> v.hasWallAt(Direction.RIGHT)) | ||||||
|         assertFalse(sut.hasWallAt(Direction.LEFT)); |                 .returns(false, v -> v.hasWallAt(Direction.BOTTOM)) | ||||||
|  |                 .returns(false, v -> v.hasWallAt(Direction.LEFT)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -72,9 +73,10 @@ class TileTest { | ||||||
|         sut.preventDiggingToOrFrom(Direction.LEFT); |         sut.preventDiggingToOrFrom(Direction.LEFT); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertFalse(sut.digTo(Direction.LEFT)); |         assertThat(sut) | ||||||
|         assertFalse(sut.digFrom(Direction.LEFT)); |                 .returns(false, v -> v.digTo(Direction.LEFT)) | ||||||
|         assertTrue(sut.hasWallAt(Direction.LEFT)); |                 .returns(false, v -> v.digFrom(Direction.LEFT)) | ||||||
|  |                 .returns(true, v -> v.hasWallAt(Direction.LEFT)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -87,11 +89,12 @@ class TileTest { | ||||||
|         // then, re-enable digging |         // then, re-enable digging | ||||||
|         sut.enableDiggingToOrFrom(Direction.LEFT); |         sut.enableDiggingToOrFrom(Direction.LEFT); | ||||||
|         // also, enable it from a previously non-disabled direction |         // also, enable it from a previously non-disabled direction | ||||||
| 
 |  | ||||||
|         sut.enableDiggingToOrFrom(Direction.BOTTOM); |         sut.enableDiggingToOrFrom(Direction.BOTTOM); | ||||||
|  | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(sut.digTo(Direction.LEFT)); |         assertThat(sut) | ||||||
|         assertFalse(sut.hasWallAt(Direction.LEFT)); |                 .returns(true, v -> v.digTo(Direction.LEFT)) | ||||||
|  |                 .returns(false, v -> v.hasWallAt(Direction.LEFT)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -104,7 +107,7 @@ class TileTest { | ||||||
|         sut.undigTo(Direction.BOTTOM); |         sut.undigTo(Direction.BOTTOM); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(sut.hasWallAt(Direction.BOTTOM)); |         assertThat(sut.hasWallAt(Direction.BOTTOM)).isTrue(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -116,7 +119,7 @@ class TileTest { | ||||||
|         sut.setSolution(); |         sut.setSolution(); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(sut.isSolution()); |         assertThat(sut.isSolution()).isTrue(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -130,8 +133,9 @@ class TileTest { | ||||||
|         Option<Direction> result = sut.getRandomAvailableDirection(dummyRandom); |         Option<Direction> result = sut.getRandomAvailableDirection(dummyRandom); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(result.isDefined()); |         assertThat(result) | ||||||
|         assertEquals(Direction.TOP, result.get()); |                 .singleElement() | ||||||
|  |                 .isEqualTo(Direction.TOP); | ||||||
| 
 | 
 | ||||||
|         // re-arrange |         // re-arrange | ||||||
|         sut.preventDiggingToOrFrom(Direction.TOP); |         sut.preventDiggingToOrFrom(Direction.TOP); | ||||||
|  | @ -140,8 +144,9 @@ class TileTest { | ||||||
|         result = sut.getRandomAvailableDirection(dummyRandom); |         result = sut.getRandomAvailableDirection(dummyRandom); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(result.isDefined()); |         assertThat(result) | ||||||
|         assertEquals(Direction.RIGHT, result.get()); |                 .singleElement() | ||||||
|  |                 .isEqualTo(Direction.RIGHT); | ||||||
| 
 | 
 | ||||||
|         // re-arrange |         // re-arrange | ||||||
|         sut.preventDiggingToOrFrom(Direction.RIGHT); |         sut.preventDiggingToOrFrom(Direction.RIGHT); | ||||||
|  | @ -150,8 +155,9 @@ class TileTest { | ||||||
|         result = sut.getRandomAvailableDirection(dummyRandom); |         result = sut.getRandomAvailableDirection(dummyRandom); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(result.isDefined()); |         assertThat(result) | ||||||
|         assertEquals(Direction.BOTTOM, result.get()); |                 .singleElement() | ||||||
|  |                 .isEqualTo(Direction.BOTTOM); | ||||||
| 
 | 
 | ||||||
|         // re-arrange |         // re-arrange | ||||||
|         sut.preventDiggingToOrFrom(Direction.BOTTOM); |         sut.preventDiggingToOrFrom(Direction.BOTTOM); | ||||||
|  | @ -160,8 +166,9 @@ class TileTest { | ||||||
|         result = sut.getRandomAvailableDirection(dummyRandom); |         result = sut.getRandomAvailableDirection(dummyRandom); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(result.isDefined()); |         assertThat(result) | ||||||
|         assertEquals(Direction.LEFT, result.get()); |                 .singleElement() | ||||||
|  |                 .isEqualTo(Direction.LEFT); | ||||||
| 
 | 
 | ||||||
|         // re-arrange |         // re-arrange | ||||||
|         sut.preventDiggingToOrFrom(Direction.LEFT); |         sut.preventDiggingToOrFrom(Direction.LEFT); | ||||||
|  | @ -170,7 +177,7 @@ class TileTest { | ||||||
|         result = sut.getRandomAvailableDirection(dummyRandom); |         result = sut.getRandomAvailableDirection(dummyRandom); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertFalse(result.isDefined()); |         assertThat(result).isEmpty(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static class MyDummyRandom extends Random { |     private static class MyDummyRandom extends Random { | ||||||
|  |  | ||||||
|  | @ -3,10 +3,8 @@ package ch.fritteli.labyrinth.generator.model; | ||||||
| import io.vavr.collection.Stream; | import io.vavr.collection.Stream; | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| import static org.junit.jupiter.api.Assertions.assertFalse; | import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||||||
| import static org.junit.jupiter.api.Assertions.assertThrows; |  | ||||||
| import static org.junit.jupiter.api.Assertions.assertTrue; |  | ||||||
| 
 | 
 | ||||||
| class WallsTest { | class WallsTest { | ||||||
|     @Test |     @Test | ||||||
|  | @ -15,10 +13,11 @@ class WallsTest { | ||||||
|         final Walls sut = new Walls(); |         final Walls sut = new Walls(); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertFalse(sut.isSet(Direction.TOP)); |         assertThat(sut) | ||||||
|         assertFalse(sut.isSet(Direction.RIGHT)); |                 .returns(false, v -> v.isSet(Direction.TOP)) | ||||||
|         assertFalse(sut.isSet(Direction.BOTTOM)); |                 .returns(false, v -> v.isSet(Direction.RIGHT)) | ||||||
|         assertFalse(sut.isSet(Direction.LEFT)); |                 .returns(false, v -> v.isSet(Direction.BOTTOM)) | ||||||
|  |                 .returns(false, v -> v.isSet(Direction.LEFT)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -30,19 +29,21 @@ class WallsTest { | ||||||
|         sut.set(Direction.RIGHT); |         sut.set(Direction.RIGHT); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertFalse(sut.isSet(Direction.TOP)); |         assertThat(sut) | ||||||
|         assertTrue(sut.isSet(Direction.RIGHT)); |                 .returns(false, v -> v.isSet(Direction.TOP)) | ||||||
|         assertFalse(sut.isSet(Direction.BOTTOM)); |                 .returns(true, v -> v.isSet(Direction.RIGHT)) | ||||||
|         assertFalse(sut.isSet(Direction.LEFT)); |                 .returns(false, v -> v.isSet(Direction.BOTTOM)) | ||||||
|  |                 .returns(false, v -> v.isSet(Direction.LEFT)); | ||||||
| 
 | 
 | ||||||
|         //act: Setting twice has no effect |         //act: Setting twice has no effect | ||||||
|         sut.set(Direction.RIGHT); |         sut.set(Direction.RIGHT); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertFalse(sut.isSet(Direction.TOP)); |         assertThat(sut) | ||||||
|         assertTrue(sut.isSet(Direction.RIGHT)); |                 .returns(false, v -> v.isSet(Direction.TOP)) | ||||||
|         assertFalse(sut.isSet(Direction.BOTTOM)); |                 .returns(true, v -> v.isSet(Direction.RIGHT)) | ||||||
|         assertFalse(sut.isSet(Direction.LEFT)); |                 .returns(false, v -> v.isSet(Direction.BOTTOM)) | ||||||
|  |                 .returns(false, v -> v.isSet(Direction.LEFT)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -54,10 +55,11 @@ class WallsTest { | ||||||
|         sut.setAll(); |         sut.setAll(); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(sut.isSet(Direction.TOP)); |         assertThat(sut) | ||||||
|         assertTrue(sut.isSet(Direction.RIGHT)); |                 .returns(true, v -> v.isSet(Direction.TOP)) | ||||||
|         assertTrue(sut.isSet(Direction.BOTTOM)); |                 .returns(true, v -> v.isSet(Direction.RIGHT)) | ||||||
|         assertTrue(sut.isSet(Direction.LEFT)); |                 .returns(true, v -> v.isSet(Direction.BOTTOM)) | ||||||
|  |                 .returns(true, v -> v.isSet(Direction.LEFT)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -71,20 +73,21 @@ class WallsTest { | ||||||
|         sut.harden(Direction.TOP); |         sut.harden(Direction.TOP); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(sut.isSet(Direction.TOP)); |         assertThat(sut) | ||||||
|         assertTrue(sut.isSet(Direction.RIGHT)); |                 .returns(true, v -> v.isSet(Direction.TOP)) | ||||||
|         assertFalse(sut.isSet(Direction.BOTTOM)); |                 .returns(true, v -> v.isSet(Direction.RIGHT)) | ||||||
|         assertFalse(sut.isSet(Direction.LEFT)); |                 .returns(false, v -> v.isSet(Direction.BOTTOM)) | ||||||
|  |                 .returns(false, v -> v.isSet(Direction.LEFT)); | ||||||
| 
 | 
 | ||||||
|         // act: try to clear hardened wall |         // act: try to clear hardened wall | ||||||
|         final boolean result = sut.clear(Direction.TOP); |         final boolean result = sut.clear(Direction.TOP); | ||||||
| 
 | 
 | ||||||
|         // assert: TOP wall is still set |         // assert: TOP wall is still set | ||||||
|         assertFalse(result); |         assertThat(result).isFalse(); | ||||||
|         assertTrue(sut.isSet(Direction.TOP)); |         assertThat(sut.isSet(Direction.TOP)).isTrue(); | ||||||
| 
 | 
 | ||||||
|         // act / assert: try to harden un-set wall |         // act / assert: try to harden un-set wall | ||||||
|         assertThrows(IllegalStateException.class, () -> sut.harden(Direction.LEFT)); |         assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> sut.harden(Direction.LEFT)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -95,13 +98,13 @@ class WallsTest { | ||||||
|         sut.harden(Direction.TOP); |         sut.harden(Direction.TOP); | ||||||
| 
 | 
 | ||||||
|         // pre-assert: TOP can't be cleared while hardened |         // pre-assert: TOP can't be cleared while hardened | ||||||
|         assertFalse(sut.clear(Direction.TOP)); |         assertThat(sut.clear(Direction.TOP)).isFalse(); | ||||||
| 
 | 
 | ||||||
|         // act |         // act | ||||||
|         sut.unharden(Direction.TOP); |         sut.unharden(Direction.TOP); | ||||||
| 
 | 
 | ||||||
|         // assert: TOP can be cleared |         // assert: TOP can be cleared | ||||||
|         assertTrue(sut.clear(Direction.TOP)); |         assertThat(sut.clear(Direction.TOP)).isTrue(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|  | @ -113,7 +116,7 @@ class WallsTest { | ||||||
|         Stream<Direction> result = sut.getUnhardenedSet(); |         Stream<Direction> result = sut.getUnhardenedSet(); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertTrue(result.isEmpty()); |         assertThat(result).isEmpty(); | ||||||
| 
 | 
 | ||||||
|         // arrange: set some directions |         // arrange: set some directions | ||||||
|         sut.set(Direction.TOP); |         sut.set(Direction.TOP); | ||||||
|  | @ -123,7 +126,7 @@ class WallsTest { | ||||||
|         result = sut.getUnhardenedSet(); |         result = sut.getUnhardenedSet(); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertEquals(Stream.of(Direction.TOP, Direction.LEFT), result); |         assertThat(result).containsExactly(Direction.TOP, Direction.LEFT); | ||||||
| 
 | 
 | ||||||
|         // arrange: harden a direction |         // arrange: harden a direction | ||||||
|         sut.harden(Direction.TOP); |         sut.harden(Direction.TOP); | ||||||
|  | @ -132,6 +135,6 @@ class WallsTest { | ||||||
|         result = sut.getUnhardenedSet(); |         result = sut.getUnhardenedSet(); | ||||||
| 
 | 
 | ||||||
|         // assert |         // assert | ||||||
|         assertEquals(Stream.of(Direction.LEFT), result); |         assertThat(result).containsExactly(Direction.LEFT); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,58 +2,58 @@ package ch.fritteli.labyrinth.generator.renderer.text; | ||||||
| 
 | 
 | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| 
 | 
 | ||||||
| class CharDefinitionTest { | class CharDefinitionTest { | ||||||
|     @Test |     @Test | ||||||
|     void testRenderingWall() { |     void testRenderingWall() { | ||||||
|         assertEquals(" ", new CharDefinition(false, false, false, false, false).toString()); |         assertThat(new CharDefinition(false, false, false, false, false)).hasToString(" "); | ||||||
|         assertEquals("╶", new CharDefinition(false, false, false, true, false).toString()); |         assertThat(new CharDefinition(false, false, false, true, false)).hasToString("╶"); | ||||||
|         assertEquals("╴", new CharDefinition(false, false, true, false, false).toString()); |         assertThat(new CharDefinition(false, false, true, false, false)).hasToString("╴"); | ||||||
|         assertEquals("─", new CharDefinition(false, false, true, true, false).toString()); |         assertThat(new CharDefinition(false, false, true, true, false)).hasToString("─"); | ||||||
|         assertEquals("╷", new CharDefinition(false, true, false, false, false).toString()); |         assertThat(new CharDefinition(false, true, false, false, false)).hasToString("╷"); | ||||||
|         assertEquals("┌", new CharDefinition(false, true, false, true, false).toString()); |         assertThat(new CharDefinition(false, true, false, true, false)).hasToString("┌"); | ||||||
|         assertEquals("┐", new CharDefinition(false, true, true, false, false).toString()); |         assertThat(new CharDefinition(false, true, true, false, false)).hasToString("┐"); | ||||||
|         assertEquals("┬", new CharDefinition(false, true, true, true, false).toString()); |         assertThat(new CharDefinition(false, true, true, true, false)).hasToString("┬"); | ||||||
|         assertEquals("╵", new CharDefinition(true, false, false, false, false).toString()); |         assertThat(new CharDefinition(true, false, false, false, false)).hasToString("╵"); | ||||||
|         assertEquals("└", new CharDefinition(true, false, false, true, false).toString()); |         assertThat(new CharDefinition(true, false, false, true, false)).hasToString("└"); | ||||||
|         assertEquals("┘", new CharDefinition(true, false, true, false, false).toString()); |         assertThat(new CharDefinition(true, false, true, false, false)).hasToString("┘"); | ||||||
|         assertEquals("┴", new CharDefinition(true, false, true, true, false).toString()); |         assertThat(new CharDefinition(true, false, true, true, false)).hasToString("┴"); | ||||||
|         assertEquals("│", new CharDefinition(true, true, false, false, false).toString()); |         assertThat(new CharDefinition(true, true, false, false, false)).hasToString("│"); | ||||||
|         assertEquals("├", new CharDefinition(true, true, false, true, false).toString()); |         assertThat(new CharDefinition(true, true, false, true, false)).hasToString("├"); | ||||||
|         assertEquals("┤", new CharDefinition(true, true, true, false, false).toString()); |         assertThat(new CharDefinition(true, true, true, false, false)).hasToString("┤"); | ||||||
|         assertEquals("┼", new CharDefinition(true, true, true, true, false).toString()); |         assertThat(new CharDefinition(true, true, true, true, false)).hasToString("┼"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     void testRenderingSolution() { |     void testRenderingSolution() { | ||||||
|         assertEquals(" ", new CharDefinition(false, false, false, false, true).toString()); |         assertThat(new CharDefinition(false, false, false, false, true)).hasToString(" "); | ||||||
|         assertEquals("╶", new CharDefinition(false, false, false, true, true).toString()); |         assertThat(new CharDefinition(false, false, false, true, true)).hasToString("╶"); | ||||||
|         assertEquals("╴", new CharDefinition(false, false, true, false, true).toString()); |         assertThat(new CharDefinition(false, false, true, false, true)).hasToString("╴"); | ||||||
|         assertEquals("─", new CharDefinition(false, false, true, true, true).toString()); |         assertThat(new CharDefinition(false, false, true, true, true)).hasToString("─"); | ||||||
|         assertEquals("╷", new CharDefinition(false, true, false, false, true).toString()); |         assertThat(new CharDefinition(false, true, false, false, true)).hasToString("╷"); | ||||||
|         assertEquals("╭", new CharDefinition(false, true, false, true, true).toString()); |         assertThat(new CharDefinition(false, true, false, true, true)).hasToString("╭"); | ||||||
|         assertEquals("╮", new CharDefinition(false, true, true, false, true).toString()); |         assertThat(new CharDefinition(false, true, true, false, true)).hasToString("╮"); | ||||||
|         assertEquals("┬", new CharDefinition(false, true, true, true, true).toString()); |         assertThat(new CharDefinition(false, true, true, true, true)).hasToString("┬"); | ||||||
|         assertEquals("╵", new CharDefinition(true, false, false, false, true).toString()); |         assertThat(new CharDefinition(true, false, false, false, true)).hasToString("╵"); | ||||||
|         assertEquals("╰", new CharDefinition(true, false, false, true, true).toString()); |         assertThat(new CharDefinition(true, false, false, true, true)).hasToString("╰"); | ||||||
|         assertEquals("╯", new CharDefinition(true, false, true, false, true).toString()); |         assertThat(new CharDefinition(true, false, true, false, true)).hasToString("╯"); | ||||||
|         assertEquals("┴", new CharDefinition(true, false, true, true, true).toString()); |         assertThat(new CharDefinition(true, false, true, true, true)).hasToString("┴"); | ||||||
|         assertEquals("│", new CharDefinition(true, true, false, false, true).toString()); |         assertThat(new CharDefinition(true, true, false, false, true)).hasToString("│"); | ||||||
|         assertEquals("├", new CharDefinition(true, true, false, true, true).toString()); |         assertThat(new CharDefinition(true, true, false, true, true)).hasToString("├"); | ||||||
|         assertEquals("┤", new CharDefinition(true, true, true, false, true).toString()); |         assertThat(new CharDefinition(true, true, true, false, true)).hasToString("┤"); | ||||||
|         assertEquals("┼", new CharDefinition(true, true, true, true, true).toString()); |         assertThat(new CharDefinition(true, true, true, true, true)).hasToString("┼"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     void testBuilderMethods() { |     void testBuilderMethods() { | ||||||
|         assertEquals(new CharDefinition(true, false, false, false, false), new CharDefinition().up()); |         assertThat(new CharDefinition().up()).isEqualTo(new CharDefinition(true, false, false, false, false)); | ||||||
|         assertEquals(new CharDefinition(false, true, false, false, false), new CharDefinition().down()); |         assertThat(new CharDefinition().down()).isEqualTo(new CharDefinition(false, true, false, false, false)); | ||||||
|         assertEquals(new CharDefinition(false, false, true, false, false), new CharDefinition().left()); |         assertThat(new CharDefinition().left()).isEqualTo(new CharDefinition(false, false, true, false, false)); | ||||||
|         assertEquals(new CharDefinition(false, false, false, true, false), new CharDefinition().right()); |         assertThat(new CharDefinition().right()).isEqualTo(new CharDefinition(false, false, false, true, false)); | ||||||
|         assertEquals(new CharDefinition(false, false, false, false, true), new CharDefinition().solution()); |         assertThat(new CharDefinition().solution()).isEqualTo(new CharDefinition(false, false, false, false, true)); | ||||||
|         assertEquals(new CharDefinition(true, true, false, false, false), new CharDefinition().vertical()); |         assertThat(new CharDefinition().vertical()).isEqualTo(new CharDefinition(true, true, false, false, false)); | ||||||
|         assertEquals(new CharDefinition(false, false, true, true, false), new CharDefinition().horizontal()); |         assertThat(new CharDefinition().horizontal()).isEqualTo(new CharDefinition(false, false, true, true, false)); | ||||||
|         assertEquals(new CharDefinition(true, true, true, true, true), new CharDefinition().vertical().horizontal().solution()); |         assertThat(new CharDefinition().vertical().horizontal().solution()).isEqualTo(new CharDefinition(true, true, true, true, true)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,33 +1,32 @@ | ||||||
| package ch.fritteli.labyrinth.generator.serialization; | package ch.fritteli.labyrinth.generator.serialization; | ||||||
| 
 | 
 | ||||||
| import ch.fritteli.labyrinth.generator.model.Labyrinth; | import ch.fritteli.labyrinth.generator.model.Labyrinth; | ||||||
| import lombok.NonNull; |  | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| 
 | 
 | ||||||
| class SerializerDeserializerTest { | class SerializerDeserializerTest { | ||||||
|     @Test |     @Test | ||||||
|     void testSerializeDeserializeTiny() { |     void testSerializeDeserializeTiny() { | ||||||
|         @NonNull final Labyrinth expected = new Labyrinth(2, 2, 255); |         final Labyrinth expected = new Labyrinth(2, 2, 255); | ||||||
|         @NonNull final byte[] bytes = SerializerDeserializer.serialize(expected); |         final byte[] bytes = SerializerDeserializer.serialize(expected); | ||||||
|         @NonNull final Labyrinth result = SerializerDeserializer.deserialize(bytes); |         final Labyrinth result = SerializerDeserializer.deserialize(bytes); | ||||||
|         assertEquals(expected, result); |         assertThat(result).isEqualTo(expected); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     void testSerializeDeserializeMedium() { |     void testSerializeDeserializeMedium() { | ||||||
|         @NonNull final Labyrinth expected = new Labyrinth(20, 20, -271828182846L); |         final Labyrinth expected = new Labyrinth(20, 20, -271828182846L); | ||||||
|         @NonNull final byte[] bytes = SerializerDeserializer.serialize(expected); |         final byte[] bytes = SerializerDeserializer.serialize(expected); | ||||||
|         @NonNull final Labyrinth result = SerializerDeserializer.deserialize(bytes); |         final Labyrinth result = SerializerDeserializer.deserialize(bytes); | ||||||
|         assertEquals(expected, result); |         assertThat(result).isEqualTo(expected); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     void testSerializeDeserializeLarge() { |     void testSerializeDeserializeLarge() { | ||||||
|         @NonNull final Labyrinth expected = new Labyrinth(200, 320, 3141592653589793238L); |         final Labyrinth expected = new Labyrinth(200, 320, 3141592653589793238L); | ||||||
|         @NonNull final byte[] bytes = SerializerDeserializer.serialize(expected); |         final byte[] bytes = SerializerDeserializer.serialize(expected); | ||||||
|         @NonNull final Labyrinth result = SerializerDeserializer.deserialize(bytes); |         final Labyrinth result = SerializerDeserializer.deserialize(bytes); | ||||||
|         assertEquals(expected, result); |         assertThat(result).isEqualTo(expected); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue