def test_validation_extended_cell_bad_reference(self) -> None: description: List[List[Union[Cell[int], ExtendedCell[int]]]] = [[ Cell(123, columns=2), ExtendedCell(Cell(123), 0, 1) ]] with pytest.raises(ExtendedCellReferenceError): Table(description)
def test_to_dict(self) -> None: c10 = Cell("1,0") c11 = Cell("1,1") c0x = Cell("0,x", 1, 2) d = { (0, 0): c0x, (1, 0): c10, (1, 1): c11, } assert Table.from_dict(d).to_dict() == d
def test_validation_extended_cell_in_wrong_place(self) -> None: # Top left corner with pytest.raises(CellExpectedError): Table([[ExtendedCell(Cell(123), 0, 0)]]) # Elsewhere description: List[List[Union[Cell[int], ExtendedCell[int]]]] = [[ Cell(123), ExtendedCell(Cell(123), 0, 1) ]] with pytest.raises(CellExpectedError): Table(description)
def test_expand_single_cell(self) -> None: t1 = Table.from_dict({(0, 0): Cell(123)}) assert right_pad_table(t1, 2) == Table.from_dict({ (0, 0): Cell(123, columns=2) }) t2 = Table.from_dict({(0, 0): Cell(123, columns=2)}) assert right_pad_table(t2, 4) == Table.from_dict({ (0, 0): Cell(123, columns=4) })
def test_already_wide_enough(self) -> None: # Two cells t1 = Table([[Cell(123), Cell(123)]]) assert right_pad_table(t1, 2) == t1 # A wide cell t2 = Table.from_dict({(0, 0): Cell(123, columns=2)}) assert right_pad_table(t2, 2) == t2 # Wider than needed t3 = Table.from_dict({(0, 0): Cell(123, columns=3)}) assert right_pad_table(t3, 2) == t3
def test_single_cell(self) -> None: assert set_border_around_table( Table.from_dict({(0, 0): Cell(123)}), BorderType.none, ) == Table.from_dict({ (0, 0): Cell( 123, border_left=BorderType.none, border_right=BorderType.none, border_top=BorderType.none, border_bottom=BorderType.none, ), })
def test_single_output_sub_recipe_hidden() -> None: ingredient = Ingredient(SVS("spam")) step = Step(SVS("fry"), (ingredient, )) sub_recipe = SubRecipe(step, (SVS("out"), ), show_output_names=False) assert recipe_tree_to_table(sub_recipe) == set_border_around_table( Table.from_dict( cast( Mapping[Tuple[int, int], Cell[RecipeTreeNode]], { (0, 0): Cell(ingredient), (0, 1): Cell(step) }, )), BorderType.sub_recipe, )
def test_mismatched_shapes(self) -> None: with pytest.raises(MissingCellError): combine_tables( [ Table.from_dict({(0, 0): Cell(123, columns=2)}), Table.from_dict({(0, 0): Cell(123)}), ], axis=0, ) with pytest.raises(MissingCellError): combine_tables( [ Table.from_dict({(0, 0): Cell(123, rows=2)}), Table.from_dict({(0, 0): Cell(123)}), ], axis=1, )
def test_subrecipe_outputs(self) -> None: assert render_cell( Cell(SubRecipe(Ingredient(SVS("spam")), (SVS("foo"), SVS("bar"))))) == ( '<td class="rg-sub-recipe-outputs">\n' ' <ul class="rg-sub-recipe-output-list">\n' ' <li id="sub-recipe-foo">foo</li>\n' ' <li id="sub-recipe-bar">bar</li>\n' " </ul>\n" "</td>")
def test_validation_extended_cell_bad_coordinate(self) -> None: cell = Cell(123, 1, 2) description: List[List[Union[Cell[int], ExtendedCell[int]]]] description = [[cell, ExtendedCell(cell, 1, 1)]] with pytest.raises(ExtendedCellCoordinateError): Table(description) description = [[cell, ExtendedCell(cell, 0, 0)]] with pytest.raises(ExtendedCellCoordinateError): Table(description)
def test_render_table(id: Optional[str], exp_attrs: str) -> None: assert render_table( Table.from_dict({ (0, 0): Cell(Ingredient(SVS("spam"))), (1, 0): Cell(Ingredient(SVS("eggs"))), (0, 1): Cell( Step(SVS("fry"), (Ingredient(SVS("spam")), Ingredient(SVS("eggs")))), rows=2, ), }), id=id, ) == (f'<table class="rg-table"{exp_attrs}>\n' " <tr>\n" ' <td class="rg-ingredient">spam</td>\n' ' <td class="rg-step" rowspan="2">fry</td>\n' " </tr>\n" ' <tr><td class="rg-ingredient">eggs</td></tr>\n' "</table>")
def test_step() -> None: input_0 = Ingredient(SVS("input 0")) input_1 = Ingredient(SVS("input 1")) input_2_ingredient = Ingredient(SVS("input 2")) input_2 = Step(SVS("chopped"), (input_2_ingredient, )) step = Step(SVS("combine"), (input_0, input_1, input_2)) assert recipe_tree_to_table(step) == set_border_around_table( Table.from_dict( cast( Mapping[Tuple[int, int], Cell[RecipeTreeNode]], { (0, 0): Cell(input_0, columns=2), (1, 0): Cell(input_1, columns=2), (2, 0): Cell(input_2_ingredient), (2, 1): Cell(input_2), (0, 2): Cell(step, rows=3), }, )), BorderType.sub_recipe, )
def test_multiple_output_sub_recipe() -> None: ingredient_0 = Ingredient(SVS("spam")) ingredient_1 = Ingredient(SVS("eggs")) ingredient_2 = Ingredient(SVS("more spam")) step = Step(SVS("fry"), (ingredient_0, ingredient_1, ingredient_2)) sub_recipe = SubRecipe(step, (SVS("output 0"), SVS("output 1"))) assert recipe_tree_to_table(sub_recipe) == combine_tables( cast( List[Table[RecipeTreeNode]], [ set_border_around_table( Table.from_dict( cast( Mapping[Tuple[int, int], Cell[RecipeTreeNode]], { (0, 0): Cell(ingredient_0), (1, 0): Cell(ingredient_1), (2, 0): Cell(ingredient_2), (0, 1): Cell(step, rows=3), }, )), BorderType.sub_recipe, ), Table.from_dict({ (0, 0): Cell( sub_recipe, rows=3, border_top=BorderType.none, border_right=BorderType.none, border_bottom=BorderType.none, ) }), ], ), axis=1, )
def test_edges(self) -> None: assert render_cell( Cell( Ingredient(SVS("spam")), border_top=BorderType.sub_recipe, border_left=BorderType.none, border_bottom=BorderType.sub_recipe, border_right=BorderType.none, ), ) == ('<td class="' "rg-ingredient " "rg-border-left-none " "rg-border-right-none " "rg-border-top-sub-recipe " "rg-border-bottom-sub-recipe" '">spam</td>')
def test_expand_multiple_cells_including_rows_with_only_extended_cells( self, ) -> None: t1 = Table.from_dict({ (0, 0): Cell(123, columns=2, rows=2), (2, 0): Cell(123), (2, 1): Cell(123), }) assert right_pad_table(t1, 4) == Table.from_dict({ (0, 0): Cell(123, columns=4, rows=2), (2, 0): Cell(123), (2, 1): Cell(123, columns=3), })
def test_from_dict(self) -> None: # Minimal case c00 = Cell("0,0") assert Table.from_dict({(0, 0): c00}) == Table([[c00]]) # Plain cells only c01 = Cell("0,1") c10 = Cell("1,0") c11 = Cell("1,1") assert Table.from_dict({ (0, 0): c00, (0, 1): c01, (1, 0): c10, (1, 1): c11 }) == Table([[c00, c01], [c10, c11]]) # With Simple extended cell cxx = Cell("0,x", 2, 3) description: List[List[Union[Cell[str], ExtendedCell[str]]]] = [ [cxx, ExtendedCell(cxx, 0, 1), ExtendedCell(cxx, 0, 2)], [ ExtendedCell(cxx, 1, 0), ExtendedCell(cxx, 1, 1), ExtendedCell(cxx, 1, 2), ], ] assert Table.from_dict({(0, 0): cxx}) == Table(description) # With normal and extended cells c0x = Cell("0,x", 1, 2) description = [[c0x, ExtendedCell(c0x, 0, 1)], [c10, c11]] assert Table.from_dict({ (0, 0): c0x, (1, 0): c10, (1, 1): c11 }) == Table(description)
def test_indexing(self) -> None: # Minimal case c00 = Cell("0,0") t = Table([[c00]]) assert t[0, 0] == c00 assert t.rows == 1 assert t.columns == 1 # Plain cells only c01 = Cell("0,1") c10 = Cell("1,0") c11 = Cell("1,1") t = Table([[c00, c01], [c10, c11]]) assert t[0, 0] == c00 assert t[0, 1] == c01 assert t[1, 0] == c10 assert t[1, 1] == c11 assert t.rows == 2 assert t.columns == 2 # With extended cells c0x = Cell("1,x", 1, 2) t = Table([[c0x, ExtendedCell(c0x, 0, 1)], [c10, c11]]) assert t[0, 0] == c0x assert t[0, 1] == ExtendedCell(c0x, 0, 1) assert t[1, 0] == c10 assert t[1, 1] == c11 assert t.rows == 2 assert t.columns == 2 # With asymmetry c0x = Cell("1,x", 1, 2) t = Table([[c0x, ExtendedCell(c0x, 0, 1)]]) assert t[0, 0] == c0x assert t[0, 1] == ExtendedCell(c0x, 0, 1) assert t.rows == 1 assert t.columns == 2
def test_rowspan(self) -> None: assert (render_cell( Cell( Step(SVS("fry"), (Ingredient(SVS("spam")), )), rows=3, ), ) == '<td class="rg-step" rowspan="3">fry</td>')
def test_colspan(self) -> None: assert (render_cell(Cell( Ingredient(SVS("spam")), columns=3, ), ) == '<td class="rg-ingredient" colspan="3">spam</td>')
def test_subrecipe_header(self) -> None: assert (render_cell( Cell(SubRecipe(Ingredient(SVS("spam")), (SVS("foo"), )))) == '<td class="rg-sub-recipe-header">foo</td>')
def test_step(self) -> None: assert (render_cell(Cell(Step( SVS("fry"), (Ingredient(SVS("spam")), )))) == '<td class="rg-step">fry</td>')
def test_reference(self) -> None: assert (render_cell( Cell( Reference(SubRecipe(Ingredient(SVS("spam")), (SVS("foo"), )), 0)) ) == '<td class="rg-reference"><a href="#sub-recipe-foo">foo</a></td>')
def test_validation_ragged_rows(self) -> None: with pytest.raises(MissingCellError): Table([[Cell(123)], [Cell(123), Cell(123)]]) with pytest.raises(MissingCellError): Table([[Cell(123), Cell(123)], [Cell(123)]])
def test_validation_extended_cell_is_missing(self, rows: int, columns: int) -> None: with pytest.raises(MissingCellError): Table([[Cell(123, rows, columns)]])
def test_validation_extended_cell_is_cell(self, rows: int, columns: int) -> None: with pytest.raises(ExtendedCellExpectedError): Table([[Cell(123, rows, columns), Cell(123)], [Cell(123), Cell(123)]])
def test_from_dict_validation_missing_cells(self, row: int, column: int) -> None: with pytest.raises(MissingCellError): Table.from_dict({(0, 0): Cell(123), (row, column): Cell(123)})
def test_single_table(self) -> None: orig = Table.from_dict({(0, 0): Cell(123, columns=2)}) assert combine_tables([orig], axis=0) == orig assert combine_tables([orig], axis=1) == orig
def test_multiple_tables(self) -> None: t1 = Table.from_dict({(0, 0): Cell(123, columns=2)}) t2 = Table.from_dict({(0, 0): Cell(123), (0, 1): Cell(123)}) assert combine_tables([t1, t2], axis=0) == Table.from_dict({ (0, 0): Cell(123, columns=2), (1, 0): Cell(123), (1, 1): Cell(123) }) t3 = Table.from_dict({(0, 0): Cell(123, rows=2)}) t4 = Table.from_dict({(0, 0): Cell(123), (1, 0): Cell(123)}) assert combine_tables([t3, t4], axis=1) == Table.from_dict({ (0, 0): Cell(123, rows=2), (0, 1): Cell(123), (1, 1): Cell(123) })
def test_all_edge_kinds(self) -> None: assert set_border_around_table( Table([ [Cell(100), Cell(101), Cell(102)], [Cell(110), Cell(111), Cell(112)], [Cell(120), Cell(121), Cell(122)], ]), BorderType.none, ) == Table([ [ Cell(100, border_left=BorderType.none, border_top=BorderType.none), Cell(101, border_top=BorderType.none), Cell(102, border_top=BorderType.none, border_right=BorderType.none), ], [ Cell(110, border_left=BorderType.none), Cell(111), Cell(112, border_right=BorderType.none), ], [ Cell(120, border_left=BorderType.none, border_bottom=BorderType.none), Cell(121, border_bottom=BorderType.none), Cell(122, border_bottom=BorderType.none, border_right=BorderType.none), ], ])
def test_ingredient(self) -> None: assert (render_cell(Cell(Ingredient( SVS("spam")))) == '<td class="rg-ingredient">spam</td>')