/* * 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.passes.testing.AstPrinter; import com.google.common.css.compiler.passes.testing.PassesTestBase; import java.util.Locale; /** * Functional tests for {@link BiDiFlipper}. * * @author roozbeh@google.com (Roozbeh Pournader) */ public class BiDiFlipperFunctionalTest extends PassesTestBase { /** * Tests that * border-left : green * is flipped to * border-right : green */ public void test1() { testTreeConstruction( "foo { border-left: green; }", "[[foo]{[border-right:[[green]];]}]"); } /** * Tests that * padding : 0px 3px 1px 5px * is flipped to * padding : 0px 5px 1px 3px */ public void test2() { testTreeConstruction( "foo { padding: 0px 3px 1px 5px; }", "[[foo]{[padding:[[0px][5px][1px][3px]];]}]"); } /** * Tests that * padding : 0px 3px 1px * remains * padding : 0px 3px 1px */ public void test3() { testTreeConstruction( "foo { padding: 0px 3px 1px; }", "[[foo]{[padding:[[0px][3px][1px]];]}]"); } /** * Tests that * background : 10% 3px red * is flipped to * background : 90% 3px red */ public void test4() { testTreeConstruction( "foo { background: 10% 3px red; }", "[[foo]{[background:[[90%][3px][red]];]}]"); } /** * Tests that * background : 5.43521% 3px red * is flipped to * background : 94.56479% 3px red */ public void test4_withDecimals() { testTreeConstruction( "foo { background: 5.43521% 3px red; }", "[[foo]{[background:[[94.56479%][3px][red]];]}]"); } /** * Tests that * background : 5.43521% 3px red * is flipped to * background : 94.56479% 3px red */ public void test4_withDecimalsInOtherLocale() { Locale.setDefault(Locale.FRANCE); try { testTreeConstruction( "foo { background: 5.43521% 3px red; }", "[[foo]{[background:[[94.56479%][3px][red]];]}]"); } finally { Locale.setDefault(Locale.US); } } /** * Tests that * background-position-x : 10%; padding-right: 2px * is flipped to * background-position-x : 90%; padding-left: 2px */ public void test5() { testTreeConstruction( "foo { background-position-x: 10%; padding-right: 2px; }", "[[foo]{[background-position-x:[[90%]];padding-left:[[2px]];]}]"); } /** * Tests that * background : url(/foo/rtl/background.png) * is flipped to * background : url(/foo/ltr/background.png) */ public void test6() { testTreeConstruction( "foo { background: url(/foo/rtl/background.png); }", "[[foo]{[background:[url(/foo/ltr/background.png)];]}]"); } /** * Tests that * background : url(/foo/ltr/background.png) * is flipped to * background : url('/foo/rtl/background.png') */ public void test7() { testTreeConstruction( "foo { background: url(/foo/ltr/background.png); }", "[[foo]{[background:[url(/foo/rtl/background.png)];]}]"); } /** * Tests that * background : url(/foo/background-left.png) * is flipped to * background : url('/foo/background-right.png') */ public void test8() { testTreeConstruction( "foo { background: url(/foo/background-left.png); }", "[[foo]{[background:[url(/foo/background-right.png)];]}]"); } /** * Tests that * background : url(/foo/background-right.png) * is flipped to * background : url(/foo/background-left.png) */ public void test9() { testTreeConstruction( "foo { background: url(/foo/background-right.png); }", "[[foo]{[background:[url(/foo/background-left.png)];]}]"); } /** * Tests that * background : url(/foo/background.png) * remains * background : url(/foo/background.png) */ public void test10() { testTreeConstruction( "foo { background: url('/foo/background.png'); }", "[[foo]{[background:[url('/foo/background.png')];]}]"); } /** * Tests that * background : 10% * is flipped to * background : 90% * inside a conditional block. */ public void test11() { testTreeConstruction( "@if COND1 {" + " foo {" + " background: 10%;" + " }" + "}", "[@if [COND1]{[foo]{[background:[[90%]];]}}]"); } /** * Tests that * padding : 0px 3px 1px 5px * is flipped to * padding : 0px 5px 1px 3px * and * background : 40% * is flipped to * background : 60% * and * background : url(/foo/background-right.png) * is flipped to * background : url(/foo/background-left.png) * inside a slightly complex conditional block. */ public void test12() { testTreeConstruction( "@if COND1 {" + " foo {" + " background: 40%;" + " }" + "} @elseif COND2 {" + " foo {" + " padding: 0px 3px 1px 5px;" + " }" + "} @else {" + " bar {" + " background: url('/foo/background-right.png');" + " }" + "}", "[@if [COND1]{[foo]{[background:[[60%]];]}}" + "@elseif [COND2]{[foo]{[padding:[[0px][5px][1px][3px]];]}}" + "@else{[bar]{[background:[url('/foo/background-left.png')];]}}]"); } /** * Tests that * background-position-x : 10% * is flipped to * background-position-x : 90% * and * padding-left : 2px * is flipped to * padding-right : 2px * inside a media rule. */ public void test13() { testTreeConstruction( "@media print {" + " @if COND1 {" + " @if COND2 {" + " foo { background-position-x: 10% }" + " } " + " } @else {" + " foo { padding-left: 2px }" + " }" + "}", "[@media [print]{@if [COND1]{@if [COND2]" + "{[foo]{[background-position-x:[[90%]];]}}}" + "@else{[foo]{[padding-right:[[2px]];]}}}]"); } /** * Test to make sure that percentage value in 'font' node is not flipped. */ public void test14() { testTreeConstruction( "foo { font: 100%/1.3em Verdana, Sans-serif; }", "[[foo]{[font:[[[100%]/[1.3em]][[Verdana],[Sans-serif]]];]}]"); } /** * Test to make sure that the star hack property does not disappear in the * process of flipping. */ public void test15() { testTreeConstruction( "foo { *height: 13px }", "[[foo]{[*height:[[13px]];]}]"); } /** * Tests that * float : left * is flipped to * float : right */ public void test16() { testTreeConstruction( "foo { float: left }", "[[foo]{[float:[[right]];]}]"); } /** * Tests that * left : 5px * is flipped to * right : 5px */ public void test17() { testTreeConstruction( "foo { left: 5px }", "[[foo]{[right:[[5px]];]}]"); } /** * Tests that * cursor : e-resize * is flipped to * cursor : w-resize */ public void test18() { testTreeConstruction( "foo { cursor: e-resize }", "[[foo]{[cursor:[[w-resize]];]}]"); } /** * Tests that * border-top-left-radius : 3px * is flipped to * border-top-right-radius : 3px */ public void test19() { testTreeConstruction( "foo { border-top-left-radius: 3px }", "[[foo]{[border-top-right-radius:[[3px]];]}]"); } /** * Tests that * -moz-border-radius-topleft : 3px * is flipped to * -moz-border-radius-topright : 3px */ public void test20() { testTreeConstruction( "foo { -moz-border-radius-topleft: 3px }", "[[foo]{[-moz-border-radius-topright:[[3px]];]}]"); } /** * Tests that @defs get expanded and flipped correctly. */ public void test21() { parseAndBuildTree( "@def RTL rtl;" + "@def WHOLE_PADDING 1px 2px 3px 4px;" + "@def TOP_RIGHT_PADDING 1px 2px;" + "@def BOTTOM_LEFT_PADDING 3px 4px;" + ".b {" + " direction: RTL;" + " padding: WHOLE_PADDING;" + " padding: TOP_RIGHT_PADDING BOTTOM_LEFT_PADDING;" + "}"); new CreateDefinitionNodes(tree.getMutatingVisitController(), errorManager).runPass(); new CreateConstantReferences(tree.getMutatingVisitController()).runPass(); CollectConstantDefinitions collectConstantDefinitionsPass = new CollectConstantDefinitions(tree); collectConstantDefinitionsPass.runPass(); new ReplaceConstantReferences(tree, collectConstantDefinitionsPass.getConstantDefinitions(), true /* removeDefs */, errorManager, true /* allowUndefinedConstants */).runPass(); new BiDiFlipper(tree.getMutatingVisitController(), true, true).runPass(); String expectedOutput = "[[.b]{[" + "direction:[[ltr]];" + "padding:[[1px][4px][3px][2px]];" + "padding:[[1px][4px][3px][2px]];" + "]}]"; assertEquals(expectedOutput, AstPrinter.print(tree)); } /** * Tests that * border-color: #fff #aaa #ccc transparent * is flipped to * border-color: #fff transparent #ccc #aaa */ public void test22() { testTreeConstruction( "foo { border-color: #fff #aaa #ccc transparent; }", "[[foo]{[border-color:[[#fff][transparent][#ccc][#aaa]];]}]"); } /** * Tests that * -ms-background-position-x : 10% * is flipped to * -ms-background-position-x : 90% */ public void test23() { testTreeConstruction( "foo { -ms-background-position-x: 10%; }", "[[foo]{[-ms-background-position-x:[[90%]];]}]"); } /** * Tests that * background-position-y : 10% * is not flipped. */ public void test24() { testTreeConstruction( "foo { background-position-y: 10%; }", "[[foo]{[background-position-y:[[10%]];]}]"); } /** * Tests that * background-size : 10% 20% * is not flipped. */ public void test25() { testTreeConstruction( "foo { background-size: 10% 20%; }", "[[foo]{[background-size:[[10%][20%]];]}]"); } /** * Tests that * background-position: 10% 20% * is flipped to * background-position: 90% 20% */ public void test26() { testTreeConstruction( "foo { background-position: 10% 20%; }", "[[foo]{[background-position:[[90%][20%]];]}]"); } /** * Tests that * background-position: 0 0 * is not flipped. */ public void test27() { testTreeConstruction( "foo { background-position: 0 0; }", "[[foo]{[background-position:[[0][0]];]}]"); } /** * Tests that * background: rgb(1%, 2%, 3%) 4% 5% * is flipped to * background: rgb(1%, 2%, 3%) 96% 5% */ public void test28() { testTreeConstruction( "foo { background: rgb(1%, 2%, 3%) 4% 5%; }", "[[foo]{[background:[rgb(1%,2%,3%) [96%][5%]];]}]"); } /** * Tests that * background: red 4% 5% * is flipped to * background: red 96% 5% */ public void test29() { testTreeConstruction( "foo { background: red 4% 5%; }", "[[foo]{[background:[[red][96%][5%]];]}]"); } /** * Tests that * background: center 5% * is not flipped. */ public void test30() { testTreeConstruction( "foo { background: center 5%; }", "[[foo]{[background:[[center][5%]];]}]"); } /** * Tests that * box-shadow: 1px 2px 3px 4px * is not flipped. */ public void test31() { testTreeConstruction( "foo { box-shadow: 1px 2px 3px 4px; }", "[[foo]{[box-shadow:[[1px][2px][3px][4px]];]}]"); } /** * Tests that * text-shadow: 1px 2px 3px 4px * is not flipped. */ public void test32() { testTreeConstruction( "foo { text-shadow: 1px 2px 3px 4px; }", "[[foo]{[text-shadow:[[1px][2px][3px][4px]];]}]"); } /** * Tests that * border-radius: 1px * is not flipped. */ public void test33() { testTreeConstruction( "foo { border-radius: 1px; }", "[[foo]{[border-radius:[[1px]];]}]"); } /** * Tests that * border-radius: 1px / 5px * is not flipped. */ public void test34() { testTreeConstruction( "foo { border-radius: 1px / 5px; }", "[[foo]{[border-radius:[[[1px]/[5px]]];]}]"); } /** * Tests that * border-radius: 1px 2px * is flipped to * border-radius: 2px 1px */ public void test35() { testTreeConstruction( "foo { border-radius: 1px 2px; }", "[[foo]{[border-radius:[[2px][1px]];]}]"); } /** * Tests that * border-radius: 1px 2px 3px * is flipped to * border-radius: 2px 1px 2px 3px */ public void test36() { testTreeConstruction( "foo { border-radius: 1px 2px 3px; }", "[[foo]{[border-radius:[[2px][1px][2px][3px]];]}]"); } /** * Tests that * border-radius: 1px 2px 3px 4px * is flipped to * border-radius: 2px 1px 4px 3px */ public void test37() { testTreeConstruction( "foo { border-radius: 1px 2px 3px 4px; }", "[[foo]{[border-radius:[[2px][1px][4px][3px]];]}]"); } /** * Tests that * border-radius: 1px 2px 3px 4px / 5px 6px 7px 8px * is flipped to * border-radius: 2px 1px 4px 3px / 6px 5px 8px 7px */ public void test38() { testTreeConstruction( "foo { border-radius: 1px 2px 3px 4px / 5px 6px 7px 8px; }", "[[foo]{[border-radius:" + "[[2px][1px][4px][[3px]/[6px]][5px][8px][7px]];]}]"); } /** * Tests that * border-radius: 1px / 5px 6px 7px 8px * is flipped to * border-radius: 1px / 6px 5px 8px 7px */ public void test39() { testTreeConstruction( "foo { border-radius: 1px / 5px 6px 7px 8px; }", "[[foo]{[border-radius:[[[1px]/[6px]][5px][8px][7px]];]}]"); } /** * Tests that * border-radius: 1px 2px 3px / 5px 6px * is flipped to * border-radius: 2px 1px 2px 3px / 6px 5px */ public void test40() { testTreeConstruction( "foo { border-radius: 1px 2px 3px / 5px 6px; }", "[[foo]{[border-radius:[[2px][1px][2px][[3px]/[6px]][5px]];]}]"); } /** * Tests that * -webkit-border-radius: 1px 2px 3px / 5px 6px * is flipped to * -webkit-border-radius: 2px 1px 2px 3px / 6px 5px */ public void test41() { testTreeConstruction( "foo { -webkit-border-radius: 1px 2px 3px / 5px 6px; }", "[[foo]{[-webkit-border-radius:[[2px][1px][2px][[3px]/[6px]][5px]];]}]"); } /** * Tests that * border-color: red yellow green blue * is flipped to * border-color: red blue green yellow */ public void test42() { testTreeConstruction( "foo { border-color: red yellow green blue; }", "[[foo]{[border-color:[[red][blue][green][yellow]];]}]"); } /** * Tests that * border-width: thin medium thick 2px * is flipped to * border-width: thin 2px thick medium */ public void test43() { testTreeConstruction( "foo { border-width: thin medium thick 2px; }", "[[foo]{[border-width:[[thin][2px][thick][medium]];]}]"); } /** * Tests that * border-image-slice: 5% 10% 15% 20% * is not flipped. */ public void test44() { testTreeConstruction( "foo { border-image-slice: 5% 10% 15% 20%; }", "[[foo]{[border-image-slice:[[5%][10%][15%][20%]];]}]"); } /** * Tests that * border-image-slice: 5% 10% 15% 20% fill * is not flipped. */ public void test45() { testTreeConstruction( "foo { border-image-slice: 5% 10% 15% 20% fill; }", "[[foo]{[border-image-slice:[[5%][10%][15%][20%][fill]];]}]"); } /** * Tests that * border-image-slice: 5% 10% 15% fill * is not flipped. */ public void test46() { testTreeConstruction( "foo { border-image-slice: 5% 10% 15% fill; }", "[[foo]{[border-image-slice:[[5%][10%][15%][fill]];]}]"); } /** * Tests that * border-image-slice: 5% 10% fill * is not flipped. */ public void test47() { testTreeConstruction( "foo { border-image-slice: 5% 10% fill; }", "[[foo]{[border-image-slice:[[5%][10%][fill]];]}]"); } /** * Tests that * border-image-slice: 5% fill * is not flipped. */ public void test48() { testTreeConstruction( "foo { border-image-slice: 5% fill; }", "[[foo]{[border-image-slice:[[5%][fill]];]}]"); } /** * Tests that * border-image-outset: 1 2 3 4 * is not flipped. */ public void test49() { testTreeConstruction( "foo { border-image-outset: 1 2 3 4; }", "[[foo]{[border-image-outset:[[1][2][3][4]];]}]"); } /** * Tests that * border-image-width: 1px auto 0 3% * is not flipped. */ public void test50() { testTreeConstruction( "foo { border-image-width: 1px auto 0 3%; }", "[[foo]{[border-image-width:[[1px][auto][0][3%]];]}]"); } /** * Tests that * background: url() * is handled fine. */ public void test51() { testTreeConstruction( "foo { background: url(); }", "[[foo]{[background:[url()];]}]"); } /** * Tests that * future-property: e-mail * is not flipped. */ public void test52() { testTreeConstruction( "foo { future-property: e-mail }", "[[foo]{[future-property:[[e-mail]];]}]"); } /** * Tests that * cursor: nesw-resize * is flipped to * cursor: nwse-resize */ public void test53() { testTreeConstruction( "foo { cursor: nesw-resize }", "[[foo]{[cursor:[[nwse-resize]];]}]"); } @Override protected void runPass() { BiDiFlipper pass = new BiDiFlipper(tree.getMutatingVisitController(), true, true); pass.runPass(); } }