/** * Copyright (c) 2009-2011, The HATS Consortium. All rights reserved. * This file is licensed under the terms of the Modified BSD License. */ package abs.frontend.delta; import java.util.ArrayList; import java.util.Arrays; import org.junit.Test; import static org.junit.Assert.*; import abs.frontend.ast.*; /* test: * 1. add/remove implemented interfaces of a class * 2. add/remove/modify interface declarations */ public class AddRemoveInterfacesTest extends DeltaTest { @Test public void addIfaceDecl() throws DeltaModellingException { final ArrayList<String> codeVariants = new ArrayList<String>(Arrays.asList( "module M;" + "interface I { Int fooi(); }" + "delta D;" +"uses M;" + "adds interface J { Int fooj(); }" , "module M;" + "interface I { Int fooi(); }" + "delta D;" +"uses M;" + "adds interface J extends I { Int fooj(); }" , "module M;" + "interface I { Int fooi(); }" + "delta D;" +"uses M;" + "adds interface J extends I { Int fooj(); }" , "module M;" + "interface I { Int fooi(); }" + "delta D; uses M;" + "adds interface J { Int fooj(); }" , "module M;" + "interface I { Int fooi(); }" + "delta D; uses M;" + "adds interface J extends I { Int fooj(); }" )); // both qualified and unqualified interface names should yield the same result for (String code : codeVariants) { Model model = assertParseOk(code); InterfaceDecl ifaceI = (InterfaceDecl) findDecl(model, "M", "I"); assertNotNull(ifaceI); DeltaDecl delta = findDelta(model, "D"); assertNotNull(delta); InterfaceDecl ifaceJ = (InterfaceDecl) findDecl(model, "M", "J"); assertNull(ifaceJ); model.applyDelta(delta); ifaceJ = (InterfaceDecl) findDecl(model, "M", "J"); assertNotNull(ifaceJ); } } @Test public void removeIfaceDecl() throws DeltaModellingException { final ArrayList<String> codeVariants = new ArrayList<String>(Arrays.asList( "module M;" + "interface I { Int fooi(); }" + "delta D;" + "removes interface M.I;" , "module M;" + "interface I { Int fooi(); }" + "delta D; uses M;" + "removes interface I;" )); // both qualified and unqualified interface names should yield the same result for (String code : codeVariants) { Model model = assertParseOk(code); InterfaceDecl iface = (InterfaceDecl) findDecl(model, "M", "I"); assertNotNull(iface); DeltaDecl delta = findDelta(model, "D"); assertNotNull(delta); ModuleDecl m = iface.getModuleDecl(); assertEquals(1, m.getDecls().getNumChild()); model.applyDelta(delta); assertEquals(0, m.getDecls().getNumChild()); } } @Test public void modifyIfaceDeclAddMethodSig() throws DeltaModellingException { final ArrayList<String> codeVariants = new ArrayList<String>(Arrays.asList( "module M;" + "interface I { Int a(); }" + "delta D;" + "modifies interface M.I { adds Unit b(); }" , "module M;" + "interface I { Int a(); }" + "delta D; uses M;" + "modifies interface I { adds Unit b(); }" )); for (String code : codeVariants) { Model model = assertParseOk(code); InterfaceDecl iface = (InterfaceDecl) findDecl(model, "M", "I"); assertEquals(1, iface.getBodys().getNumChild()); assertEquals("a", iface.getBody(0).getName()); DeltaDecl delta = findDelta(model, "D"); model.applyDelta(delta); assertEquals(2, iface.getBodys().getNumChild()); assertEquals("a", iface.getBody(0).getName()); assertEquals("b", iface.getBody(1).getName()); } } @Test public void modifyIfaceDeclRemoveMethodSig() throws DeltaModellingException { final ArrayList<String> codeVariants = new ArrayList<String>(Arrays.asList( "module M;" + "interface I { Int a(); Unit b(); }" + "delta D;" + "modifies interface M.I { removes Int a(); }" , "module M;" + "interface I { Int a(); Unit b(); }" + "delta D; uses M;" + "modifies interface I { removes Int a(); }" )); for (String code : codeVariants) { Model model = assertParseOk(code); InterfaceDecl iface = (InterfaceDecl) findDecl(model, "M", "I"); assertEquals(2, iface.getBodys().getNumChild()); assertEquals("a", iface.getBody(0).getName()); assertEquals("b", iface.getBody(1).getName()); DeltaDecl delta = findDelta(model, "D"); model.applyDelta(delta); assertEquals(1, iface.getBodys().getNumChild()); assertEquals("b", iface.getBody(0).getName()); } } @Test public void addImplements() throws DeltaModellingException { Model model = assertParseOk( "module M;" + "interface I {}" + "class C implements I {}" + "delta D;" +"uses M;" + "adds interface J { Int foo(); }" + "modifies class C adds J { adds Int foo() { return 99; } }" ); ClassDecl cls = (ClassDecl) findDecl(model, "M", "C"); DeltaDecl delta = findDelta(model, "D"); assertEquals(1, cls.getImplementedInterfaceUses().getNumChild()); assertEquals("I", cls.getImplementedInterfaceUse(0).getName()); model.applyDelta(delta); // make sure the class now also implements interface J assertEquals(2, cls.getImplementedInterfaceUses().getNumChild()); assertEquals("I", cls.getImplementedInterfaceUse(0).getName()); assertEquals("J", cls.getImplementedInterfaceUse(1).getName()); } @Test public void removeImplements() throws DeltaModellingException { Model model = assertParseOk( "module M;" + "interface I {}" + "class C implements I {}" + "delta D;" + "modifies class M.C removes I {}" ); ClassDecl cls = (ClassDecl) findDecl(model, "M", "C"); DeltaDecl delta = findDelta(model, "D"); assertEquals(1, cls.getImplementedInterfaceUses().getNumChild()); assertEquals("I", cls.getImplementedInterfaceUse(0).getName()); model.applyDelta(delta); assertEquals(0, cls.getImplementedInterfaceUses().getNumChild()); } @Test public void removeImplementsNotFound() throws DeltaModellingException { Model model = assertParseOk( "module M;" + "interface I {}" + "class C implements I {}" + "delta D;" + "modifies class M.C removes K {}" ); ClassDecl cls = (ClassDecl) findDecl(model, "M", "C"); DeltaDecl delta = findDelta(model, "D"); assertEquals(1, cls.getImplementedInterfaceUses().getNumChild()); assertEquals("I", cls.getImplementedInterfaceUse(0).getName()); try { model.applyDelta(delta); } catch (DeltaModellingException e) { return; // this is the expected outcome } fail("Expected DeltaModellingException"); } @Test public void addRemoveImplements() throws DeltaModellingException { Model model = assertParseOk( "module M;" + "interface I {}" + "class C implements I {}" + "delta D;" +"uses M;" + "adds interface J {}" + "modifies class C adds J removes I {}" ); ClassDecl cls = (ClassDecl) findDecl(model, "M", "C"); DeltaDecl delta = findDelta(model, "D"); assertEquals(1, cls.getImplementedInterfaceUses().getNumChild()); assertEquals("I", cls.getImplementedInterfaceUse(0).getName()); model.applyDelta(delta); assertEquals(1, cls.getImplementedInterfaceUses().getNumChild()); assertEquals("J", cls.getImplementedInterfaceUse(0).getName()); } @Test public void addRemove2Implements() throws DeltaModellingException { Model model = assertParseOk( "module M;" + "interface H {}" + "interface I {}" + "class C implements H,I {}" + "delta D;" +"uses M;" + "adds interface J {}" + "adds interface K {}" + "modifies class C adds J,K removes H,I {}" ); ClassDecl cls = (ClassDecl) findDecl(model, "M", "C"); DeltaDecl delta = findDelta(model, "D"); assertEquals(2, cls.getImplementedInterfaceUses().getNumChild()); assertEquals("H", cls.getImplementedInterfaceUse(0).getName()); assertEquals("I", cls.getImplementedInterfaceUse(1).getName()); model.applyDelta(delta); assertEquals(2, cls.getImplementedInterfaceUses().getNumChild()); assertEquals("J", cls.getImplementedInterfaceUse(0).getName()); assertEquals("K", cls.getImplementedInterfaceUse(1).getName()); } }