1# Created: 21.03.2010, adapted 2018 for ezdxf
2# Copyright (C) 2010-2019, Manfred Moitzi
3# License: MIT License
4import pytest
5import ezdxf
6from ezdxf.addons.table import Table, CustomCell
7from ezdxf.addons.table import Grid, Style, DEFAULT_BORDER_COLOR
8
9
10@pytest.fixture(scope='module')
11def dxf():
12    return ezdxf.new('R12')
13
14
15class MockCell(CustomCell):
16    counter = 0
17
18    def render(self, layout, coords, layer):
19        MockCell.counter += 1
20
21    @staticmethod
22    def reset():
23        MockCell.counter = 0
24
25
26def test_init():
27    table = Table((0, 0), 10, 10, default_grid=False)
28    assert bool(table) is True
29    style = table.get_cell_style('default')
30    for border in ['left', 'right', 'top', 'bottom']:
31        assert style[border]['status'] is False
32
33    table = Table((0, 0), 10, 10, default_grid=True)
34    style = table.get_cell_style('default')
35    for border in ['left', 'right', 'top', 'bottom']:
36        assert style[border]['status'] is True
37
38
39def test_name():
40    table = Table((0, 0), 10, 10)
41    assert table.name == 'TABLE'
42
43
44def test_setter_methods():
45    table = Table((0, 0), 10, 10)
46    table.set_col_width(0, 3.)
47    assert table.col_widths[0] == 3.
48    table.set_row_height(0, 4.)
49    assert table.row_heights[0] == 4.
50
51
52def test_cell_index():
53    table = Table((0, 0), 10, 10)
54    with pytest.raises(IndexError):
55        table.get_cell(10, 10)
56    with pytest.raises(IndexError):
57        table.get_cell(-1, 10)
58
59
60def test_default_text_cell():
61    table = Table((0, 0), 10, 10)
62    table.text_cell(0, 0, 'test')
63    cell = table.get_cell(0, 0)
64    assert cell.span == (1, 1)
65    assert cell.text == 'test'
66    assert cell.stylename == 'default'
67
68
69def test_text_cell():
70    table = Table((0, 0), 10, 10)
71    table.text_cell(8, 8, 'test88', span=(2, 2), style='extrastyle')
72    cell = table.get_cell(8, 8)
73    assert cell.span == (2, 2)
74    assert cell.text == 'test88'
75    assert cell.stylename == 'extrastyle'
76
77
78def test_block_cell():
79    table = Table((0, 0), 10, 10)
80    table.block_cell(1, 1, None, span=(3, 3))
81    cell = table.get_cell(1, 1)
82    assert cell.span == (3, 3)
83    assert cell.blockdef is None
84    assert cell.stylename == 'default'
85
86
87def test_frame():
88    table = Table((0, 0), 10, 10)
89    frame = table.frame(0, 0, width=10, height=2)
90    assert frame.pos == (0, 0)
91    assert frame.span == (2, 10)
92
93
94def test_cell_style():
95    table = Table((0, 0), 10, 10)
96    style = table.new_cell_style('extra', textcolor=199)
97    style = table.get_cell_style('extra')
98    assert style['textcolor'] == 199
99    with pytest.raises(KeyError):
100        table.get_cell_style('extraextra')
101
102
103def test_border_style():
104    table = Table((0, 0), 10, 10)
105    border_style = table.new_border_style(color=1, status=True, linetype='DOT', priority=99)
106    assert border_style == {'color': 1, 'status': True, 'linetype': 'DOT', 'priority': 99}
107
108
109def test_visibility_map():
110    from ezdxf.addons.table import VisibilityMap
111
112    table = Table((0, 0), 3, 3)
113    textcell = table.text_cell(0, 0, 'text', span=(2, 2))
114    vmap = VisibilityMap(table)
115    empty = table.empty_cell
116    expected = [(0, 0, textcell), (0, 2, empty),  # cell (0, 1) is covered by (0,0)
117                (1, 2, empty),  # cells (1, 0), (1, 2) are coverd by cell (0, 0)
118                (2, 0, empty), (2, 1, empty), (2, 2, empty)]  # row 2
119    for got, should in zip(table.iter_visible_cells(vmap), expected):
120        assert got[0] == should[0]  # row
121        assert got[1] == should[1]  # col
122        assert got[2] == should[2]  # cell
123
124
125def test_rendering(dxf):
126    MockCell.reset()
127    layout = dxf.blocks.new('test_rendering')
128    table = Table((0, 0), 3, 3)
129    indices = [(0, 0), (0, 1), (0, 2),
130               (1, 0), (1, 1), (1, 2),
131               (2, 0), (2, 1), (2, 2)]
132    cell = MockCell(table, 'default', (1, 1))
133    for row, col in indices:
134        table.set_cell(row, col, cell)
135    table.render(layout)
136    assert cell.counter == 9  # count get_dxf_entity calls
137
138
139def test_dxf_creation_span(dxf):
140    MockCell.reset()
141    layout = dxf.blocks.new('test_dxf_creation_span')
142    table = Table((0, 0), 3, 3)
143    indices = [(0, 0), (0, 1), (0, 2),
144               (1, 0), (1, 1), (1, 2),
145               (2, 0), (2, 1), (2, 2)]
146    cell = MockCell(table, 'default', (1, 1))
147    for row, col in indices:
148        table.set_cell(row, col, cell)
149    spancell = MockCell(table, 'default', span=(2, 2)) # hides 3 cells
150    table.set_cell(0, 0, spancell)
151    table.render(layout)
152    assert cell.counter == 6  # count get_dxf_entity calls
153
154
155def test_span_beyond_table_borders(dxf):
156    layout = dxf.blocks.new('test_span_beyond_table_borders')
157    table = Table((0, 0), 3, 3)
158    table.text_cell(0, 2, "ERROR", span=(1, 2))
159    with pytest.raises(IndexError):
160        table.render(layout)
161    table.text_cell(2, 0, "ERROR", span=(2, 1))
162    with pytest.raises(IndexError):
163        table.render(layout)
164
165
166@pytest.fixture
167def table():
168    table = Table((0, 0), 3, 3)
169    for x in range(3):
170        table.set_col_width(x, 3.0)
171        table.set_row_height(x, 3.0)
172    return table
173
174
175def test_grid_coords(table):
176    grid = Grid(table)
177    left, right, top, bottom = grid.cell_coords(1, 1, span=(1, 1))
178    assert left == 3. #, places=4)
179    assert right == 6.
180    assert top == -3.
181    assert bottom == -6.
182
183
184def test_grid_coords_span(table):
185    grid = Grid(table)
186    left, right, top, bottom = grid.cell_coords(0, 0, span=(2, 2))
187    assert left == 0.
188    assert right == 6.
189    assert top == 0.
190    assert bottom == -6.
191
192
193def test_draw_cell_background(dxf, table):
194    grid = Grid(table)
195    layout = dxf.blocks.new('test_draw_cell_background')
196    table.new_cell_style('fill', bgcolor=17)
197    cell = table.get_cell(0, 0)
198    cell.stylename = 'fill'
199    grid.render_cell_background(layout, 0, 0, cell)
200    solid = list(layout)[0]
201    assert solid.dxftype() == 'SOLID'
202
203
204def test_set_border_status():
205    style = Style.get_default_cell_style()
206    style.set_border_status(False, True, False, True)
207    assert style['left']['status'] is False
208    assert style['right']['status'] is True
209    assert style['top']['status'] is False
210    assert style['bottom']['status']is True
211
212
213def test_set_border_style():
214    style = Style.get_default_cell_style()
215    border_style = Style.get_default_border_style()
216    border_style['color'] = 17
217
218    style.set_border_style(border_style, False, True, False, True)
219    assert style['left']['color'] == DEFAULT_BORDER_COLOR
220    assert style['right']['color'] == 17
221    assert style['top']['color'] == DEFAULT_BORDER_COLOR
222    assert style['bottom']['color'] == 17
223
224