aboutsummaryrefslogtreecommitdiffstats
path: root/src/test/java/org/anarres
diff options
context:
space:
mode:
authorShevek <[email protected]>2013-12-27 05:49:13 -0800
committerShevek <[email protected]>2013-12-27 05:49:13 -0800
commitbdc6c852f418c3e042aa41469d84544e5f60a526 (patch)
tree7866346f0fa48ad46a6a427d016dd4b83451dbbe /src/test/java/org/anarres
parent39264fd6d2a6646e49f83b5b2b3512c1663a1c9b (diff)
Version bump to 1.4.0-SNAPSHOT.
Rewrite build system to use gradle. Clean up source for the new generation.
Diffstat (limited to 'src/test/java/org/anarres')
-rw-r--r--src/test/java/org/anarres/cpp/CppReaderTest.java34
-rw-r--r--src/test/java/org/anarres/cpp/ErrorTest.java65
-rw-r--r--src/test/java/org/anarres/cpp/JavaFileSystemTest.java38
-rw-r--r--src/test/java/org/anarres/cpp/JoinReaderTest.java41
-rw-r--r--src/test/java/org/anarres/cpp/LexerSourceTest.java86
-rw-r--r--src/test/java/org/anarres/cpp/MainTest.java11
-rw-r--r--src/test/java/org/anarres/cpp/PreprocessorTest.java167
7 files changed, 442 insertions, 0 deletions
diff --git a/src/test/java/org/anarres/cpp/CppReaderTest.java b/src/test/java/org/anarres/cpp/CppReaderTest.java
new file mode 100644
index 0000000..27eba06
--- /dev/null
+++ b/src/test/java/org/anarres/cpp/CppReaderTest.java
@@ -0,0 +1,34 @@
+package org.anarres.cpp;
+
+import java.util.Collections;
+
+import java.io.StringReader;
+import java.io.BufferedReader;
+import org.junit.Test;
+
+public class CppReaderTest {
+
+ 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().setSystemIncludePath(
+ Collections.singletonList("src/test/resources")
+ );
+ p.getPreprocessor().getFeatures().add(Feature.LINEMARKERS);
+ BufferedReader b = new BufferedReader(p);
+
+ String line;
+ while ((line = b.readLine()) != null) {
+ System.out.println(" >> " + line);
+ }
+ }
+
+ @Test
+ public void testCppReader()
+ throws Exception {
+ testCppReader("#include <test0.h>\n", "ab");
+ }
+
+}
diff --git a/src/test/java/org/anarres/cpp/ErrorTest.java b/src/test/java/org/anarres/cpp/ErrorTest.java
new file mode 100644
index 0000000..8777452
--- /dev/null
+++ b/src/test/java/org/anarres/cpp/ErrorTest.java
@@ -0,0 +1,65 @@
+package org.anarres.cpp;
+
+import java.io.IOException;
+import org.junit.Test;
+import static org.anarres.cpp.Token.*;
+import static org.junit.Assert.*;
+
+public class ErrorTest {
+
+ private boolean testError(Preprocessor p)
+ throws LexerException,
+ IOException {
+ for (;;) {
+ Token tok = p.token();
+ if (tok.getType() == EOF)
+ break;
+ if (tok.getType() == INVALID)
+ return true;
+ }
+ return false;
+ }
+
+ private void testError(String input) throws Exception {
+ StringLexerSource sl;
+ PreprocessorListener pl;
+ Preprocessor p;
+
+ /* Without a PreprocessorListener, throws an exception. */
+ sl = new StringLexerSource(input, true);
+ p = new Preprocessor();
+ p.addFeature(Feature.CSYNTAX);
+ p.addInput(sl);
+ try {
+ assertTrue(testError(p));
+ fail("Lexing unexpectedly succeeded without listener.");
+ } catch (LexerException e) {
+ /* required */
+ }
+
+ /* With a PreprocessorListener, records the error. */
+ sl = new StringLexerSource(input, true);
+ p = new Preprocessor();
+ p.addFeature(Feature.CSYNTAX);
+ p.addInput(sl);
+ pl = new PreprocessorListener();
+ p.setListener(pl);
+ assertNotNull("CPP has listener", p.getListener());
+ assertTrue(testError(p));
+ assertTrue("Listener has errors", pl.getErrors() > 0);
+
+ /* Without CSYNTAX, works happily. */
+ sl = new StringLexerSource(input, true);
+ p = new Preprocessor();
+ p.addInput(sl);
+ assertTrue(testError(p));
+ }
+
+ @Test
+ public void testErrors() throws Exception {
+ testError("\"");
+ testError("'");
+ // testError("''");
+ }
+
+}
diff --git a/src/test/java/org/anarres/cpp/JavaFileSystemTest.java b/src/test/java/org/anarres/cpp/JavaFileSystemTest.java
new file mode 100644
index 0000000..0ca44be
--- /dev/null
+++ b/src/test/java/org/anarres/cpp/JavaFileSystemTest.java
@@ -0,0 +1,38 @@
+package org.anarres.cpp;
+
+import java.io.FileNotFoundException;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class JavaFileSystemTest {
+
+ @Test
+ public void testJavaFileSystem() throws Exception {
+ JavaFileSystem fs = new JavaFileSystem();
+ VirtualFile f;
+
+ /* Anyone who has this file on their Unix box is messed up. */
+ f = fs.getFile("/foo/bar baz");
+ try {
+ f.getSource(); /* drop on floor */
+
+ assertTrue("Got a source for a non-file", f.isFile());
+ } catch (FileNotFoundException e) {
+ assertFalse("Got no source for a file", f.isFile());
+ }
+
+ /* We hope we have this. */
+ f = fs.getFile("/usr/include/stdio.h");
+ try {
+ f.getSource(); /* drop on floor */
+
+ System.out.println("Opened stdio.h");
+ assertTrue("Got a source for a non-file", f.isFile());
+ } catch (FileNotFoundException e) {
+ System.out.println("Failed to open stdio.h");
+ assertFalse("Got no source for a file", f.isFile());
+ }
+
+ }
+
+}
diff --git a/src/test/java/org/anarres/cpp/JoinReaderTest.java b/src/test/java/org/anarres/cpp/JoinReaderTest.java
new file mode 100644
index 0000000..527aa81
--- /dev/null
+++ b/src/test/java/org/anarres/cpp/JoinReaderTest.java
@@ -0,0 +1,41 @@
+package org.anarres.cpp;
+
+import java.io.StringReader;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class JoinReaderTest {
+
+ 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);
+ }
+
+ @Test
+ 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/test/java/org/anarres/cpp/LexerSourceTest.java b/src/test/java/org/anarres/cpp/LexerSourceTest.java
new file mode 100644
index 0000000..76bc673
--- /dev/null
+++ b/src/test/java/org/anarres/cpp/LexerSourceTest.java
@@ -0,0 +1,86 @@
+package org.anarres.cpp;
+
+import java.util.Arrays;
+import org.junit.Test;
+import static org.anarres.cpp.Token.*;
+import static org.junit.Assert.*;
+
+public class LexerSourceTest {
+
+ private void testLexerSource(String in, int... out)
+ throws Exception {
+ System.out.println("Testing '" + in + "' => "
+ + Arrays.toString(out));
+ StringLexerSource s = new StringLexerSource(in);
+
+ int col = 0;
+ for (int i = 0; i < out.length; i++) {
+ Token tok = s.token();
+ System.out.println("Token is " + tok);
+ assertEquals(out[i], tok.getType());
+ // assertEquals(col, tok.getColumn());
+ col += tok.getText().length();
+ }
+
+ Token tok = s.token();
+ System.out.println("Token is " + tok);
+ assertEquals(EOF, tok.getType());
+ }
+
+ @Test
+ public void testLexerSource()
+ throws Exception {
+
+ testLexerSource("int a = 5;",
+ IDENTIFIER, WHITESPACE, IDENTIFIER, WHITESPACE,
+ '=', WHITESPACE, NUMBER, ';', EOF
+ );
+
+ // \n is WHITESPACE because ppvalid = false
+ testLexerSource("# # \r\n\n\r \rfoo",
+ HASH, WHITESPACE, '#', WHITESPACE, IDENTIFIER
+ );
+
+ testLexerSource("%:%:", PASTE);
+ testLexerSource("%:?", '#', '?');
+ testLexerSource("%:%=", '#', MOD_EQ);
+ testLexerSource("0x1234ffdUL 0765I",
+ NUMBER, WHITESPACE, NUMBER);
+
+ testLexerSource("+= -= *= /= %= <= >= >>= <<= &= |= ^= x",
+ PLUS_EQ, WHITESPACE,
+ SUB_EQ, WHITESPACE,
+ MULT_EQ, WHITESPACE,
+ DIV_EQ, WHITESPACE,
+ MOD_EQ, WHITESPACE,
+ LE, WHITESPACE,
+ GE, WHITESPACE,
+ RSH_EQ, WHITESPACE,
+ LSH_EQ, WHITESPACE,
+ AND_EQ, WHITESPACE,
+ OR_EQ, WHITESPACE,
+ XOR_EQ, WHITESPACE,
+ IDENTIFIER);
+
+ testLexerSource("/**/", CCOMMENT);
+ testLexerSource("/* /**/ */", CCOMMENT, WHITESPACE, '*', '/');
+ testLexerSource("/** ** **/", CCOMMENT);
+ testLexerSource("//* ** **/", CPPCOMMENT);
+ testLexerSource("'\\r' '\\xf' '\\xff' 'x' 'aa' ''",
+ CHARACTER, WHITESPACE,
+ CHARACTER, WHITESPACE,
+ CHARACTER, WHITESPACE,
+ CHARACTER, WHITESPACE,
+ SQSTRING, WHITESPACE,
+ SQSTRING);
+
+ testLexerSource("1i1I1l1L1ui1ul",
+ NUMBER, NUMBER,
+ NUMBER, NUMBER,
+ NUMBER, NUMBER);
+
+ testLexerSource("'' 'x' 'xx'",
+ SQSTRING, WHITESPACE, CHARACTER, WHITESPACE, SQSTRING);
+ }
+
+}
diff --git a/src/test/java/org/anarres/cpp/MainTest.java b/src/test/java/org/anarres/cpp/MainTest.java
new file mode 100644
index 0000000..5ff7350
--- /dev/null
+++ b/src/test/java/org/anarres/cpp/MainTest.java
@@ -0,0 +1,11 @@
+package org.anarres.cpp;
+
+import org.junit.Test;
+
+public class MainTest {
+
+ @Test
+ public void testMain() throws Exception {
+ Main.main(new String[]{"--version"});
+ }
+}
diff --git a/src/test/java/org/anarres/cpp/PreprocessorTest.java b/src/test/java/org/anarres/cpp/PreprocessorTest.java
new file mode 100644
index 0000000..fb2a8ac
--- /dev/null
+++ b/src/test/java/org/anarres/cpp/PreprocessorTest.java
@@ -0,0 +1,167 @@
+package org.anarres.cpp;
+
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import org.junit.Before;
+import org.junit.Test;
+import static org.anarres.cpp.Token.*;
+import static org.junit.Assert.*;
+
+public class PreprocessorTest {
+
+ private OutputStreamWriter writer;
+ private Preprocessor p;
+
+ @Before
+ public void setUp() throws Exception {
+ final PipedOutputStream po = new PipedOutputStream();
+ writer = new OutputStreamWriter(po);
+
+ p = new Preprocessor();
+ p.addInput(
+ new LexerSource(
+ new InputStreamReader(
+ new PipedInputStream(po)
+ ),
+ true
+ )
+ );
+ }
+
+ private static class I {
+
+ private String t;
+
+ public I(String t) {
+ this.t = t;
+ }
+
+ public String getText() {
+ return t;
+ }
+
+ public String toString() {
+ return getText();
+ }
+ }
+
+ private static I I(String t) {
+ return new I(t);
+ }
+
+ /*
+ * When writing tests in this file, remember the preprocessor
+ * stashes NLs, so you won't see an immediate NL at the end of any
+ * input line. You will see it right before the next nonblank on
+ * the following input line.
+ */
+ @Test
+ public void testPreprocessor() throws Exception {
+ /* Magic macros */
+ testInput("line = __LINE__\n",
+ I("line"), WHITESPACE, '=', WHITESPACE, NUMBER
+ /*, 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, CCOMMENT);
+ testInput("#define one two\n", NL);
+ testInput("one /* three */\n", NL, I("three"), WHITESPACE, CCOMMENT);
+ testInput("#undef two\n", NL);
+ testInput("#define two five\n", NL);
+ testInput("one /* five */\n", NL, I("five"), WHITESPACE, CCOMMENT);
+ testInput("#undef two\n", NL);
+ testInput("one /* two */\n", NL, I("two"), WHITESPACE, CCOMMENT);
+ testInput("#undef one\n", NL);
+ testInput("#define one four\n", NL);
+ testInput("one /* four */\n", NL, I("four"), WHITESPACE, CCOMMENT);
+ testInput("#undef one\n", NL);
+ testInput("#define one one\n", NL);
+ testInput("one /* one */\n", NL, I("one"), WHITESPACE, CCOMMENT);
+
+ /* Variadic macros. */
+ testInput("#define var(x...) a x b\n", NL);
+ testInput("var(e, f, g)\n", NL,
+ I("a"), WHITESPACE,
+ I("e"), ',', WHITESPACE,
+ I("f"), ',', WHITESPACE,
+ I("g"), WHITESPACE,
+ I("b")
+ );
+
+ testInput("#define _Widen(x) L ## x\n", NL);
+ testInput("#define Widen(x) _Widen(x)\n", NL);
+ testInput("#define LStr(x) _Widen(#x)\n", NL);
+ testInput("LStr(x);\n", NL, I("L"), "x");
+
+ 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 " + v + ", 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());
+ }
+ }
+}