| from buddy_fusion.assembler import bbox, assemble_part |
|
|
| |
| CUBE = [{"x": 0, "y": 0, "z": 0, "w": 2, "h": 2, "d": 2, "color": "#888888"}] |
|
|
|
|
| def test_bbox_center_x_bottom_y(): |
| minx, maxx, miny, maxy, minz, maxz = bbox(CUBE) |
| assert (minx, maxx) == (-1, 1) |
| assert (miny, maxy) == (0, 2) |
| assert (minz, maxz) == (-1, 1) |
|
|
|
|
| def test_assemble_appends_and_keeps_original(): |
| out = assemble_part(CUBE, "horns", "top", 1, None) |
| assert out[: len(CUBE)] == CUBE |
| assert len(out) > len(CUBE) |
|
|
|
|
| def test_top_anchor_sits_on_top(): |
| out = assemble_part(CUBE, "horns", "top", 1, None) |
| added = out[len(CUBE):] |
| assert min(b["y"] for b in added) >= 2 |
|
|
|
|
| def test_symmetric_part_is_mirrored(): |
| out = assemble_part(CUBE, "horns", "top", 1, None) |
| added = out[len(CUBE):] |
| xs = {b["x"] for b in added} |
| assert any(x < 0 for x in xs) and any(x > 0 for x in xs) |
|
|
|
|
| def test_scale_enlarges_part_footprint(): |
| small = assemble_part(CUBE, "house", "rear", 1, None)[len(CUBE):] |
| big = assemble_part(CUBE, "house", "rear", 2, None)[len(CUBE):] |
| assert max(b["w"] for b in big) >= max(b["w"] for b in small) |
|
|
|
|
| def test_color_override_recolors_added_boxes(): |
| out = assemble_part(CUBE, "house", "rear", 1, "#ff0000") |
| added = out[len(CUBE):] |
| assert all(b["color"] == "#ff0000" for b in added) |
|
|
|
|
| def test_unknown_part_returns_original_unchanged(): |
| assert assemble_part(CUBE, "nope", "top", 1, None) == CUBE |
|
|
|
|
| def _cell_count(boxes): |
| return sum(b["w"] * b["h"] * b["d"] for b in boxes) |
|
|
|
|
| def test_float_scale_grows_cell_count(): |
| one = assemble_part(CUBE, "house", "rear", 1.0, None)[len(CUBE):] |
| big = assemble_part(CUBE, "house", "rear", 1.5, None)[len(CUBE):] |
| assert _cell_count(big) > _cell_count(one) |
|
|
|
|
| def test_count_distributes_more_instances(): |
| one = assemble_part(CUBE, "tail", "rear", 1, None, count=1)[len(CUBE):] |
| three = assemble_part(CUBE, "tail", "rear", 1, None, count=3)[len(CUBE):] |
| assert _cell_count(three) > _cell_count(one) * 2 |
|
|
|
|
| def test_rotation_preserves_cell_count(): |
| base = assemble_part(CUBE, "horns", "top", 1, None)[len(CUBE):] |
| rot = assemble_part(CUBE, "horns", "top", 1, None, rotation=("y", 1))[len(CUBE):] |
| assert _cell_count(rot) == _cell_count(base) |
|
|
|
|
| BIG = [{"x": 0, "y": 0, "z": 0, "w": 6, "h": 6, "d": 6, "color": "#caa06f"}] |
|
|
|
|
| def test_repeated_add_accumulates_not_stacks(): |
| once = assemble_part(BIG, "wing_bird", "left", 1, None) |
| twice = assemble_part(once, "wing_bird", "left", 1, None) |
| p1 = [b for b in once if b.get("_part") == "wing_bird"] |
| p2 = [b for b in twice if b.get("_part") == "wing_bird"] |
| assert p1[0]["_pc"] == 1 and p2[0]["_pc"] == 2 |
| assert _cell_count(p2) == 2 * _cell_count(p1) |
| |
| assert len({b["z"] for b in p2}) > len({b["z"] for b in p1}) |
|
|
|
|
| def test_symmetric_part_straddles_both_faces(): |
| out = assemble_part(BIG, "wing_bird", "left", 1, None) |
| added = [b for b in out if b.get("_part") == "wing_bird"] |
| assert any(b["x"] < 0 for b in added) and any(b["x"] > 0 for b in added) |
|
|
|
|
| def test_distribution_hugs_body_extent(): |
| |
| out = assemble_part(BIG, "wing_bird", "left", 1, None, count=4) |
| zs = [b["z"] for b in out if b.get("_part") == "wing_bird"] |
| assert min(zs) >= -6 and max(zs) <= 6 |
|
|