package metalexer.jflex;

import junit.framework.TestCase;

public class ReturnWrapTests extends TestCase {
    public void testSingleLineComments() {
        checkWrap("//return x;", "//return x;");
        checkWrap("return x;\n//return y;", "return Maybe.Just(x);\n//return y;");
        checkWrap("//return x;\nreturn y;", "//return x;\nreturn Maybe.Just(y);");
        checkWrap("return x;\n//return y;\nreturn z;", "return Maybe.Just(x);\n//return y;\nreturn Maybe.Just(z);");
    }

    public void testMultiLineComments() {
        checkWrap("/*return x;*/", "/*return x;*/");
        checkWrap("return x;\n/*return y;*/", "return Maybe.Just(x);\n/*return y;*/");
        checkWrap("/*return x;*/\nreturn y;", "/*return x;*/\nreturn Maybe.Just(y);");
        checkWrap("return x;\n/*return y;*/\nreturn z;", "return Maybe.Just(x);\n/*return y;*/\nreturn Maybe.Just(z);");
    }

    public void testNestedComments() {
        checkWrap("/*return x; /*return y;*/*/", "/*return x; /*return y;*/*/");
        checkWrap("/*/*return x;*/ return y;*/", "/*/*return x;*/ return y;*/");
        checkWrap("/*/*return x;*/*/ return y;", "/*/*return x;*/*/ return Maybe.Just(y);");
    }

    public void testStrings() {
        checkWrap("\"return x;\"", "\"return x;\"");
        checkWrap("return x;\n\"return y;\"", "return Maybe.Just(x);\n\"return y;\"");
        checkWrap("\"return x;\"\nreturn y;", "\"return x;\"\nreturn Maybe.Just(y);");
        checkWrap("return x;\n\"return y;\"\nreturn z;", "return Maybe.Just(x);\n\"return y;\"\nreturn Maybe.Just(z);");
    }

    public void testStringsWithEscapes() {
        checkWrap("\"return \\\"x\\\";\"", "\"return \\\"x\\\";\"");
    }

    public void testVoidReturn() {
        checkWrap("return;", "return;");
    }

    public void testValueReturn() {
        checkWrap("return\t1\n+\n\t\t\t2\n;", "return\tMaybe.Just(1\n+\n\t\t\t2\n);");
    }

    public void testValueReturns() {
        checkWrap("return x; return y; return z;", "return Maybe.Just(x); return Maybe.Just(y); return Maybe.Just(z);");
    }

    public void testMalformed() {
        checkWrap("return x", "return Maybe.Just(x)");
        checkWrap("return", "return");
        checkWrap("return ", "return Maybe.Just()");
        checkWrap("/*return", "/*return");
        checkWrap("/*/*return*/", "/*/*return*/");
        checkWrap("/*/*return", "/*/*return");
        checkWrap("//return x", "//return x");
        checkWrap("/return x", "/return Maybe.Just(x)");
        checkWrap("asdjf;ilai return x; ahdfkd; fas", "asdjf;ilai return Maybe.Just(x); ahdfkd; fas");
        checkWrap("\"return x\\\";\"", "\"return x\\\";\"");
        checkWrap("\"return x", "\"return x");
    }

    public void testIdentifier() {
        checkWrap("return1 (x);", "return1 (x);");
    }

    public void testCommentInReturn() {
        checkWrap("return x//\n;", "return Maybe.Just(x//\n);");
        checkWrap("return /* */ x\n;", "return Maybe.Just(/* */ x\n);");
        
        checkWrap("return x//;\n;", "return Maybe.Just(x//;\n);");
        checkWrap("return x/*;*/\n;", "return Maybe.Just(x/*;*/\n);");
        
        checkWrap("return//\n x\n;", "return Maybe.Just(//\n x\n);");
        checkWrap("return/* */ x\n;", "return Maybe.Just(/* */ x\n);");
    }

    private static void checkWrap(String original, String expected) {
        assertEquals("Wrapping: ", expected, ReturnWrap.wrapReturns(original));
    }
}
