summaryrefslogtreecommitdiffstats
path: root/_test/test_comments.py
diff options
context:
space:
mode:
Diffstat (limited to '_test/test_comments.py')
-rw-r--r--_test/test_comments.py964
1 files changed, 964 insertions, 0 deletions
diff --git a/_test/test_comments.py b/_test/test_comments.py
new file mode 100644
index 0000000..7973349
--- /dev/null
+++ b/_test/test_comments.py
@@ -0,0 +1,964 @@
+# coding: utf-8
+
+"""
+comment testing is all about roundtrips
+these can be done in the "old" way by creating a file.data and file.roundtrip
+but there is little flexibility in doing that
+
+but some things are not easily tested, eog. how a
+roundtrip changes
+
+"""
+
+import pytest
+
+from .roundtrip import dedent, round_trip, round_trip_dump, round_trip_load
+
+
+class TestComments:
+ def test_no_end_of_file_eol(self):
+ """not excluding comments caused some problems if at the end of
+ the file without a newline. First error, then included \0"""
+ x = """\
+ - europe: 10 # abc"""
+ round_trip(x, extra='\n')
+ with pytest.raises(AssertionError):
+ round_trip(x, extra='a\n')
+
+ def test_no_comments(self):
+ round_trip(
+ """
+ - europe: 10
+ - usa:
+ - ohio: 2
+ - california: 9
+ """
+ )
+
+ def test_round_trip_ordering(self):
+ round_trip(
+ """
+ a: 1
+ b: 2
+ c: 3
+ b1: 2
+ b2: 2
+ d: 4
+ e: 5
+ f: 6
+ """
+ )
+
+ def test_complex(self):
+ round_trip(
+ """
+ - europe: 10 # top
+ - usa:
+ - ohio: 2
+ - california: 9 # o
+ """
+ )
+
+ def test_dropped(self):
+ s = """\
+ # comment
+ scalar
+ ...
+ """
+ round_trip(s, 'scalar\n...\n')
+
+ def test_main_mapping_begin_end(self):
+ round_trip(
+ """
+ # C start a
+ # C start b
+ abc: 1
+ ghi: 2
+ klm: 3
+ # C end a
+ # C end b
+ """
+ )
+
+ def test_reindent(self):
+ x = """\
+ a:
+ b: # comment 1
+ c: 1 # comment 2
+ """
+ d = round_trip_load(x)
+ y = round_trip_dump(d, indent=4)
+ assert y == dedent(
+ """\
+ a:
+ b: # comment 1
+ c: 1 # comment 2
+ """
+ )
+
+ def test_main_mapping_begin_end_items_post(self):
+ round_trip(
+ """
+ # C start a
+ # C start b
+ abc: 1 # abc comment
+ ghi: 2
+ klm: 3 # klm comment
+ # C end a
+ # C end b
+ """
+ )
+
+ def test_main_sequence_begin_end(self):
+ round_trip(
+ """
+ # C start a
+ # C start b
+ - abc
+ - ghi
+ - klm
+ # C end a
+ # C end b
+ """
+ )
+
+ def test_main_sequence_begin_end_items_post(self):
+ round_trip(
+ """
+ # C start a
+ # C start b
+ - abc # abc comment
+ - ghi
+ - klm # klm comment
+ # C end a
+ # C end b
+ """
+ )
+
+ def test_main_mapping_begin_end_complex(self):
+ round_trip(
+ """
+ # C start a
+ # C start b
+ abc: 1
+ ghi: 2
+ klm:
+ 3a: alpha
+ 3b: beta # it is all greek to me
+ # C end a
+ # C end b
+ """
+ )
+
+ def test_09(self): # 2.9 from the examples in the spec
+ s = """\
+ hr: # 1998 hr ranking
+ - Mark McGwire
+ - Sammy Sosa
+ rbi:
+ # 1998 rbi ranking
+ - Sammy Sosa
+ - Ken Griffey
+ """
+ round_trip(s, indent=4, block_seq_indent=2)
+
+ def test_09a(self):
+ round_trip(
+ """
+ hr: # 1998 hr ranking
+ - Mark McGwire
+ - Sammy Sosa
+ rbi:
+ # 1998 rbi ranking
+ - Sammy Sosa
+ - Ken Griffey
+ """
+ )
+
+ def test_simple_map_middle_comment(self):
+ round_trip(
+ """
+ abc: 1
+ # C 3a
+ # C 3b
+ ghi: 2
+ """
+ )
+
+ def test_map_in_map_0(self):
+ round_trip(
+ """
+ map1: # comment 1
+ # comment 2
+ map2:
+ key1: val1
+ """
+ )
+
+ def test_map_in_map_1(self):
+ # comment is moved from value to key
+ round_trip(
+ """
+ map1:
+ # comment 1
+ map2:
+ key1: val1
+ """
+ )
+
+ def test_application_arguments(self):
+ # application configur
+ round_trip(
+ """
+ args:
+ username: anthon
+ passwd: secret
+ fullname: Anthon van der Neut
+ tmux:
+ session-name: test
+ loop:
+ wait: 10
+ """
+ )
+
+ def test_substitute(self):
+ x = """
+ args:
+ username: anthon # name
+ passwd: secret # password
+ fullname: Anthon van der Neut
+ tmux:
+ session-name: test
+ loop:
+ wait: 10
+ """
+ data = round_trip_load(x)
+ data['args']['passwd'] = 'deleted password'
+ # note the requirement to add spaces for alignment of comment
+ x = x.replace(': secret ', ': deleted password')
+ assert round_trip_dump(data) == dedent(x)
+
+ def test_set_comment(self):
+ round_trip(
+ """
+ !!set
+ # the beginning
+ ? a
+ # next one is B (lowercase)
+ ? b # You see? Promised you.
+ ? c
+ # this is the end
+ """
+ )
+
+ def test_omap_comment_roundtrip(self):
+ round_trip(
+ """
+ !!omap
+ - a: 1
+ - b: 2 # two
+ - c: 3 # three
+ - d: 4
+ """
+ )
+
+ def test_omap_comment_roundtrip_pre_comment(self):
+ round_trip(
+ """
+ !!omap
+ - a: 1
+ - b: 2 # two
+ - c: 3 # three
+ # last one
+ - d: 4
+ """
+ )
+
+ def test_non_ascii(self):
+ round_trip(
+ """
+ verbosity: 1 # 0 is minimal output, -1 none
+ base_url: http://gopher.net
+ special_indices: [1, 5, 8]
+ also_special:
+ - a
+ - 19
+ - 32
+ asia and europe: &asia_europe
+ Turkey: Ankara
+ Russia: Moscow
+ countries:
+ Asia:
+ <<: *asia_europe
+ Japan: Tokyo # 東京
+ Europe:
+ <<: *asia_europe
+ Spain: Madrid
+ Italy: Rome
+ """
+ )
+
+ def test_dump_utf8(self):
+ import ruyaml # NOQA
+
+ x = dedent(
+ """\
+ ab:
+ - x # comment
+ - y # more comment
+ """
+ )
+ data = round_trip_load(x)
+ for utf in [True, False]:
+ y = round_trip_dump(data, default_flow_style=False, allow_unicode=utf)
+ assert y == x
+
+ def test_dump_unicode_utf8(self):
+ import ruyaml # NOQA
+
+ x = dedent(
+ """\
+ ab:
+ - x # comment
+ - y # more comment
+ """
+ )
+ data = round_trip_load(x)
+ for utf in [True, False]:
+ y = round_trip_dump(data, default_flow_style=False, allow_unicode=utf)
+ assert y == x
+
+ def test_mlget_00(self):
+ x = """\
+ a:
+ - b:
+ c: 42
+ - d:
+ f: 196
+ e:
+ g: 3.14
+ """
+ d = round_trip_load(x)
+ assert d.mlget(['a', 1, 'd', 'f'], list_ok=True) == 196
+ # with pytest.raises(AssertionError):
+ # d.mlget(['a', 1, 'd', 'f']) == 196
+
+
+class TestInsertPopList:
+ """list insertion is more complex than dict insertion, as you
+ need to move the values to subsequent keys on insert"""
+
+ @property
+ def ins(self):
+ return """\
+ ab:
+ - a # a
+ - b # b
+ - c
+ - d # d
+
+ de:
+ - 1
+ - 2
+ """
+
+ def test_insert_0(self):
+ d = round_trip_load(self.ins)
+ d['ab'].insert(0, 'xyz')
+ y = round_trip_dump(d, indent=2)
+ assert y == dedent(
+ """\
+ ab:
+ - xyz
+ - a # a
+ - b # b
+ - c
+ - d # d
+
+ de:
+ - 1
+ - 2
+ """
+ )
+
+ def test_insert_1(self):
+ d = round_trip_load(self.ins)
+ d['ab'].insert(4, 'xyz')
+ y = round_trip_dump(d, indent=2)
+ assert y == dedent(
+ """\
+ ab:
+ - a # a
+ - b # b
+ - c
+ - d # d
+
+ - xyz
+ de:
+ - 1
+ - 2
+ """
+ )
+
+ def test_insert_2(self):
+ d = round_trip_load(self.ins)
+ d['ab'].insert(1, 'xyz')
+ y = round_trip_dump(d, indent=2)
+ assert y == dedent(
+ """\
+ ab:
+ - a # a
+ - xyz
+ - b # b
+ - c
+ - d # d
+
+ de:
+ - 1
+ - 2
+ """
+ )
+
+ def test_pop_0(self):
+ d = round_trip_load(self.ins)
+ d['ab'].pop(0)
+ y = round_trip_dump(d, indent=2)
+ print(y)
+ assert y == dedent(
+ """\
+ ab:
+ - b # b
+ - c
+ - d # d
+
+ de:
+ - 1
+ - 2
+ """
+ )
+
+ def test_pop_1(self):
+ d = round_trip_load(self.ins)
+ d['ab'].pop(1)
+ y = round_trip_dump(d, indent=2)
+ print(y)
+ assert y == dedent(
+ """\
+ ab:
+ - a # a
+ - c
+ - d # d
+
+ de:
+ - 1
+ - 2
+ """
+ )
+
+ def test_pop_2(self):
+ d = round_trip_load(self.ins)
+ d['ab'].pop(2)
+ y = round_trip_dump(d, indent=2)
+ print(y)
+ assert y == dedent(
+ """\
+ ab:
+ - a # a
+ - b # b
+ - d # d
+
+ de:
+ - 1
+ - 2
+ """
+ )
+
+ def test_pop_3(self):
+ d = round_trip_load(self.ins)
+ d['ab'].pop(3)
+ y = round_trip_dump(d, indent=2)
+ print(y)
+ assert y == dedent(
+ """\
+ ab:
+ - a # a
+ - b # b
+ - c
+ de:
+ - 1
+ - 2
+ """
+ )
+
+
+# inspired by demux' question on stackoverflow
+# http://stackoverflow.com/a/36970608/1307905
+class TestInsertInMapping:
+ @property
+ def ins(self):
+ return """\
+ first_name: Art
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ """
+
+ def test_insert_at_pos_1(self):
+ d = round_trip_load(self.ins)
+ d.insert(1, 'last name', 'Vandelay', comment='new key')
+ y = round_trip_dump(d)
+ print(y)
+ assert y == dedent(
+ """\
+ first_name: Art
+ last name: Vandelay # new key
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ """
+ )
+
+ def test_insert_at_pos_0(self):
+ d = round_trip_load(self.ins)
+ d.insert(0, 'last name', 'Vandelay', comment='new key')
+ y = round_trip_dump(d)
+ print(y)
+ assert y == dedent(
+ """\
+ last name: Vandelay # new key
+ first_name: Art
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ """
+ )
+
+ def test_insert_at_pos_3(self):
+ # much more simple if done with appending.
+ d = round_trip_load(self.ins)
+ d.insert(3, 'last name', 'Vandelay', comment='new key')
+ y = round_trip_dump(d)
+ print(y)
+ assert y == dedent(
+ """\
+ first_name: Art
+ occupation: Architect # This is an occupation comment
+ about: Art Vandelay is a fictional character that George invents...
+ last name: Vandelay # new key
+ """
+ )
+
+
+class TestCommentedMapMerge:
+ def test_in_operator(self):
+ data = round_trip_load(
+ """
+ x: &base
+ a: 1
+ b: 2
+ c: 3
+ y:
+ <<: *base
+ k: 4
+ l: 5
+ """
+ )
+ assert data['x']['a'] == 1
+ assert 'a' in data['x']
+ assert data['y']['a'] == 1
+ assert 'a' in data['y']
+
+ def test_issue_60(self):
+ data = round_trip_load(
+ """
+ x: &base
+ a: 1
+ y:
+ <<: *base
+ """
+ )
+ assert data['x']['a'] == 1
+ assert data['y']['a'] == 1
+ assert str(data['y']) == """ordereddict([('a', 1)])"""
+
+ def test_issue_60_1(self):
+ data = round_trip_load(
+ """
+ x: &base
+ a: 1
+ y:
+ <<: *base
+ b: 2
+ """
+ )
+ assert data['x']['a'] == 1
+ assert data['y']['a'] == 1
+ assert str(data['y']) == """ordereddict([('b', 2), ('a', 1)])"""
+
+
+class TestEmptyLines:
+ # prompted by issue 46 from Alex Harvey
+ def test_issue_46(self):
+ yaml_str = dedent(
+ """\
+ ---
+ # Please add key/value pairs in alphabetical order
+
+ aws_s3_bucket: 'mys3bucket'
+
+ jenkins_ad_credentials:
+ bind_name: 'CN=svc-AAA-BBB-T,OU=Example,DC=COM,DC=EXAMPLE,DC=Local'
+ bind_pass: 'xxxxyyyy{'
+ """
+ )
+ d = round_trip_load(yaml_str, preserve_quotes=True)
+ y = round_trip_dump(d, explicit_start=True)
+ assert yaml_str == y
+
+ def test_multispace_map(self):
+ round_trip(
+ """
+ a: 1x
+
+ b: 2x
+
+
+ c: 3x
+
+
+
+ d: 4x
+
+ """
+ )
+
+ @pytest.mark.xfail(strict=True)
+ def test_multispace_map_initial(self):
+ round_trip(
+ """
+
+ a: 1x
+
+ b: 2x
+
+
+ c: 3x
+
+
+
+ d: 4x
+
+ """
+ )
+
+ def test_embedded_map(self):
+ round_trip(
+ """
+ - a: 1y
+ b: 2y
+
+ c: 3y
+ """
+ )
+
+ def test_toplevel_seq(self):
+ round_trip(
+ """\
+ - 1
+
+ - 2
+
+ - 3
+ """
+ )
+
+ def test_embedded_seq(self):
+ round_trip(
+ """
+ a:
+ b:
+ - 1
+
+ - 2
+
+
+ - 3
+ """
+ )
+
+ def test_line_with_only_spaces(self):
+ # issue 54
+ yaml_str = "---\n\na: 'x'\n \nb: y\n"
+ d = round_trip_load(yaml_str, preserve_quotes=True)
+ y = round_trip_dump(d, explicit_start=True)
+ stripped = ""
+ for line in yaml_str.splitlines():
+ stripped += line.rstrip() + '\n'
+ print(line + '$')
+ assert stripped == y
+
+ def test_some_eol_spaces(self):
+ # spaces after tokens and on empty lines
+ yaml_str = '--- \n \na: "x" \n \nb: y \n'
+ d = round_trip_load(yaml_str, preserve_quotes=True)
+ y = round_trip_dump(d, explicit_start=True)
+ stripped = ""
+ for line in yaml_str.splitlines():
+ stripped += line.rstrip() + '\n'
+ print(line + '$')
+ assert stripped == y
+
+ def test_issue_54_not_ok(self):
+ yaml_str = dedent(
+ """\
+ toplevel:
+
+ # some comment
+ sublevel: 300
+ """
+ )
+ d = round_trip_load(yaml_str)
+ print(d.ca)
+ y = round_trip_dump(d, indent=4)
+ print(y.replace('\n', '$\n'))
+ assert yaml_str == y
+
+ def test_issue_54_ok(self):
+ yaml_str = dedent(
+ """\
+ toplevel:
+ # some comment
+ sublevel: 300
+ """
+ )
+ d = round_trip_load(yaml_str)
+ y = round_trip_dump(d, indent=4)
+ assert yaml_str == y
+
+ def test_issue_93(self):
+ round_trip(
+ """\
+ a:
+ b:
+ - c1: cat # a1
+ # my comment on catfish
+ - c2: catfish # a2
+ """
+ )
+
+ def test_issue_93_00(self):
+ round_trip(
+ """\
+ a:
+ - - c1: cat # a1
+ # my comment on catfish
+ - c2: catfish # a2
+ """
+ )
+
+ def test_issue_93_01(self):
+ round_trip(
+ """\
+ - - c1: cat # a1
+ # my comment on catfish
+ - c2: catfish # a2
+ """
+ )
+
+ def test_issue_93_02(self):
+ # never failed as there is no indent
+ round_trip(
+ """\
+ - c1: cat
+ # my comment on catfish
+ - c2: catfish
+ """
+ )
+
+ def test_issue_96(self):
+ # inserted extra line on trailing spaces
+ round_trip(
+ """\
+ a:
+ b:
+ c: c_val
+ d:
+
+ e:
+ g: g_val
+ """
+ )
+
+
+class TestUnicodeComments:
+ def test_issue_55(self): # reported by Haraguroicha Hsu
+ round_trip(
+ """\
+ name: TEST
+ description: test using
+ author: Harguroicha
+ sql:
+ command: |-
+ select name from testtbl where no = :no
+
+ ci-test:
+ - :no: 04043709 # 小花
+ - :no: 05161690 # 茶
+ - :no: 05293147 # 〇𤋥川
+ - :no: 05338777 # 〇〇啓
+ - :no: 05273867 # 〇
+ - :no: 05205786 # 〇𤦌
+ """
+ )
+
+
+class TestEmptyValueBeforeComments:
+ def test_issue_25a(self):
+ round_trip(
+ """\
+ - a: b
+ c: d
+ d: # foo
+ - e: f
+ """
+ )
+
+ def test_issue_25a1(self):
+ round_trip(
+ """\
+ - a: b
+ c: d
+ d: # foo
+ e: f
+ """
+ )
+
+ def test_issue_25b(self):
+ round_trip(
+ """\
+ var1: #empty
+ var2: something #notempty
+ """
+ )
+
+ def test_issue_25c(self):
+ round_trip(
+ """\
+ params:
+ a: 1 # comment a
+ b: # comment b
+ c: 3 # comment c
+ """
+ )
+
+ def test_issue_25c1(self):
+ round_trip(
+ """\
+ params:
+ a: 1 # comment a
+ b: # comment b
+ # extra
+ c: 3 # comment c
+ """
+ )
+
+ def test_issue_25_00(self):
+ round_trip(
+ """\
+ params:
+ a: 1 # comment a
+ b: # comment b
+ """
+ )
+
+ def test_issue_25_01(self):
+ round_trip(
+ """\
+ a: # comment 1
+ # comment 2
+ - b: # comment 3
+ c: 1 # comment 4
+ """
+ )
+
+ def test_issue_25_02(self):
+ round_trip(
+ """\
+ a: # comment 1
+ # comment 2
+ - b: 2 # comment 3
+ """
+ )
+
+ def test_issue_25_03(self):
+ s = """\
+ a: # comment 1
+ # comment 2
+ - b: 2 # comment 3
+ """
+ round_trip(s, indent=4, block_seq_indent=2)
+
+ def test_issue_25_04(self):
+ round_trip(
+ """\
+ a: # comment 1
+ # comment 2
+ b: 1 # comment 3
+ """
+ )
+
+ def test_flow_seq_within_seq(self):
+ round_trip(
+ """\
+ # comment 1
+ - a
+ - b
+ # comment 2
+ - c
+ - d
+ # comment 3
+ - [e]
+ - f
+ # comment 4
+ - []
+ """
+ )
+
+ def test_comment_after_block_scalar_indicator(self):
+ round_trip(
+ """\
+ a: | # abc
+ test 1
+ test 2
+ # all done
+ """
+ )
+
+
+test_block_scalar_commented_line_template = """\
+y: p
+# Some comment
+
+a: |
+ x
+{}b: y
+"""
+
+
+class TestBlockScalarWithComments:
+ # issue 99 reported by Colm O'Connor
+ def test_scalar_with_comments(self):
+ import ruyaml # NOQA
+
+ for x in [
+ "",
+ '\n',
+ '\n# Another comment\n',
+ '\n\n',
+ '\n\n# abc\n#xyz\n',
+ '\n\n# abc\n#xyz\n',
+ '# abc\n\n#xyz\n',
+ '\n\n # abc\n #xyz\n',
+ ]:
+
+ commented_line = test_block_scalar_commented_line_template.format(x)
+ data = round_trip_load(commented_line)
+
+ assert round_trip_dump(data) == commented_line