3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # pylint: disable=invalid-name
16 from collections import OrderedDict
20 from tools.convert import to_json, CsvConverter
23 class TestJson(object):
26 _input = dict(b=1, a=2)
27 expected = '\n'.join(['{',
31 assert to_json(_input) == expected
34 class TestCsv(object):
36 @pytest.mark.parametrize('_input, expected', [
39 ([dict(a=1)], '\r\n'.join(['"a"',
41 ([dict(a=1), dict(a=2)], '\r\n'.join(['"a"',
44 ([dict(a=1, b=2), dict(a=3, b=4)], '\r\n'.join(['"a","b"',
47 ([dict(x=OrderedDict({'b': 1, 'a': 2})),
48 dict(x={'a': 2, 'b': 1})], '\r\n'.join(['"x"',
49 '"{""a"": 2, ""b"": 1}"',
50 '"{""a"": 2, ""b"": 1}"']))
53 def test_csv(_input, expected):
54 assert str(CsvConverter(_input)) == expected
59 assert str(CsvConverter(_input)) == CsvConverter(_input).convert()
62 @pytest.mark.parametrize('_input, exception_re', [
63 ('boom', r'NOT a list'),
64 ([['boom']], r'NOT a dict')
66 def test_to_csv_fail(_input, exception_re):
67 with pytest.raises(Exception, match=exception_re):
68 str(CsvConverter(_input))
71 def test_newlines_are_escaped():
73 ...in order to get properly formatted file when written
75 _input = [dict(a='1"2')]
76 expected = '\r\n'.join(['"a"',
78 assert CsvConverter(_input).convert() == expected
81 def test_missing_fields_are_filled_with_none():
82 _input = [dict(a='1"2')]
83 expected = '\r\n'.join(['"a"',
85 assert CsvConverter(_input).convert() == expected
88 def test_double_quote_is_escaped_with_double_quote():
92 _input = [dict(a='1"2')]
93 expected = '\r\n'.join(['"a"',
95 assert CsvConverter(_input).convert() == expected
98 @pytest.mark.parametrize('_input, expected', [
99 ([dict(a=1, b=2)], '\r\n'.join(['"b","a"', '"2","1"'])),
100 ([dict(a=1, c=2)], '\r\n'.join(['"a","c"', '"1","2"']))
102 def test_csv_preferred_order(_input, expected):
103 assert CsvConverter(_input, preferred_field_order=['b', 'a']).convert() == expected
106 @pytest.mark.parametrize('_input, expected', [
107 ([dict(a='Copyright \xc2\xa9 2014')], '\r\n'.join(['"a"',
108 '"Copyright \xc2\xa9 2014"'])),
109 ([dict(a=u'Copyright \xa9 2014')], '\r\n'.join(['"a"',
110 '"Copyright \xc2\xa9 2014"'])),
112 def test_unicode_input(_input, expected):
113 assert str(CsvConverter(_input)) == expected
116 class TestCsvMSExcel(object):
118 def test_ms_excel_format():
120 MS Excel treats CSV files with 'sep=,' as the first line to get automatically columnized
122 _input = [dict(a=1, b=2)]
123 expected = '\r\n'.join(['sep=,',
126 assert CsvConverter(_input).convert_to_ms_excel() == expected
129 def test_text_fields():
131 MS Excel CSV fields prefixed with '=' will be treated as equations to string.
132 This makes it possible to e.g. to have all RPM version strings treated equally instead
133 of making some of them treated as generic and some of them as integers.
135 _input = [dict(a=1, b=2)]
136 expected = '\r\n'.join(['sep=,',
139 assert CsvConverter(_input).convert_to_ms_excel(text_fields=['b']) == expected
142 def test_field_with_beginning_minus_is_prefixed():
144 MS Excel CSV fields beginning with '-' are treated as an equation even they would be
145 essentially just strings. Make sure to escape the beginning signs with something in order
146 not to get field braking equation.
148 _input = [dict(a=-1), dict(a="-2a")]
149 expected = '\r\n'.join(['sep=,',
153 assert CsvConverter(_input).convert_to_ms_excel() == expected
156 def test_too_big_cell_is_truncated():
158 MS Excel has ~32k character limit per cell. BOM information can easily exceed this.
160 _input = [dict(a='1' * 32000), dict(a='2' * 32001)]
161 expected = '\r\n'.join(['sep=,',
163 '"{}"'.format('1' * 32000),
164 '"{}...{}"'.format('2' * 16000, '2' * 16000)])
165 assert CsvConverter(_input).convert_to_ms_excel() == expected