def test_parser_is_selector_token(): parser = Parser("", {}) tokens = [Token("atrule"), Token("ident"), Token("comment"), Token("not")] parser.lexer.lookahead = MagicMock(side_effect=tokens) assert parser.is_selector_token(1) is False assert parser.is_selector_token(2) is True assert parser.is_selector_token(3) is True assert parser.is_selector_token(4) is False
def test_parser_line_contains(): parser = Parser("", {}) tokens = [Token("space"), Token("indent"), Token("comments")] parser.lexer.lookahead = MagicMock(side_effect=tokens) assert parser.line_contains("{") is False tokens = [Token("space"), Token("{"), Token("outdent")] parser.lexer.lookahead = MagicMock(side_effect=tokens) assert parser.line_contains("{") is True
def parse(selector): from stilus.parser import Parser parser = Parser(selector, {}) parser.state.append("selector-parts") nodes = parser.stmt_selector() for node in nodes: node.value = "".join([str(segment) for segment in node.segments]) return nodes
def test_parser_iterator(): parser = Parser("abc\n color: red\n", {}) tokens = [token for token in parser] assert len(tokens) == 6 assert tokens[3].type == ":" parser = Parser("abc\n color red\n", {}) tokens = [token for token in parser] assert len(tokens) == 6 assert tokens[3].type == "space"
def test_parser_property(): parser = Parser("color: red\n", {}) property = parser.property() assert property.segments[0] == Ident( "color", null, False, lineno=1, column=1 ) assert property.expr.nodes[0] == Ident( "red", null, False, lineno=1, column=8 )
def parse_string(str: String): from stilus.parser import Parser try: parser = Parser(str, {}) result = parser.list() except BaseException: result = Literal(str) return result
def test_parser_accept(): parser = Parser("abc\n color: red\n", {}) assert parser.accept(":") is None # invalid assert parser.accept("ident").type == "ident" # abc assert parser.accept("indent").type == "indent" assert parser.accept("ident").type == "ident" # color assert parser.accept(":").type == ":" assert parser.accept("ident").type == "ident" # red assert parser.accept("outdent").type == "outdent" assert parser.accept("eos").type == "eos"
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)
def visit_querylist(self, queries): for node in queries.nodes: self.visit(node) if len(queries.nodes) == 1: query = queries.nodes[0] val = self.lookup(query.type) if val: if hasattr(val, "first") and hasattr(val.first(), "string"): val = val.first().string else: return queries parser = Parser(val, self.options) queries = self.visit(parser.queries()) return queries
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
def test_parser_selector(): parser = Parser("abc\n color: red\n", {}) selector = parser.stmt_selector() assert selector.node_name == "group" assert type(selector) == Group assert len(selector.nodes) == 1 assert selector.nodes[0].node_name == "selector" assert len(selector.nodes[0].segments) == 1 assert selector.nodes[0].segments[0] == Literal("abc") block = selector.nodes[0].block assert block.node_name == "block" assert len(block.nodes) == 1 property = 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)
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
def test_parser_selector_parts(): parser = Parser("abc\n color: red\n", {}) assert parser.selector_parts() == deque([Literal("abc")]) parser = Parser("abc def efg\n color: red\n", {}) assert parser.selector_parts() == deque( [ Literal("abc"), Literal(" "), Literal("def"), Literal(" "), Literal("efg"), ] ) parser = Parser("abc:\n color: red\n", {}) assert parser.selector_parts() == deque( [ Literal("abc"), Literal(":"), Literal("color"), Literal(":"), Literal(" "), Literal("red"), ] )
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
def test_parser_expect(): parser = Parser("abc\n color: red\n", {}) assert parser.expect("ident").type == "ident" # abc assert parser.expect("indent").type == "indent" assert parser.expect("ident").type == "ident" # color assert parser.expect(":").type == ":" assert parser.expect("ident").type == "ident" # red assert parser.expect("outdent").type == "outdent" with pytest.raises(ParseError) as excinfo: parser.expect(":") is None # invalid assert 'expected ":", got "eos"' in str(excinfo.value) assert parser.expect("eos").type == "eos"
def test_parser_list(): parser = Parser("color: red\n", {}) list = parser.list() assert len(list) == 1 assert list.nodes[0] == Ident("color", null, False, lineno=1, column=1)
def test_parser_peek_lookahead_and_next(): parser = Parser("abc\n color: red\n", {}) # next node = parser.next() assert node.type == "ident" assert node.value == Ident("abc", lineno=1, column=1) node = parser.next() assert node.type == "indent" assert node.value is None # peek assert parser.peek().type == "ident" assert parser.peek().type == "ident" assert parser.peek().type == "ident" # lookahead assert parser.lookahead(1) == parser.peek() assert parser.lookahead(2).type == ":" assert parser.lookahead(2).value == ":" assert parser.lookahead(2).space == " " # next parser.next() node = parser.next() assert node.type == ":" assert node.value == ":" assert node.space == " " # combo assert parser.peek().type == "ident" parser.next() assert parser.peek().type == "outdent" parser.next() assert parser.peek().type == "eos"
def test_parser_construct(): parser = Parser("abc\n color: red\n", {}) assert parser.css == 0 assert parser.parens == 0 assert parser.prefix == ""
def test_parser_selector_token(): parser = Parser("", {}) tokens = [Token("ident"), Token(":")] parser.lexer.lookahead = MagicMock(side_effect=tokens) parser.lexer.next = MagicMock(side_effect=tokens) assert parser.selector_token() == Token("ident")