Skip to content

Commit

Permalink
[tdd-diamond] Refactor: Delegate rendering to Board
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelszymczak committed Apr 9, 2017
1 parent 0d65319 commit 0906c04
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 2 deletions.
3 changes: 3 additions & 0 deletions tdd-diamond/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ repositories {
}

dependencies {
compile group: 'com.google.guava', name: 'guava', version: '21.0'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'

testCompile 'org.codehaus.groovy:groovy-all:2.4.7'
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
testCompile 'junit:junit:4.12'
Expand Down
52 changes: 52 additions & 0 deletions tdd-diamond/src/main/java/com/michaelszymczak/diamond/Board.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.michaelszymczak.diamond;

import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;

import static java.util.Arrays.asList;

public class Board {

private final PositionedLetter[][] board;
private final String emptyCell;

public Board(PositionedLetter... cells) {
this(" ", asList(cells));
}

public Board(Collection<PositionedLetter> cells) {
this(" ", cells);
}

public Board(String emptyCell, Collection<PositionedLetter> cells) {
this.emptyCell = emptyCell;
this.board = boardWith(cells);
}


private static PositionedLetter[][] boardWith(Collection<PositionedLetter> cells) {
int maxCellPosition = cells.stream()
.mapToInt(PositionedLetter::maxXorY)
.max()
.orElse(0);
PositionedLetter[][] board = new PositionedLetter[maxCellPosition+1][maxCellPosition+1];
cells.forEach(cell -> board[cell.getY()][cell.getX()] = cell);

return board;
}

@Override
public String toString() {
return Arrays.stream(board)
.map(this::rendered)
.collect(Collectors.joining("\n"));
}

private String rendered(PositionedLetter[] row) {
return Arrays.stream(row)
.map(cell -> (cell != null) ? cell.letterAsString() : emptyCell)
.collect(Collectors.joining());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.michaelszymczak.diamond;

public class Coordinates extends ValueObject {

private final int y;
private final int x;

public static Coordinates ofYX(int y, int x)
{
return new Coordinates(y, x);
}

private Coordinates(int y, int x) {
this.y = y;
this.x = x;
}

public int getY() {
return y;
}

public int getX() {
return x;
}

public int maxXorY() {
return x > y ? x : y;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.michaelszymczak.diamond;

import static com.michaelszymczak.diamond.Coordinates.ofYX;
import static com.michaelszymczak.diamond.Letter.A;
import static com.michaelszymczak.diamond.Letter.B;

public class Diamond {

private Letter letter;
Expand All @@ -13,6 +17,11 @@ private Diamond(Letter letter) {
}

public String rendered() {
return letter == Letter.A ? "A" : " A \nB B\n A ";
return letter == A ? new Board(new PositionedLetter(ofYX(0,0), A)).toString()
: new Board(
new PositionedLetter(ofYX(0,1), A),
new PositionedLetter(ofYX(1,0), B), new PositionedLetter(ofYX(1,2), B),
new PositionedLetter(ofYX(2,1), A)
).toString();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.michaelszymczak.diamond;

public enum Letter {
A, B
A, B, C, D
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.michaelszymczak.diamond;

public class PositionedLetter extends ValueObject {
private final Coordinates coordinates;
private final Letter letter;

public PositionedLetter(Coordinates coordinates, Letter letter) {
this.coordinates = coordinates;
this.letter = letter;
}

public int maxXorY() {
return coordinates.maxXorY();
}

public String letterAsString() {
return letter.toString();
}

public int getX() {
return coordinates.getX();
}

public int getY() {
return coordinates.getY();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.michaelszymczak.diamond;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

public class ValueObject {

@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
}

@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.michaelszymczak.diamond

import spock.lang.Specification

class BoardShould extends Specification {

def "should print a symbol"() {
expect: new Board([new PositionedLetter(Coordinates.ofYX(0,0),Letter.B)]).toString() == "B"
}

def "should print symbols respecting their positions"() {
expect:
new Board([
new PositionedLetter(Coordinates.ofYX(0,0),Letter.A),
new PositionedLetter(Coordinates.ofYX(0,1),Letter.B),
new PositionedLetter(Coordinates.ofYX(1,0),Letter.C),
new PositionedLetter(Coordinates.ofYX(1,1),Letter.D),
]).toString() == shapeOf("""
AB
CD
""")
}

def "should fill gaps with defined symbol "() {
expect:
new Board("_", [
new PositionedLetter(Coordinates.ofYX(0,2),Letter.A),
new PositionedLetter(Coordinates.ofYX(1,1),Letter.B),
new PositionedLetter(Coordinates.ofYX(1,3),Letter.B),
new PositionedLetter(Coordinates.ofYX(2,0),Letter.C),
new PositionedLetter(Coordinates.ofYX(2,4),Letter.C),
new PositionedLetter(Coordinates.ofYX(3,1),Letter.B),
new PositionedLetter(Coordinates.ofYX(3,3),Letter.B),
new PositionedLetter(Coordinates.ofYX(4,2),Letter.A),
]).toString() == shapeOf("""
__A__
_B_B_
C___C
_B_B_
__A__
""")
}
private static String shapeOf(String shape) {
shape.replaceAll("^\n", "").replaceAll("\n\$", "")
}
}

0 comments on commit 0906c04

Please sign in to comment.