/*
* 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.CssConditionalBlockNode;
import com.google.common.css.compiler.ast.CssConditionalRuleNode;
import com.google.common.css.compiler.ast.CssDeclarationBlockNode;
import com.google.common.css.compiler.ast.CssMediaRuleNode;
import com.google.common.css.compiler.ast.CssNode;
import com.google.common.css.compiler.ast.CssRulesetNode;
import com.google.common.css.compiler.ast.GssParserException;
import com.google.common.css.compiler.passes.testing.PassesTestBase;
/**
* Unit tests for {@link MarkNonFlippableNodes}.
*
* @author oana@google.com (Oana Florescu)
* @author fbenz@google.com (Florian Benz)
*/
public class MarkNonFlippableNodesTest extends PassesTestBase {
public void testMisplacedAnnotation() throws GssParserException {
parseAndRun(linesToString(
".CLASSX,",
"/* @noflip */ .CLASSY {",
" left:10px;",
"}"),
MarkNonFlippableNodes.INVALID_NOFLIP_ERROR_MESSAGE);
}
public void testMarkNonFlippableSingelDeclaration() {
parseAndBuildTree(linesToString(
".CLASSX {",
" /* @noflip */ left: 10px;",
" margin: 10px 9px 8px 7px;",
"}"));
runPass();
CssRulesetNode ruleset =
(CssRulesetNode) tree.getRoot().getBody().getChildren().get(0);
// The ruleset itself has to be marked as flippable.
assertTrue(ruleset.getShouldBeFlipped());
CssDeclarationBlockNode block = ruleset.getDeclarations();
assertEquals(2, block.getChildren().size());
// The first declaration has to be marked as not flippable.
assertFalse(block.getChildren().get(0).getShouldBeFlipped());
// The second declaration has to be marked as flippable.
assertTrue(block.getChildren().get(1).getShouldBeFlipped());
}
public void testMarkNonFlippableRuleset() {
parseAndBuildTree(linesToString(
"/* @noflip */ .CLASSX {",
" left: 10px;",
" margin: 10px 9px 8px 7px;",
"}"));
runPass();
CssRulesetNode ruleset =
(CssRulesetNode) tree.getRoot().getBody().getChildren().get(0);
// The ruleset itself has to be marked as not flippable.
assertFalse(ruleset.getShouldBeFlipped());
// All declaration in the ruleset have to be marked as flippable.
CssDeclarationBlockNode block = ruleset.getDeclarations();
assertEquals(2, block.getChildren().size());
assertFalse(block.getChildren().get(0).getShouldBeFlipped());
assertFalse(block.getChildren().get(1).getShouldBeFlipped());
}
public void testMarkNonFlippableConditional() {
parseAndBuildTree(linesToString(
"/* @noflip */ @if COND {",
" foo { top : expression('cond') }",
" bar { bottom : expression('cond') }",
"} @else {",
" bar { top : expression('cond') }",
"}"));
new CreateConditionalNodes(tree.getMutatingVisitController(),
errorManager).runPass();
runPass();
CssConditionalBlockNode block =
(CssConditionalBlockNode) tree.getRoot().getBody().getChildren().get(0);
assertFalse(block.getShouldBeFlipped());
// Check each of the conditional rules.
for (CssConditionalRuleNode rule : block.getChildren()) {
assertFalse(rule.getShouldBeFlipped());
// Check each of the rules inside the conditional rule.
for (CssNode node : rule.getBlock().getChildren()) {
assertTrue(node instanceof CssRulesetNode);
assertFalse(node.getShouldBeFlipped());
// Check each of the declarations inside the style rule.
for (CssNode decl
: ((CssRulesetNode) node).getDeclarations().getChildren()) {
assertFalse(decl.getShouldBeFlipped());
}
}
}
}
public void testMarkNonFlippableInConditional() {
parseAndBuildTree(linesToString(
"@if COND {",
" /* @noflip */foo { top : expression('cond') }",
" bar { bottom : expression('cond') }",
"} @else {",
" bar { top : expression('cond') }",
"}"));
new CreateConditionalNodes(tree.getMutatingVisitController(),
errorManager).runPass();
runPass();
CssConditionalBlockNode block =
(CssConditionalBlockNode) tree.getRoot().getBody().getChildren().get(0);
assertTrue(block.getShouldBeFlipped());
// Check each of the conditional rules.
// First conditional rule.
CssConditionalRuleNode rule = block.getChildren().get(0);
assertTrue(rule.getShouldBeFlipped());
// Check each of the rules inside the conditional rule.
int i = 0;
for (CssNode node : rule.getBlock().getChildren()) {
assertTrue(node instanceof CssRulesetNode);
if (i == 0) {
// Only the first rule is non flippable.
assertFalse(node.getShouldBeFlipped());
i++;
// Check each of the declarations inside the style rule.
for (CssNode decl
: ((CssRulesetNode) node).getDeclarations().getChildren()) {
assertFalse(decl.getShouldBeFlipped());
}
} else {
assertTrue(node.getShouldBeFlipped());
// Check each of the declarations inside the style rule.
for (CssNode decl
: ((CssRulesetNode) node).getDeclarations().getChildren()) {
assertTrue(decl.getShouldBeFlipped());
}
}
}
// Second conditional rule.
rule = block.getChildren().get(1);
assertTrue(rule.getShouldBeFlipped());
// Check each of the rules inside the conditional rule.
for (CssNode node : rule.getBlock().getChildren()) {
assertTrue(node instanceof CssRulesetNode);
assertTrue(node.getShouldBeFlipped());
// Check each of the declarations inside the style rule.
for (CssNode decl
: ((CssRulesetNode) node).getDeclarations().getChildren()) {
assertTrue(decl.getShouldBeFlipped());
}
}
}
public void testMarkNonFlippableMedia() {
parseAndBuildTree(linesToString(
"@media print /* @noflip */{",
" .CSS_RULE_1, .CSS_RULE_2:hover a {",
" border: thickBorder(red, 2px);",
" }",
"}",
"@media tv {",
" .CSS_RULE_1, .CSS_RULE_2:hover a /* @noflip */{",
" border: thickBorder(green, 2px);",
" }",
"}",
".CSS_RULE_3 { /* @noflip */top : expression('cond') }"
));
new CreateStandardAtRuleNodes(tree.getMutatingVisitController(),
errorManager).runPass();
runPass();
CssNode rule = tree.getRoot().getBody().getChildren().get(0);
assertTrue(rule instanceof CssMediaRuleNode);
assertFalse(rule.getShouldBeFlipped());
// Check the rules inside the media rule.
for (CssNode ruleset : ((CssMediaRuleNode) rule).getBlock().getChildren()) {
assertTrue(ruleset instanceof CssRulesetNode);
assertFalse(ruleset.getShouldBeFlipped());
// Check the declarations inside the ruleset.
for (CssNode decl
: ((CssRulesetNode) ruleset).getDeclarations().getChildren()) {
assertFalse(decl.getShouldBeFlipped());
}
}
// Check the second media rule.
rule = tree.getRoot().getBody().getChildren().get(1);
assertTrue(rule instanceof CssMediaRuleNode);
assertTrue(rule.getShouldBeFlipped());
for (CssNode ruleset : ((CssMediaRuleNode) rule).getBlock().getChildren()) {
assertTrue(ruleset instanceof CssRulesetNode);
assertFalse(ruleset.getShouldBeFlipped());
// Check the declarations inside the ruleset.
for (CssNode decl
: ((CssRulesetNode) ruleset).getDeclarations().getChildren()) {
assertFalse(decl.getShouldBeFlipped());
}
}
// Check the ruleset following the media rule.
rule = tree.getRoot().getBody().getChildren().get(2);
assertTrue(rule instanceof CssRulesetNode);
assertTrue(rule.getShouldBeFlipped());
// Check the declarations inside the ruleset.
for (CssNode decl
: ((CssRulesetNode) rule).getDeclarations().getChildren()) {
assertFalse(decl.getShouldBeFlipped());
}
}
@Override
protected void runPass() {
MarkNonFlippableNodes pass = new MarkNonFlippableNodes(
tree.getVisitController(), errorManager);
pass.runPass();
}
}