Esempio n. 1
0
def test_parser_parse_basic():
    parser = Parser("abc\n  color: red\n", {})
    root = parser.parse()
    assert root.node_name == "root"
    assert root.nodes[0].node_name == "group"
    selector = root.nodes[0].nodes[0]
    assert selector.segments[0] == Literal("abc")
    assert selector.block.parent == root
    assert selector.block.node.node_name == "group"
    property = selector.block.nodes[0]
    assert property.node_name == "property"
    assert len(property.segments) == 1
    assert property.segments[0] == Ident("color", null, lineno=2, column=3)
    assert len(property.expr.nodes) == 1
    assert property.expr.nodes[0] == Ident("red", null, lineno=2, column=10)
Esempio n. 2
0
def test_evaluator_create():
    parser = Parser("abc\n  color: red\n", {})
    root = parser.parse()
    evaluator = Evaluator(root, parser=parser, options={})
    result = evaluator.evaluate()
    assert result.node_name == "root"
    assert result.nodes[0].node_name == "group"
    assert result.nodes[0].nodes[0].node_name == "selector"
    assert result.nodes[0].nodes[0].block.node_name == "block"
    assert result.nodes[0].nodes[0].block.nodes[0].node_name == "property"
    property = result.nodes[0].nodes[0].block.nodes[0]
    assert property.expr.node_name == "expression"
    assert property.expr.nodes[0].r == 255
    assert property.expr.nodes[0].name == "red"
    assert property.expr.nodes[0].a == 1
    assert property.expr.nodes[0].b == 0
    assert property.expr.nodes[0].g == 0
Esempio n. 3
0
    def mixin_object(self, object: ObjectNode):
        s = f"$block {object.to_block()}"
        p = Parser(s, utils.merge({"root": Root()}, self.options))
        try:
            block = p.parse()
        except StilusError as e:
            e.filename = self.filename
            e.lineno = p.lexer.lineno
            e.column = p.lexer.column
            e.input = s
            raise e

        block.parent = self.root
        block.scope = False

        ret = self.visit(block)
        values = ret.first().nodes
        for value in values:
            if value.block:
                self.mixin(value.block.nodes, self.get_current_block())
                break
Esempio n. 4
0
    def import_file(self, node: Import, file, literal, lineno=1, column=1):
        log.debug(f"importing {file}; {self.import_stack}")

        # handling 'require'
        if node.once:
            if self.require_history.get(file, False):
                return null
            self.require_history[file] = True

            if literal and not self.include_css:
                return node

        # avoid overflows from reimporting the same file
        if file in self.import_stack:
            raise ImportError("import loop has been found")

        with open(file, "r") as f:
            source = f.read()

        # shortcut for empty files
        if not source.strip():
            return null

        # expose imports
        node.path = file
        node.dirname = Path(file).parent
        # store modified time
        node.mtime = os.stat(file).st_mtime
        self.paths.append(str(node.dirname))

        if "_imports" in self.options:
            self.options["_imports"].append(node.clone())

        # parse the file
        self.import_stack.append(file)
        filename_node.current_filename = file

        if literal:
            re.sub("\n\n?", "\n", source)
            literal = Literal(source,
                              lineno=self.parser.lineno,
                              column=self.parser.column)
            literal.lineno = 1
            literal.column = 1
            if not self.resolve_url:
                return literal

        # create block
        block = Block(None, None, lineno=lineno, column=column)
        block.filename = file

        # parse
        merged = {}
        merged.update(self.options)
        merged.update({"root": block})
        parser = Parser(source, merged)

        try:
            block = parser.parse()
        except Exception:
            line = parser.lexer.lineno
            column = parser.lexer.column
            if literal and self.include_css and self.resolve_url:
                self.warn(f"ParseError: {file}:{line}:{column}. "
                          f"This file is included as-is")
                return literal
            else:
                raise ParseError(
                    "Issue when parsing an imported file",
                    filename=file,
                    lineno=line,
                    column=column,
                    input=source,
                )

        # evaluate imported 'root'
        block = block.clone(self.get_current_block())
        block.parent = self.get_current_block()
        block.scope = False
        ret = self.visit(block)
        self.import_stack.pop()

        if not self.resolve_url:  # or not self.resolve_url no_check:
            self.paths.pop()

        return ret