/******************************************************************************* * Copyright 2015 Analog Devices, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ********************************************************************************/ package com.analog.lyric.dimple.test.model.variables; import static com.analog.lyric.dimple.model.sugar.ModelSyntacticSugar.*; import static com.analog.lyric.util.test.ExceptionTester.*; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import org.junit.Test; import com.analog.lyric.dimple.model.core.FactorGraph; import com.analog.lyric.dimple.model.core.Ids; import com.analog.lyric.dimple.model.sugar.ModelSyntacticSugar.CurrentModel; import com.analog.lyric.dimple.model.variables.Real; import com.analog.lyric.dimple.model.variables.Variable; import com.analog.lyric.dimple.model.variables.VariableBlock; import com.analog.lyric.dimple.test.DimpleTestBase; /** * * @since 0.08 * @author Christopher Barber */ public class TestVariableBlock extends DimpleTestBase { @Test public void test() { FactorGraph root = new FactorGraph("root"); try (CurrentModel cur = using(root)) { Variable v1 = real("v1"); Variable v2 = real("v2"); VariableBlock block1 = root.addVariableBlock(v1, v2); assertBlock(block1, v1, v2); assertEquals(block1, block1); assertNotEquals(block1, "foo"); assertEquals(root, block1.getParentGraph()); VariableBlock block1a = root.addVariableBlock(v1, v2); assertSame(block1, block1a); // Blocks are only the same if the variable order is the same VariableBlock block2 = root.addVariableBlock(v2, v1); assertNotEquals(block1, block2); assertBlock(block2, v2, v1); assertNotEquals(block1.hashCode(), block2.hashCode()); assertArrayEquals(new Object[] { block1, block2 }, root.getOwnedVariableBlocks().toArray()); FactorGraph subgraph = root.addGraph(new FactorGraph()); subgraph.setName("subgraph"); assertSame(block2, subgraph.getChildByGraphTreeId(block2.getGraphTreeId())); try (CurrentModel cur2 = using(subgraph)) { Variable v3 = real("v3"); VariableBlock block3 = subgraph.addVariableBlock(v1,v3); assertBlock(block3, v1, v3); } } } private void assertBlock(VariableBlock block, Variable ... expectedVariables) { assertInvariants(block); final int expectedLength = expectedVariables.length; assertEquals(expectedLength, block.size()); for (int i = expectedLength; --i>=0;) { assertSame(expectedVariables[i], block.get(i)); } } private void assertInvariants(VariableBlock block) { int id = block.getLocalId(); assertEquals(Ids.VARIABLE_BLOCK_TYPE, Ids.typeIndexFromLocalId(id)); FactorGraph parent = block.getParentGraph(); assertSame(block, parent.getVariableBlockByLocalId(id)); assertSame(block, parent.getChildByGraphTreeId(block.getGraphTreeId())); assertTrue(parent.ownsDirectly(block)); FactorGraph grandparent = parent.getParentGraph(); if (grandparent != null) { assertNotSame(block, grandparent.getVariableBlockByLocalId(id)); assertSame(block, grandparent.getChildByGraphTreeId(block.getGraphTreeId())); } /* * Test IDimpleEventSource methods */ assertEquals(block.toString(), block.getEventSourceName()); assertEquals(block.getParentGraph(), block.getModelEventSource()); block.notifyListenerChanged(); // does nothing /* * Test List invariants */ assertFalse(block.isEmpty()); assertTrue(block.size() > 0); Object[] objs = block.toArray(); Variable[] vars = block.toArray(new Variable[0]); assertEquals(block.size(), objs.length); assertArrayEquals(objs, vars); int i = -1; for (Variable var : block) { ++i; assertSame(var, block.get(i)); assertSame(var, vars[i]); assertEquals(var.getGraphTreeId(), block.getVariableGraphTreeId(i)); assertEquals(i, block.indexOf(var)); assertEquals(i, block.lastIndexOf(var)); assertTrue(block.contains(var)); } assertEquals(i+1, block.size()); assertFalse(block.contains("foo")); assertEquals(-1, block.indexOf("bogus")); assertEquals(-1, block.indexOf(new Real())); assertEquals(-1, block.lastIndexOf("bogus")); assertEquals(-1, block.lastIndexOf(new Real())); assertTrue(block.containsAll(Collections.emptyList())); assertTrue(block.containsAll(Arrays.asList(vars))); assertFalse(block.containsAll(Arrays.asList("foo"))); assertEquals(block.subList(0, block.size()), block); // VariableBlock.equals only true if other object is also a VariableBlock assertNotEquals(block, block.subList(0, block.size())); } @Test public void testErrors() { FactorGraph fg = new FactorGraph("fg"); expectThrow(IllegalArgumentException.class, "Cannot create empty VariableBlock", fg, "addVariableBlock"); Variable v1 = new Real(); v1.setName("v1"); expectThrow(IllegalArgumentException.class, "Variable 'v1' not in graph tree", fg, "addVariableBlock", v1); fg.addVariables(v1); expectThrow(IllegalArgumentException.class, "Variable 'v1' was specified more than once", fg, "addVariableBlock", v1, v1); FactorGraph fg2 = new FactorGraph("fg2"); expectThrow(IllegalArgumentException.class, "Variable 'v1' not in graph tree", fg2, "addVariableBlock", v1); VariableBlock block = fg.addVariableBlock(v1); assertUnsupported(block, "add", v1); assertUnsupported(block, "add", 1, v1); assertUnsupported(block, "addAll", new ArrayList<Variable>()); assertUnsupported(block, "addAll", 42, new ArrayList<Variable>()); assertUnsupported(block, "clear"); assertUnsupported(block, "remove", "foo"); assertUnsupported(block, "remove", 42); assertUnsupported(block, "removeAll", Collections.emptyList()); assertUnsupported(block, "retainAll", Collections.emptyList()); assertUnsupported(block, "set", 42, v1); assertEquals(v1, block.get(0)); fg.remove(v1); expectThrow(IllegalStateException.class, ".*no longer in graph", block, "get", 0); } private void assertUnsupported(VariableBlock block, String methodName, Object ... args) { expectThrow(UnsupportedOperationException.class, block, methodName, args); } }