diff --git a/.gitignore b/.gitignore index 1bc94f3..d08c7af 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* /.idea/ +/target \ No newline at end of file diff --git a/README.md b/README.md index 44dea50..d4c303d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ # BinaryTattoo +Transform text into it's binary representation (ASCII) in many ways with this lovely little cmd line tool! -The goal of this project is to provide binary representation of the ASCII character code points. Basic usage is to print them in vertical or horizontal direction, for making a tattoo out of it. +# Usage +* '-i' (required) - input to be binarized (string; might some wise sentence, like 'I never don't give up') +* '-s' (optional) - separator you want to use in between the binary words (I discourage to use '0' or '1', for obvious reasons). Defaults to ' ' (single space) +* '-d' (optional) - the direction in which the binarized tattoo will be printed. Available options in 2D world are: 'HORIZONTAL' and 'VERTICAL'. Sorry non-euclideans... + +Have any suggestions? Well, I don't care, this is my baby and I will implement only the things I want (or even less, due to procrastination) diff --git a/pom.xml b/pom.xml index 3348a7f..bed6a7f 100644 --- a/pom.xml +++ b/pom.xml @@ -17,10 +17,77 @@ 8 + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + Main + + + + + + + maven-assembly-plugin + + + + Main + + + + jar-with-dependencies + + + + + package + + single + + + + + + org.projectlombok + lombok + 1.18.16 + + + + org.slf4j + slf4j-simple + 1.6.4 + + + + org.junit.jupiter + junit-jupiter-engine + 5.5.2 + test + + + + org.mockito + mockito-all + 1.10.19 + test + + + + commons-cli + commons-cli + 1.4 + + diff --git a/src/main/java/BinaryParser.java b/src/main/java/BinaryParser.java new file mode 100644 index 0000000..f8bf35d --- /dev/null +++ b/src/main/java/BinaryParser.java @@ -0,0 +1,43 @@ +import lombok.extern.slf4j.Slf4j; +import model.BinaryLetter; +import model.BinaryWord; + +@Slf4j +public class BinaryParser { + + public static BinaryWord parseBinaryWord(String input) { + log.info("Parsing input: {}", input); + long startTime = System.currentTimeMillis(); + + BinaryWord word = new BinaryWord(); + for (char c : input.toCharArray()) { + word.appendLetter(parseBinaryLetter(c)); + } + + long duration = System.currentTimeMillis() - startTime; + log.info("Parsing complete, result: {} (took: {}ms)", word, duration); + return word; + } + + private static BinaryLetter parseBinaryLetter(char input) { + int divider = 1; + + // Find closest binary incrementation, i.e. 8, 16, 32 etc... + while (input > divider) { + divider *= 2; + } + + BinaryLetter.Builder letterBuilder = new BinaryLetter.Builder(); + while (divider > 0) { + if (input >= divider) { + letterBuilder.appendBit(true); + input -= divider; + } else { + letterBuilder.appendBit(false); + } + divider /= 2; + } + + return letterBuilder.build(); + } +} diff --git a/src/main/java/BinaryTattoo.java b/src/main/java/BinaryTattoo.java new file mode 100644 index 0000000..0a0d1e5 --- /dev/null +++ b/src/main/java/BinaryTattoo.java @@ -0,0 +1,29 @@ +import lombok.extern.slf4j.Slf4j; +import model.BinaryWord; +import model.TattooData; +import model.phrase.BinaryPhrase; +import model.phrase.BinaryPhraseBuilder; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Slf4j +public class BinaryTattoo { + + private static final String DEFAULT_SEPARAOR = " "; + + public static String toBinaryString(TattooData tattooData) { + + final List words = Stream.of(tattooData.tattooString().split(DEFAULT_SEPARAOR)) + .map(BinaryParser::parseBinaryWord).collect(Collectors.toList()); + + final BinaryPhrase phrase = new BinaryPhraseBuilder() + .words(words) + .separator(tattooData.separator()) + .direction(tattooData.printDirection()) + .build(); + + return phrase.toString(); + } +} diff --git a/src/main/java/CmdLineTattooParser.java b/src/main/java/CmdLineTattooParser.java new file mode 100644 index 0000000..ad72c2b --- /dev/null +++ b/src/main/java/CmdLineTattooParser.java @@ -0,0 +1,88 @@ +import lombok.extern.slf4j.Slf4j; +import model.TattooData; +import model.phrase.PrintDirection; +import org.apache.commons.cli.*; + +import java.util.Arrays; +import java.util.stream.Collectors; + +@Slf4j +public class CmdLineTattooParser { + + public static final String INPUT_FLAG = "i"; + public static final String INPUT_FLAG_DESCRIPTION = "input string to be binarized"; + + public static final String SEPARATOR_FLAG = "s"; + public static final String SEPARATOR_FLAG_DESCRIPTION = "word separator (default: space, i.e. ' ')"; + public static final String DEFAULT_SEPARATOR = " "; + + public static final String DIRECTION_FLAG = "d"; + public static final String DIRECTION_FLAG_DESCRIPTION = "print direction (default: vertical)"; + public static final PrintDirection DEFAULT_DIRECTION = PrintDirection.VERTICAL; + + public TattooData readArgs(String[] args) throws ParseException { + Options cmdOptions = buildOptions(); + try { + CommandLine parsedArgs = new DefaultParser().parse(cmdOptions, args); + + return parseTattooData(parsedArgs); + } catch (IllegalArgumentException ex) { + String generalMessage = String.format("Unable to parse input, cause: %s", ex.getMessage()); + printHelp(generalMessage, cmdOptions); + throw new ParseException(generalMessage); + } + } + + private Options buildOptions() { + Options cmdOptions = new Options(); + cmdOptions.addOption(new Option(INPUT_FLAG, true, INPUT_FLAG_DESCRIPTION)); + cmdOptions.addOption(new Option(SEPARATOR_FLAG, true, SEPARATOR_FLAG_DESCRIPTION)); + cmdOptions.addOption(new Option(DIRECTION_FLAG, true, DIRECTION_FLAG_DESCRIPTION)); + return cmdOptions; + } + + private TattooData parseTattooData(CommandLine parsedArgs) { + String tattooString = parsedArgs.getOptionValue(INPUT_FLAG); + if (tattooString == null || tattooString.isEmpty()) { + throw new IllegalArgumentException("Input tattoo string cannot be empty!"); + } + if (tattooString.length() > 100000) { + throw new IllegalArgumentException("Seriously? You don't have long enough body for this shit"); + } + + log.trace("Provided tattooString is correct: '{}'", tattooString); + TattooData tattooData = new TattooData(tattooString); + + String separator = parsedArgs.getOptionValue(SEPARATOR_FLAG); + if (separator == null || separator.isEmpty()) { + log.warn("You've provided empty separator, defaulting to '{}'", DEFAULT_SEPARATOR); + tattooData.separator(DEFAULT_SEPARATOR); + } else { + if (separator.length() > 100) { + log.warn("Seriously? Such long separation should only be between you and this program.."); + tattooData.separator(DEFAULT_SEPARATOR); + } else { + log.trace("Provided separator is correct: '{}'", separator); + tattooData.separator(separator); + } + } + + try { + String directionString = parsedArgs.getOptionValue(DIRECTION_FLAG); + tattooData.printDirection(PrintDirection.valueOf(directionString)); + log.trace("Provided print direction is correct: '{}'", directionString); + } catch (IllegalArgumentException ex) { + log.error("Invalid print direction specified, allowed values: {}, defaulting to: {}", + Arrays.stream(PrintDirection.values()).map(PrintDirection::toString).collect(Collectors.joining(",")), + DEFAULT_DIRECTION); + tattooData.printDirection(DEFAULT_DIRECTION); + } + + return tattooData; + } + + private void printHelp(String generalMessage, Options options) { + log.error(generalMessage); + new HelpFormatter().printHelp("[packaged_jar]", options); + } +} diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 0000000..fb0534f --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,14 @@ +import model.TattooData; +import org.apache.commons.cli.ParseException; + +public class Main { + + public static void main(String[] args) { + try { + TattooData tattooData = new CmdLineTattooParser().readArgs(args); + System.out.println(BinaryTattoo.toBinaryString(tattooData)); + } catch (ParseException ex) { + // CmdLineTattooParser print help message, we just want to 'Enjoy the silence' here + } + } +} diff --git a/src/main/java/model/BinaryLetter.java b/src/main/java/model/BinaryLetter.java new file mode 100644 index 0000000..e56c6f6 --- /dev/null +++ b/src/main/java/model/BinaryLetter.java @@ -0,0 +1,69 @@ +package model; + +import java.util.ArrayDeque; +import java.util.Queue; + +public class BinaryLetter { + + private final Queue bits; + + private BinaryLetter(Builder b) { + this.bits = b.bits; + } + + public boolean hasNextBit() { + return !bits.isEmpty(); + } + + public boolean pollNextBit() { + Boolean bit = bits.poll(); + if (bit == null) { + throw new IllegalArgumentException("No bits left!"); + } + return bit; + } + + /** + * Return the number of bits, that consists to the letter + * + * @return number of bits + */ + public int length() { + return bits.size(); + } + + @Override + public String toString() { + return bits.stream() + .map(bit -> bit ? "1" : "0") + .reduce(String::concat) + .orElse("!"); + } + + public static class Builder { + private int bitRange = 8; + private final Queue bits = new ArrayDeque<>(); + + public Builder bitRange(int bitRange) { + this.bitRange = bitRange; + return this; + } + + /** + * Sets the next bit, from left to right. + * + * @param bit true (1), or false (0) + */ + public Builder appendBit(boolean bit) { + bits.add(bit); + return this; + } + + public BinaryLetter build() throws IllegalArgumentException { + if (bitRange < 1 || bits.size() != bitRange) { + throw new IllegalArgumentException("Invalid bit range!"); + } + return new BinaryLetter(this); + } + } +} diff --git a/src/main/java/model/BinaryWord.java b/src/main/java/model/BinaryWord.java new file mode 100644 index 0000000..edbd4f9 --- /dev/null +++ b/src/main/java/model/BinaryWord.java @@ -0,0 +1,42 @@ +package model; + +import java.util.ArrayDeque; +import java.util.Queue; + +public class BinaryWord { + + private final Queue letters = new ArrayDeque<>(); + + public void appendLetter(BinaryLetter letter) { + letters.add(letter); + } + + public boolean hasNextLetter() { + return !letters.isEmpty(); + } + + public BinaryLetter pollNextLetter() { + BinaryLetter letter = letters.poll(); + if (letter == null) { + throw new IllegalArgumentException("No letters left!"); + } + return letter; + } + + /** + * Return the number of bits, that consists to the word + * + * @return number of bits + */ + public int length() { + return letters.stream().map(BinaryLetter::length).reduce(Integer::sum).orElse(0); + } + + @Override + public String toString() { + return letters.stream() + .map(BinaryLetter::toString) + .reduce((letter1, letter2) -> letter1 + " " + letter2) + .orElse("EMPTY"); + } +} diff --git a/src/main/java/model/TattooData.java b/src/main/java/model/TattooData.java new file mode 100644 index 0000000..1b981c2 --- /dev/null +++ b/src/main/java/model/TattooData.java @@ -0,0 +1,18 @@ +package model; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import model.phrase.PrintDirection; + +@Setter +@Getter +@Accessors(fluent = true) +@RequiredArgsConstructor +public class TattooData { + + private final String tattooString; + private String separator; + private PrintDirection printDirection; +} diff --git a/src/main/java/model/phrase/BinaryPhrase.java b/src/main/java/model/phrase/BinaryPhrase.java new file mode 100644 index 0000000..bcf5db5 --- /dev/null +++ b/src/main/java/model/phrase/BinaryPhrase.java @@ -0,0 +1,20 @@ +package model.phrase; + +import model.BinaryWord; + +public abstract class BinaryPhrase { + protected static final int BIT_RANGE = 8; + + protected final boolean[][] bitMatrix; + protected int heightCursor = 0; + protected int widthCursor = 0; + protected final String separator; + + protected BinaryPhrase(int maxWidth, int maxHeight, String separator) { + this.bitMatrix = new boolean[maxHeight][maxWidth]; + this.separator = separator; + } + + protected abstract void appendBitWord(BinaryWord word); +} + diff --git a/src/main/java/model/phrase/BinaryPhraseBuilder.java b/src/main/java/model/phrase/BinaryPhraseBuilder.java new file mode 100644 index 0000000..44fdd78 --- /dev/null +++ b/src/main/java/model/phrase/BinaryPhraseBuilder.java @@ -0,0 +1,39 @@ +package model.phrase; + +import model.BinaryWord; + +import java.util.ArrayList; +import java.util.Collection; + +public class BinaryPhraseBuilder { + + private Collection words = new ArrayList<>(); + private PrintDirection direction = PrintDirection.HORIZONTAL; + private String separator; + + public BinaryPhraseBuilder direction(PrintDirection d) { + this.direction = d; + return this; + } + + public BinaryPhraseBuilder words(Collection words) { + this.words = words; + return this; + } + + public BinaryPhraseBuilder separator(String separator) { + this.separator = separator; + return this; + } + + public BinaryPhrase build() { + int longestWordLength = words.stream().map(BinaryWord::length).reduce(Integer::max).orElse(0); + int wordCount = words.size(); + + if (PrintDirection.HORIZONTAL.equals(direction)) { + return new HorizontalBinaryPhrase(longestWordLength, wordCount, separator, words); + } else { + return new VerticalBinaryPhrase(wordCount, longestWordLength, separator, words); + } + } +} diff --git a/src/main/java/model/phrase/HorizontalBinaryPhrase.java b/src/main/java/model/phrase/HorizontalBinaryPhrase.java new file mode 100644 index 0000000..6a50b08 --- /dev/null +++ b/src/main/java/model/phrase/HorizontalBinaryPhrase.java @@ -0,0 +1,45 @@ +package model.phrase; + +import model.BinaryLetter; +import model.BinaryWord; + +import java.util.Collection; + +public class HorizontalBinaryPhrase extends BinaryPhrase { + + public HorizontalBinaryPhrase(int maxWidth, int maxHeight, String separator, Collection words) { + super(maxWidth, maxHeight, separator); + words.forEach(this::appendBitWord); + } + + @Override + protected void appendBitWord(BinaryWord word) { + + while (word.hasNextLetter()) { + BinaryLetter letter = word.pollNextLetter(); + while (letter.hasNextBit()) { + boolean bit = letter.pollNextBit(); + bitMatrix[heightCursor][widthCursor] = bit; + widthCursor++; + } + } + widthCursor = 0; + heightCursor++; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (boolean[] row : bitMatrix) { + for (int j = 0; j < row.length; j++) { + sb.append(row[j] ? '1' : '0'); + if ((j+1) % BIT_RANGE == 0) { + sb.append(separator); + } + } + sb.append("\n"); + } + + return sb.toString(); + } +} diff --git a/src/main/java/model/phrase/PrintDirection.java b/src/main/java/model/phrase/PrintDirection.java new file mode 100644 index 0000000..3188f22 --- /dev/null +++ b/src/main/java/model/phrase/PrintDirection.java @@ -0,0 +1,5 @@ +package model.phrase; + +public enum PrintDirection { + HORIZONTAL, VERTICAL +} diff --git a/src/main/java/model/phrase/VerticalBinaryPhrase.java b/src/main/java/model/phrase/VerticalBinaryPhrase.java new file mode 100644 index 0000000..f1c4606 --- /dev/null +++ b/src/main/java/model/phrase/VerticalBinaryPhrase.java @@ -0,0 +1,46 @@ +package model.phrase; + +import model.BinaryLetter; +import model.BinaryWord; + +import java.util.Collection; + +public class VerticalBinaryPhrase extends BinaryPhrase { + + public VerticalBinaryPhrase(int maxWidth, int maxHeight, String separator, Collection words) { + super(maxWidth, maxHeight, separator); + words.forEach(this::appendBitWord); + } + + @Override + protected void appendBitWord(BinaryWord word) { + + while (word.hasNextLetter()) { + BinaryLetter letter = word.pollNextLetter(); + while (letter.hasNextBit()) { + boolean bit = letter.pollNextBit(); + bitMatrix[heightCursor][widthCursor] = bit; + heightCursor++; + } + } + heightCursor = 0; + widthCursor++; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < bitMatrix.length; i++) { + boolean[] row = bitMatrix[i]; + for (boolean b : row) { + sb.append(b ? '1' : '0').append(separator); + } + if ((i+1) % BIT_RANGE == 0) { + sb.append("\n"); + } + sb.append("\n"); + } + + return sb.toString(); + } +} diff --git a/src/test/java/BinaryParserTest.java b/src/test/java/BinaryParserTest.java new file mode 100644 index 0000000..835b80e --- /dev/null +++ b/src/test/java/BinaryParserTest.java @@ -0,0 +1,33 @@ +import model.BinaryWord; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class BinaryParserTest { + + @Test + public void parseWordTest() { + // given + final int defaultBitRange = 8; + String rawWord = "miscellaneous"; + + // when + BinaryWord parsedWord = BinaryParser.parseBinaryWord(rawWord); + + // then + assertEquals(rawWord.length(), parsedWord.length()/defaultBitRange); + } + + @Test + public void parseEmptyWordTest() { + // given + final int defaultBitRange = 8; + String rawWord = ""; + + // when + BinaryWord parsedWord = BinaryParser.parseBinaryWord(rawWord); + + // then + assertEquals(0, parsedWord.length()/defaultBitRange); + } +} \ No newline at end of file diff --git a/src/test/java/model/BinaryLetterTest.java b/src/test/java/model/BinaryLetterTest.java new file mode 100644 index 0000000..cefe1ed --- /dev/null +++ b/src/test/java/model/BinaryLetterTest.java @@ -0,0 +1,96 @@ +package model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class BinaryLetterTest { + + @Test + public void appendOnlyTest() { + + // given + BinaryLetter.Builder letterBuilder = new BinaryLetter.Builder().bitRange(1); + letterBuilder.appendBit(true); + + // when + BinaryLetter letter = letterBuilder.build(); + + // then + assertEquals(1, letter.length()); + assertTrue(letter.hasNextBit()); + } + + @Test + public void appendAndPollTest() { + + // given + boolean bit = true; + BinaryLetter.Builder letterBuilder = new BinaryLetter.Builder().bitRange(1); + letterBuilder.appendBit(true); + BinaryLetter letter = letterBuilder.build(); + + // when + boolean polledBit = letter.pollNextBit(); + + // then + assertEquals(bit, polledBit); + assertEquals(0, letter.length()); + assertFalse(letter.hasNextBit()); + } + + @Test + public void lengthTest() { + + // given + int bitsToAppend = 5; + int bitsToPoll = 3; + BinaryLetter.Builder letterBuilder = new BinaryLetter.Builder().bitRange(bitsToAppend); + + // when + for (int i = 0; i < bitsToAppend; i++) { + letterBuilder.appendBit(true); + } + + BinaryLetter letter = letterBuilder.build(); + for (int i = 0; i < bitsToPoll; i++) { + letter.pollNextBit(); + } + + // then + assertEquals(2, letter.length()); + } + + @Test + public void buildEmptyLetterTest() { + + // given + BinaryLetter.Builder letterBuilder = new BinaryLetter.Builder(); + + // when / then + assertThrows(IllegalArgumentException.class, letterBuilder::build); + } + + @Test + public void negativeBitRangeTest() { + + // given + BinaryLetter.Builder letterBuilder = new BinaryLetter.Builder().bitRange(-1); + + // when / then + assertThrows(IllegalArgumentException.class, letterBuilder::build); + } + + @Test + public void incompleteLetterTest() { + + // given + BinaryLetter.Builder letterBuilder = new BinaryLetter.Builder() + .bitRange((byte)8) + .appendBit(true) + .appendBit(false); + + // when / then + assertThrows(IllegalArgumentException.class, letterBuilder::build); + } +} diff --git a/src/test/java/model/BinaryWordTest.java b/src/test/java/model/BinaryWordTest.java new file mode 100644 index 0000000..668b1ae --- /dev/null +++ b/src/test/java/model/BinaryWordTest.java @@ -0,0 +1,87 @@ +package model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class BinaryWordTest { + + @Test + public void appendOnlyTest() { + + int bitsCountInLetter = 8; + + // given + BinaryLetter letterMock = mock(BinaryLetter.class); + when(letterMock.length()).thenReturn(bitsCountInLetter); + + // when + BinaryWord word = new BinaryWord(); + word.appendLetter(letterMock); + + // then + assertEquals(bitsCountInLetter, word.length()); + assertTrue(word.hasNextLetter()); + } + + @Test + public void appendAndPollTest() { + + // given + int bitsCountInLetter = 8; + + BinaryLetter letterMock = mock(BinaryLetter.class); + when(letterMock.length()).thenReturn(bitsCountInLetter); + + BinaryWord word = new BinaryWord(); + word.appendLetter(letterMock); + + // when + BinaryLetter polledLetter = word.pollNextLetter(); + + // then + assertEquals(letterMock, polledLetter); + assertEquals(0, word.length()); + assertFalse(word.hasNextLetter()); + } + + @Test + public void lengthTest() { + + // given + int bitsCountInLetter = 8; + int lettersToAppend = 5; + int lettersToPoll = 3; + + BinaryLetter letterMock = mock(BinaryLetter.class); + when(letterMock.length()).thenReturn(bitsCountInLetter); + + BinaryWord word = new BinaryWord(); + + // when + for (int i = 0; i < lettersToAppend; i++) { + word.appendLetter(letterMock); + } + + for (int i = 0; i < lettersToPoll; i++) { + word.pollNextLetter(); + } + + // then + assertEquals((lettersToAppend-lettersToPoll)*bitsCountInLetter, word.length()); + } + + @Test + public void pollBitEmptyLetterTest() { + + // given + BinaryWord word = new BinaryWord(); + + // when / then + assertEquals(0, word.length()); + assertFalse(word.hasNextLetter()); + assertThrows(IllegalArgumentException.class, word::pollNextLetter); + } +} \ No newline at end of file diff --git a/src/test/java/model/phrase/BinaryPhraseBuilderTest.java b/src/test/java/model/phrase/BinaryPhraseBuilderTest.java new file mode 100644 index 0000000..e258793 --- /dev/null +++ b/src/test/java/model/phrase/BinaryPhraseBuilderTest.java @@ -0,0 +1,44 @@ +package model.phrase; + +import model.BinaryWord; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Collection; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class BinaryPhraseBuilderTest { + + @Test + public void verticalTest() { + + // given + Collection emptyWordCollection = new ArrayList<>(); + + // when + final BinaryPhrase phrase = new BinaryPhraseBuilder() + .words(emptyWordCollection) + .direction(PrintDirection.VERTICAL) + .build(); + + // then + assertEquals(VerticalBinaryPhrase.class, phrase.getClass()); + } + + @Test + public void horizontalTest() { + + // given + Collection emptyWordCollection = new ArrayList<>(); + + // when + final BinaryPhrase phrase = new BinaryPhraseBuilder() + .words(emptyWordCollection) + .direction(PrintDirection.HORIZONTAL) + .build(); + + // then + assertEquals(HorizontalBinaryPhrase.class, phrase.getClass()); + } +} diff --git a/src/test/java/model/phrase/BinaryPhraseTest.java b/src/test/java/model/phrase/BinaryPhraseTest.java new file mode 100644 index 0000000..53c1b66 --- /dev/null +++ b/src/test/java/model/phrase/BinaryPhraseTest.java @@ -0,0 +1,112 @@ +package model.phrase; + +import model.*; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Collection; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class BinaryPhraseTest { + + private static final String SEPARATOR = " "; + + @Test + public void emptyTest() { + // given + Collection words = new ArrayList<>(); + + // when + final BinaryPhrase phrase = new BinaryPhraseBuilder() + .words(words) + .direction(PrintDirection.VERTICAL) + .build(); + + // then + String actual = phrase.toString(); + assertEquals("", actual); + } + +// @Test + public void verticalTest() { + + String expected = "01000110" + SEPARATOR + "01001111" + SEPARATOR + "01010010" + SEPARATOR + "01010100" + SEPARATOR + "01001001" + SEPARATOR + "01010011" + SEPARATOR + "00000000" + SEPARATOR + "\n" + + "01000110" + SEPARATOR + "01001111" + SEPARATOR + "01010010" + SEPARATOR + "01010100" + SEPARATOR + "01010101" + SEPARATOR + "01001110" + SEPARATOR + "01000001 \n" + + "01000001" + SEPARATOR + "01000100" + SEPARATOR + "01001010" + SEPARATOR + "01010101" + SEPARATOR + "01010110" + SEPARATOR + "01000001" + SEPARATOR + "01010100 "; + + // given + Collection words = new ArrayList<>(); + + // when + final BinaryPhrase phrase = new BinaryPhraseBuilder() + .words(words) + .direction(PrintDirection.VERTICAL) + .build(); + + // then + String actual = phrase.toString(); + assertEquals(expected, actual); + } + +// @Test + public void horizontalTest() { + + String expected = "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "1" + SEPARATOR + "\n" + + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "1" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "1" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "0" + SEPARATOR + "\n" + + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "1" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "1" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "1" + SEPARATOR + "0" + SEPARATOR + "\n" + + "1" + SEPARATOR + "0" + SEPARATOR + "1" + SEPARATOR + "\n" + + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "1" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "1" + SEPARATOR + "\n" + + "0" + SEPARATOR + "0" + SEPARATOR + "0" + SEPARATOR + "\n" + + "0" + SEPARATOR + "1" + SEPARATOR + "0" + SEPARATOR + ""; + + // given + Collection words = new ArrayList<>(); + + // when + final BinaryPhrase phrase = new BinaryPhraseBuilder() + .words(words) + .direction(PrintDirection.HORIZONTAL) + .build(); + + // then + assertEquals(expected, phrase.toString()); + } +}