Skip to content
Snippets Groups Projects
Commit 20985d40 authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
# Project-specific
# none (for now)
# Mac file finder metadata
.DS_Store
# MS Office temporary file
~*
# Emacs backup file
*~
# Java files
*.class
javadoc/
# JetBrains (IntelliJ IDEA, PyCharm, etc) files
.idea/
cmake-build-*/
out/
*.iml
*.iws
*.ipr
# Eclipse files
bin/
.settings/
.classpath
.project
# Visual Studio / VS Code files
.vs*/
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Netbeans files
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml
# Xcode files
*.xcodeproj/
xcuserdata/
.build/
# Maven
target/
# Miscellaneous
tmp/
*.tmp
*.bak
*.bk
*.swp
*.gcno
pom.xml 0 → 100644
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.unl.cse.bohn</groupId>
<artifactId>string_box</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>5.1.1</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
/*
* string_box Copyright (c) 2020 Christopher Bohn, bohn@unl.edu
*/
package edu.unl.cse.bohn;
public class StringBox {
private int maximumWidth;
private int maximumHeight;
private int logicalHeight;
private StringRow[] rows;
public StringBox() {
this(23, 80); // standard terminal is 24x80, but leave room for the user's input
}
public StringBox(int maximumHeight, int maximumWidth) {
if (maximumHeight > 0 && maximumWidth > 0) {
this.maximumHeight = maximumHeight;
this.maximumWidth = maximumWidth;
rows = new StringRow[maximumHeight];
for (int i = 0; i < maximumHeight; i++) {
rows[i] = new StringRow(maximumWidth);
}
logicalHeight = 0;
} else {
throw new IllegalArgumentException("String Box must be at least 1 character wide by 1 character tall. " +
"Dimensions " + maximumWidth + "×" + maximumHeight + " are too small.");
}
}
public StringBox placeString(String string, int topRow, int leftColumn) {
return placeStringAlignTopLeft(string, topRow, leftColumn);
}
public StringBox placeStringAlignTopLeft(String string, int topRow, int leftColumn) {
String[] strings = string.split("\n");
int firstRow = Math.max(topRow, 0);
int lastRow = Math.min(topRow + strings.length, maximumHeight);
int offset = -topRow;
for (int i = firstRow; i < lastRow; i++) {
rows[i].placeSubstringAlignLeft(strings[i + offset], leftColumn);
}
logicalHeight = Math.max(logicalHeight, lastRow);
return this;
}
public StringBox placeStringAlignBottomLeft(String string, int bottomRow, int leftColumn) {
String[] strings = string.split("\n");
return placeStringAlignTopLeft(string, bottomRow - strings.length + 1, leftColumn);
}
public StringBox placeStringAlignTopRight(String string, int topRow, int leftColumn) {
String[] strings = string.split("\n");
int firstRow = Math.max(topRow, 0);
int lastRow = Math.min(topRow + strings.length, maximumHeight);
int offset = -topRow;
for (int i = firstRow; i < lastRow; i++) {
rows[i].placeSubstringAlignRight(strings[i + offset], leftColumn);
}
logicalHeight = Math.max(logicalHeight, lastRow);
return this;
}
public StringBox placeStringAlignBottomRight(String string, int bottomRow, int leftColumn) {
String[] strings = string.split("\n");
return placeStringAlignTopRight(string, bottomRow - strings.length + 1, leftColumn);
}
@Override
public String toString() {
return toString(false);
}
public String toString(boolean padToHeight) {
StringBuilder returnString = new StringBuilder(maximumHeight * (maximumWidth + 1));
if (logicalHeight > 0) {
returnString.append(rows[0].toString());
}
for (int i = 1; i < logicalHeight; i++) {
returnString.append("\n").append(rows[i].toString());
}
if (padToHeight) {
for (int i = logicalHeight; i < maximumHeight; i++) {
returnString.append("\n").append(rows[i].toString());
}
}
return returnString.toString();
}
static class StringRow {
private StringBuilder stringBuilder;
private int maximumWidth;
private int rightEdge;
public StringRow(int maximumWidth) {
this.maximumWidth = maximumWidth;
stringBuilder = new StringBuilder(maximumWidth);
}
public StringRow placeSubstring(String string, int leftColumn) {
return placeSubstringAlignLeft(string, leftColumn);
}
public StringRow placeSubstringAlignLeft(String string, int leftColumn) {
String modifiedString = string
.replace("\t", " ")
.replace("\r", "")
.replace("\n", "\\");
int actualLeftColumn = leftColumn;
if (actualLeftColumn > rightEdge) {
int paddingSize = actualLeftColumn - rightEdge;
StringBuilder padding = new StringBuilder(paddingSize);
for (int i = 0; i < paddingSize; i++) { // This is a job made for String.repeat() in Java 11
padding.append(" ");
}
modifiedString = padding.toString() + modifiedString;
actualLeftColumn -= paddingSize;
}
if (actualLeftColumn < 0) {
modifiedString = modifiedString.substring(-actualLeftColumn);
actualLeftColumn = 0;
}
int stringLength = modifiedString.length();
stringBuilder.replace(actualLeftColumn, actualLeftColumn + stringLength, modifiedString);
rightEdge = Math.max(rightEdge, actualLeftColumn + stringLength);
int overshoot = rightEdge - maximumWidth;
if (overshoot > 0) {
rightEdge -= overshoot;
stringBuilder.setLength(rightEdge);
}
return this;
} // TODO: handle leftColumn < 0
public StringRow placeSubstringAlignRight(String string, int rightColumn) {
String modifiedString = string
.replace("\t", " ")
.replace("\r", "")
.replace("\n", "\\");
int leftColumn = rightColumn - modifiedString.length();
return placeSubstringAlignLeft(modifiedString, leftColumn);
}
@Override
public String toString() {
return stringBuilder.toString();
}
}
}
/*
* string_box Copyright (c) 2020 Christopher Bohn, bohn@unl.edu
*/
package edu.unl.cse.bohn;
import com.vdurmont.emoji.EmojiParser;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class StringBoxTest {
private StringBox stringBox;
private StringBox.StringRow stringRow;
@Before
public void setUp() {
stringBox = new StringBox();
stringRow = new StringBox.StringRow(10);
}
@After
public void tearDown() {
}
/* Tests for one row */
@Test
public void testStringOnLeftEdge() {
// Arrange
String input = "foo";
int position = 0;
String expectedOutput = "foo";
// Act
String actualOutput = stringRow.placeSubstring(input, position).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testStringOnTab() {
// Arrange
String input = "\tfoo";
int position = 0;
String expectedOutput = " foo";
// Act
String actualOutput = stringRow.placeSubstringAlignLeft(input, position).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testStringAtColumnFour() {
// Arrange
String input = "foo";
int position = 4;
String expectedOutput = " foo";
// Act
String actualOutput = stringRow.placeSubstringAlignLeft(input, position).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testStringAtColumnEight() {
// Arrange
String input = "foo";
int position = 8;
String expectedOutput = " fo";
// Act
String actualOutput = stringRow.placeSubstringAlignLeft(input, position).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testStringAtColumnTwelve() {
// Arrange
String input = "foo";
int position = 12;
String expectedOutput = " ";
// Act
String actualOutput = stringRow.placeSubstringAlignLeft(input, position).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testTwoStrings() {
// Arrange
String input1 = "foo";
int position1 = 0;
String input2 = "bar";
int position2 = 5;
String expectedOutput = "foo bar";
// Act
String actualOutput = stringRow.placeSubstringAlignLeft(input1, position1).placeSubstringAlignLeft(input2,
position2).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testEmoji() {
// Arrange
String input1 = EmojiParser.parseToUnicode(":smile:");
int position1 = 1;
String input2 = "bar";
int position2 = 8;
String expectedOutput = " \uD83D\uDE04 ba";
// Act
String actualOutput = stringRow.placeSubstringAlignLeft(input1, position1).placeSubstringAlignLeft(input2,
position2).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testRightToLeft() {
// Arrange
String input1 = "foo";
int position1 = 0;
String input2 = "bar";
int position2 = 5;
String expectedOutput = "foo bar";
// Act
String actualOutput = stringRow.placeSubstringAlignLeft(input2, position2).placeSubstringAlignLeft(input1,
position1).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testOverlapLeft() {
// Arrange
String input1 = "foo";
int position1 = 3;
String input2 = "bar";
int position2 = 5;
@SuppressWarnings("SpellCheckingInspection") String expectedOutput = " fooar";
// Act
String actualOutput = stringRow.placeSubstringAlignLeft(input2, position2).placeSubstringAlignLeft(input1,
position1).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testOverlapRight() {
// Arrange
String input1 = "foo";
int position1 = 7;
String input2 = "bar";
int position2 = 5;
@SuppressWarnings("SpellCheckingInspection") String expectedOutput = " bafoo";
// Act
String actualOutput = stringRow.placeSubstringAlignLeft(input2, position2).placeSubstringAlignLeft(input1,
position1).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testAlignRight() {
// Arrange
String input = "foo";
int position = 10;
String expectedOutput = " foo";
// Act
String actualOutput = stringRow.placeSubstringAlignRight(input, position).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testNegativeLeftColumn() {
// Arrange
String input = "foo";
int position = -1;
String expectedOutput = "oo";
// Act
String actualOutput = stringRow.placeSubstring(input, position).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
/* Tests for multiple rows */
@Test
public void testOneString() {
// Arrange
String input = "foo";
int row = 2;
int column = 10;
String expectedOutput = "\n\n foo";
// Act
String actualOutput = stringBox.placeString(input, row, column).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testNormalCases() {
// Arrange
@SuppressWarnings("SpellCheckingInspection") String[] inputs = {"foo\nbar", "larry\ncurly\nmoe", "quux\nxyzzy"
, "one\ntwo\nthree"};
int[] rows = {2, 5, 3, 10};
int[] columns = {10, 5, 20, 15};
@SuppressWarnings("SpellCheckingInspection") String expectedOutput =
"\n" + // 0
"\n" + // 1
" foo\n" + // 2
" larrybar quux\n" + // 3
" curly xyzzy\n" + // 4
" moe\n" + // 5
"\n" + // 6
"\n" + // 7
" one\n" + // 8
" two\n" + // 9
" three\n" + // 10
"\n" + // 11
"\n" + // 12
"\n" + // 13
"\n" + // 14
"\n" + // 15
"\n" + // 16
"\n" + // 17
"\n" + // 18
"\n" + // 19
"\n" + // 20
"\n" + // 21
""; // 22
// Act
String actualOutput = stringBox
.placeStringAlignTopLeft(inputs[0], rows[0], columns[0])
.placeStringAlignBottomLeft(inputs[1], rows[1], columns[1])
.placeStringAlignTopRight(inputs[2], rows[2], columns[2])
.placeStringAlignBottomRight(inputs[3], rows[3], columns[3])
.toString(true);
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testEmptyBox() {
// Arrange
String expectedOutput = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
// Act
String actualOutput = stringBox.toString(true);
// Assert
assertEquals(expectedOutput, actualOutput);
}
@Test
public void testNegativeTopRow() {
// Arrange
String input = "foo\nbar";
int row = -1;
int column = 10;
String expectedOutput = " bar";
// Act
String actualOutput = stringBox.placeString(input, row, column).toString();
// Assert
assertEquals(expectedOutput, actualOutput);
}
/* Tests for exceptional conditions */
@Test
public void testHeightTooSmall() {
try {
stringBox = new StringBox(0, 3);
fail("Did not catch IllegalArgumentException.");
} catch (IllegalArgumentException exception) {
assertEquals("String Box must be at least 1 character wide by 1 character tall. " +
"Dimensions 3×0 are too small.", exception.getMessage());
}
}
@Test
public void testWidthTooSmall() {
try {
stringBox = new StringBox(3, 0);
fail("Did not catch IllegalArgumentException.");
} catch (IllegalArgumentException exception) {
assertEquals("String Box must be at least 1 character wide by 1 character tall. " +
"Dimensions 0×3 are too small.", exception.getMessage());
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment