import pytest from app import materials, tagcodec from app.tagcodec import TagData, encode_commands, parse_commands TEMPLATE = ("A2:04:0103A00C,A2:05:34030FD1,A2:06:010B5502,A2:07:656C6567,A2:08:6F6F2E63,A2:09:6F6DFE00," "A2:10:36EEEEEE,A2:11:EE000000,A2:12:00807665,A2:13:00010000,A2:14:000000FF,A2:15:00BE00E6," "A2:16:00000000,A2:17:00AF2711,A2:18:0036C800") def pla_plus(spool_id, color): return TagData(spool_id=spool_id, color=color, material="PLA", subtype=0x0001, temp_min=190, temp_max=230) def test_template_reproduced_exactly(): assert encode_commands(pla_plus(1, "000000")) == TEMPLATE @pytest.mark.parametrize("spool_id,color,p14,p17", [ (1, "000000", "A2:14:000000FF", "A2:17:00AF2711"), (5, "2850DF", "A2:14:2850DFFF", "A2:17:00AF2715"), (8, "F88D36", "A2:14:F88D36FF", "A2:17:00AF2718"), ]) def test_expected_pages(spool_id, color, p14, p17): cmds = encode_commands(pla_plus(spool_id, color)).split(",") assert p14 in cmds and p17 in cmds # only pages 14 and 17 differ from the template diff = set(cmds) ^ set(TEMPLATE.split(",")) assert {c[:5] for c in diff} <= {"A2:14", "A2:17"} def test_never_writes_pages_0_to_3(): pages = tagcodec.encode_pages(pla_plus(1, "000000")) assert min(pages) == 4 with pytest.raises(tagcodec.TagError): tagcodec.pages_to_commands({3: b"\0\0\0\0"}) def test_decode_roundtrip(): d = tagcodec.decode_pages(parse_commands(TEMPLATE)) assert d["url"] == "https://www.elegoo.com" assert d["material"] == "PLA" and d["subtype_name"] == "PLA+" assert (d["temp_min"], d["temp_max"]) == (190, 230) assert d["diameter"] == 1.75 and d["weight"] == 10001 and d["spool_id"] == 1 assert d["manufacturer"] == "EEEEEEEE" def test_rapid_petg_codes(): tag = TagData(spool_id=12, color="FFFFFF", material="PETG", subtype=0x0105, temp_min=240, temp_max=255) pages = tagcodec.encode_pages(tag) assert pages[0x12].hex().upper() == "80698471" assert pages[0x13].hex().upper() == "01050000" assert pages[0x15].hex().upper() == "00F000FF" def test_validation(): with pytest.raises(tagcodec.TagError): encode_commands(TagData(spool_id=1, color="000000", material="PLA", subtype=0x0100)) # PETG subtype with pytest.raises(tagcodec.TagError): encode_commands(pla_plus(60000, "000000")) # does not fit 2 bytes with pytest.raises(tagcodec.TagError): encode_commands(pla_plus(1, "zzzzzz")) with pytest.raises(tagcodec.TagError): encode_commands(TagData(spool_id=1, color="000000", temp_min=240, temp_max=200)) def test_custom_url_fits_before_canvas_pages(): tag = pla_plus(123, "000000") tag.url = "http://10.10.6.10:7912/spool/show/123" pages = tagcodec.encode_pages(tag) assert max(p for p in pages if p < 0x10) <= 0x0F assert tagcodec.decode_pages(pages)["url"] == tag.url tag.url = "https://example.com/" + "x" * 40 with pytest.raises(tagcodec.TagError): tagcodec.encode_pages(tag) @pytest.mark.parametrize("weight,expected", [ ("10001", 1), ("10005", 5), ("10000", 0), ("9999", None), ("1000", None), ("", None), ("abc", None), ("70000", None), ("10008.000", 8), ]) def test_spool_id_from_weight(weight, expected): assert tagcodec.spool_id_from_weight(weight) == expected def test_parse_record(): rec = {"channels0": {"weight": "10001", "type": "PLA"}, "channels1": {"weight": "", "type": ""}, "channels3": {"weight": "1000", "type": "PETG"}} slots = tagcodec.parse_record(rec) assert [s["spool_id"] for s in slots] == [1, None, None, None] assert [s["occupied"] for s in slots] == [True, False, False, True] @pytest.mark.parametrize("color,expected", [ ("000000", "000000"), ("2850DF", "2850DF"), ("0000FF", "2850DF"), ("0047AB", "2850DF"), ("FF8000", "F88D36"), ("FF0000", "F72221"), ("FFFFFF", "FFFFFF"), ("808080", "898989"), ("1E90FF", "48A7FA"), ("800080", "433089"), (None, "000000"), ("#ffa500", "F88D36"), ]) def test_palette_suggestion(color, expected): assert tagcodec.nearest_palette_color(color) == expected @pytest.mark.parametrize("material,name,mat,sub", [ ("PLA+", "", "PLA", 0x0001), ("PLA", "Silk Gold", "PLA", 0x0003), ("PETG", "", "PETG", 0x0100), ("PETG", "Rapid PETG", "PETG", 0x0105), ("PLA", "Matte Black", "PLA", 0x0006), ("PETG-CF", "", "PETG", 0x0101), ("ABS", "", "ABS", 0x0200), ("TPU", "95A", "TPU", 0x0301), ("PCTG", "", "PC", 0x0601), ("ASA", "", "ASA", 0x0800), ("", "", "PLA", 0x0000), ("PLA", "Rapid PLA+", "PLA", 0x000A), ]) def test_material_suggestion(material, name, mat, sub): s = materials.suggest(material, name) assert (s["material"], s["subtype"]) == (mat, sub) def test_tables_complete(): assert len(materials.MATERIALS) == 15 assert len(materials.SUBTYPES) == 50 for code, name, _ in materials.SUBTYPES: assert materials.material_of_subtype(code) is not None, name