summaryrefslogtreecommitdiffstats
path: root/src/tests/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/org')
-rw-r--r--src/tests/org/anarres/cpp/BaseTestCase.java6
-rw-r--r--src/tests/org/anarres/cpp/CppReaderTestCase.java34
-rw-r--r--src/tests/org/anarres/cpp/ErrorTestCase.java50
-rw-r--r--src/tests/org/anarres/cpp/JoinReaderTestCase.java40
-rw-r--r--src/tests/org/anarres/cpp/LexerSourceTestCase.java43
-rw-r--r--src/tests/org/anarres/cpp/PreprocessorTestCase.java154
6 files changed, 327 insertions, 0 deletions
diff --git a/src/tests/org/anarres/cpp/BaseTestCase.java b/src/tests/org/anarres/cpp/BaseTestCase.java
new file mode 100644
index 0000000..ad6ae6a
--- /dev/null
+++ b/src/tests/org/anarres/cpp/BaseTestCase.java
@@ -0,0 +1,6 @@
+package org.anarres.cpp;
+
+import junit.framework.TestCase;
+
+public abstract class BaseTestCase extends TestCase {
+}
diff --git a/src/tests/org/anarres/cpp/CppReaderTestCase.java b/src/tests/org/anarres/cpp/CppReaderTestCase.java
new file mode 100644
index 0000000..5aeee06
--- /dev/null
+++ b/src/tests/org/anarres/cpp/CppReaderTestCase.java
@@ -0,0 +1,34 @@
+package org.anarres.cpp;
+
+import java.util.Collections;
+
+import java.io.StringReader;
+import java.io.BufferedReader;
+
+import junit.framework.Test;
+
+public class CppReaderTestCase extends BaseTestCase implements Test {
+
+ private void testCppReader(String in, String out)
+ throws Exception {
+ System.out.println("Testing " + in + " => " + out);
+ StringReader r = new StringReader(in);
+ CppReader p = new CppReader(r);
+ p.getPreprocessor().setIncludePath(
+ Collections.singletonList("src/input")
+ );
+ p.getPreprocessor().setFlags(Preprocessor.FL_LINEMARKER);
+ BufferedReader b = new BufferedReader(p);
+
+ String line;
+ while ((line = b.readLine()) != null) {
+ System.out.println(" >> " + line);
+ }
+ }
+
+ public void testJoinReader()
+ throws Exception {
+ testCppReader("#include <test0.h>\n", "ab");
+ }
+
+}
diff --git a/src/tests/org/anarres/cpp/ErrorTestCase.java b/src/tests/org/anarres/cpp/ErrorTestCase.java
new file mode 100644
index 0000000..d5d44a3
--- /dev/null
+++ b/src/tests/org/anarres/cpp/ErrorTestCase.java
@@ -0,0 +1,50 @@
+package org.anarres.cpp;
+
+import java.io.*;
+
+import junit.framework.Test;
+
+import static org.anarres.cpp.Token.*;
+
+public class ErrorTestCase extends BaseTestCase {
+
+ private void testError(Source source)
+ throws LexerException,
+ IOException {
+ for (;;) {
+ Token tok = source.token();
+ if (tok.getType() == EOF)
+ break;
+ }
+
+ }
+
+ private void testError(String input) throws Exception {
+ StringLexerSource sl;
+ PreprocessorListener pl;
+
+ /* Without a PreprocessorListener, throws an exception. */
+ sl = new StringLexerSource(input, true);
+ try {
+ testError(sl);
+ fail("Lexing succeeded");
+ }
+ catch (LexerException e) {
+ /* ignored */
+ }
+
+ /* With a PreprocessorListener, records the error. */
+ sl = new StringLexerSource(input, true);
+ pl = new PreprocessorListener();
+ sl.setListener(pl);
+ testError(sl);
+ assertTrue(pl.getErrors() > 0);
+ }
+
+ public void testErrors() throws Exception {
+ testError("\"");
+ testError("'");
+ testError("''");
+ }
+
+}
diff --git a/src/tests/org/anarres/cpp/JoinReaderTestCase.java b/src/tests/org/anarres/cpp/JoinReaderTestCase.java
new file mode 100644
index 0000000..2b99c2f
--- /dev/null
+++ b/src/tests/org/anarres/cpp/JoinReaderTestCase.java
@@ -0,0 +1,40 @@
+package org.anarres.cpp;
+
+import java.io.StringReader;
+
+import junit.framework.Test;
+
+public class JoinReaderTestCase extends BaseTestCase implements Test {
+
+ private void testJoinReader(String in, String out, boolean tg)
+ throws Exception {
+ System.out.println("Testing " + in + " => " + out);
+ StringReader r = new StringReader(in);
+ JoinReader j = new JoinReader(r, tg);
+
+ for (int i = 0; i < out.length(); i++) {
+ int c = j.read();
+ // System.out.println("At offset " + i + ": " + (char)c);
+ assertEquals((char)out.charAt(i), c);
+ }
+ assertEquals(-1, j.read());
+ assertEquals(-1, j.read());
+ }
+
+ private void testJoinReader(String in, String out)
+ throws Exception {
+ testJoinReader(in, out, true);
+ testJoinReader(in, out, false);
+ }
+
+ public void testJoinReader()
+ throws Exception {
+ testJoinReader("ab", "ab");
+ testJoinReader("a\\b", "a\\b");
+ testJoinReader("a\nb", "a\nb");
+ testJoinReader("a\\\nb", "ab\n");
+ testJoinReader("foo??(bar", "foo[bar", true);
+ testJoinReader("foo??/\nbar", "foobar\n", true);
+ }
+
+}
diff --git a/src/tests/org/anarres/cpp/LexerSourceTestCase.java b/src/tests/org/anarres/cpp/LexerSourceTestCase.java
new file mode 100644
index 0000000..e8fb410
--- /dev/null
+++ b/src/tests/org/anarres/cpp/LexerSourceTestCase.java
@@ -0,0 +1,43 @@
+package org.anarres.cpp;
+
+import java.io.StringReader;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.Test;
+
+import static org.anarres.cpp.Token.*;
+
+public class LexerSourceTestCase extends BaseTestCase implements Test {
+
+ private void testLexerSource(String in, int[] out)
+ throws Exception {
+ System.out.println("Testing '" + in + "' => " +
+ Arrays.toString(out));
+ StringLexerSource s = new StringLexerSource(in);
+
+ for (int i = 0; i < out.length; i++) {
+ Token tok = s.token();
+ System.out.println("Token is " + tok);
+ assertEquals(out[i], tok.getType());
+ }
+ assertEquals(EOF, s.token().getType());
+ }
+
+ public void testJoinReader()
+ throws Exception {
+
+ testLexerSource("int a = 5;", new int[] {
+ IDENTIFIER, WHITESPACE, IDENTIFIER, WHITESPACE,
+ '=', WHITESPACE, INTEGER, ';', EOF
+ });
+
+ testLexerSource("# # foo", new int[] {
+ HASH, WHITESPACE, '#', WHITESPACE, IDENTIFIER
+ });
+
+ }
+
+}
diff --git a/src/tests/org/anarres/cpp/PreprocessorTestCase.java b/src/tests/org/anarres/cpp/PreprocessorTestCase.java
new file mode 100644
index 0000000..ea6aab7
--- /dev/null
+++ b/src/tests/org/anarres/cpp/PreprocessorTestCase.java
@@ -0,0 +1,154 @@
+package org.anarres.cpp;
+
+import java.io.*;
+
+import junit.framework.Test;
+
+import static org.anarres.cpp.Token.*;
+
+public class PreprocessorTestCase extends BaseTestCase {
+ private OutputStreamWriter writer;
+ private Preprocessor p;
+
+ public void setUp() throws Exception {
+ final PipedOutputStream po = new PipedOutputStream();
+ writer = new OutputStreamWriter(po);
+
+ p = new Preprocessor(
+ new LexerSource(
+ new InputStreamReader(
+ new PipedInputStream(po)
+ ),
+ true
+ ) {
+ public File getFile() {
+ return new File("test-input");
+ }
+ }
+ ) {
+ @Override
+ protected void include(File parent, int line,
+ String name, boolean quoted) {
+ /* XXX Perform a useful assertion. */
+ }
+ };
+ }
+
+ private static class I {
+ private String t;
+ public I(String t) {
+ this.t = t;
+ }
+ public String getText() {
+ return t;
+ }
+ }
+
+ private static I I(String t) {
+ return new I(t);
+ }
+
+ public void testPreprocessor() throws Exception {
+ /* Magic macros */
+ testInput("line = __LINE__\n",
+ I("line"), WHITESPACE, '=', WHITESPACE, INTEGER
+ /*, NL - all nls deferred so as not to block the reader */
+ );
+ testInput("file = __FILE__\n", NL, /* from before, etc */
+ I("file"), WHITESPACE, '=', WHITESPACE, STRING
+ );
+
+ /* Simple definitions */
+ testInput("#define A a /* a defined */\n", NL);
+ testInput("#define B b /* b defined */\n", NL);
+ testInput("#define C c /* c defined */\n", NL);
+
+ /* Expansion of arguments */
+ testInput("#define EXPAND(x) x\n", NL);
+ testInput("EXPAND(a)\n", NL, I("a"));
+ testInput("EXPAND(A)\n", NL, I("a"));
+
+ /* Stringification */
+ testInput("#define _STRINGIFY(x) #x\n", NL);
+ testInput("_STRINGIFY(A)\n", NL, "A");
+ testInput("#define STRINGIFY(x) _STRINGIFY(x)\n", NL);
+ testInput("STRINGIFY(b)\n", NL, "b");
+ testInput("STRINGIFY(A)\n", NL, "a");
+
+ /* Concatenation */
+ testInput("#define _CONCAT(x, y) x ## y\n", NL);
+ testInput("_CONCAT(A, B)\n", NL, I("AB"));
+ testInput("#define A_CONCAT done_a_concat\n", NL);
+ testInput("_CONCAT(A, _CONCAT(B, C))\n", NL,
+ I("done_a_concat"), '(', I("b"), ',', WHITESPACE, I("c"), ')'
+ );
+ testInput("#define CONCAT(x, y) _CONCAT(x, y)\n", NL);
+ testInput("CONCAT(A, CONCAT(B, C))\n", NL, I("abc"));
+ testInput("#define _CONCAT3(x, y, z) x ## y ## z\n", NL);
+ testInput("_CONCAT3(a, b, c)\n", NL, I("abc"));
+ testInput("_CONCAT3(A, B, C)\n", NL, I("ABC"));
+
+/* Redefinitions, undefinitions. */
+testInput("#define two three\n", NL);
+testInput("one /* one */\n", NL, I("one"), WHITESPACE, COMMENT);
+testInput("#define one two\n", NL);
+testInput("one /* three */\n", NL, I("three"), WHITESPACE, COMMENT);
+testInput("#undef two\n", NL);
+testInput("#define two five\n", NL);
+testInput("one /* five */\n", NL, I("five"), WHITESPACE, COMMENT);
+testInput("#undef two\n", NL);
+testInput("one /* two */\n", NL, I("two"), WHITESPACE, COMMENT);
+testInput("#undef one\n", NL);
+testInput("#define one four\n", NL);
+testInput("one /* four */\n", NL, I("four"), WHITESPACE, COMMENT);
+testInput("#undef one\n", NL);
+testInput("#define one one\n", NL);
+testInput("one /* one */\n", NL, I("one"), WHITESPACE, COMMENT);
+
+ /* Variadic macros. */
+ testInput("#define var(x...) a x b\n", NL);
+ testInput("var(e, f, g)", NL,
+ I("a"), WHITESPACE,
+ I("e"), ',', WHITESPACE,
+ I("f"), ',', WHITESPACE,
+ I("g"), WHITESPACE,
+ I("b")
+ );
+
+ writer.close();
+
+ Token t;
+ do {
+ t = p.token();
+ System.out.println("Remaining token " + t);
+ } while(t.getType() != EOF);
+ }
+
+ private void testInput(String in, Object... out)
+ throws Exception {
+ System.out.print("Input: " + in);
+ writer.write(in);
+ writer.flush();
+ for (int i = 0; i < out.length; i++) {
+ Token t = p.token();
+ System.out.println(t);
+ Object v = out[i];
+ if (v instanceof String) {
+ if (t.getType() != STRING)
+ fail("Expected STRING, but got " + t);
+ assertEquals((String)v, (String)t.getValue());
+ }
+ else if (v instanceof I) {
+ if (t.getType() != IDENTIFIER)
+ fail("Expected IDENTIFIER, but got " + t);
+ assertEquals( ((I)v).getText(), (String)t.getText());
+ }
+ else if (v instanceof Character)
+ assertEquals( (int)((Character)v).charValue(), t.getType());
+ else if (v instanceof Integer)
+ assertEquals( ((Integer)v).intValue(), t.getType());
+ else
+ fail("Bad object " + v.getClass());
+ }
+ }
+}