def test_list_node_str_should_return_formatted(): # Test a node with PairNodes as items node = ListNode( type=SyntaxToken("filters"), left_bracket=LeftBracket(), items=( PairNode(SyntaxToken("created_date"), QuotedSyntaxToken("7 days")), PairNode(SyntaxToken("user.status", prefix=" "), QuotedSyntaxToken("-disabled")), ), right_bracket=RightBracket(), ) assert str( node) == 'filters: [created_date: "7 days", user.status: "-disabled"]' # Test a node with SyntaxTokens as items node = ListNode( type=SyntaxToken("fields"), left_bracket=LeftBracket(), items=( SyntaxToken("user.user_id", prefix="\n "), SyntaxToken("user.age", prefix="\n ", suffix="\n"), ), right_bracket=RightBracket(), ) assert str(node) == "fields: [\n user.user_id,\n user.age\n]" # Test a node with zero items node = ListNode( type=SyntaxToken("fields"), left_bracket=LeftBracket(), items=tuple(), right_bracket=RightBracket(), ) assert str(node) == "fields: []"
def test_parse_list_with_pairs(): stream = ( tokens.LiteralToken("sorts", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.LiteralToken("orders.customer_id", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.LiteralToken("asc", 1), tokens.CommaToken(1), tokens.LiteralToken("orders.order_id", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.LiteralToken("desc", 1), tokens.ListEndToken(1), tokens.StreamEndToken(1), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("sorts"), left_bracket=LeftBracket(), items=( PairNode(SyntaxToken("orders.customer_id"), SyntaxToken("asc")), PairNode(SyntaxToken("orders.order_id"), SyntaxToken("desc")), ), right_bracket=RightBracket(), ) stream = ( tokens.LiteralToken("filters", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.WhitespaceToken("\n ", 1), tokens.LiteralToken("view_name.field_one", 2), tokens.ValueToken(2), tokens.WhitespaceToken(" ", 2), tokens.QuotedLiteralToken("-0,-1,-8,-9,-99,-NULL,-EMPTY", 2), tokens.WhitespaceToken("\n", 2), tokens.ListEndToken(3), tokens.StreamEndToken(3), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("filters"), left_bracket=LeftBracket(), items=( PairNode( SyntaxToken("view_name.field_one", prefix="\n "), QuotedSyntaxToken("-0,-1,-8,-9,-99,-NULL,-EMPTY"), ), ), right_bracket=RightBracket(prefix="\n"), )
def test_parse_list_with_inner_comment(): stream = ( tokens.LiteralToken("drill_fields", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.WhitespaceToken("\n ", 1), tokens.LiteralToken("view_name.field_one", 2), tokens.CommaToken(2), tokens.WhitespaceToken("\n ", 2), tokens.LiteralToken("view_name.field_two", 3), tokens.WhitespaceToken(" ", 3), tokens.CommentToken("# This is a comment", 3), tokens.WhitespaceToken("\n", 3), tokens.ListEndToken(4), tokens.StreamEndToken(4), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("drill_fields", 1), colon=Colon(line_number=1, suffix=" "), left_bracket=LeftBracket(), items=( SyntaxToken("view_name.field_one", 2, prefix="\n "), SyntaxToken("view_name.field_two", 3, prefix="\n ", suffix=" # This is a comment\n"), ), right_bracket=RightBracket(), )
def test_block_node_str_should_return_formatted(): # Test a regular block node = BlockNode( type=SyntaxToken("set"), name=SyntaxToken("user_dimensions"), left_brace=LeftCurlyBrace(prefix=" ", suffix=" "), container=ContainerNode((ListNode( type=SyntaxToken("fields"), left_bracket=LeftBracket(), items=( SyntaxToken("user.user_id"), SyntaxToken("user.age", prefix=" "), ), right_bracket=RightBracket(), ), )), right_brace=RightCurlyBrace(prefix=" "), ) assert str( node) == "set: user_dimensions { fields: [user.user_id, user.age] }" # Test a block with no expression node = BlockNode( type=SyntaxToken("set"), name=SyntaxToken("foo"), left_brace=LeftCurlyBrace(prefix=" "), container=tuple(), right_brace=RightCurlyBrace(), ) assert str(node) == "set: foo {}"
def test_parse_list_with_literals(): stream = ( tokens.LiteralToken("drill_fields", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.LiteralToken("view_name.field_one", 1), tokens.CommaToken(1), tokens.WhitespaceToken(" ", 1), tokens.LiteralToken("view_name.field_two", 1), tokens.CommaToken(1), tokens.WhitespaceToken(" ", 1), tokens.LiteralToken("view_name.field_three", 1), tokens.ListEndToken(1), tokens.StreamEndToken(1), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("drill_fields"), left_bracket=LeftBracket(), items=( SyntaxToken("view_name.field_one"), SyntaxToken("view_name.field_two", prefix=" "), SyntaxToken("view_name.field_three", prefix=" "), ), right_bracket=RightBracket(), )
def test_parse_list_with_trailing_comma(): stream = ( tokens.LiteralToken("drill_fields", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.LiteralToken("view_name.field_one", 1), tokens.CommaToken(1), tokens.ListEndToken(1), tokens.StreamEndToken(1), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("drill_fields", 1), colon=Colon(line_number=1, suffix=" "), left_bracket=LeftBracket(), items=(SyntaxToken("view_name.field_one", 1), ), trailing_comma=Comma(), right_bracket=RightBracket(), ) # Test when the list items are separated by newlines stream = ( tokens.LiteralToken("drill_fields", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.WhitespaceToken("\n ", 1), tokens.LiteralToken("view_name.field_one", 2), tokens.CommaToken(2), tokens.WhitespaceToken("\n", 2), tokens.ListEndToken(3), tokens.StreamEndToken(3), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("drill_fields", 1), colon=Colon(line_number=1, suffix=" "), left_bracket=LeftBracket(), items=(SyntaxToken("view_name.field_one", 2, prefix="\n "), ), trailing_comma=Comma(), right_bracket=RightBracket(prefix="\n"), )
def test_parse_list_with_no_contents(): stream = ( tokens.LiteralToken("drill_fields", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.ListEndToken(1), tokens.StreamEndToken(1), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("drill_fields", 1), colon=Colon(line_number=1, suffix=" "), left_bracket=LeftBracket(), items=tuple(), right_bracket=RightBracket(), ) # Add whitespace between brackets stream = ( tokens.LiteralToken("drill_fields", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListEndToken(1), tokens.StreamEndToken(1), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("drill_fields", 1), colon=Colon(line_number=1, suffix=" "), left_bracket=LeftBracket(), items=tuple(), right_bracket=RightBracket(prefix=" "), )
def test_container_node_str_should_return_formatted(): node = ContainerNode(( PairNode(SyntaxToken("hidden"), SyntaxToken("true")), BlockNode( type=SyntaxToken("set", prefix=" "), name=SyntaxToken("foo"), left_brace=LeftCurlyBrace(prefix=" "), container=tuple(), right_brace=RightCurlyBrace(), ), ListNode( type=SyntaxToken("fields", prefix=" "), left_bracket=LeftBracket(), items=tuple(), right_bracket=RightBracket(), ), )) assert str(node) == "hidden: true set: foo {} fields: []"
def test_parse_list_with_only_comment(): stream = ( tokens.LiteralToken("drill_fields", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.WhitespaceToken("\n ", 1), tokens.CommentToken("# Put some fields here", 2), tokens.WhitespaceToken("\n", 2), tokens.ListEndToken(3), tokens.StreamEndToken(3), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("drill_fields"), left_bracket=LeftBracket(), items=tuple(), right_bracket=RightBracket(prefix="\n # Put some fields here\n"), )
def test_parse_list_with_leading_comma(): stream = ( tokens.LiteralToken("drill_fields", 1), tokens.ValueToken(1), tokens.WhitespaceToken(" ", 1), tokens.ListStartToken(1), tokens.CommaToken(1), tokens.LiteralToken("view_name.field_one", 1), tokens.ListEndToken(1), tokens.StreamEndToken(1), ) parser = lkml.parser.Parser(stream) result = parser.parse_list() assert result == ListNode( type=SyntaxToken("drill_fields", 1), colon=Colon(line_number=1, suffix=" "), left_bracket=LeftBracket(), items=(SyntaxToken("view_name.field_one", 1), ), right_bracket=RightBracket(), leading_comma=Comma(), )
def parse_list(self, key: str, values: Sequence[Union[str, Dict]]) -> ListNode: """Serializes a sequence to a LookML block. Args: key: A LookML field type (e.g. "fields") values: A sequence to serialize (e.g. ["orders.order_id", "orders.item"]) Returns: A generator of serialized string chunks """ # `suggestions` is only quoted when it's a list, so override the default force_quote = True if key == "suggestions" else False prev_parent_key = self.parent_key self.parent_key = key type_token = SyntaxToken(key, prefix=self.prefix) right_bracket = RightBracket() items: list = [] pair_mode = False # Check the first element to see if it's a single value or a pair if values and not isinstance(values[0], (str, int)): pair_mode = True # Coerce type depending on pair mode value if pair_mode: items = cast(List[PairNode], items) else: items = cast(List[SyntaxToken], items) # Choose newline delimiting or space delimiting based on contents if len(values) >= 5 or pair_mode: trailing_comma = True self.increase_level() for value in values: if pair_mode: value = cast(dict, value) # Extract key and value from dictionary with only one key [(key, val)] = value.items() pair: PairNode = self.parse_pair(key, val) items.append(pair) else: value = cast(str, value) token: SyntaxToken = self.parse_token( key, value, force_quote, prefix=self.newline_indent ) items.append(token) self.decrease_level() right_bracket = RightBracket(prefix=self.newline_indent) else: trailing_comma = False for i, value in enumerate(values): value = cast(str, value) if i == 0: token = self.parse_token(key, value, force_quote) else: token = self.parse_token(key, value, force_quote, prefix=" ") items.append(token) self.parent_key = prev_parent_key node = ListNode( type=type_token, left_bracket=LeftBracket(), items=tuple(items), right_bracket=right_bracket, trailing_comma=trailing_comma, ) self.latest_node = ListNode return node