diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2014-03-14 22:13:57 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2014-03-14 22:13:57 +0100 |
commit | beaaed4bc33977b4c61013a553563758eeff35c4 (patch) | |
tree | c59a8b972c34bde84a69895acde9d34fda73949a /sonar-channel/src/test/java | |
parent | 9509868d743145761211e1ce74c26f01057cc67f (diff) | |
download | sonarqube-beaaed4bc33977b4c61013a553563758eeff35c4.tar.gz sonarqube-beaaed4bc33977b4c61013a553563758eeff35c4.zip |
SONAR-5128 Package a release version of sonar-channel
Diffstat (limited to 'sonar-channel/src/test/java')
4 files changed, 0 insertions, 614 deletions
diff --git a/sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java b/sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java deleted file mode 100644 index 329c09841b4..00000000000 --- a/sonar-channel/src/test/java/org/sonar/channel/ChannelDispatcherTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.channel; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.Test; - -public class ChannelDispatcherTest { - - @Test - public void shouldRemoveSpacesFromString() { - ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().addChannel(new SpaceDeletionChannel()).build(); - StringBuilder output = new StringBuilder(); - dispatcher.consume(new CodeReader("two words"), output); - assertThat(output.toString(), is("twowords")); - } - - @Test - public void shouldAddChannels() { - ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().addChannels(new SpaceDeletionChannel(), new FakeChannel()).build(); - assertThat(dispatcher.getChannels().length, is(2)); - assertThat(dispatcher.getChannels()[0], is(SpaceDeletionChannel.class)); - assertThat(dispatcher.getChannels()[1], is(FakeChannel.class)); - } - - @Test(expected = IllegalStateException.class) - public void shouldThrowExceptionWhenNoChannelToConsumeNextCharacter() { - ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().failIfNoChannelToConsumeOneCharacter().build(); - dispatcher.consume(new CodeReader("two words"), new StringBuilder()); - } - - private static class SpaceDeletionChannel extends Channel<StringBuilder> { - @Override - public boolean consume(CodeReader code, StringBuilder output) { - if (code.peek() == ' ') { - code.pop(); - } else { - output.append((char) code.pop()); - } - return true; - } - } - - private static class FakeChannel extends Channel<StringBuilder> { - @Override - public boolean consume(CodeReader code, StringBuilder output) { - boolean b = true; - return b; - } - } - -} diff --git a/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java b/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java deleted file mode 100644 index 4077fbad02c..00000000000 --- a/sonar-channel/src/test/java/org/sonar/channel/CodeBufferTest.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.channel; - -import static junit.framework.Assert.assertEquals; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.regex.Pattern; - -import org.junit.Test; - -public class CodeBufferTest { - - private CodeReaderConfiguration defaulConfiguration = new CodeReaderConfiguration(); - - @Test - public void testPop() { - CodeBuffer code = new CodeBuffer("pa", defaulConfiguration); - assertThat((char) code.pop(), is('p')); - assertThat((char) code.pop(), is('a')); - assertThat(code.pop(), is( -1)); - } - - @Test - public void testPeek() { - CodeBuffer code = new CodeBuffer("pa", defaulConfiguration); - assertThat((char) code.peek(), is('p')); - assertThat((char) code.peek(), is('p')); - code.pop(); - assertThat((char) code.peek(), is('a')); - code.pop(); - assertThat(code.peek(), is( -1)); - } - - @Test - public void testLastCharacter() { - CodeBuffer reader = new CodeBuffer("bar", defaulConfiguration); - assertThat(reader.lastChar(), is( -1)); - reader.pop(); - assertThat((char) reader.lastChar(), is('b')); - } - - @Test - public void testGetColumnAndLinePosition() { - CodeBuffer reader = new CodeBuffer("pa\nc\r\ns\r\n\r\n", defaulConfiguration); - assertThat(reader.getColumnPosition(), is(0)); - assertThat(reader.getLinePosition(), is(1)); - reader.pop(); // p - reader.pop(); // a - assertThat(reader.getColumnPosition(), is(2)); - assertThat(reader.getLinePosition(), is(1)); - reader.peek(); // \n - reader.lastChar(); // a - assertThat(reader.getColumnPosition(), is(2)); - assertThat(reader.getLinePosition(), is(1)); - reader.pop(); // \n - assertThat(reader.getColumnPosition(), is(0)); - assertThat(reader.getLinePosition(), is(2)); - reader.pop(); // c - assertThat(reader.getColumnPosition(), is(1)); - assertThat(reader.getLinePosition(), is(2)); - reader.pop(); // \r - reader.pop(); // \n - assertThat(reader.getColumnPosition(), is(0)); - assertThat(reader.getLinePosition(), is(3)); - assertThat((char) reader.pop(), is('s')); - reader.pop(); // \r - assertThat(reader.getColumnPosition(), is(2)); - assertThat(reader.getLinePosition(), is(3)); - reader.pop(); // \n - assertThat(reader.getColumnPosition(), is(0)); - assertThat(reader.getLinePosition(), is(4)); - reader.pop(); // \r - reader.pop(); // \n - assertThat(reader.getColumnPosition(), is(0)); - assertThat(reader.getLinePosition(), is(5)); - } - - @Test - public void testStartAndStopRecording() { - CodeBuffer reader = new CodeBuffer("123456", defaulConfiguration); - reader.pop(); - assertEquals("", reader.stopRecording().toString()); - - reader.startRecording(); - reader.pop(); - reader.pop(); - reader.peek(); - assertEquals("23", reader.stopRecording().toString()); - assertEquals("", reader.stopRecording().toString()); - } - - @Test - public void testCharAt() { - CodeBuffer reader = new CodeBuffer("123456", defaulConfiguration); - assertEquals('1', reader.charAt(0)); - assertEquals('6', reader.charAt(5)); - } - - @Test - public void testCharAtIndexOutOfBoundsException() { - CodeBuffer reader = new CodeBuffer("12345", defaulConfiguration); - assertEquals(reader.charAt(5), (char) -1); - } - - @Test - public void testReadWithSpecificTabWidth() { - CodeReaderConfiguration configuration = new CodeReaderConfiguration(); - configuration.setTabWidth(4); - CodeBuffer reader = new CodeBuffer("pa\n\tc", configuration); - assertEquals('\n', reader.charAt(2)); - assertEquals('\t', reader.charAt(3)); - assertEquals('c', reader.charAt(4)); - assertThat(reader.getColumnPosition(), is(0)); - assertThat(reader.getLinePosition(), is(1)); - reader.pop(); // p - reader.pop(); // a - assertThat(reader.getColumnPosition(), is(2)); - assertThat(reader.getLinePosition(), is(1)); - reader.peek(); // \n - reader.lastChar(); // a - assertThat(reader.getColumnPosition(), is(2)); - assertThat(reader.getLinePosition(), is(1)); - reader.pop(); // \n - assertThat(reader.getColumnPosition(), is(0)); - assertThat(reader.getLinePosition(), is(2)); - reader.pop(); // \t - assertThat(reader.getColumnPosition(), is(4)); - assertThat(reader.getLinePosition(), is(2)); - reader.pop(); // c - assertThat(reader.getColumnPosition(), is(5)); - assertThat(reader.getLinePosition(), is(2)); - } - - @Test - public void testCodeReaderFilter() throws Exception { - CodeReaderConfiguration configuration = new CodeReaderConfiguration(); - configuration.setCodeReaderFilters(new ReplaceNumbersFilter()); - CodeBuffer code = new CodeBuffer("abcd12efgh34", configuration); - // test #charAt - assertEquals('a', code.charAt(0)); - assertEquals('-', code.charAt(4)); - assertEquals('-', code.charAt(5)); - assertEquals('e', code.charAt(6)); - assertEquals('-', code.charAt(10)); - assertEquals('-', code.charAt(11)); - // test peek and pop - assertThat((char) code.peek(), is('a')); - assertThat((char) code.pop(), is('a')); - assertThat((char) code.pop(), is('b')); - assertThat((char) code.pop(), is('c')); - assertThat((char) code.pop(), is('d')); - assertThat((char) code.peek(), is('-')); - assertThat((char) code.pop(), is('-')); - assertThat((char) code.pop(), is('-')); - assertThat((char) code.pop(), is('e')); - assertThat((char) code.pop(), is('f')); - assertThat((char) code.pop(), is('g')); - assertThat((char) code.pop(), is('h')); - assertThat((char) code.pop(), is('-')); - assertThat((char) code.pop(), is('-')); - } - - @Test - public void theLengthShouldBeTheSameThanTheStringLength() { - String myCode = "myCode"; - assertThat(new CodeBuffer(myCode, new CodeReaderConfiguration()).length(), is(6)); - } - - @Test - public void theLengthShouldDecreaseEachTimeTheInputStreamIsConsumed() { - String myCode = "myCode"; - CodeBuffer codeBuffer = new CodeBuffer(myCode, new CodeReaderConfiguration()); - codeBuffer.pop(); - codeBuffer.pop(); - assertThat(codeBuffer.length(), is(4)); - } - - @Test - public void testSeveralCodeReaderFilter() throws Exception { - CodeReaderConfiguration configuration = new CodeReaderConfiguration(); - configuration.setCodeReaderFilters(new ReplaceNumbersFilter(), new ReplaceCharFilter()); - CodeBuffer code = new CodeBuffer("abcd12efgh34", configuration); - // test #charAt - assertEquals('*', code.charAt(0)); - assertEquals('-', code.charAt(4)); - assertEquals('-', code.charAt(5)); - assertEquals('*', code.charAt(6)); - assertEquals('-', code.charAt(10)); - assertEquals('-', code.charAt(11)); - // test peek and pop - assertThat((char) code.peek(), is('*')); - assertThat((char) code.pop(), is('*')); - assertThat((char) code.pop(), is('*')); - assertThat((char) code.pop(), is('*')); - assertThat((char) code.pop(), is('*')); - assertThat((char) code.peek(), is('-')); - assertThat((char) code.pop(), is('-')); - assertThat((char) code.pop(), is('-')); - assertThat((char) code.pop(), is('*')); - assertThat((char) code.pop(), is('*')); - assertThat((char) code.pop(), is('*')); - assertThat((char) code.pop(), is('*')); - assertThat((char) code.pop(), is('-')); - assertThat((char) code.pop(), is('-')); - } - - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void testChannelCodeReaderFilter() throws Exception { - // create a windowing channel that drops the 2 first characters, keeps 6 characters and drops the rest of the line - CodeReaderConfiguration configuration = new CodeReaderConfiguration(); - configuration.setCodeReaderFilters(new ChannelCodeReaderFilter(new Object(), new WindowingChannel())); - CodeBuffer code = new CodeBuffer("0123456789\nABCDEFGHIJ", configuration); - // test #charAt - assertEquals('2', code.charAt(0)); - assertEquals('7', code.charAt(5)); - assertEquals('\n', code.charAt(6)); - assertEquals('C', code.charAt(7)); - assertEquals('H', code.charAt(12)); - assertEquals( -1, code.intAt(13)); - // test peek and pop - assertThat((char) code.peek(), is('2')); - assertThat((char) code.pop(), is('2')); - assertThat((char) code.pop(), is('3')); - assertThat((char) code.pop(), is('4')); - assertThat((char) code.pop(), is('5')); - assertThat((char) code.pop(), is('6')); - assertThat((char) code.pop(), is('7'));// and 8 shouldn't show up - assertThat((char) code.pop(), is('\n')); - assertThat((char) code.peek(), is('C')); - assertThat((char) code.pop(), is('C')); - assertThat((char) code.pop(), is('D')); - assertThat((char) code.pop(), is('E')); - assertThat((char) code.pop(), is('F')); - assertThat((char) code.pop(), is('G')); - assertThat((char) code.pop(), is('H')); - assertThat(code.pop(), is( -1)); - } - - /** - * Backward compatibility with a COBOL plugin: filter returns 0 instead of -1, when end of the stream has been reached. - */ - @Test(timeout = 1000) - public void testWrongEndOfStreamFilter() { - CodeReaderConfiguration configuration = new CodeReaderConfiguration(); - configuration.setCodeReaderFilters(new WrongEndOfStreamFilter()); - new CodeBuffer("foo", configuration); - } - - class WrongEndOfStreamFilter extends CodeReaderFilter<Object> { - @Override - public int read(char[] filteredBuffer, int offset, int length) throws IOException { - return 0; - } - } - - class ReplaceNumbersFilter extends CodeReaderFilter<Object> { - - private Pattern pattern = Pattern.compile("\\d"); - private String REPLACEMENT = "-"; - - @Override - public int read(char[] cbuf, int off, int len) throws IOException { - char[] tempBuffer = new char[cbuf.length]; - int charCount = getReader().read(tempBuffer, off, len); - if (charCount != -1) { - String filteredString = pattern.matcher(new String(tempBuffer)).replaceAll(REPLACEMENT); - System.arraycopy(filteredString.toCharArray(), 0, cbuf, 0, tempBuffer.length); - } - return charCount; - } - } - - class ReplaceCharFilter extends CodeReaderFilter<Object> { - - private Pattern pattern = Pattern.compile("[a-zA-Z]"); - private String REPLACEMENT = "*"; - - @Override - public int read(char[] cbuf, int off, int len) throws IOException { - char[] tempBuffer = new char[cbuf.length]; - int charCount = getReader().read(tempBuffer, off, len); - if (charCount != -1) { - String filteredString = pattern.matcher(new String(tempBuffer)).replaceAll(REPLACEMENT); - System.arraycopy(filteredString.toCharArray(), 0, cbuf, 0, tempBuffer.length); - } - return charCount; - } - } - - @SuppressWarnings("rawtypes") - class WindowingChannel extends Channel { - - @Override - public boolean consume(CodeReader code, Object output) { - int columnPosition = code.getColumnPosition(); - if (code.peek() == '\n') { - return false; - } - if (columnPosition < 2 || columnPosition > 7) { - code.pop(); - return true; - } - return false; - } - } -} diff --git a/sonar-channel/src/test/java/org/sonar/channel/CodeReaderTest.java b/sonar-channel/src/test/java/org/sonar/channel/CodeReaderTest.java deleted file mode 100644 index 21c5394961c..00000000000 --- a/sonar-channel/src/test/java/org/sonar/channel/CodeReaderTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.channel; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.io.StringReader; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; - -public class CodeReaderTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void testPopWithAppendable() { - CodeReader reader = new CodeReader("package org.sonar;"); - - StringBuilder sw = new StringBuilder(); - reader.pop(sw); - assertEquals("p", sw.toString()); - reader.pop(sw); - assertEquals("pa", sw.toString()); - - } - - @Test - public void testPeekACharArray() { - CodeReader reader = new CodeReader(new StringReader("bar")); - char[] chars = reader.peek(2); - assertThat(chars.length, is(2)); - assertThat(chars[0], is('b')); - assertThat(chars[1], is('a')); - } - - @Test - public void testPeekTo() { - CodeReader reader = new CodeReader(new StringReader("package org.sonar;")); - StringBuilder result = new StringBuilder(); - reader.peekTo(new EndMatcher() { - - public boolean match(int endFlag) { - return 'r' == (char) endFlag; - } - }, result); - assertEquals("package o", result.toString()); - assertThat(reader.peek(), is((int) 'p')); // never called pop() - } - - @Test - public void testPopTo() { - CodeReader reader = new CodeReader(new StringReader("package org.sonar;")); - StringBuilder result = new StringBuilder(); - reader.popTo(new EndMatcher() { - - public boolean match(int endFlag) { - return 'r' == (char) endFlag; - } - }, result); - assertThat(result.toString(), is("package o")); - assertThat(reader.peek(), is((int) 'r')); - CodeReader.Cursor previousCursor = reader.getPreviousCursor(); - assertThat(previousCursor.getColumn(), is(0)); - assertThat(previousCursor.getLine(), is(1)); - } - - @Test - public void testPopToWithRegex() { - CodeReader reader = new CodeReader(new StringReader("123ABC")); - StringBuilder token = new StringBuilder(); - assertEquals(3, reader.popTo(Pattern.compile("\\d+").matcher(new String()), token)); - assertEquals("123", token.toString()); - assertEquals( -1, reader.popTo(Pattern.compile("\\d+").matcher(new String()), token)); - assertEquals(3, reader.popTo(Pattern.compile("\\w+").matcher(new String()), token)); - assertEquals("123ABC", token.toString()); - assertEquals( -1, reader.popTo(Pattern.compile("\\w+").matcher(new String()), token)); - } - - @Test - public void testStackOverflowError() { - StringBuilder sb = new StringBuilder(); - sb.append("\n"); - for (int i = 0; i < 10000; i++) { - sb.append(Integer.toHexString(i)); - } - CodeReader reader = new CodeReader(sb.toString()); - reader.pop(); - reader.pop(); - - thrown.expect(ChannelException.class); - thrown.expectMessage("Unable to apply regular expression '([a-fA-F]|\\d)+' at line 2 and column 1," + - " because it led to a stack overflow error." + - " This error may be due to an inefficient use of alternations - see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507"); - reader.popTo(Pattern.compile("([a-fA-F]|\\d)+").matcher(""), new StringBuilder()); - } - - @Test - public void testPopToWithRegexAndFollowingMatcher() { - Matcher digitMatcher = Pattern.compile("\\d+").matcher(new String()); - Matcher alphabeticMatcher = Pattern.compile("[a-zA-Z]").matcher(new String()); - StringBuilder token = new StringBuilder(); - assertEquals( -1, new CodeReader(new StringReader("123 ABC")).popTo(digitMatcher, alphabeticMatcher, token)); - assertEquals("", token.toString()); - assertEquals(3, new CodeReader(new StringReader("123ABC")).popTo(digitMatcher, alphabeticMatcher, token)); - assertEquals("123", token.toString()); - } -} diff --git a/sonar-channel/src/test/java/org/sonar/channel/RegexChannelTest.java b/sonar-channel/src/test/java/org/sonar/channel/RegexChannelTest.java deleted file mode 100644 index 77c184e53e9..00000000000 --- a/sonar-channel/src/test/java/org/sonar/channel/RegexChannelTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.channel; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.Test; - -public class RegexChannelTest { - - @Test - public void shouldMatch() { - ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().addChannel(new MyWordChannel()).addChannel(new BlackholeChannel()).build(); - StringBuilder output = new StringBuilder(); - dispatcher.consume(new CodeReader("my word"), output); - assertThat(output.toString(), is("<w>my</w> <w>word</w>")); - } - - @Test - public void shouldMatchTokenLongerThanBuffer() { - ChannelDispatcher<StringBuilder> dispatcher = ChannelDispatcher.builder().addChannel(new MyLiteralChannel()).build(); - StringBuilder output = new StringBuilder(); - - CodeReaderConfiguration codeReaderConfiguration = new CodeReaderConfiguration(); - - int literalLength = 100000; - String veryLongLiteral = String.format(String.format("%%0%dd", literalLength), 0).replace("0", "a"); - - assertThat(veryLongLiteral.length(), is(100000)); - dispatcher.consume(new CodeReader("\">" + veryLongLiteral + "<\"", codeReaderConfiguration), output); - assertThat(output.toString(), is("<literal>\">" + veryLongLiteral + "<\"</literal>")); - } - - private static class MyLiteralChannel extends RegexChannel<StringBuilder> { - - public MyLiteralChannel() { - super("\"[^\"]*+\""); - } - - @Override - protected void consume(CharSequence token, StringBuilder output) { - output.append("<literal>" + token + "</literal>"); - } - } - - private static class MyWordChannel extends RegexChannel<StringBuilder> { - - public MyWordChannel() { - super("\\w++"); - } - - @Override - protected void consume(CharSequence token, StringBuilder output) { - output.append("<w>" + token + "</w>"); - } - } - - private static class BlackholeChannel extends Channel<StringBuilder> { - - @Override - public boolean consume(CodeReader code, StringBuilder output) { - output.append((char) code.pop()); - return true; - } - } - -} |