Thomas Papendieck
4 years ago
commit
d44f4f98b5
8 changed files with 450 additions and 0 deletions
-
209pom.xml
-
11src/main/java/de/edu/hsfulda/ciip/tdd/NumberRepeater.java
-
7src/main/java/de/edu/hsfulda/ciip/tdd/StringRepeater.java
-
11src/main/java/de/edu/hsfulda/ciip/tdd/SymbolRepeater.java
-
48src/main/java/de/edu/hsfulda/ciip/tdd/TannenbaumRenderer.java
-
42src/main/java/de/edu/hsfulda/ciip/tdd/TannenbaumUi.java
-
39src/test/java/de/edu/hsfulda/ciip/tdd/TannenbaumRendererTest.java
-
83src/test/java/de/edu/hsfulda/ciip/tdd/TannenbaumUiTest.java
@ -0,0 +1,209 @@ |
|||
<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/maven-v4_0_0.xsd"> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
<groupId>de.edu.hsfulda.ciip.tdd</groupId> |
|||
<artifactId>tannenbaum</artifactId> |
|||
<version>1.0-SNAPSHOT</version> |
|||
<properties> |
|||
<maven.compiler.source>14</maven.compiler.source> |
|||
<maven.compiler.target>14</maven.compiler.target> |
|||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
|||
<junit.version>5.6.0</junit.version> |
|||
<maven-enforcer-plugin.version>3.0.0-M3</maven-enforcer-plugin.version> |
|||
<maven-checkstyle-plugin.version>3.1.0</maven-checkstyle-plugin.version> |
|||
<checkstyle.version>8.29</checkstyle.version> |
|||
<checkstyle-rules.version>4.0.1</checkstyle-rules.version> |
|||
<maven-surefire-plugin.version>3.0.0-M4</maven-surefire-plugin.version> |
|||
<jacoco-maven-plugin.version>0.8.4</jacoco-maven-plugin.version> |
|||
<maven-javadoc-plugin.version>3.0.0</maven-javadoc-plugin.version> |
|||
<coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version> |
|||
<!-- JaCoCo thresholds. Increase gradually as you add tests. --> |
|||
<jacoco.unit-tests.limit.instruction-ratio>0%</jacoco.unit-tests.limit.instruction-ratio> |
|||
<jacoco.unit-tests.limit.branch-ratio>0%</jacoco.unit-tests.limit.branch-ratio> |
|||
<jacoco.unit-tests.limit.class-complexity>20</jacoco.unit-tests.limit.class-complexity> |
|||
<jacoco.unit-tests.limit.method-complexity>5</jacoco.unit-tests.limit.method-complexity> |
|||
</properties> |
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.junit.jupiter</groupId> |
|||
<artifactId>junit-jupiter-api</artifactId> |
|||
<version>${junit.version}</version> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.junit.jupiter</groupId> |
|||
<artifactId>junit-jupiter-engine</artifactId> |
|||
<version>${junit.version}</version> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.mockito</groupId> |
|||
<artifactId>mockito-core</artifactId> |
|||
<version>2.21.0</version> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.mockito</groupId> |
|||
<artifactId>mockito-junit-jupiter</artifactId> |
|||
<version>2.23.0</version> |
|||
<scope>test</scope> |
|||
</dependency> |
|||
</dependencies> |
|||
<build> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-enforcer-plugin</artifactId> |
|||
<version>${maven-enforcer-plugin.version}</version> |
|||
<executions> |
|||
<execution> |
|||
<goals> |
|||
<goal>enforce</goal> |
|||
</goals> |
|||
<configuration> |
|||
<rules> |
|||
<requireMavenVersion> |
|||
<version>3.6.3</version> |
|||
</requireMavenVersion> |
|||
</rules> |
|||
<fail>true</fail> |
|||
</configuration> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-checkstyle-plugin</artifactId> |
|||
<version>${maven-checkstyle-plugin.version}</version> |
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>com.puppycrawl.tools</groupId> |
|||
<artifactId>checkstyle</artifactId> |
|||
<version>${checkstyle.version}</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.github.ngeor</groupId> |
|||
<artifactId>checkstyle-rules</artifactId> |
|||
<version>${checkstyle-rules.version}</version> |
|||
</dependency> |
|||
</dependencies> |
|||
<configuration> |
|||
<configLocation>com/github/ngeor/checkstyle.xml</configLocation> |
|||
<includeTestSourceDirectory>true</includeTestSourceDirectory> |
|||
<skip>true</skip> |
|||
</configuration> |
|||
<executions> |
|||
<execution> |
|||
<id>checkstyle</id> |
|||
<phase>validate</phase> |
|||
<goals> |
|||
<goal>check</goal> |
|||
</goals> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-surefire-plugin</artifactId> |
|||
<version>${maven-surefire-plugin.version}</version> |
|||
</plugin> |
|||
<plugin> |
|||
<groupId>org.jacoco</groupId> |
|||
<artifactId>jacoco-maven-plugin</artifactId> |
|||
<version>${jacoco-maven-plugin.version}</version> |
|||
<executions> |
|||
<execution> |
|||
<id>pre-unit-test</id> |
|||
<goals> |
|||
<goal>prepare-agent</goal> |
|||
</goals> |
|||
</execution> |
|||
<execution> |
|||
<id>post-unit-test</id> |
|||
<phase>test</phase> |
|||
<goals> |
|||
<goal>report</goal> |
|||
</goals> |
|||
</execution> |
|||
<execution> |
|||
<id>check-unit-test</id> |
|||
<phase>test</phase> |
|||
<goals> |
|||
<goal>check</goal> |
|||
</goals> |
|||
<configuration> |
|||
<dataFile>${project.build.directory}/jacoco.exec</dataFile> |
|||
<rules> |
|||
<rule> |
|||
<element>BUNDLE</element> |
|||
<limits> |
|||
<limit> |
|||
<counter>INSTRUCTION</counter> |
|||
<value>COVEREDRATIO</value> |
|||
<minimum>${jacoco.unit-tests.limit.instruction-ratio}</minimum> |
|||
</limit> |
|||
<limit> |
|||
<counter>BRANCH</counter> |
|||
<value>COVEREDRATIO</value> |
|||
<minimum>${jacoco.unit-tests.limit.branch-ratio}</minimum> |
|||
</limit> |
|||
</limits> |
|||
</rule> |
|||
<rule> |
|||
<element>CLASS</element> |
|||
<limits> |
|||
<limit> |
|||
<counter>COMPLEXITY</counter> |
|||
<value>TOTALCOUNT</value> |
|||
<maximum>${jacoco.unit-tests.limit.class-complexity}</maximum> |
|||
</limit> |
|||
</limits> |
|||
</rule> |
|||
<rule> |
|||
<element>METHOD</element> |
|||
<limits> |
|||
<limit> |
|||
<counter>COMPLEXITY</counter> |
|||
<value>TOTALCOUNT</value> |
|||
<maximum>${jacoco.unit-tests.limit.method-complexity}</maximum> |
|||
</limit> |
|||
</limits> |
|||
</rule> |
|||
</rules> |
|||
</configuration> |
|||
</execution> |
|||
</executions> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
<reporting> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.apache.maven.plugins</groupId> |
|||
<artifactId>maven-javadoc-plugin</artifactId> |
|||
<version>${maven-javadoc-plugin.version}</version> |
|||
</plugin> |
|||
</plugins> |
|||
</reporting> |
|||
<profiles> |
|||
<!-- Publish coverage report to Coveralls, only when running in Travis. --> |
|||
<profile> |
|||
<id>travis</id> |
|||
<activation> |
|||
<property> |
|||
<name>env.TRAVIS</name> |
|||
</property> |
|||
</activation> |
|||
<build> |
|||
<plugins> |
|||
<plugin> |
|||
<groupId>org.eluder.coveralls</groupId> |
|||
<artifactId>coveralls-maven-plugin</artifactId> |
|||
<version>${coveralls-maven-plugin.version}</version> |
|||
</plugin> |
|||
</plugins> |
|||
</build> |
|||
</profile> |
|||
</profiles> |
|||
</project> |
@ -0,0 +1,11 @@ |
|||
package de.edu.hsfulda.ciip.tdd; |
|||
|
|||
public class NumberRepeater implements StringRepeater { |
|||
|
|||
@Override |
|||
public void repeatSymbol(StringBuilder slice, int i, String symbolIndent) { |
|||
// TODO Auto-generated method stub |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,7 @@ |
|||
package de.edu.hsfulda.ciip.tdd; |
|||
|
|||
public interface StringRepeater { |
|||
|
|||
void repeatSymbol(StringBuilder slice, int i, String symbolIndent); |
|||
|
|||
} |
@ -0,0 +1,11 @@ |
|||
package de.edu.hsfulda.ciip.tdd; |
|||
|
|||
public class SymbolRepeater implements StringRepeater { |
|||
|
|||
public void repeatSymbol(StringBuilder slice, int count, String symbol) { |
|||
for (int j = 0; j < count; j++) { |
|||
slice.append(symbol); |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,48 @@ |
|||
package de.edu.hsfulda.ciip.tdd; |
|||
|
|||
import java.util.LinkedList; |
|||
import java.util.List; |
|||
|
|||
public class TannenbaumRenderer { |
|||
|
|||
private static final int BOTH_DIRECTIONS = 2; |
|||
private static final int OFFSET = 1; |
|||
private static final int MIDDLE_BRANCH = 1; |
|||
private static final String SYMBOL_TRUNK = "I"; |
|||
private static final String SYMBOL_BRANCH = "X"; |
|||
private static final String SYMBOL_INDENT = " "; |
|||
private final StringRepeater symbolRepeater; |
|||
|
|||
|
|||
public TannenbaumRenderer(StringRepeater symbolRepeater) { |
|||
this.symbolRepeater = symbolRepeater; |
|||
} |
|||
|
|||
public List<String> getTreeOf(int size) { |
|||
List<String> tree = new LinkedList<>(); |
|||
renderTreeSlices(size, tree); |
|||
renderTrunk(size, tree); |
|||
return tree; |
|||
} |
|||
|
|||
private void renderTrunk(int size, List<String> tree) { |
|||
StringBuilder slice = new StringBuilder(); |
|||
symbolRepeater.repeatSymbol(slice, size - MIDDLE_BRANCH, SYMBOL_INDENT); |
|||
symbolRepeater.repeatSymbol(slice, MIDDLE_BRANCH, SYMBOL_TRUNK); |
|||
tree.add(slice.toString()); |
|||
} |
|||
|
|||
private void renderTreeSlices(int size, List<String> tree) { |
|||
for (int sliceWidth = 0; sliceWidth < size; sliceWidth++) { |
|||
renderSingleSlice(size, tree, sliceWidth); |
|||
} |
|||
} |
|||
|
|||
private void renderSingleSlice(int size, List<String> tree, int sliceWidth) { |
|||
StringBuilder slice = new StringBuilder(); |
|||
symbolRepeater.repeatSymbol(slice, size - (sliceWidth + OFFSET), SYMBOL_INDENT); |
|||
symbolRepeater.repeatSymbol(slice, sliceWidth * BOTH_DIRECTIONS + MIDDLE_BRANCH, SYMBOL_BRANCH); |
|||
tree.add(slice.toString()); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,42 @@ |
|||
package de.edu.hsfulda.ciip.tdd; |
|||
|
|||
import java.io.IOException; |
|||
import java.io.InputStream; |
|||
import java.io.PrintStream; |
|||
import java.util.List; |
|||
|
|||
public class TannenbaumUi { |
|||
|
|||
public static final String TREE_SIZE_PROMPT = "enter tree size:"; |
|||
private InputStream input; |
|||
private PrintStream output; |
|||
|
|||
public TannenbaumUi(InputStream input, PrintStream output) { |
|||
this.input = input; |
|||
this.output = output; |
|||
// TODO Auto-generated constructor stub |
|||
} |
|||
|
|||
public int getTreeSize() { |
|||
output.println("enter tree size:"); |
|||
try { |
|||
int available = input.available(); |
|||
int treesize = 0; |
|||
for (int i = 0; i < available; i++) { |
|||
treesize *= 10; |
|||
treesize += input.read() - '0'; |
|||
} |
|||
return treesize; |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
throw new RuntimeException(e); |
|||
} |
|||
} |
|||
|
|||
public void print(List<String> messageLines) { |
|||
for (String line : messageLines) { |
|||
output.println(line); |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,39 @@ |
|||
package de.edu.hsfulda.ciip.tdd; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.*; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
|
|||
import org.junit.jupiter.api.BeforeEach; |
|||
import org.junit.jupiter.api.Test; |
|||
|
|||
class TannenbaumRendererTest { |
|||
|
|||
private final SymbolRepeater symbolRepeater = new SymbolRepeater(); |
|||
|
|||
@BeforeEach |
|||
void setUp() throws Exception { |
|||
} |
|||
|
|||
@Test |
|||
void renderTreeSize1() { |
|||
int size = 1; |
|||
List<String> expectedTree = Arrays.asList("X", "I"); |
|||
|
|||
List<String> tree = new TannenbaumRenderer(symbolRepeater).getTreeOf(size); |
|||
|
|||
assertArrayEquals(expectedTree.toArray(), tree.toArray(), "tree"); |
|||
} |
|||
|
|||
@Test |
|||
void renderTreeSize2() { |
|||
int size = 2; |
|||
List<String> expectedTree = Arrays.asList(" X", "XXX", " I"); |
|||
|
|||
List<String> tree = new TannenbaumRenderer(symbolRepeater).getTreeOf(size); |
|||
|
|||
assertArrayEquals(expectedTree.toArray(), tree.toArray(), "tree"); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,83 @@ |
|||
package de.edu.hsfulda.ciip.tdd; |
|||
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals; |
|||
|
|||
import java.io.IOException; |
|||
import java.io.InputStream; |
|||
import java.io.PrintStream; |
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
|
|||
import org.junit.jupiter.api.Test; |
|||
import org.junit.jupiter.api.extension.ExtendWith; |
|||
import org.mockito.InOrder; |
|||
import org.mockito.Mock; |
|||
import org.mockito.Mockito; |
|||
import org.mockito.junit.jupiter.MockitoExtension; |
|||
|
|||
@ExtendWith(MockitoExtension.class) |
|||
class TannenbaumUiTest { |
|||
|
|||
@Mock |
|||
PrintStream output; |
|||
|
|||
@Mock |
|||
InputStream input; |
|||
|
|||
@Test |
|||
void parseUserInputToInteger() throws IOException { |
|||
Mockito.doReturn(1).when(input).available(); |
|||
Mockito.doReturn((int) '7').when(input).read(); |
|||
int expected = 7; |
|||
|
|||
int treeSize = new TannenbaumUi(input, output).getTreeSize(); |
|||
|
|||
assertEquals(expected, treeSize, "tree size"); |
|||
|
|||
InOrder inOrder = Mockito.inOrder(input, output); |
|||
|
|||
inOrder.verify(output).println(TannenbaumUi.TREE_SIZE_PROMPT); |
|||
inOrder.verify(input).available(); |
|||
} |
|||
|
|||
@Test |
|||
void parseUserInputToInteger2() throws IOException { |
|||
Mockito.doReturn(1).when(input).available(); |
|||
Mockito.doReturn((int) '9').when(input).read(); |
|||
int expected = 9; |
|||
|
|||
int treeSize = new TannenbaumUi(input, output).getTreeSize(); |
|||
|
|||
assertEquals(expected, treeSize, "tree size"); |
|||
} |
|||
|
|||
@Test |
|||
void parseUserInputToInteger2Digits() throws IOException { |
|||
Mockito.doReturn(2).when(input).available(); |
|||
Mockito.doReturn((int) '3').doReturn((int) '5').when(input).read(); |
|||
int expected = 35; |
|||
|
|||
int treeSize = new TannenbaumUi(input, output).getTreeSize(); |
|||
|
|||
assertEquals(expected, treeSize, "tree size"); |
|||
} |
|||
|
|||
@Test |
|||
void writeSingleLine() throws Exception { |
|||
String message = "hello world"; |
|||
|
|||
new TannenbaumUi(input, output).print(Arrays.asList(message)); |
|||
|
|||
Mockito.verify(output).println(message); |
|||
} |
|||
|
|||
@Test |
|||
void writeMultipeleLines() throws Exception { |
|||
List<String> messageLines = Arrays.asList("hello", "world"); |
|||
|
|||
new TannenbaumUi(input, output).print(messageLines); |
|||
|
|||
Mockito.verify(output).println(messageLines.get(0)); |
|||
Mockito.verify(output).println(messageLines.get(1)); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue