package metalexer.jflex;

import java.util.List;

import junit.framework.TestCase;

public class StaticFindTests extends TestCase {
    public void testSingleLineComments() {
        checkStatic("//static x;", 1, 1, new int[][] {});
        checkStatic("static x;\n//static y;", 1, 1, new int[][] {{1, 1}});
        checkStatic("//static x;\nstatic y;", 1, 1, new int[][] {{2, 1}});
        checkStatic("static x;\n//static y;\nstatic z;", 1, 1, new int[][] {{1, 1}, {3, 1}});
    }

    public void testMultiLineComments() {
        checkStatic("/*static x;*/", 1, 1, new int[][] {});
        checkStatic("static x;\n/*static y;*/", 1, 1, new int[][] {{1, 1}});
        checkStatic("/*static x;*/\nstatic y;", 1, 1, new int[][] {{2, 1}});
        checkStatic("static x;\n/*static y;*/\nstatic z;", 1, 1, new int[][] {{1, 1}, {3, 1}});
    }

    public void testNestedComments() {
        checkStatic("/*static x; /*static y;*/*/", 1, 1, new int[][] {});
        checkStatic("/*/*static x;*/ static y;*/", 1, 1, new int[][] {});
        checkStatic("/*/*static x;*/*/ static y;", 1, 1, new int[][] {{1, 19}});
    }

    public void testStrings() {
        checkStatic("\"static x;\"", 1, 1, new int[][] {});
        checkStatic("static x;\n\"static y;\"", 1, 1, new int[][] {{1, 1}});
        checkStatic("\"static x;\"\nstatic y;", 1, 1, new int[][] {{2, 1}});
        checkStatic("static x;\n\"static y;\"\nstatic z;", 1, 1, new int[][] {{1, 1}, {3, 1}});
    }

    public void testStringsWithEscapes() {
        checkStatic("\"static \\\"x\\\";\"", 1, 1, new int[][] {});
    }

    public void testMalformed() {
        checkStatic("static x", 1, 1, new int[][] {{1, 1}});
        checkStatic("static", 1, 1, new int[][] {{1, 1}});
        checkStatic("static ", 1, 1, new int[][] {{1, 1}});
        checkStatic("/*static", 1, 1, new int[][] {});
        checkStatic("/*/*static*/", 1, 1, new int[][] {});
        checkStatic("/*/*static", 1, 1, new int[][] {});
        checkStatic("//static x", 1, 1, new int[][] {});
        checkStatic("/static x", 1, 1, new int[][] {{1, 2}});
        checkStatic("asdjf;ilai static x; ahdfkd; fas", 1, 1, new int[][] {{1, 12}});
        checkStatic("\"static x\\\";\"", 1, 1, new int[][] {});
        checkStatic("\"static x", 1, 1, new int[][] {});
    }

    public void testIdentifier() {
        checkStatic("static1 x;", 1, 1, new int[][] {});
    }

    public void testBasePos() {
        checkStatic("static", 1, 1, new int[][] {{1, 1}});
        checkStatic("+static", 1, 1, new int[][] {{1, 2}});
        checkStatic("+\nstatic", 1, 1, new int[][] {{2, 1}});
        checkStatic("+\n+static", 1, 1, new int[][] {{2, 2}});
        
        checkStatic("static", 1, 2, new int[][] {{1, 2}});
        checkStatic("+static", 1, 2, new int[][] {{1, 3}});
        checkStatic("+\nstatic", 1, 2, new int[][] {{2, 1}});
        checkStatic("+\n+static", 1, 2, new int[][] {{2, 2}});
        
        
        checkStatic("static", 2, 1, new int[][] {{2, 1}});
        checkStatic("+static", 2, 1, new int[][] {{2, 2}});
        checkStatic("+\nstatic", 2, 1, new int[][] {{3, 1}});
        checkStatic("+\n+static", 2, 1, new int[][] {{3, 2}});
    }

    private static void checkStatic(String original, int baseLine, int baseCol, int[][] expected) {
        List<StaticFind.Position> actualList = StaticFind.findStaticKeywords(baseLine, baseCol, original);
        assertEquals("Number of keywords", expected.length, actualList.size());
        for(int i = 0; i < actualList.size(); i++) {
            StaticFind.Position pos = actualList.get(i);
            assertEquals("Static keyword #" + (i+1) + " (line)", expected[i][0], pos.getLine());
            assertEquals("Static keyword #" + (i+1) + " (column)", expected[i][1], pos.getColumn());
        }
    }
}
