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