Last active
November 19, 2015 22:54
-
-
Save ffbit/3e2f36e4bd9c1f0f7250 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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>ru.yandex.shad</groupId> | |
<artifactId>shad-reader</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<properties> | |
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
<java.version>1.8</java.version> | |
</properties> | |
<dependencies> | |
<dependency> | |
<groupId>org.hamcrest</groupId> | |
<artifactId>hamcrest-all</artifactId> | |
<version>1.3</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.12</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>com.github.stefanbirkner</groupId> | |
<artifactId>system-rules</artifactId> | |
<version>1.13.0</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>pl.pragmatists</groupId> | |
<artifactId>JUnitParams</artifactId> | |
<version>1.0.4</version> | |
</dependency> | |
</dependencies> | |
<build> | |
<plugins> | |
<plugin> | |
<groupId>org.apache.maven.plugins</groupId> | |
<artifactId>maven-compiler-plugin</artifactId> | |
<version>3.1</version> | |
<configuration> | |
<source>${java.version}</source> | |
<target>${java.version}</target> | |
</configuration> | |
</plugin> | |
</plugins> | |
</build> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.Closeable; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.util.NoSuchElementException; | |
public class ShadReader implements Closeable { | |
private static final int BUFFER_SIZE = 1024; | |
private final BufferedReader source; | |
private int currentCodePoint = ' '; | |
public ShadReader(InputStream stream) { | |
source = new BufferedReader(new InputStreamReader(stream), BUFFER_SIZE); | |
} | |
@Override | |
public void close() throws IOException { | |
source.close(); | |
} | |
public boolean hasNext() { | |
return hasNextNonWhitespaceSymbol(); | |
} | |
public int nextInt() { | |
return Integer.parseInt(nextToken()); | |
} | |
public long nextLong() { | |
return Long.parseLong(nextToken()); | |
} | |
public double nextDouble() { | |
return Double.parseDouble(nextToken()); | |
} | |
public String nextToken() { | |
if (!hasNext()) { | |
throw new NoSuchElementException("Input is already exhausted."); | |
} | |
StringBuilder token = new StringBuilder(); | |
do { | |
token.appendCodePoint(currentCodePoint); | |
advance(); | |
} while (isNotEndOfFile() && !isWhitespace()); | |
return token.toString(); | |
} | |
private boolean hasNextNonWhitespaceSymbol() { | |
while (isNotEndOfFile() && isWhitespace()) { | |
advance(); | |
} | |
return isNotEndOfFile() && !isWhitespace(); | |
} | |
private void advance() { | |
try { | |
currentCodePoint = source.read(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
private boolean isWhitespace() { | |
return Character.isWhitespace(currentCodePoint); | |
} | |
private boolean isNotEndOfFile() { | |
return currentCodePoint != -1; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import junitparams.JUnitParamsRunner; | |
import junitparams.Parameters; | |
import org.junit.After; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.junit.contrib.java.lang.system.TextFromStandardInputStream; | |
import org.junit.runner.RunWith; | |
import java.io.IOException; | |
import java.util.NoSuchElementException; | |
import static org.hamcrest.Matchers.is; | |
import static org.junit.Assert.assertThat; | |
@RunWith(JUnitParamsRunner.class) | |
public class ShadReaderTest { | |
private ShadReader reader; | |
@Rule | |
public TextFromStandardInputStream systemIn = | |
TextFromStandardInputStream.emptyStandardInputStream(); | |
@Test | |
@Parameters(method = "notBlankStrings") | |
public void itShouldHasNext(String text) { | |
systemIn.provideText(text); | |
reader = new ShadReader(System.in); | |
assertThat(reader.hasNext(), is(true)); | |
} | |
private Object[][] notBlankStrings() { | |
return new Object[][]{ | |
{"apple"}, | |
{" banana "}, | |
{" \t \r\n pear \n \t"}, | |
{" \r\npeach\t\n "}, | |
{"\t 12345678901234567890 \r\n "} | |
}; | |
} | |
@Test | |
@Parameters(method = "blankStrings") | |
public void itShouldNotHaveNext(String text) { | |
systemIn.provideText(text); | |
reader = new ShadReader(System.in); | |
assertThat(reader.hasNext(), is(false)); | |
} | |
@Test(expected = NoSuchElementException.class) | |
@Parameters(method = "blankStrings") | |
public void itShouldThrowNoSuchElementExceptionOnBlankInput(String text) { | |
systemIn.provideText(text); | |
reader = new ShadReader(System.in); | |
reader.nextToken(); | |
} | |
private Object[][] blankStrings() { | |
return new Object[][]{ | |
{""}, | |
{" \t "}, | |
{" \t \r\n \n \t"}, | |
{" \r\n \t\n "}, | |
{"\t \r\n "} | |
}; | |
} | |
@Test | |
@Parameters(method = "notBlankStrings,blankStrings") | |
public void hasNextShouldBeIdempotent(String text) { | |
systemIn.provideText(text); | |
reader = new ShadReader(System.in); | |
assertThat(reader.hasNext(), is(reader.hasNext())); | |
} | |
@Test | |
@Parameters(method = "tokens") | |
public void itShouldReadNextToken(String text, String token) { | |
systemIn.provideText(text); | |
reader = new ShadReader(System.in); | |
assertThat(reader.nextToken(), is(token)); | |
} | |
private Object[][] tokens() { | |
return new Object[][]{ | |
{"apple", "apple"}, | |
{" banana ", "banana"}, | |
{" \t \r\n pear \n \t", "pear"}, | |
{" \r\npeach\t\n ", "peach"}, | |
{"\t 12345678901234567890 \r\n ", "12345678901234567890"} | |
}; | |
} | |
@Test | |
@Parameters(method = "ints") | |
public void itShouldReadNextInt(String text, int number) { | |
systemIn.provideText(text); | |
reader = new ShadReader(System.in); | |
assertThat(reader.nextInt(), is(number)); | |
} | |
private Object[][] ints() { | |
return new Object[][]{ | |
{"1", 1}, | |
{" 0 ", 0}, | |
{" \t \r\n 12345 \r\n \t", 12345}, | |
{" \r\n-567890 \n ", -567890}, | |
{" \n+5 ", 5} | |
}; | |
} | |
@Test | |
@Parameters(method = "longs") | |
public void itShouldReadNextLong(String text, long number) { | |
systemIn.provideText(text); | |
reader = new ShadReader(System.in); | |
assertThat(reader.nextLong(), is(number)); | |
} | |
private Object[][] longs() { | |
return new Object[][]{ | |
{"1", 1L}, | |
{" 0 ", 0L}, | |
{" \t \r\n 9876543210 \n \t", 9876543210L}, | |
{" \n-1234567890\r\n", -1234567890L}, | |
{" \r\n+5 ", 5L} | |
}; | |
} | |
@Test | |
@Parameters(method = "doubles") | |
public void itShouldReadNextDouble(String text, double number) { | |
systemIn.provideText(text); | |
reader = new ShadReader(System.in); | |
assertThat(reader.nextDouble(), is(number)); | |
} | |
private Object[][] doubles() { | |
return new Object[][]{ | |
{"1", 1D}, | |
{" 0 ", 0D}, | |
{" \t \r\n 9876543210 \n \t", 9876543210D}, | |
{" \n-1234567890\r\n", -1234567890D}, | |
{" \r\n+5 ", 5D}, | |
{" \r\n1.2345678E7 ", 1.2345678E7}, | |
{" \r\n -1.2345678E-7 \t", -1.2345678E-7}, | |
}; | |
} | |
@Test | |
public void itShouldReadDataSequence() { | |
systemIn.provideText(" \t apple \r\n \t123 \n 2.0 \n 567 \t \n "); | |
reader = new ShadReader(System.in); | |
assertThat(reader.nextToken(), is("apple")); | |
assertThat(reader.nextInt(), is(123)); | |
assertThat(reader.nextDouble(), is(2D)); | |
assertThat(reader.nextLong(), is(567L)); | |
} | |
@After | |
public void tearDown() throws IOException { | |
reader.close(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment