1# Copyright (c) 2010-2019 Manfred Moitzi
2# License: MIT License
3import pytest
4from io import StringIO
5
6from ezdxf.lldxf.tagger import internal_tag_compiler, ascii_tags_loader, tag_compiler, DXFStructureError
7from ezdxf.lldxf.types import strtag, DXFTag, DXFVertex
8from ezdxf.math import Vec3
9
10
11def test_strtag_int():
12    assert '  1\n1\n' == strtag((1, 1))
13
14
15def test_strtag_float():
16    assert ' 10\n3.1415\n' == strtag((10, 3.1415))
17
18
19def test_strtag_str():
20    assert '  0\nSECTION\n' == strtag((0, 'SECTION'))
21
22
23def test_strtag2_vector():
24    assert ' 10\n1.0\n 20\n2.0\n 30\n3.0\n' == DXFVertex(10, Vec3(1, 2, 3)).dxfstr()
25    assert ' 10\n1.0\n 20\n2.0\n 30\n3.0\n' == DXFVertex(10, Vec3((1, 2, 3))).dxfstr()
26    assert ' 10\n1.0\n 20\n2.0\n 30\n0.0\n' == DXFVertex(10, Vec3(1, 2)).dxfstr()
27    assert ' 10\n1.0\n 20\n2.0\n 30\n0.0\n' == DXFVertex(10, Vec3((1, 2))).dxfstr()
28
29
30def test_int_not_skip_comments():
31    tags = list(internal_tag_compiler(TAGS1))
32    assert 9 == len(tags)
33    assert DXFTag(999, 'comment') == tags[0]
34
35
36def test_int_3d_coords():
37    tags = list(internal_tag_compiler(TAGS_3D_COORDS))
38    assert 2 == len(tags)
39    assert DXFTag(10, (100, 200, 300)) == tags[1]
40
41
42def test_int_2d_coords():
43    tags = list(internal_tag_compiler(TAGS_2D_COORDS))
44    assert 2 == len(tags)
45    assert DXFTag(10, (100, 200)) == tags[1]
46
47
48def test_int_multiple_2d_coords():
49    tags = list(internal_tag_compiler(TAGS_2D_COORDS2))
50    assert 3 == len(tags)
51    assert DXFTag(10, (100, 200)) == tags[1]
52    assert DXFTag(11, (1000, 2000)) == tags[2]
53
54
55def test_int_no_line_break_at_eof():
56    tags = list(internal_tag_compiler(TAGS_NO_LINE_BREAK_AT_EOF))
57    assert 3 == len(tags)
58    assert DXFTag(10, (100, 200)) == tags[1]
59    assert DXFTag(11, (1000, 2000)) == tags[2]
60
61
62def test_int_float_to_int():
63    with pytest.raises(ValueError):
64        # Floats as int not allowed for internal tag compiler.
65        list(internal_tag_compiler(FLOAT_FOR_INT_TAGS))
66
67
68def test_int_no_eof():
69    tags = list(internal_tag_compiler(TEST_NO_EOF))
70    assert 7 == len(tags)
71    assert (0, 'ENDSEC') == tags[-1]
72
73
74def external_tag_compiler(text):
75    return tag_compiler(ascii_tags_loader(StringIO(text)))
76
77
78def test_low_level_tagger_skip_comments():
79    tags = list(ascii_tags_loader(StringIO('999\ncomment\n0\nEOF\n')))
80    assert (0, 'EOF') == tags[0]
81    assert len(tags) == 1
82
83
84def test_low_level_tagger_not_skip_comments():
85    tags = list(ascii_tags_loader(StringIO('999\ncomment\n0\nEOF\n'), skip_comments=False))
86    assert (999, 'comment') == tags[0]
87    assert (0, 'EOF') == tags[1]
88    assert len(tags) == 2
89
90
91@pytest.fixture
92def reader():
93    return external_tag_compiler(TEST_TAGREADER)
94
95
96def test_ext_next(reader):
97    assert (0, 'SECTION') == next(reader)
98
99
100def test_ext_to_list(reader):
101    assert 8 == len(list(reader))
102
103
104def test_ext_one_point_reader():
105    tags = list(external_tag_compiler(POINT_TAGS))
106    point_tag = tags[1]
107    assert (100, 200, 300) == point_tag.value
108
109
110def test_xdata_coords():
111    tags = list(external_tag_compiler(XDATA_COORDS))
112    assert tags[0] == (1011, (100, 200, 300))
113    assert len(tags) == 1
114
115
116def test_ext_read_2D_points():
117    stri = internal_tag_compiler(POINT_2D_TAGS)
118    tags = list(stri)
119    tag = tags[0]  # 2D point
120    assert (100, 200) == tag.value
121    tag = tags[1]  # check mark
122    assert 'check mark 1' == tag.value
123    tag = tags[2]  # 3D point
124    assert (100, 200, 300) == tag.value
125    tag = tags[3]  # check mark
126    assert 'check mark 2' == tag.value
127
128
129def test_ext_error_tag():
130    tags = list(external_tag_compiler(TAGS_WITH_ERROR))
131    assert 1 == len(tags)
132
133
134def test_ext_float_to_int():
135    # Floats as int allowed for external tag compiler (thx ProE).
136    assert list(external_tag_compiler(FLOAT_FOR_INT_TAGS))[0] == (71, 1)
137
138
139def test_ext_coord_error_tag():
140    with pytest.raises(DXFStructureError):
141        list(external_tag_compiler(TAGS_WITH_COORD_ERROR))
142
143
144def test_polyline_with_xdata():
145    tags = list(tag_compiler(ascii_tags_loader(StringIO(POLYLINE_WITH_XDATA))))
146    assert len(tags) == 49
147
148
149TAGS1 = """999
150comment
151  0
152SECTION
153  2
154HEADER
155  9
156$ACADVER
157  1
158AC1018
159  9
160$DWGCODEPAGE
161  3
162ANSI_1252
163  0
164ENDSEC
165  0
166EOF
167"""
168
169TAGS_3D_COORDS = """  9
170$EXTMIN
171 10
172100
173 20
174200
175 30
176300
177"""
178
179XDATA_COORDS = """1011
180100
1811021
182200
1831031
184300
185"""
186
187TAGS_2D_COORDS = """  9
188$EXTMIN
189 10
190100
191 20
192200
193"""
194
195TAGS_2D_COORDS2 = """  9
196$EXTMIN
197 10
198100
199 20
200200
201 11
2021000
203 21
2042000
205"""
206
207TAGS_NO_LINE_BREAK_AT_EOF = """  9
208$EXTMIN
209 10
210100
211 20
212200
213 11
2141000
215 21
2162000"""
217
218TEST_TAGREADER = """  0
219SECTION
220  2
221HEADER
222  9
223$ACADVER
224  1
225AC1018
226  9
227$DWGCODEPAGE
228  3
229ANSI_1252
230  0
231ENDSEC
232  0
233EOF
234"""
235
236TEST_NO_EOF = """  0
237SECTION
238  2
239HEADER
240  9
241$ACADVER
242  1
243AC1018
244  9
245$DWGCODEPAGE
246  3
247ANSI_1252
248  0
249ENDSEC
250"""
251
252TEST_TAGREADER_COMMENTS = """999
253Comment0
254  0
255SECTION
256  2
257HEADER
258  9
259$ACADVER
260999
261Comment1
262  1
263AC1018
264  9
265$DWGCODEPAGE
266  3
267ANSI_1252
268  0
269ENDSEC
270  0
271EOF
272"""
273
274POINT_TAGS = """  9
275$EXTMIN
276 10
277100
278 20
279200
280 30
281300
282"""
283
284POINT_2D_TAGS = """ 10
285100
286 20
287200
288  9
289check mark 1
290 10
291100
292 20
293200
294 30
295300
296  9
297check mark 2
298"""
299
300FLOAT_FOR_INT_TAGS = """  71
3011.0
302"""
303
304TAGS_WITH_ERROR = """  9
305$EXTMIN
306 10
307100
308 20
309"""
310
311TAGS_WITH_COORD_ERROR = """  9
312$EXTMIN
313 20
314100
315 10
316100
317 40
3181.0
319"""
320
321POLYLINE_WITH_XDATA = """  0
322POLYLINE
323  5
3242A
325  8
326T-POLYFACE-3DS
327 62
328     3
329 66
330     1
331 10
3320.0
333 20
3340.0
335 30
3360.0
337 70
338    64
339 71
340     8
341 72
342    12
3431001
344AVE_FINISH
3451002
346{
3471070
348     0
3491005
3500
3511002
352}
3531001
354AVE_ENTITY_MATERIAL
3551002
356{
3571000
358
3591002
360{
3611071
362        0
3631070
364     0
3651070
366     0
3671002
368{
3691070
370     0
3711070
372     0
3731070
374     0
3751040
3760.0
3771002
378}
3791070
380     0
3811070
382     0
3831002
384{
3851002
386}
3871002
388}
3891002
390{
3911002
392}
3931002
394{
3951002
396}
3971011
3980.0
3991021
4000.0
4011031
4020.0
4031021
4040.0
4051031
4060.0
4071011
4081.0
4091021
4100.0
4111031
4120.0
4131021
4140.0
4151031
4160.0
4171011
4180.0
4191021
4200.0
4211031
4220.0
4231021
4241.0
4251031
4260.0
4271011
4280.0
4291021
4300.0
4311031
4320.0
4331021
4340.0
4351031
4361.0
4371002
438}
439"""
440