diff --git a/src/hcl/parser.py b/src/hcl/parser.py index 2b07d04..834d9f7 100644 --- a/src/hcl/parser.py +++ b/src/hcl/parser.py @@ -330,7 +330,7 @@ def p_function_0(self, p): self.print_p(p) p[0] = p[1] + p[2] + self.flatten(p[3]) + p[4] - + def p_function_1(self, p): ''' function : IDENTIFIER LEFTPAREN listitems COMMA RIGHTPAREN @@ -343,31 +343,11 @@ def p_function_1(self, p): def flatten(self, value): returnValue = "" if type(value) is dict: - returnValue += "{" - isFirstTime = True - for key in value: - if isFirstTime: - isFirstTime = False - else: - returnValue += "," - returnValue += key + ":" + self.flatten(value[key]) - returnValue += "}" + returnValue = "{" + ",".join(key + ":" + self.flatten(value[key]) for key in value) + "}" elif type(value) is list: - isFirstTime = True - for v in value: - if isFirstTime: - isFirstTime = False - else: - returnValue += "," - returnValue += self.flatten(v) + returnValue = ",".join(self.flatten(v) for v in value) elif type(value) is tuple: - isFirstTime = True - for v in value: - if isFirstTime: - isFirstTime = False - else: - returnValue += "," - returnValue += self.flatten(v) + returnValue = " ".join(self.flatten(v) for v in value) else: returnValue = value return returnValue @@ -400,13 +380,20 @@ def p_listitems_2(self, p): | objectkey COMMA objectkey | objectkey COMMA object | objectkey COMMA list - | objectkey COMMA IDENTIFIER ASTERISK_PERIOD IDENTIFIER ''' if DEBUG: self.print_p(p) p[0] = [p[1], p[3]] def p_listitems_3(self, p): + ''' + listitems : objectkey COMMA IDENTIFIER ASTERISK_PERIOD IDENTIFIER + ''' + if DEBUG: + self.print_p(p) + p[0] = [p[1], p[3] + p[4] + p[5]] + + def p_listitems_4(self, p): ''' listitems : objectkey list ''' diff --git a/tests/fixtures/function.hcl b/tests/fixtures/function.hcl new file mode 100644 index 0000000..c7c1ee5 --- /dev/null +++ b/tests/fixtures/function.hcl @@ -0,0 +1,7 @@ +data "resource" "object" { + vars = { + cluster_1 = join("\n", data.template_file.cluster_1.*.rendered) + cluster_2 = join("\n", data.template_file.cluster_2.*.rendered) + cluster_3 = format("name_%02d", count.index + 1) + } +} \ No newline at end of file diff --git a/tests/fixtures/function.json b/tests/fixtures/function.json new file mode 100644 index 0000000..6ccd8e9 --- /dev/null +++ b/tests/fixtures/function.json @@ -0,0 +1,13 @@ +{ + "data": { + "resource": { + "object": { + "vars": { + "cluster_1": "join(\\n,data.template_file.cluster_1.*.rendered)", + "cluster_2": "join(\\n,data.template_file.cluster_2.*.rendered)", + "cluster_3": "format(name_%02d,count.index + 1)" + } + } + } + } +} \ No newline at end of file diff --git a/tests/test_decoder.py b/tests/test_decoder.py index 60fc071..d4ba6ce 100644 --- a/tests/test_decoder.py +++ b/tests/test_decoder.py @@ -23,6 +23,7 @@ ('flat.hcl', None, {'foo': 'bar', 'Key': 7}), ('float.hcl', None, {'a': 1.02}), ('float.hcl', 'float.json', None), + ('function.hcl', 'function.json', None), ('multiline_bad.hcl', 'multiline.json', None), ('scientific.hcl', 'scientific.json', None), ('structure.hcl', 'structure_flat.json', None), diff --git a/tests/test_load_dump.py b/tests/test_load_dump.py new file mode 100644 index 0000000..5984541 --- /dev/null +++ b/tests/test_load_dump.py @@ -0,0 +1,99 @@ +# +# These tests are taken from hcl/parse_test.go +# + +from __future__ import print_function + +from os.path import join, dirname +import hcl +import json + +import pytest + +PARSE_FIXTURE_DIR = join(dirname(__file__), 'lex-fixtures') +PARSE_FIXTURES = [ + ( + "assign_colon.hcl", + False, + ), + ( + "comment.hcl", + False, + ), + ( + "list_comma.hcl", + False, + ), + ( + "list_of_maps.hcl", + False, + ), + ( + "multiple.hcl", + False, + ), + ( + "structure.hcl", + False, + ), + ( + "structure_basic.hcl", + False, + ), + ( + "structure_empty.hcl", + False, + ), + ( + "complex.hcl", + False, + ), + ( + "assign_deep.hcl", + False, + ), + ( + "types.hcl", + False, + ), + ( + "structure_comma.hcl", + False, + ), + ( + "terraform0.12syntax.hcl", + False, + ), + ( + "conditional_operator.hcl", + False, + ), +] + +@pytest.mark.parametrize("hcl_fname,invalid", PARSE_FIXTURES) +def test_parser_bytes(hcl_fname, invalid): + + with open(join(PARSE_FIXTURE_DIR, hcl_fname), 'rb') as fp: + + input = fp.read() + print(input) + + if not invalid: + hcl.loads(input) + else: + with pytest.raises(ValueError): + hcl.loads(input) + +@pytest.mark.parametrize("hcl_fname,invalid", PARSE_FIXTURES) +def test_parser_str(hcl_fname, invalid): + + with open(join(PARSE_FIXTURE_DIR, hcl_fname), 'r') as fp: + + input = fp.read() + print(input) + + if not invalid: + hcl.loads(input) + else: + with pytest.raises(ValueError): + hcl.loads(input)