/* * Copyright 2009 Google 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.google.common.css.compiler.passes; import com.google.common.css.compiler.ast.BackDoorNodeMutation; import com.google.common.css.compiler.ast.CssBlockNode; import com.google.common.css.compiler.ast.CssDeclarationNode; import com.google.common.css.compiler.ast.CssFunctionArgumentsNode; import com.google.common.css.compiler.ast.CssFunctionNode; import com.google.common.css.compiler.ast.CssFunctionNode.Function; import com.google.common.css.compiler.ast.CssLiteralNode; import com.google.common.css.compiler.ast.CssNumericNode; import com.google.common.css.compiler.ast.CssPriorityNode; import com.google.common.css.compiler.ast.CssPriorityNode.PriorityType; import com.google.common.css.compiler.ast.CssPropertyNode; import com.google.common.css.compiler.ast.CssPropertyValueNode; import com.google.common.css.compiler.ast.CssRootNode; import com.google.common.css.compiler.ast.CssRulesetNode; import com.google.common.css.compiler.ast.CssSelectorNode; import com.google.common.css.compiler.ast.CssTree; import com.google.common.css.compiler.ast.MutatingVisitController; import junit.framework.TestCase; import org.easymock.EasyMock; import org.easymock.IMocksControl; /** * Unit tests for {@link BiDiFlipper}. * */ public class BiDiFlipperTest extends TestCase { public void testRunPass() { IMocksControl controller = EasyMock.createStrictControl(); MutatingVisitController visitController = controller.createMock( MutatingVisitController.class); BiDiFlipper pass = new BiDiFlipper(visitController, true, true); visitController.startVisit(pass); controller.replay(); pass.runPass(); controller.verify(); } // Test when the node is set to be non-flippable. public void testEnterDeclaration1() { IMocksControl controller = EasyMock.createStrictControl(); MutatingVisitController visitController = controller.createMock( MutatingVisitController.class); CssDeclarationNode node = new CssDeclarationNode(new CssPropertyNode("foo")); node.setShouldBeFlipped(false); controller.replay(); // Perform action. BiDiFlipper pass = new BiDiFlipper(visitController, true, true); pass.enterDeclaration(node); // Verify. controller.verify(); } // Test when the node is set to be flippable. public void testEnterDeclaration2() { // padding: 5px 1px 2px 3px; CssPropertyNode prop1 = new CssPropertyNode("padding", null); CssPropertyValueNode value1 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value1, new CssNumericNode("5", "px")); BackDoorNodeMutation.addChildToBack(value1, new CssNumericNode("1", "px")); BackDoorNodeMutation.addChildToBack(value1, new CssNumericNode("2", "px")); BackDoorNodeMutation.addChildToBack(value1, new CssNumericNode("3", "px")); // font: 90%; CssPropertyNode prop2 = new CssPropertyNode("font", null); CssPropertyValueNode value2 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value2, new CssNumericNode("90", "%")); // background-position-x: 80%; CssPropertyNode prop3 = new CssPropertyNode("background-position-x", null); CssPropertyValueNode value3 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value3, new CssNumericNode("80", "%")); // background: url("/foo/rtl/background.png"); CssPropertyNode prop4 = new CssPropertyNode("background", null); CssPropertyValueNode value4 = new CssPropertyValueNode(); CssFunctionNode functionNode = new CssFunctionNode(Function.byName("url"), null); CssFunctionArgumentsNode argsNode = new CssFunctionArgumentsNode(); BackDoorNodeMutation.addChildToBack(argsNode, new CssLiteralNode("/foo/rtl/background.png")); functionNode.setArguments(argsNode); BackDoorNodeMutation.addChildToBack(value4, functionNode); // margin-left: 5px CssPropertyNode prop5 = new CssPropertyNode("margin-left", null); CssPropertyValueNode value5 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value5, new CssNumericNode("5", "px")); // float: left CssPropertyNode prop6 = new CssPropertyNode("float", null); CssPropertyValueNode value6 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value6, new CssLiteralNode("left")); // left: 5px CssPropertyNode prop7 = new CssPropertyNode("left", null); CssPropertyValueNode value7 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value7, new CssNumericNode("5", "px")); // cursor: e-resize CssPropertyNode prop8 = new CssPropertyNode("cursor", null); CssPropertyValueNode value8 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value8, new CssLiteralNode("e-resize")); // border-top-left-radius: 3px CssPropertyNode prop9 = new CssPropertyNode("border-top-left-radius", null); CssPropertyValueNode value9 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value9, new CssNumericNode("3", "px")); // -moz-border-radius-topleft: 3px CssPropertyNode prop10 = new CssPropertyNode("-moz-border-radius-topleft", null); CssPropertyValueNode value10 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value10, new CssNumericNode("3", "px")); CssDeclarationNode decl1 = new CssDeclarationNode(prop1); decl1.setPropertyValue(value1); CssDeclarationNode decl2 = new CssDeclarationNode(prop2); decl2.setPropertyValue(value2); CssDeclarationNode decl3 = new CssDeclarationNode(prop3); decl3.setPropertyValue(value3); CssDeclarationNode decl4 = new CssDeclarationNode(prop4); decl4.setPropertyValue(value4); CssDeclarationNode decl5 = new CssDeclarationNode(prop5); decl5.setPropertyValue(value5); CssDeclarationNode decl6 = new CssDeclarationNode(prop6); decl6.setPropertyValue(value6); CssDeclarationNode decl7 = new CssDeclarationNode(prop7); decl7.setPropertyValue(value7); CssDeclarationNode decl8 = new CssDeclarationNode(prop8); decl8.setPropertyValue(value8); CssDeclarationNode decl9 = new CssDeclarationNode(prop9); decl9.setPropertyValue(value9); CssDeclarationNode decl10 = new CssDeclarationNode(prop10); decl10.setPropertyValue(value10); CssRulesetNode ruleset = new CssRulesetNode(); CssSelectorNode sel = new CssSelectorNode("foo", null); ruleset.addSelector(sel); ruleset.addDeclaration(decl1); ruleset.addDeclaration(decl2); ruleset.addDeclaration(decl3); ruleset.addDeclaration(decl4); ruleset.addDeclaration(decl5); ruleset.addDeclaration(decl6); ruleset.addDeclaration(decl7); ruleset.addDeclaration(decl8); ruleset.addDeclaration(decl9); ruleset.addDeclaration(decl10); CssBlockNode body = new CssBlockNode(false); BackDoorNodeMutation.addChildToBack(body, ruleset); CssRootNode root = new CssRootNode(body); CssTree tree = new CssTree(null, root); BiDiFlipper pass = new BiDiFlipper(tree.getMutatingVisitController(), true, true); pass.runPass(); assertEquals(tree.getRoot().getBody().toString(), "[[foo]{[" + "padding:[5px, 3px, 2px, 1px], " + "font:[90%], " + "background-position-x:[20%], " + "background:[url(/foo/ltr/background.png)], " + "margin-right:[5px], " + "float:[right], " + "right:[5px], " + "cursor:[w-resize], " + "border-top-right-radius:[3px], " + "-moz-border-radius-topright:[3px]" + "]}]"); } public void testSubPercentValues() { // background-position-x: 1.12345678%; CssPropertyNode prop1 = new CssPropertyNode("background-position-x", null); CssPropertyValueNode value1 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value1, new CssNumericNode("1.12345678", "%")); // -ms-background-position-x: 2.5%; CssPropertyNode prop2 = new CssPropertyNode("-ms-background-position-x", null); CssPropertyValueNode value2 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value2, new CssNumericNode("2.5", "%")); CssDeclarationNode decl1 = new CssDeclarationNode(prop1); decl1.setPropertyValue(value1); CssDeclarationNode decl2 = new CssDeclarationNode(prop2); decl2.setPropertyValue(value2); CssRulesetNode ruleset = new CssRulesetNode(); CssSelectorNode sel = new CssSelectorNode("foo", null); ruleset.addSelector(sel); ruleset.addDeclaration(decl1); ruleset.addDeclaration(decl2); CssBlockNode body = new CssBlockNode(false); BackDoorNodeMutation.addChildToBack(body, ruleset); CssRootNode root = new CssRootNode(body); CssTree tree = new CssTree(null, root); BiDiFlipper pass = new BiDiFlipper(tree.getMutatingVisitController(), true, true); pass.runPass(); assertEquals(tree.getRoot().getBody().toString(), "[[foo]{[" + "background-position-x:[98.87654322%], " + "-ms-background-position-x:[97.5%]" + "]}]"); } public void testBidiImportant() { // margin: 1px 2px 3px 4px !important; CssPropertyNode prop1 = new CssPropertyNode("margin", null); CssPropertyValueNode value1 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value1, new CssNumericNode("1", "px")); BackDoorNodeMutation.addChildToBack(value1, new CssNumericNode("2", "px")); BackDoorNodeMutation.addChildToBack(value1, new CssNumericNode("3", "px")); BackDoorNodeMutation.addChildToBack(value1, new CssNumericNode("4", "px")); BackDoorNodeMutation.addChildToBack(value1, new CssPriorityNode(PriorityType.IMPORTANT)); // border-radius: 1px 2px !important; CssPropertyNode prop2 = new CssPropertyNode("border-radius", null); CssPropertyValueNode value2 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value2, new CssNumericNode("1", "px")); BackDoorNodeMutation.addChildToBack(value2, new CssNumericNode("2", "px")); BackDoorNodeMutation.addChildToBack(value2, new CssPriorityNode(PriorityType.IMPORTANT)); // padding-right: 1px !important; CssPropertyNode prop3 = new CssPropertyNode("padding-right", null); CssPropertyValueNode value3 = new CssPropertyValueNode(); BackDoorNodeMutation.addChildToBack(value3, new CssNumericNode("1", "px")); BackDoorNodeMutation.addChildToBack(value3, new CssPriorityNode(PriorityType.IMPORTANT)); CssDeclarationNode decl1 = new CssDeclarationNode(prop1); decl1.setPropertyValue(value1); CssDeclarationNode decl2 = new CssDeclarationNode(prop2); decl2.setPropertyValue(value2); CssDeclarationNode decl3 = new CssDeclarationNode(prop3); decl3.setPropertyValue(value3); CssRulesetNode ruleset = new CssRulesetNode(); CssSelectorNode sel = new CssSelectorNode("foo", null); ruleset.addSelector(sel); ruleset.addDeclaration(decl1); ruleset.addDeclaration(decl2); ruleset.addDeclaration(decl3); CssBlockNode body = new CssBlockNode(false); BackDoorNodeMutation.addChildToBack(body, ruleset); CssRootNode root = new CssRootNode(body); CssTree tree = new CssTree(null, root); BiDiFlipper pass = new BiDiFlipper(tree.getMutatingVisitController(), true, true); pass.runPass(); assertEquals( "[[foo]{[" + "margin:[1px, 4px, 3px, 2px, !important], " + "border-radius:[2px, 1px, !important], " + "padding-left:[1px, !important]" + "]}]", tree.getRoot().getBody().toString()); } }