package no.birkett.kiwi; import org.junit.Test; import java.util.*; import static org.junit.Assert.assertEquals; import org.junit.Test; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import static org.junit.Assert.assertEquals; /** * Created by alex on 20/11/2014. */ public class RealWorldTests { private static double EPSILON = 1.0e-2; public static final String LEFT = "left"; public static final String RIGHT = "right"; public static final String TOP = "top"; public static final String BOTTOM = "bottom"; public static final String HEIGHT = "height"; public static final String WIDTH = "width"; public static final String CENTERX = "centerX"; public static final String CENTERY = "centerY"; private static final String[] CONSTRAINTS = { // "container.width == 500", // "container.height == 500", // "container.left == 0", // "container.top == 0", // // "view.left == container.left + 100", // "view.top == container.top + 100", // "view.bottom == container.bottom - 100", // "view.right == container.right - 100", // // "view2.left == view.left", // "view2.right <= view.right", // "view2.width == 250 !weak" "container.columnWidth == container.width * 0.4 + 30", "container.thumbHeight == container.columnWidth / 2 - 25", "container.padding == container.width * 0.1", "container.leftPadding == container.padding", "container.rightPadding == container.width * 1.5 - 30", "container.paddingUnderThumb == 5", "container.rowPadding == 15", "container.buttonPadding == 20", "container.width == 200 !medium" // "thumb0.left == container.leftPadding", // "thumb0.top == container.padding", // "thumb0.height == container.thumbHeight", // "thumb0.width == container.columnWidth", // // "title0.left == container.leftPadding", // "title0.top == thumb0.bottom + container.paddingUnderThumb", // "title0.height == title0.intrinsicHeight", // "title0.width == container.columnWidth", // // "thumb1.right == container.rightPadding", // "thumb1.top == container.padding", // "thumb1.height == container.thumbHeight", // "thumb1.width == container.columnWidth", // // "title1.right == container.rightPadding", // "title1.top == thumb0.bottom + container.paddingUnderThumb", // "title1.height == title1.intrinsicHeight", // "title1.width == container.columnWidth", // // "thumb2.left == container.leftPadding", // "thumb2.top >= title0.bottom + container.rowPadding", // "thumb2.top == title0.bottom + container.rowPadding !weak", // "thumb2.top >= title1.bottom + container.rowPadding", // "thumb2.top == title1.bottom + container.rowPadding !weak", // "thumb2.height == container.thumbHeight", // "thumb2.width == container.columnWidth", // // "title2.left == container.leftPadding", // "title2.top == thumb2.bottom + container.paddingUnderThumb", // "title2.height == title2.intrinsicHeight", // "title2.width == container.columnWidth", // // "thumb3.right == container.rightPadding", // "thumb3.top == thumb2.top", // // "thumb3.height == container.thumbHeight", // "thumb3.width == container.columnWidth", // // "title3.right == container.rightPadding", // "title3.top == thumb3.bottom + container.paddingUnderThumb", // "title3.height == title3.intrinsicHeight", // "title3.width == container.columnWidth", // // "thumb4.left == container.leftPadding", // "thumb4.top >= title2.bottom + container.rowPadding", // "thumb4.top >= title3.bottom + container.rowPadding", // "thumb4.top == title2.bottom + container.rowPadding !weak", // "thumb4.top == title3.bottom + container.rowPadding !weak", // "thumb4.height == container.thumbHeight", // "thumb4.width == container.columnWidth", // // "title4.left == container.leftPadding", // "title4.top == thumb4.bottom + container.paddingUnderThumb", // "title4.height == title4.intrinsicHeight", // "title4.width == container.columnWidth", // // "thumb5.right == container.rightPadding", // "thumb5.top == thumb4.top", // "thumb5.height == container.thumbHeight", // "thumb5.width == container.columnWidth", // // "title5.right == container.rightPadding", // "title5.top == thumb5.bottom + container.paddingUnderThumb", // "title5.height == title5.intrinsicHeight", // "title5.width == container.columnWidth", // // "line.height == 1", // "line.width == container.width", // "line.top >= title4.bottom + container.rowPadding", // "line.top >= title5.bottom + container.rowPadding", // // "more.top == line.bottom + container.buttonPadding", // "more.height == more.intrinsicHeight", // "more.left == container.leftPadding", // "more.right == container.rightPadding", // // "container.height == more.bottom + container.buttonPadding" }; public ConstraintParser.CassowaryVariableResolver createVariableResolver(final Solver solver, final HashMap> nodeHashMap) { ConstraintParser.CassowaryVariableResolver variableResolver = new ConstraintParser.CassowaryVariableResolver() { private Variable getVariableFromNode(HashMap node, String variableName) { try { if (node.containsKey(variableName)) { return node.get(variableName); } else { Variable variable = new Variable(variableName); node.put(variableName, variable); if (RIGHT.equals(variableName)) { solver.addConstraint(Symbolics.equals(variable, Symbolics.add(getVariableFromNode(node, LEFT), getVariableFromNode(node, WIDTH)))); } else if (BOTTOM.equals(variableName)) { solver.addConstraint(Symbolics.equals(variable, Symbolics.add(getVariableFromNode(node, TOP), getVariableFromNode(node, HEIGHT)))); } else if (CENTERX.equals(variableName)) { // solver.addConstraint(Symbolics.equals(variable, Symbolics.add(Symbolics.divide(getVariableFromNode(node, WIDTH), 2), getVariableFromNode(node, LEFT))); } else if (CENTERY.equals(variableName)) { // solver.addConstraint(Symbolics.equals(variable, Symbolics.add(new Expression(Symbolics.divide(getVariableFromNode(node, HEIGHT), 2)), getVariableFromNode(node, TOP)); } return variable; } } catch(DuplicateConstraintException e) { e.printStackTrace(); } catch (UnsatisfiableConstraintException e) { e.printStackTrace(); } return null; } private HashMap getNode(String nodeName) { HashMap node; if (nodeHashMap.containsKey(nodeName)) { node = nodeHashMap.get(nodeName); } else { node = new HashMap(); nodeHashMap.put(nodeName, node); } return node; } @Override public Variable resolveVariable(String variableName) { String[] stringArray = variableName.split("\\."); if (stringArray.length == 2) { String nodeName = stringArray[0]; String propertyName = stringArray[1]; HashMap node = getNode(nodeName); return getVariableFromNode(node, propertyName); } else { throw new RuntimeException("can't resolve variable"); } } @Override public Expression resolveConstant(String name) { try { return new Expression(Double.parseDouble(name)); } catch (NumberFormatException e) { return null; } } }; return variableResolver; } @Test public void testSimple() { int a = 20; assertEquals(20, a); } @Test public void testGridLayout() throws DuplicateConstraintException, UnsatisfiableConstraintException { final Solver solver = new Solver(); final HashMap> nodeHashMap = new HashMap<>(); ConstraintParser.CassowaryVariableResolver variableResolver = createVariableResolver(solver, nodeHashMap); List cache = new ArrayList<>(); for (String constraint : CONSTRAINTS) { Constraint con = ConstraintParser.parseConstraint(constraint, variableResolver); solver.addConstraint(con); cache.add(con); } solver.updateVariables(); // assertEquals(300, nodeHashMap.get("container").get("width").getValue(), EPSILON); // assertEquals(150, nodeHashMap.get("container").get("columnWidth").getValue(), EPSILON); // assertEquals(50, nodeHashMap.get("container").get("thumbHeight").getValue(), EPSILON); // assertEquals(30, nodeHashMap.get("container").get("padding").getValue(), EPSILON); // assertEquals(30, nodeHashMap.get("container").get("leftPadding").getValue(), EPSILON); // try { // solver.removeConstraint(cache.get(cache.size() -1)); // } catch (UnknownConstraintException e) { // e.printStackTrace(); // } // solver.addConstraint(ConstraintParser.parseConstraint("container.width == 300", variableResolver, 8)); Variable width = variableResolver.resolveVariable("container.width"); try { solver.addEditVariable(width, Strength.STRONG); } catch (DuplicateEditVariableException e) { e.printStackTrace(); } catch (RequiredFailureException e) { e.printStackTrace(); } try { solver.suggestValue(width, 300); } catch (UnknownEditVariableException e) { e.printStackTrace(); } solver.updateVariables(); assertEquals(300, nodeHashMap.get("container").get("width").getValue(), EPSILON); try { solver.suggestValue(width, 200); } catch (UnknownEditVariableException e) { e.printStackTrace(); } solver.updateVariables(); assertEquals(200, nodeHashMap.get("container").get("width").getValue(), EPSILON); // assertEquals(150, nodeHashMap.get("container").get("columnWidth").getValue(), EPSILON); // assertEquals(50, nodeHashMap.get("container").get("thumbHeight").getValue(), EPSILON); // assertEquals(30, nodeHashMap.get("container").get("padding").getValue(), EPSILON); // assertEquals(30, nodeHashMap.get("container").get("leftPadding").getValue(), EPSILON); // assertEquals(280, nodeHashMap.get("container").get("test").getValue(), EPSILON); // assertEquals(270, nodeHashMap.get("container").get("width").getValue() - nodeHashMap.get("container").get("padding").getValue(), EPSILON); // assertEquals(270, nodeHashMap.get("container").get("rightPadding").getValue(), EPSILON); // assertEquals(100, nodeHashMap.get("view").get("top").getValue(), EPSILON); // assertEquals(400, nodeHashMap.get("view").get("bottom").getValue(), EPSILON); // assertEquals(350, nodeHashMap.get("view2").get("right").getValue(), EPSILON); // assertEquals(20, nodeHashMap.get("thumb0").get("top").getValue(), EPSILON); // assertEquals(20, nodeHashMap.get("thumb1").get("top").getValue(), EPSILON); // // assertEquals(85, nodeHashMap.get("title0").get("top").getValue(), EPSILON); // assertEquals(85, nodeHashMap.get("title1").get("top").getValue(), EPSILON); // // assertEquals(210, nodeHashMap.get("thumb2").get("top").getValue(), EPSILON); // assertEquals(210, nodeHashMap.get("thumb3").get("top").getValue(), EPSILON); // // assertEquals(275, nodeHashMap.get("title2").get("top").getValue(), EPSILON); // assertEquals(275, nodeHashMap.get("title3").get("top").getValue(), EPSILON); // // assertEquals(420, nodeHashMap.get("thumb4").get("top").getValue(), EPSILON); // assertEquals(420, nodeHashMap.get("thumb5").get("top").getValue(), EPSILON); // // assertEquals(485, nodeHashMap.get("title4").get("top").getValue(), EPSILON); // assertEquals(485, nodeHashMap.get("title5").get("top").getValue(), EPSILON); } /* @Test public void testGridLayoutUsingEditVariables() throws CassowaryError { final SimplexSolver solver = new SimplexSolver(); solver.setAutosolve(true); final HashMap> nodeHashMap = new HashMap>(); ConstraintParser.CassowaryVariableResolver variableResolver = createVariableResolver(solver, nodeHashMap); for (String constraint : CONSTRAINTS) { solver.addConstraint(ConstraintParser.parseConstraint(constraint, variableResolver)); } Variable containerWidth = nodeHashMap.get("container").get("width"); Variable title0IntrinsicHeight = nodeHashMap.get("title0").get("intrinsicHeight"); Variable title1IntrinsicHeight = nodeHashMap.get("title1").get("intrinsicHeight"); Variable title2IntrinsicHeight = nodeHashMap.get("title2").get("intrinsicHeight"); Variable title3IntrinsicHeight = nodeHashMap.get("title3").get("intrinsicHeight"); Variable title4IntrinsicHeight = nodeHashMap.get("title4").get("intrinsicHeight"); Variable title5IntrinsicHeight = nodeHashMap.get("title5").get("intrinsicHeight"); Variable moreIntrinsicHeight = nodeHashMap.get("more").get("intrinsicHeight"); solver.addStay(containerWidth); solver.addStay(title0IntrinsicHeight); solver.addStay(title1IntrinsicHeight); solver.addStay(title2IntrinsicHeight); solver.addStay(title3IntrinsicHeight); solver.addStay(title4IntrinsicHeight); solver.addStay(title5IntrinsicHeight); solver.addStay(moreIntrinsicHeight); solver.addEditVar(containerWidth); solver.addEditVar(title0IntrinsicHeight); solver.addEditVar(title1IntrinsicHeight); solver.addEditVar(title2IntrinsicHeight); solver.addEditVar(title3IntrinsicHeight); solver.addEditVar(title4IntrinsicHeight); solver.addEditVar(title5IntrinsicHeight); solver.addEditVar(moreIntrinsicHeight); solver.beginEdit(); solver.suggestValue(containerWidth, 300); solver.suggestValue(title0IntrinsicHeight, 100); solver.suggestValue(title1IntrinsicHeight, 110); solver.suggestValue(title2IntrinsicHeight, 120); solver.suggestValue(title3IntrinsicHeight, 130); solver.suggestValue(title4IntrinsicHeight, 140); solver.suggestValue(title5IntrinsicHeight, 150); solver.suggestValue(moreIntrinsicHeight, 160); solver.resolve(); solver.solve(); assertEquals(20, nodeHashMap.get("thumb0").get("top").value(), EPSILON); assertEquals(20, nodeHashMap.get("thumb1").get("top").value(), EPSILON); assertEquals(85, nodeHashMap.get("title0").get("top").value(), EPSILON); assertEquals(85, nodeHashMap.get("title1").get("top").value(), EPSILON); assertEquals(210, nodeHashMap.get("thumb2").get("top").value(), EPSILON); assertEquals(210, nodeHashMap.get("thumb3").get("top").value(), EPSILON); assertEquals(275, nodeHashMap.get("title2").get("top").value(), EPSILON); assertEquals(275, nodeHashMap.get("title3").get("top").value(), EPSILON); assertEquals(420, nodeHashMap.get("thumb4").get("top").value(), EPSILON); assertEquals(420, nodeHashMap.get("thumb5").get("top").value(), EPSILON); assertEquals(485, nodeHashMap.get("title4").get("top").value(), EPSILON); assertEquals(485, nodeHashMap.get("title5").get("top").value(), EPSILON); } @Test public void testGridX1000() throws ConstraintNotFound { long nanoTime = System.nanoTime(); for (int i = 0; i < 1000; i++) { testGridLayout(); } System.out.println("testGridX1000 took " + (System.nanoTime() - nanoTime) / 1000000); } @Test public void testGridWithEditsX1000() throws CassowaryError { long nanoTime = System.nanoTime(); for (int i = 0; i < 1000; i++) { testGridLayoutUsingEditVariables(); } System.out.println("testGridWithEditsX1000 took " + (System.nanoTime() - nanoTime) / 1000000 + " ms"); }*/ private static void printNodes(HashMap> variableHashMap) { Iterator>> it = variableHashMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry> pairs = it.next(); System.out.println("node " + pairs.getKey()); printVariables(pairs.getValue()); } } private static void printVariables(HashMap variableHashMap) { Iterator> it = variableHashMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry pairs = it.next(); System.out.println(" " + pairs.getKey() + " = " + pairs.getValue().getValue() + " (address:" + pairs.getValue().hashCode() + ")"); } } }