diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag index 20f11a528618c0e3a4b3f04b83fd4497e9c02694..c25ccdc6c9f36568ccf451af47c87157bdaed30e 100644 --- a/src/main/jastadd/Analysis.jrag +++ b/src/main/jastadd/Analysis.jrag @@ -131,6 +131,10 @@ aspect Constructors { } aspect Utils { + + syn boolean RelationComponent.isMany() = false; + eq ManyRelationComponent.isMany() = true; + public String SimpleTypeUse.toString() { return getID(); } diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd index 59d8c53c1a0601580a234df1e94a46f66514c934..2a43b1154f180a0f277b3de06629de3e14cb4fb1 100644 --- a/src/main/jastadd/Backend.jadd +++ b/src/main/jastadd/Backend.jadd @@ -594,6 +594,18 @@ aspect NameResolutionHelper { sb.append("}\n\n"); + sb.append("aspect ResolverTrigger {\n\n"); + + resolveAll(sb); + + for (TypeDecl decl : getTypeDeclList()) { + if (!decl.isUnresolved()) { + decl.resolveAll(sb); + } + } + + sb.append("}\n\n"); + sb.append("aspect RefResolverHelpers {\n\n"); sb.append(ind(1) + "syn boolean ASTNode.unresolved() = false;\n"); @@ -679,6 +691,35 @@ aspect NameResolutionHelper { sb.append(ind(2) + "return resolve" + ofTypeDecl() + "(id);\n"); sb.append(ind(1) + "}\n"); } + + public void Program.resolveAll(StringBuilder sb) { + sb.append(ind(1) + "// enforce resolving of all non-containment relations of the current non-terminal\n"); + sb.append(ind(1) + "public void ASTNode.resolveAll() {\n"); + sb.append(ind(1) + "}\n\n"); + + sb.append(ind(1) + "// enforce resolving in the entire subtree\n"); + sb.append(ind(1) + "public void ASTNode.treeResolveAll() {\n"); + sb.append(ind(2) + "if (children != null) {\n"); + sb.append(ind(3) + "for (int i = 0; i < children.length; ++i) {\n"); + sb.append(ind(4) + "ASTNode child = children[i];\n"); + sb.append(ind(4) + "if (child != null) {\n"); + sb.append(ind(5) + "child.treeResolveAll();\n"); + sb.append(ind(4) + "}\n"); + sb.append(ind(3) + "}\n"); + sb.append(ind(2) + "}\n"); + sb.append(ind(2) + "resolveAll();\n"); + sb.append(ind(1) + "}\n"); + } + + public void TypeDecl.resolveAll(StringBuilder sb) { + sb.append(ind(1) + "// enforce resolving of all non-containment relations of the current non-terminal\n"); + sb.append(ind(1) + "public void " + getID() + ".resolveAll() {\n"); + for (RelationComponent relationComponent : relationComponents()) { + sb.append(ind(2) + "get" + relationComponent.nameCapitalized() + (relationComponent.isMany()?"List":"") + "();\n"); + } + sb.append(ind(2) + "super.resolveAll();\n"); + sb.append(ind(1) + "}\n"); + } } aspect PrettyPrint { diff --git a/src/test/java/org/jastadd/relast/tests/ResolveAll.java b/src/test/java/org/jastadd/relast/tests/ResolveAll.java new file mode 100644 index 0000000000000000000000000000000000000000..3332f88c5ae919624486174b1c0e388ed0ab62f0 --- /dev/null +++ b/src/test/java/org/jastadd/relast/tests/ResolveAll.java @@ -0,0 +1,691 @@ +package org.jastadd.relast.tests; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import resolver.ast.A; +import resolver.ast.B; +import resolver.ast.Root; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; + +import static org.jastadd.relast.tests.TestHelpers.readFile; +import static org.junit.jupiter.api.Assertions.*; + +@SuppressWarnings("ArraysAsListWithZeroOrOneArgument") +class ResolveAll { + private Root r; + private A a1; + private A a2; + private A a3; + private B b1; + private B b2; + private B b3; + + + @Test + void doubleRelastRun() throws IOException { + + String firstRun = "./src/test/jastadd/relations/Relations.ast"; + String secondRun = "./src/test/jastadd/relations/Relations2.ast"; + + + String first = readFile(firstRun, Charset.defaultCharset()); + String second = readFile(secondRun, Charset.defaultCharset()); + + Assertions.assertEquals(first, second); + } + + /** + * rel A.Di1 -> B; + */ + @Test + void testDi1() { + setup(); + a1.setDi1(B.createRef("b2")); + a2.setDi1(B.createRef("b1")); + a1.resolveAll(); + a2.resolveAll(); + + assertSame(a1.getDi1(), b2); + assertSame(a2.getDi1(), b1); + + a2.setDi1(B.createRef("b2")); + a2.resolveAll(); + + assertSame(a1.getDi1(), b2); + assertSame(a2.getDi1(), b2); + + try { + a3.setDi1(null); + fail("should throw an exception"); + } catch (Exception e) { + // OK + } + } + + + /** + * rel A.Di2? -> B; + */ + @Test + void testDi2() { + setup(); + a1.setDi2(B.createRef("b2")); + a2.setDi2(B.createRef("b1")); + a1.resolveAll(); + a2.resolveAll(); + + assertSame(a1.getDi2(), b2); + assertSame(a2.getDi2(), b1); + + a2.setDi2(B.createRef("b2")); + a2.resolveAll(); + + assertSame(a1.getDi2(), b2); + assertSame(a2.getDi2(), b2); + + a2.clearDi2(); + + assertSame(a1.getDi2(), b2); + assertNull(a2.getDi2()); + + assertTrue(a1.hasDi2()); + assertFalse(a2.hasDi2()); + assertFalse(a3.hasDi2()); + } + + + /** + * rel A.Di3* -> B; + */ + @Test + void testDi3() { + setup(); + a1.addDi3(B.createRef("b1")); + a1.addDi3(B.createRef("b2")); + a1.addDi3(B.createRef("b3")); + a2.addDi3(B.createRef("b2")); + a1.resolveAll(); + a2.resolveAll(); + + + assertEquals(a1.getDi3s(), Arrays.asList(b1, b2, b3)); + assertEquals(a1.getDi3List(), Arrays.asList(b1, b2, b3)); + assertEquals(a2.getDi3s(), Arrays.asList(b2)); + assertEquals(a2.getDi3List(), Arrays.asList(b2)); + assertEquals(a3.getDi3s(), Arrays.asList()); + assertEquals(a3.getDi3List(), Arrays.asList()); + + a1.addDi3(B.createRef("b1")); + a2.addDi3(B.createRef("b1")); + a2.addDi3(B.createRef("b2")); + a1.resolveAll(); + a2.resolveAll(); + + assertEquals(a1.getDi3s(), Arrays.asList(b1, b2, b3, b1)); + assertEquals(a1.getDi3List(), Arrays.asList(b1, b2, b3, b1)); + assertEquals(a2.getDi3s(), Arrays.asList(b2, b1, b2)); + assertEquals(a2.getDi3List(), Arrays.asList(b2, b1, b2)); + assertEquals(a3.getDi3s(), Arrays.asList()); + assertEquals(a3.getDi3List(), Arrays.asList()); + + a1.removeDi3(b1); + a2.removeDi3(b2); + a1.resolveAll(); + a2.resolveAll(); + + assertEquals(a1.getDi3s(), Arrays.asList(b2, b3, b1)); + assertEquals(a1.getDi3List(), Arrays.asList(b2, b3, b1)); + assertEquals(a2.getDi3s(), Arrays.asList(b1, b2)); + assertEquals(a2.getDi3List(), Arrays.asList(b1, b2)); + assertEquals(a3.getDi3s(), Arrays.asList()); + assertEquals(a3.getDi3List(), Arrays.asList()); + } + + + /** + * rel A.Bi1 <-> B.Bi1; + */ + + + @Test + void testBi11() { + // Init + setup(); + a1.setBi1(B.createRef("b1")); + a2.setBi1(B.createRef("b2")); + a1.resolveAll(); + a2.resolveAll(); + + // Change + a2.setBi1(B.createRef("b1")); + a2.resolveAll(); + + assertNull(a1.getBi1()); + assertSame(a2.getBi1(), b1); + assertSame(b1.getBi1(), a2); + assertNull(b2.getBi1()); + } + + @Test + void testBi12() { + // Init + setup(); + a1.setBi1(B.createRef("b2")); + a1.resolveAll(); + + // Change + a2.setBi1(B.createRef("b2")); + a2.resolveAll(); + + assertNull(a1.getBi1()); + assertSame(a2.getBi1(), b2); + assertNull(b1.getBi1()); + assertSame(b2.getBi1(), a2); + } + + + /** + * rel A.Bi2 <-> B.Bi2?; + */ + + @Test + void testBi21() { + // Init + setup(); + a1.setBi2(B.createRef("b1")); + a2.setBi2(B.createRef("b2")); + a1.resolveAll(); + a2.resolveAll(); + + // Change + a2.setBi2(B.createRef("b1")); + a2.resolveAll(); + + assertNull(a1.getBi2()); + assertSame(a2.getBi2(), b1); + assertSame(b1.getBi2(), a2); + assertNull(b2.getBi2()); + } + + @Test + void testBi22() { + // Init + setup(); + a1.setBi2(B.createRef("b2")); + a1.resolveAll(); + + // Change + a2.setBi2(B.createRef("b2")); + a2.resolveAll(); + + assertNull(a1.getBi2()); + assertSame(a2.getBi2(), b2); + assertNull(b1.getBi2()); + assertSame(b2.getBi2(), a2); + } + + + /** + * rel A.Bi3 <-> B.Bi3*; + */ + @Test + void testBi3() { + setup(); + a2.setBi3(B.createRef("b2")); + a2.resolveAll(); + + assertNull(a1.getBi3()); + assertSame(a2.getBi3(), b2); + assertEquals(b1.getBi3s(), Arrays.asList()); + assertEquals(b1.getBi3List(), Arrays.asList()); + assertEquals(b2.getBi3s(), Arrays.asList(a2)); + assertEquals(b2.getBi3List(), Arrays.asList(a2)); + assertEquals(b3.getBi3s(), Arrays.asList()); + assertEquals(b3.getBi3List(), Arrays.asList()); + + a2.setBi3(B.createRef("b3")); + a2.resolveAll(); + + assertNull(a1.getBi3()); + assertSame(a2.getBi3(), b3); + assertEquals(b1.getBi3s(), Arrays.asList()); + assertEquals(b1.getBi3List(), Arrays.asList()); + assertEquals(b2.getBi3s(), Arrays.asList()); + assertEquals(b2.getBi3List(), Arrays.asList()); + assertEquals(b3.getBi3s(), Arrays.asList(a2)); + assertEquals(b3.getBi3List(), Arrays.asList(a2)); + + a1.setBi3(B.createRef("b3")); + a3.setBi3(B.createRef("b3")); + a1.resolveAll(); + a2.resolveAll(); + + assertSame(a1.getBi3(), b3); + assertSame(a2.getBi3(), b3); + assertSame(a3.getBi3(), b3); + assertEquals(b1.getBi3s(), Arrays.asList()); + assertEquals(b1.getBi3List(), Arrays.asList()); + assertEquals(b2.getBi3s(), Arrays.asList()); + assertEquals(b2.getBi3List(), Arrays.asList()); + assertEquals(b3.getBi3s(), Arrays.asList(a2, a1, a3)); + assertEquals(b3.getBi3List(), Arrays.asList(a2, a1, a3)); + + a2.setBi3(B.createRef("b1")); + a2.resolveAll(); + + assertSame(a1.getBi3(), b3); + assertSame(a2.getBi3(), b1); + assertSame(a3.getBi3(), b3); + assertEquals(b1.getBi3s(), Arrays.asList(a2)); + assertEquals(b1.getBi3List(), Arrays.asList(a2)); + assertEquals(b2.getBi3s(), Arrays.asList()); + assertEquals(b2.getBi3List(), Arrays.asList()); + assertEquals(b3.getBi3s(), Arrays.asList(a1, a3)); + assertEquals(b3.getBi3List(), Arrays.asList(a1, a3)); + + try { + a2.setBi3(null); + fail("should throw an exception"); + } catch (Exception e) { + // OK + } + } + + + /** + * rel A.Bi4? <-> B.Bi4; + */ + @Test + void testBi41() { + // Init + setup(); + a1.setBi4(B.createRef("b1")); + a2.setBi4(B.createRef("b2")); + a1.resolveAll(); + a2.resolveAll(); + + // Change + a2.setBi4(B.createRef("b1")); + a2.resolveAll(); + + assertNull(a1.getBi4()); + assertSame(a2.getBi4(), b1); + assertSame(b1.getBi4(), a2); + assertNull(b2.getBi4()); + } + + @Test + void testBi42() { + // Init + setup(); + a1.setBi4(B.createRef("b2")); + a1.resolveAll(); + + // Change + a2.setBi4(B.createRef("b2")); + a2.resolveAll(); + + assertNull(a1.getBi4()); + assertSame(a2.getBi4(), b2); + assertNull(b1.getBi4()); + assertSame(b2.getBi4(), a2); + } + + + /** + * rel A.Bi5? <-> B.Bi5?; + */ + @Test + void testBi51() { + // Init + setup(); + a1.setBi5(B.createRef("b1")); + a2.setBi5(B.createRef("b2")); + a1.resolveAll(); + a2.resolveAll(); + + // Change + a2.setBi5(B.createRef("b1")); + a2.resolveAll(); + + assertNull(a1.getBi5()); + assertSame(a2.getBi5(), b1); + assertSame(b1.getBi5(), a2); + assertNull(b2.getBi5()); + } + + @Test + void testBi52() { + // Init + setup(); + a1.setBi5(B.createRef("b2")); + a1.resolveAll(); + + // Change + a2.setBi5(B.createRef("b2")); + a2.resolveAll(); + + assertNull(a1.getBi5()); + assertSame(a2.getBi5(), b2); + assertNull(b1.getBi5()); + assertSame(b2.getBi5(), a2); + } + + + /** + * rel A.Bi6? <-> B.Bi6*; + */ + @Test + void testBi6() { + setup(); + a2.setBi6(B.createRef("b2")); + a2.resolveAll(); + + assertNull(a1.getBi6()); + assertSame(a2.getBi6(), b2); + assertEquals(b1.getBi6s(), Arrays.asList()); + assertEquals(b1.getBi6List(), Arrays.asList()); + assertEquals(b2.getBi6s(), Arrays.asList(a2)); + assertEquals(b2.getBi6List(), Arrays.asList(a2)); + assertEquals(b3.getBi6s(), Arrays.asList()); + assertEquals(b3.getBi6List(), Arrays.asList()); + + a2.setBi6(B.createRef("b3")); + a2.resolveAll(); + + assertNull(a1.getBi6()); + assertSame(a2.getBi6(), b3); + assertEquals(b1.getBi6s(), Arrays.asList()); + assertEquals(b1.getBi6List(), Arrays.asList()); + assertEquals(b2.getBi6s(), Arrays.asList()); + assertEquals(b2.getBi6List(), Arrays.asList()); + assertEquals(b3.getBi6s(), Arrays.asList(a2)); + assertEquals(b3.getBi6List(), Arrays.asList(a2)); + + a1.setBi6(B.createRef("b3")); + a3.setBi6(B.createRef("b3")); + a1.resolveAll(); + a2.resolveAll(); + + assertSame(a1.getBi6(), b3); + assertSame(a2.getBi6(), b3); + assertSame(a3.getBi6(), b3); + assertEquals(b1.getBi6s(), Arrays.asList()); + assertEquals(b1.getBi6List(), Arrays.asList()); + assertEquals(b2.getBi6s(), Arrays.asList()); + assertEquals(b2.getBi6List(), Arrays.asList()); + assertEquals(b3.getBi6s(), Arrays.asList(a2, a1, a3)); + assertEquals(b3.getBi6List(), Arrays.asList(a2, a1, a3)); + + a2.setBi6(B.createRef("b1")); + a2.resolveAll(); + + assertSame(a1.getBi6(), b3); + assertSame(a2.getBi6(), b1); + assertSame(a3.getBi6(), b3); + assertEquals(b1.getBi6s(), Arrays.asList(a2)); + assertEquals(b1.getBi6List(), Arrays.asList(a2)); + assertEquals(b2.getBi6s(), Arrays.asList()); + assertEquals(b2.getBi6List(), Arrays.asList()); + assertEquals(b3.getBi6s(), Arrays.asList(a1, a3)); + assertEquals(b3.getBi6List(), Arrays.asList(a1, a3)); + + a2.clearBi6(); + + assertSame(a1.getBi6(), b3); + assertNull(a2.getBi6()); + assertSame(a3.getBi6(), b3); + assertEquals(b1.getBi6s(), Arrays.asList()); + assertEquals(b1.getBi6List(), Arrays.asList()); + assertEquals(b2.getBi6s(), Arrays.asList()); + assertEquals(b2.getBi6List(), Arrays.asList()); + assertEquals(b3.getBi6s(), Arrays.asList(a1, a3)); + assertEquals(b3.getBi6List(), Arrays.asList(a1, a3)); + + assertTrue(a1.hasBi6()); + assertFalse(a2.hasBi6()); + assertTrue(a3.hasBi6()); + } + + + /** + * rel A.Bi7* <-> B.Bi7; + */ + @Test + void testBi7() { + setup(); + a2.addBi7(B.createRef("b2")); + a2.resolveAll(); + + assertEquals(a1.getBi7s(), Arrays.asList()); + assertEquals(a1.getBi7List(), Arrays.asList()); + assertEquals(a2.getBi7s(), Arrays.asList(b2)); + assertEquals(a2.getBi7List(), Arrays.asList(b2)); + assertNull(b1.getBi7()); + assertSame(b2.getBi7(), a2); + assertNull(b3.getBi7()); + + a2.addBi7(B.createRef("b3")); + a1.addBi7(B.createRef("b2")); + a2.resolveAll(); + a1.resolveAll(); + + assertEquals(a1.getBi7s(), Arrays.asList(b2)); + assertEquals(a1.getBi7List(), Arrays.asList(b2)); + assertEquals(a2.getBi7s(), Arrays.asList(b3)); + assertEquals(a2.getBi7List(), Arrays.asList(b3)); + assertNull(b1.getBi7()); + assertSame(b2.getBi7(), a1); + assertSame(b3.getBi7(), a2); + + a1.addBi7(B.createRef("b1")); + a1.resolveAll(); + + assertEquals(a1.getBi7s(), Arrays.asList(b2, b1)); + assertEquals(a1.getBi7List(), Arrays.asList(b2, b1)); + assertEquals(a2.getBi7s(), Arrays.asList(b3)); + assertEquals(a2.getBi7List(), Arrays.asList(b3)); + assertSame(b1.getBi7(), a1); + assertSame(b2.getBi7(), a1); + assertSame(b3.getBi7(), a2); + + a1.addBi7(B.createRef("b1")); + a1.resolveAll(); + + assertEquals(a1.getBi7s(), Arrays.asList(b2, b1)); + assertEquals(a1.getBi7List(), Arrays.asList(b2, b1)); + assertEquals(a2.getBi7s(), Arrays.asList(b3)); + assertEquals(a2.getBi7List(), Arrays.asList(b3)); + assertSame(b1.getBi7(), a1); + assertSame(b2.getBi7(), a1); + assertSame(b3.getBi7(), a2); + + a1.removeBi7(b1); + + assertEquals(a1.getBi7s(), Arrays.asList(b2)); + assertEquals(a1.getBi7List(), Arrays.asList(b2)); + assertEquals(a2.getBi7s(), Arrays.asList(b3)); + assertEquals(a2.getBi7List(), Arrays.asList(b3)); + assertNull(b1.getBi7()); + assertSame(b2.getBi7(), a1); + assertSame(b3.getBi7(), a2); + } + + + /** + * rel A.Bi8* <-> B.Bi8?; + */ + @Test + void testBi8() { + setup(); + a2.addBi8(B.createRef("b2")); + a2.resolveAll(); + + assertEquals(a1.getBi8s(), Arrays.asList()); + assertEquals(a1.getBi8List(), Arrays.asList()); + assertEquals(a2.getBi8s(), Arrays.asList(b2)); + assertEquals(a2.getBi8List(), Arrays.asList(b2)); + assertNull(b1.getBi8()); + assertSame(b2.getBi8(), a2); + assertNull(b3.getBi8()); + + a2.addBi8(B.createRef("b3")); + a1.addBi8(B.createRef("b2")); + a2.resolveAll(); + a1.resolveAll(); + + assertEquals(a1.getBi8s(), Arrays.asList(b2)); + assertEquals(a1.getBi8List(), Arrays.asList(b2)); + assertEquals(a2.getBi8s(), Arrays.asList(b3)); + assertEquals(a2.getBi8List(), Arrays.asList(b3)); + assertNull(b1.getBi8()); + assertSame(b2.getBi8(), a1); + assertSame(b3.getBi8(), a2); + + a1.addBi8(B.createRef("b1")); + a1.resolveAll(); + + assertEquals(a1.getBi8s(), Arrays.asList(b2, b1)); + assertEquals(a1.getBi8List(), Arrays.asList(b2, b1)); + assertEquals(a2.getBi8s(), Arrays.asList(b3)); + assertEquals(a2.getBi8List(), Arrays.asList(b3)); + assertSame(b1.getBi8(), a1); + assertSame(b2.getBi8(), a1); + assertSame(b3.getBi8(), a2); + + a1.addBi8(B.createRef("b1")); + a1.resolveAll(); + + assertEquals(a1.getBi8s(), Arrays.asList(b2, b1)); + assertEquals(a1.getBi8List(), Arrays.asList(b2, b1)); + assertEquals(a2.getBi8s(), Arrays.asList(b3)); + assertEquals(a2.getBi8List(), Arrays.asList(b3)); + assertSame(b1.getBi8(), a1); + assertSame(b2.getBi8(), a1); + assertSame(b3.getBi8(), a2); + + a1.removeBi8(b1); + + assertEquals(a1.getBi8s(), Arrays.asList(b2)); + assertEquals(a1.getBi8List(), Arrays.asList(b2)); + assertEquals(a2.getBi8s(), Arrays.asList(b3)); + assertEquals(a2.getBi8List(), Arrays.asList(b3)); + assertNull(b1.getBi8()); + assertSame(b2.getBi8(), a1); + assertSame(b3.getBi8(), a2); + } + + + /** + * rel A.Bi9* <-> B.Bi9*; + */ + @Test + void testBi9() { + setup(); + a1.addBi9(B.createRef("b1")); + a1.addBi9(B.createRef("b2")); + a1.resolveAll(); + + assertEquals(a1.getBi9s(), Arrays.asList(b1, b2)); + assertEquals(a1.getBi9List(), Arrays.asList(b1, b2)); + assertEquals(a2.getBi9s(), Arrays.asList()); + assertEquals(a2.getBi9List(), Arrays.asList()); + assertEquals(a3.getBi9s(), Arrays.asList()); + assertEquals(a3.getBi9List(), Arrays.asList()); + assertEquals(b1.getBi9s(), Arrays.asList(a1)); + assertEquals(b1.getBi9List(), Arrays.asList(a1)); + assertEquals(b2.getBi9s(), Arrays.asList(a1)); + assertEquals(b2.getBi9List(), Arrays.asList(a1)); + assertEquals(b3.getBi9s(), Arrays.asList()); + assertEquals(b3.getBi9List(), Arrays.asList()); + + b3.addBi9(A.createRef("a1")); + b3.addBi9(A.createRef("a3")); + b3.addBi9(A.createRef("a1")); + b3.resolveAll(); + + assertEquals(a1.getBi9s(), Arrays.asList(b1, b2, b3, b3)); + assertEquals(a1.getBi9List(), Arrays.asList(b1, b2, b3, b3)); + assertEquals(a2.getBi9s(), Arrays.asList()); + assertEquals(a2.getBi9List(), Arrays.asList()); + assertEquals(a3.getBi9s(), Arrays.asList(b3)); + assertEquals(a3.getBi9List(), Arrays.asList(b3)); + assertEquals(b1.getBi9s(), Arrays.asList(a1)); + assertEquals(b1.getBi9List(), Arrays.asList(a1)); + assertEquals(b2.getBi9s(), Arrays.asList(a1)); + assertEquals(b2.getBi9List(), Arrays.asList(a1)); + assertEquals(b3.getBi9s(), Arrays.asList(a1, a3, a1)); + assertEquals(b3.getBi9List(), Arrays.asList(a1, a3, a1)); + + b3.removeBi9(a1); + + assertEquals(a1.getBi9s(), Arrays.asList(b1, b2, b3)); + assertEquals(a1.getBi9List(), Arrays.asList(b1, b2, b3)); + assertEquals(a2.getBi9s(), Arrays.asList()); + assertEquals(a2.getBi9List(), Arrays.asList()); + assertEquals(a3.getBi9s(), Arrays.asList(b3)); + assertEquals(a3.getBi9List(), Arrays.asList(b3)); + assertEquals(b1.getBi9s(), Arrays.asList(a1)); + assertEquals(b1.getBi9List(), Arrays.asList(a1)); + assertEquals(b2.getBi9s(), Arrays.asList(a1)); + assertEquals(b2.getBi9List(), Arrays.asList(a1)); + assertEquals(b3.getBi9s(), Arrays.asList(a3, a1)); + assertEquals(b3.getBi9List(), Arrays.asList(a3, a1)); + } + + + @Test + void testImmutableList() { + setup(); + + a1.addDi3(b1); + a1.addDi3(b2); + try { + a1.getDi3s().add(b3); + fail("should throw an exception"); + } catch (Exception e) { + // OK + } + + a1.addBi7(b1); + a1.addBi7(b2); + try { + a1.getBi7s().add(b3); + fail("should throw an exception"); + } catch (Exception e) { + // OK + } + + a1.addBi9(b1); + a1.addBi9(b2); + try { + a1.getBi9s().add(b3); + fail("should throw an exception"); + } catch (Exception e) { + // OK + } + } + + @BeforeEach + void setup() { + r = new Root(); + a1 = new A("a1"); + a2 = new A("a2"); + a3 = new A("a3"); + b1 = new B("b1"); + b2 = new B("b2"); + b3 = new B("b3"); + + r.addA(a1); + r.addA(a2); + r.addA(a3); + r.addB(b1); + r.addB(b2); + r.addB(b3); + } + +}