package is.L42.connected.withSafeOperators; import static helpers.TestHelper.getClassB; import static helpers.TestHelper.lineNumber; import static org.junit.Assert.fail; import helpers.TestHelper; import is.L42.connected.withSafeOperators.Rename.UserForMethodResult; import java.util.Arrays; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; import platformSpecific.javaTranslation.Resources; import ast.Ast; import ast.Ast.C; import ast.Ast.MethodSelector; import ast.Ast.Path; import ast.ExpCore; import ast.PathAux; import ast.ExpCore.ClassB; import ast.ExpCore.ClassB.Phase; import ast.Util.PathMx; import auxiliaryGrammar.Functions; import programReduction.Program; import facade.Configuration; public class TestRename { @RunWith(Parameterized.class) public static class TestRenameMethod {//add more test for error cases @Parameter(0) public String _cb1; @Parameter(1) public String _path; @Parameter(2) public String _ms1; @Parameter(3) public String _ms2; @Parameter(4) public String _expected; @Parameter(5) public boolean isError; @Parameterized.Parameters public static List<Object[]> createData() { return Arrays.asList(new Object[][] { { // "{B:{ method Void m() void}}", "B", "m()", "k()", "{B:{ method Void k() void}}", false // }, { // "{ method Void m() void}", "This0", "m()", "k()", "{ method Void k() void}", false // }, { // "{ method Void m() void method This0::m() mm() void}", "This0", "m()", "k()", "{ method Void k() void method This0::k() mm() void}", false // }, { // "{ method Void m() void method//@private\n Void mm() void}", "This0", "m()", "mm()", "{method Void mm() void" + " method //@private\n" + "Void mm__0_0() void}", false // }, { // "{ class method //@private\n" +" This0 a(Any n) \n" +" mut method //@private\n" +" Any #n() \n" +" read method //@private\n" +" Any n() \n" +" class method\n" +" This0 _1(This0 new) new\n" +" class method \n" +" This0 a_1(Any n) This0._1(new:This0.a(n:n))}\n", "This0", "a_1(n)", "a(n)", "{class method //@private\n" +"This0 a__0_0(Any n__0_0)\n" +"mut method //@private\n" +"Any #n__0_0()\n" +"read method //@private\n" +"Any n__0_0()\n" +"class method\n" +"This0 _1(This0 new) new\n" +"class method\n" +"This0 a(Any n) This0._1(new:This0.a__0_0(n__0_0:n))}",false }, { // "{ method Void m() void}", "This0", "m()", "k(x)", "{ Kind:{//@stringU\n"+ "//MethodClash\n"+ "}\n"+ "Path:{//@.\n"+ "}\n"+ "Left:{//@stringU\n"+ "//method Void m() void\n"+ "}\n"+ "Right:{//@stringU\n"+ "//method Void k(Void x) void\n"+ "}\n"+ "LeftKind:{//@stringU\n"+ "//ImplementedMethod\n"+ "}\n"+ "RightKind:{//@stringU\n"+ "//ImplementedMethod\n"+ "}\n"+ "DifferentParameters:{//@stringU\n"+ "//[0]\n"+ "}\n"+ "DifferentReturnType:{//@stringU\n"+ "//false\n"+ "}\n"+ "DifferentThisMdf:{//@stringU\n"+ "//false\n"+ "}\n"+ "IncompatibleException:{//@stringU\n"+ "//false\n"+ "}}", true // } }); } @Test public void test() { TestHelper.configureForTest(); ClassB cb1 = getClassB(_cb1); List<Ast.C> path=TestHelper.cs(_path); MethodSelector ms1 = MethodSelector.parse(_ms1); MethodSelector ms2 = MethodSelector.parse(_ms2); ClassB expected = getClassB(_expected); if (!isError) { ClassB res = Rename.renameMethod(Program.emptyLibraryProgram(), cb1, path, ms1, ms2); TestHelper.assertEqualExp(expected, res); } else { try { Rename.renameMethod(Program.emptyLibraryProgram(), cb1, path, ms1, ms2); fail("error expected"); } catch (Resources.Error err) { ClassB res = (ClassB) err.unbox; TestHelper.assertEqualExp(expected, res); } } } } @RunWith(Parameterized.class) public static class TestUserForMethod{//add more test for error cases @Parameter(0) public int _lineNumber; @Parameter(1) public String _cb1; @Parameter(2) public String _path; @Parameter(3) public String _ms1; @Parameter(4) public String expected1; @Parameter(5) public String expected2; @Parameter(6) public boolean isError; @Parameters(name = "{index}: line {0}") public static List<Object[]> createData() { return Arrays.asList(new Object[][] { { // lineNumber(),"{B:{ method Void m() void}}", "B", "m()", "[]","[]", false // }, { // lineNumber(),"{ method Void m() this.m()}", "This0", "m()", "[]","[m()]", false // }, { // lineNumber(),"{ B:{method Void m() this.m()} method Void mm(B b) b.m()}", "B", "m()", "[This0::mm(b)]","[m()]", false // }, { // lineNumber(),"{ B:{method Void m() this.m() method B::m() k() void} method Void mm(B b) b.m()}", "B", "m()", "[This0::mm(b)]","[m()]", false // } }); } @Test public void test() { TestHelper.configureForTest(); ClassB cb1 = getClassB(_cb1); List<Ast.C> path=TestHelper.cs(_path); MethodSelector ms1 = MethodSelector.parse(_ms1); if (!isError) { UserForMethodResult res = Rename.userForMethod(Program.emptyLibraryProgram(), cb1, path, ms1,true); Assert.assertEquals(expected1, res.asClient.toString()); Assert.assertEquals(expected2, res.asThis.toString()); } else { try { Rename.userForMethod(Program.emptyLibraryProgram(), cb1, path, ms1,true); fail("error expected"); } catch (Resources.Error err) { ClassB res = (ClassB) err.unbox; TestHelper.assertEqualExp(new ExpCore._void(), res); } } } } @RunWith(Parameterized.class) public static class TestRenameClassStrict {//add more test for error cases @Parameter(0) public String _cb1; @Parameter(1) public String _path1; @Parameter(2) public String _path2; @Parameter(3) public String _expected; @Parameter(4) public boolean isError; @Parameterized.Parameters public static List<Object[]> createData() { return Arrays.asList(new Object[][] { {// "{B:{ method Void m() void}}", "B", "C", "{C:{ method Void m() void}}", false// }, {// "{B:{ method Void m() void}}", "B", "C.D", "{C:{ D:{method Void m() void}}}", false// },{// "{A:{interface method This0 m() } B:{ implements A method m() this.m().m()} User:{ method A mm(B b) b.m().m()}}","B","C", "{A:{interface method This0 m() } User:{ method A mm(C b) b.m().m()} C:{ implements A method m() this.m().m()} }",false },{// "{A:{interface method This0 m() } B:{ implements A method m() this.m().m()} User:{ method A mm(B b) b.m().m()} }","A","C", "{B:{ implements C method m() this.m().m()} User:{ method C mm(B b) b.m().m()} C:{interface method This0 m() } }",false } }); } @Test public void test() { TestHelper.configureForTest(); ClassB cb1 = getClassB(_cb1); List<Ast.C> path1=TestHelper.cs(_path1); List<Ast.C> path2=TestHelper.cs(_path2); ClassB expected = getClassB(_expected); if (!isError) { ClassB res = Rename.renameClassStrict(Program.emptyLibraryProgram(), cb1, path1, path2); newTypeSystem.TypeSystem.instance().topTypeLib(Phase.Typed, Program.emptyLibraryProgram().updateTop(res)); TestHelper.assertEqualExp(expected, res); } else { try { Rename.renameClassStrict(Program.emptyLibraryProgram(), cb1, path1, path2); fail("error expected"); } catch (Resources.Error err) { ClassB res = (ClassB) err.unbox; TestHelper.assertEqualExp(expected, res); } } } } //----- @Test public void testToTop() { List<Ast.C> res = ClassOperations.toTop(Arrays.asList(),Path.parse("This0.A")); Assert.assertEquals(res,PathAux.sToC(Arrays.asList("A"))); res = ClassOperations.toTop(Arrays.asList(),Path.parse("This0.A.B")); Assert.assertEquals(res,PathAux.sToC(Arrays.asList("A","B"))); res = ClassOperations.toTop(PathAux.sToC(Arrays.asList("C")),Path.parse("This1.A.B")); Assert.assertEquals(res,PathAux.sToC(Arrays.asList("A","B"))); res = ClassOperations.toTop(PathAux.sToC(Arrays.asList("C")),Path.parse("This0.A.B")); Assert.assertEquals(res,PathAux.sToC(Arrays.asList("C","A","B"))); } @Test public void testNormalizePath() { Path res = ClassOperations.normalizePath(Arrays.asList(),0,Arrays.asList()); Assert.assertEquals(res,Path.outer(0)); res = ClassOperations.normalizePath(Arrays.asList(C.of("A")),1,Arrays.asList(C.of("B"))); Assert.assertEquals(res,Path.parse("This1.B")); res = ClassOperations.normalizePath(Arrays.asList(C.of("B")),1,Arrays.asList(C.of("B"))); Assert.assertEquals(res,Path.parse("This0")); } @RunWith(Parameterized.class) public static class TestRenameClass {//add more test for error cases @Parameter(0) public int _lineNumber; @Parameter(1) public String _cb1; @Parameter(2) public String _path1; @Parameter(3) public String _path2; @Parameter(4) public String _expected; @Parameter(5) public boolean isError; @Parameters(name = "{index}: line {0}") public static List<Object[]> createData() { return Arrays.asList(new Object[][] { {// lineNumber(),"{B:{ method Void m() void}}", "B", "C", "{C:{ method Void m() void}}", false// }, {lineNumber(),// "{B:{ method Void m() void}}", "B", "C.D", "{C:{ D:{method Void m() void}}}", false// }, {lineNumber(),// "{A:{}}","A","B","{B:{}}",false// }, {lineNumber(),// "{A:{ class method class A m() A}}","A","B", "{B:{class method class This0 m() This0}}" ,false// }, {lineNumber(),// "{A:{ class method class A m() {return A}}}","A","B", "{B:{class method class This0 m() {return This0}}}" ,false// }, {lineNumber(),// "{A:{ method A ()} B:{method Void foo()}}","A","B", "{B:{ method Void foo() method This0 ()}}" ,false// }, {lineNumber(),// "{C:{A:{ method A ()}} B:{method Void foo()}}","C.A","B", "{C:{} B:{ method Void foo() method This0 () }}" ,false// }, {lineNumber(),// "{D:{C:{A:{ method A ()}}} B:{method Void foo()}}","D.C.A","B", "{D:{C:{}} B:{ method Void foo() method This0 ()}}" ,false// }, {lineNumber(),// "{A:{ method A ()} C:{B:{method Void foo()}}}","A","C.B", "{C:{B:{ method Void foo() method This0 () }}}" ,false// }, {lineNumber(),// "{A:{ method A ()} D:{C:{B:{method Void foo()}}}}","A","D.C.B", "{D:{C:{B:{ method Void foo() method This0 ()}}}}" ,false// }, {lineNumber(),// //// "{ A:{ class method This1.B () } B:{ }}","A","This0", "{ B:{ } class method This0.B () }" ,false// }, {lineNumber(),// "{ A:{ class method This1.B () } B:{ }}" ,"A","C", "{ B:{ } C:{class method This1.B () }}" ,false// }, {lineNumber(),// "{ A1:{ A2:{ class method B () }} B:{ }}","A1.A2","A1", "{ A1:{ class method B () } B:{ }}" ,false// }, {lineNumber(),// "{ A1:{ A2:{ class method B () }} B:{ }}" ,"A1.A2","This0", "{ A1:{ } B:{ } class method B () }" ,false// }, {lineNumber(),// "{ A1:{ A2:{ class method B () } B:{ } }}","A1.A2","A1", "{ A1:{B:{ } class method B () }}" ,false// }, {lineNumber(),// "{ A1:{ A2:{ class method This1.B () } B:{ } }}","A1.A2","This0", "{ A1:{B:{ }} class method This0.A1.B () }" ,false// }, {lineNumber(),// "{ A:{ D:{ class method This0 d() This0.d() } class method This1.B foo()This0.foo() } B:{ }}" , "A","This0", "{ B:{ } D:{ class method This0 d() This0.d() } class method This0.B foo()This0.foo() }" ,false// }, {lineNumber(),// helpers.TestHelper.multiLine("" ,"{ A:{" ," OptMax:{" ," TOpt:{interface}" ," TEmpty:{ implements This1.TOpt}" ," }" ," }}"), "A","This0", helpers.TestHelper.multiLine("" ,"{" ,"OptMax:{" ," TOpt:{interface }" ," TEmpty:{ implements This1.TOpt}" ,"}}") ,false// }, {lineNumber(),// "{ A:{class method This1.B ()} B:{ }}", "A","A.C", "{ B:{} A:{ C:{class method This2.B #apply() }}}" ,false// }, {lineNumber(),// "{ A:{class method This0.B () B:{ }}}" ,"A","A.C", "{ A:{ C:{class method This0.B #apply() B:{} }}}",false// },{lineNumber(),////the sub parts of test above "{ Result:{ A:{ class method This0.B #apply() B:{}}}}", "Result.A","Tmp", "{Result:{} Tmp:{ class method This0.B #apply() B:{}}}",false /* "{ Result:{} Tmp:{ class method This2.Tmp #apply() B:{}}} "Tmp","Result.A.C",false*/ }, {lineNumber(),// "{ class method This0.B () B:{ }}" ,"This0","C", "{ C:{ class method This0.B #apply() B:{}}}",false// }, {lineNumber(),// "{ A:{B:{ method A m(B x)}} }" ,"A.B","C.B", "{ A:{ } C:{B:{ method A m(This0 x)}} }",false// }, {lineNumber(),// "{ A:{B:{ } method Void ma(B x)} }" ,"A.B","C.D", "{ A:{method Void ma(This1.C.D x)} C:{D:{ }}}",false// }, {lineNumber(),// "{ A:{B:{ method A mab(B x)} method A ma(B x)} method A m(A.B x) }" ,"A.B","C.D", "{ A:{method This0 ma(This1.C.D x)} method A m(C.D x) C:{D:{ method This2.A mab(This0 x)}}}",false// }, {lineNumber(),// "{ A:{B:{ method A mab(B x)} method A ma(B x)} method A m(A.B x) }" ,"A","C.D", "{ method C.D m(C.D.B x) C:{D:{B:{ method This1 mab(This0 x)} method This0 ma(B x)}} }",false// }, {lineNumber(),//simplified method from before "{ A:{B:{}} method Void m(A.B x) }" ,"A","C.D", "{ method Void m(C.D.B x) C:{D:{B:{}}} }",false// }, {lineNumber(),//simplified method from before2 "{ A:{B:{}} method A m() }" ,"A","C.D", "{ method C.D m() C:{D:{B:{}}} }",false// }, {lineNumber(),//nested method from before "{ A:{B:{method A m()}} }" ,"A","C.D", "{ C:{D:{B:{method This1 m() }}} }",false// }, {lineNumber(),// "{ A:{method Library m() {method A k()}} }" ,"A","B", "{ B:{method Library m() {method This1 k()}} }",false// } }); } @Test public void test() { TestHelper.configureForTest(); ClassB cb1 = getClassB(_cb1); List<Ast.C> path1=TestHelper.cs(_path1); List<Ast.C> path2=TestHelper.cs(_path2); ClassB expected = getClassB(_expected); if (!isError) { ClassB res = Rename.renameClass(Program.emptyLibraryProgram(), cb1, path1, path2); TestHelper.assertEqualExp(expected, res); } else { try { Rename.renameClass(Program.emptyLibraryProgram(), cb1, path1, path2); fail("error expected"); } catch (Resources.Error err) { ClassB res = (ClassB) err.unbox; TestHelper.assertEqualExp(expected, res); } } } } }