TextLineWrapTest: be more calculating rather than use arbitrary strings

This commit is contained in:
Paul Campbell 2020-05-20 22:07:55 +01:00
parent ccae310017
commit e3547f26d3

View file

@ -7,6 +7,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import java.awt.*; import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
@ -17,15 +18,23 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class TextLineWrapTest public class TextLineWrapTest
implements WithAssertions { implements WithAssertions {
private static final String WORD = "word";
private static final String SPACE = " ";
private final WordWrapper textLineWrap = TextFit.wrapper(); private final WordWrapper textLineWrap = TextFit.wrapper();
private final int imageSize = 300; private final int imageSize = 300;
private final int fontSize = 20; private final int fontSize = 20;
private final Graphics2D graphics2D = graphics(imageSize, imageSize); private final Graphics2D graphics2D = graphics(imageSize, imageSize);
private final Font font; private final Font font;
private final int spaceWidth;
private final int wordWidth;
private final int wordsPerLine;
public TextLineWrapTest() public TextLineWrapTest()
throws FontFormatException, throws FontFormatException,
@ -34,6 +43,15 @@ public class TextLineWrapTest
URL resource = this.getClass().getResource("alice/Alice-Regular.ttf"); URL resource = this.getClass().getResource("alice/Alice-Regular.ttf");
font = Font.createFont(Font.TRUETYPE_FONT, new File(resource.toURI())) font = Font.createFont(Font.TRUETYPE_FONT, new File(resource.toURI()))
.deriveFont(Font.PLAIN, fontSize); .deriveFont(Font.PLAIN, fontSize);
spaceWidth = stringWidth(SPACE, font, graphics2D);
wordWidth = stringWidth(WORD, font, graphics2D);
wordsPerLine = imageSize / (wordWidth + spaceWidth);
}
private int stringWidth(String string, Font font, Graphics2D graphics2D) {
FontRenderContext context = graphics2D.getFontRenderContext();
Rectangle2D stringBounds = font.getStringBounds(string, context);
return (int) stringBounds.getWidth();
} }
@Nested @Nested
@ -57,28 +75,37 @@ public class TextLineWrapTest
} }
@Test @Test
@DisplayName("Longer string fits on two lines") @DisplayName("Fits max 'words' per line on one line")
public void longerStringOnTwoLines() { public void fitMaxWordsOneLine() {
assertThat(invoke( String input = words(wordsPerLine);
"xxxxxxxxxxx xxxxxxxxxxxx " + assertThat(invoke(input)).containsExactly(input);
"xxxxxxxxxxx xxxxxxxxxxxx"))
.containsExactly(
"xxxxxxxxxxx xxxxxxxxxxxx",
"xxxxxxxxxxx xxxxxxxxxxxx");
} }
@Test @Test
@DisplayName("Longer string fits on three lines") @DisplayName("Wraps just over max 'words' per line onto two lines")
public void longerStringOnThreeLines() { public void wrapOneWordTooManyOntoTwoLines() {
assertThat(invoke( assertThat(invoke(words(wordsPerLine + 1)))
"xxxxxxxxxxx xxxxxxxxxxxx " +
"xxxxxxxxxxx xxxxxxxxxxxx " +
"xxxxxxxxxxx xxxxxxxxxxxx"))
.containsExactly( .containsExactly(
"xxxxxxxxxxx xxxxxxxxxxxx", words(wordsPerLine),
"xxxxxxxxxxx xxxxxxxxxxxx", WORD);
"xxxxxxxxxxx xxxxxxxxxxxx");
} }
@Test
@DisplayName("Wraps onto three lines")
public void longerStringOnThreeLines() {
String oneLinesWorthOfWords = words(wordsPerLine);
assertThat(invoke(words(wordsPerLine + wordsPerLine + 1)))
.containsExactly(
oneLinesWorthOfWords,
oneLinesWorthOfWords,
WORD);
}
}
private String words(int number) {
return IntStream.range(0, number)
.mapToObj(i -> WORD + SPACE)
.collect(Collectors.joining()).trim();
} }
private Graphics2D graphics(int width, int height) { private Graphics2D graphics(int width, int height) {
@ -123,27 +150,31 @@ public class TextLineWrapTest
} }
@Test @Test
@DisplayName("Longer string fits on two lines") @DisplayName("Fits max 'words' per line on one line")
public void longerStringOnTwoLines() { public void fitMaxWordsOneLine() {
assertThat(invoke( String input = words(wordsPerLine);
"xxxxxxxxxxx xxxxxxxxxxxx " + assertThat(invoke(input))
"xxxxxxxxxxx xxxxxxxxxxxx")) .containsExactly(Collections.singletonList(input));
.containsExactly(Arrays.asList(
"xxxxxxxxxxx xxxxxxxxxxxx",
"xxxxxxxxxxx xxxxxxxxxxxx"));
} }
@Test @Test
@DisplayName("Longer string fits on three lines") @DisplayName("Wraps just over max 'words' per line onto two lines")
public void wrapOneWordTooManyOntoTwoLines() {
String input = words(wordsPerLine + 1);
assertThat(invoke(input)).containsExactly(Arrays.asList(
words(wordsPerLine),
WORD));
}
@Test
@DisplayName("Wraps onto three lines")
public void longerStringOnThreeLines() { public void longerStringOnThreeLines() {
assertThat(invoke( String input = words(wordsPerLine + wordsPerLine + 1);
"xxxxxxxxxxx xxxxxxxxxxxx " + String oneLinesWorthOfWords = words(wordsPerLine);
"xxxxxxxxxxx xxxxxxxxxxxx " + assertThat(invoke(input)).containsExactly(Arrays.asList(
"xxxxxxxxxxx xxxxxxxxxxxx")) oneLinesWorthOfWords,
.containsExactly(Arrays.asList( oneLinesWorthOfWords,
"xxxxxxxxxxx xxxxxxxxxxxx", WORD));
"xxxxxxxxxxx xxxxxxxxxxxx",
"xxxxxxxxxxx xxxxxxxxxxxx"));
} }
} }
@ -158,6 +189,47 @@ public class TextLineWrapTest
boxes.add(box); boxes.add(box);
} }
@Test
@DisplayName("Empty String give empty List")
public void emptyStringEmptyList() {
assertThat(invoke("")).isEmpty();
}
@Test
@DisplayName("Short string fits on one line")
public void shortStringOnOneLine() {
assertThat(invoke("x"))
.containsExactly(Collections.singletonList("x"));
}
@Test
@DisplayName("Fits max 'words' per line on one line")
public void fitMaxWordsOneLine() {
String input = words(wordsPerLine);
assertThat(invoke(input))
.containsExactly(Collections.singletonList(input));
}
@Test
@DisplayName("Wraps just over max 'words' per line onto two lines")
public void wrapOneWordTooManyOntoTwoLines() {
String input = words(wordsPerLine + 1);
assertThat(invoke(input)).containsExactly(Arrays.asList(
words(wordsPerLine),
WORD));
}
@Test
@DisplayName("Wraps onto three lines")
public void longerStringOnThreeLines() {
String input = words(wordsPerLine + wordsPerLine + 1);
String oneLinesWorthOfWords = words(wordsPerLine);
assertThat(invoke(input)).containsExactly(Arrays.asList(
oneLinesWorthOfWords,
oneLinesWorthOfWords,
WORD));
}
} }
} }
} }