@FactoryTest
  public void compareScssWithCss(String scssResourceName) throws Exception {
    File scssFile = getSassLangResourceFile(scssResourceName);

    SCSSDocumentHandler documentHandler = new SCSSDocumentHandlerImpl();
    SCSSErrorHandler errorHandler =
        new SCSSErrorHandler() {
          @Override
          public void error(CSSParseException arg0) throws CSSException {
            super.error(arg0);
            Assert.fail(arg0.getMessage());
          }

          @Override
          public void fatalError(CSSParseException arg0) throws CSSException {
            super.error(arg0);
            Assert.fail(arg0.getMessage());
          }

          @Override
          public void traverseError(Exception e) {
            super.traverseError(e);
            Assert.fail(e.getMessage());
          }

          @Override
          public void traverseError(String message) {
            super.traverseError(message);
            Assert.fail(message);
          }
        };

    ScssStylesheet scssStylesheet =
        ScssStylesheet.get(scssFile.getCanonicalPath(), null, documentHandler, errorHandler);
    scssStylesheet.compile();
    String parsedCss = scssStylesheet.printState();

    if (getCssFile(scssFile) != null) {
      String referenceCss = IOUtils.toString(new FileInputStream(getCssFile(scssFile)));
      String normalizedReference = normalize(referenceCss);
      String normalizedParsed = normalize(parsedCss);

      Assert.assertEquals(
          "Original CSS and parsed CSS do not match for " + scssResourceName,
          normalizedReference,
          normalizedParsed);
    }
  }
Example #2
0
  @Override
  public void traverse() {
    try {
      // limit variable scope to the mixin
      Map<String, VariableNode> variableScope = ScssStylesheet.openVariableScope();

      replaceVariables(ScssStylesheet.getVariables());
      replaceVariablesForChildren();
      MixinNodeHandler.traverse(this);

      ScssStylesheet.closeVariableScope(variableScope);

    } catch (Exception e) {
      Logger.getLogger(MixinNode.class.getName()).log(Level.SEVERE, null, e);
    }
  }
Example #3
0
 protected void replaceVariablesForChildren() {
   for (Node child : getChildren()) {
     if (child instanceof IVariableNode) {
       ((IVariableNode) child).replaceVariables(ScssStylesheet.getVariables());
     }
   }
 }
Example #4
0
 @Override
 public void traverse() {
   /*
    * "replaceVariables(ScssStylesheet.getVariables());" seems duplicated
    * and can be extracted out of if, but it is not.
    * containsArithmeticalOperator must be called before replaceVariables.
    * Because for the "/" operator, it needs to see if its predecessor or
    * successor is a Variable or not, to determine it is an arithmetic
    * operator.
    */
   if (ArithmeticExpressionEvaluator.get().containsArithmeticalOperator(value)) {
     replaceVariables(ScssStylesheet.getVariables());
     value = ArithmeticExpressionEvaluator.get().evaluate(value);
   } else {
     replaceVariables(ScssStylesheet.getVariables());
   }
 }
  @Test
  public void test() {
    /*
     * Read initial css code
     */
    CssParser cssParserInputFile = new Css3Parser();
    try {
      cssParserInputFile.parse(Config.getInstance().inputFile());
      cssParserInputFile.removeDuplicates();
    } catch (CssParsingException e) {
      IoUtils.printErrorAndExit(e);
    }

    /*
     * Generate sass code from initial css code
     */
    Pair<List<SslMixin>, List<SslRuleset>> statements = null;
    try {
      statements = CssToSsl.compute(cssParserInputFile.getRulesets());
    } catch (Exception e) {
      IoUtils.printErrorAndExit(e);
    }

    /*
     * Write generated sass code
     */
    try {
      SslWriter sslWriter = new SassWriterDebug();
      sslWriter.writeGeneratedCode(statements, Config.getInstance().outputFile());
    } catch (IOException e) {
      IoUtils.printErrorAndExit(e);
    }

    /*
     * Generate css code from generated sass code
     */
    try {
      ScssStylesheet stylesheet = ScssStylesheet.get(this.sassGeneratedFile.toString());
      stylesheet.compile();
      Files.write(this.cssGeneratedFile.toPath(), stylesheet.printState().getBytes());
    } catch (Exception e) {
      IoUtils.printErrorAndExit(e);
    }

    /*
     * Read generated css code
     */
    CssParser cssParserGeneratedFile = new Css3Parser();
    try {
      cssParserGeneratedFile.parse(this.cssGeneratedFile);
      if (!Config.getInstance().noDuplicatesInRuleset()) {
        cssParserGeneratedFile.removeDuplicates();
      }
    } catch (CssParsingException e) {
      IoUtils.printErrorAndExit(e);
    }

    /*
     * Compare initial css file and generated css file,
     * according to the configuration
     */
    List<CssRuleset> initialRulesets = cssParserInputFile.getRulesets();
    List<CssRuleset> generatedRulesets = cssParserGeneratedFile.getRulesets();

    if (Config.getInstance().preserveSemantic()) {
      Consumer<List<CssRuleset>> rulesetsSorting =
          r -> {
            Collections.sort(
                r,
                (CssRuleset r1, CssRuleset r2) -> {
                  Selector s1 = r1.getSelector();
                  Selector s2 = r2.getSelector();
                  int firstRulesetPosition = s1.getPosition().getLineNumber();
                  int secondRulesetPosition = s2.getPosition().getLineNumber();
                  if (firstRulesetPosition < secondRulesetPosition) {
                    return -1;
                  } else if (firstRulesetPosition == secondRulesetPosition) {
                    return s1.getSelector().compareTo(s2.getSelector());
                  } else {
                    return 1;
                  }
                });
          };

      assertEquals(initialRulesets.size(), generatedRulesets.size());

      rulesetsSorting.accept(initialRulesets);
      rulesetsSorting.accept(generatedRulesets);

      for (int i = 0; i < initialRulesets.size(); i++) {
        CssRuleset initialRuleset = initialRulesets.get(i);
        CssRuleset generatedRuleset = generatedRulesets.get(i);

        String initialSelector = initialRuleset.getSelector().getSelector();
        String generatedSelector = generatedRuleset.getSelector().getSelector();

        List<DeclarationConcrete> initialDeclarations = initialRuleset.getDeclarations();
        List<DeclarationConcrete> generatedDeclarations = generatedRuleset.getDeclarations();

        assertEquals(initialSelector, generatedSelector);

        if (Config.getInstance().noDuplicatesInRuleset()) {
          assertEquals(initialDeclarations.size(), generatedDeclarations.size());
        }

        assertEquals(Sets.newHashSet(initialDeclarations), Sets.newHashSet(generatedDeclarations));
      }
    } else {
      Function<List<CssRuleset>, Map<String, List<DeclarationConcrete>>> mergeIdenticalSelectors =
          rulesets -> {
            Map<String, List<DeclarationConcrete>> result = new HashMap<>();
            rulesets.forEach(
                ruleset -> {
                  String selector = ruleset.getSelector().getSelector();
                  List<DeclarationConcrete> declarations = ruleset.getDeclarations();
                  if (!result.containsKey(selector)) {
                    result.put(selector, Lists.newArrayList());
                  }
                  result.get(selector).addAll(declarations);
                });
            return result;
          };

      Map<String, List<DeclarationConcrete>> initialData =
          mergeIdenticalSelectors.apply(initialRulesets);
      Map<String, List<DeclarationConcrete>> generatedData =
          mergeIdenticalSelectors.apply(generatedRulesets);

      assertEquals(initialData.keySet(), generatedData.keySet());

      initialData.forEach(
          (initialSelector, initialDeclarations) -> {
            List<DeclarationConcrete> generatedDeclarations = generatedData.get(initialSelector);

            if (Config.getInstance().noDuplicatesInRuleset()) {
              assertEquals(initialDeclarations.size(), generatedDeclarations.size());
            }

            assertEquals(
                Sets.newHashSet(initialDeclarations), Sets.newHashSet(generatedDeclarations));
          });
    }
  }