|
1 | 1 | import unittest |
2 | 2 |
|
3 | | -# from benedict.serializers import TOMLSerializer |
| 3 | +from benedict import benedict |
| 4 | +from benedict.dicts.io import IODict |
| 5 | +from benedict.serializers import TOMLSerializer |
4 | 6 |
|
5 | 7 |
|
6 | 8 | class toml_serializer_test_case(unittest.TestCase): |
7 | 9 | """ |
8 | 10 | This class describes a toml serializer test case. |
| 11 | +
|
| 12 | + Regression coverage for issue #439 — the uiri/toml encoder crashes |
| 13 | + on certain strings. These tests pin the encode path to a library |
| 14 | + that handles them correctly and guard against regression. |
9 | 15 | """ |
10 | 16 |
|
11 | | - def test_decode_toml(self) -> None: |
12 | | - # TODO |
13 | | - pass |
| 17 | + def test_encode_ansi_control_character(self) -> None: |
| 18 | + """Scenario 1 — falsification clause #1. |
| 19 | +
|
| 20 | + `benedict({"color": "\\033[31m"}).to_toml()` must not raise. On |
| 21 | + baseline (uiri/toml) this raises IndexError in the encoder. |
| 22 | + """ |
| 23 | + payload = {"color": "\033[31m"} |
| 24 | + encoded = benedict(payload).to_toml() |
| 25 | + self.assertIsInstance(encoded, str) |
| 26 | + self.assertGreater(len(encoded), 0) |
| 27 | + # Round-trip: decoded value must equal the original string. |
| 28 | + decoded = IODict.from_toml(encoded) |
| 29 | + self.assertEqual(decoded["color"], "\033[31m") |
| 30 | + |
| 31 | + def test_encode_issue_439_literal_examples(self) -> None: |
| 32 | + """Scenario 2 — regression guard for issue #439's cited examples. |
| 33 | +
|
| 34 | + These pass on baseline (literal backslashes, not control chars). |
| 35 | + Kept so the encoder swap does not silently regress them. |
| 36 | + """ |
| 37 | + payload = { |
| 38 | + "reset": "\\033\\[00;00m", |
| 39 | + "lightblue": "\\033\\[01;30m", |
| 40 | + } |
| 41 | + encoded = benedict(payload).to_toml() |
| 42 | + self.assertIsInstance(encoded, str) |
| 43 | + decoded = IODict.from_toml(encoded) |
| 44 | + self.assertEqual(decoded["reset"], "\\033\\[00;00m") |
| 45 | + self.assertEqual(decoded["lightblue"], "\\033\\[01;30m") |
| 46 | + |
| 47 | + def test_roundtrip_control_chars_and_unicode(self) -> None: |
| 48 | + """Scenario 4 — round-trip integrity across tricky values.""" |
| 49 | + payload = { |
| 50 | + "ansi_red": "\033[31m", |
| 51 | + "ansi_reset": "\033[0m", |
| 52 | + "bell": "\x07", |
| 53 | + "tab_and_newline": "a\tb\nc", |
| 54 | + "unicode_emoji": "benedict 🎩", |
| 55 | + "backslash": "path\\to\\file", |
| 56 | + "quotes": 'he said "hi"', |
| 57 | + } |
| 58 | + encoded = benedict(payload).to_toml() |
| 59 | + decoded = IODict.from_toml(encoded) |
| 60 | + for key, value in payload.items(): |
| 61 | + self.assertEqual(decoded[key], value, f"round-trip mismatch for {key!r}") |
| 62 | + |
| 63 | + def test_encode_nested_dict(self) -> None: |
| 64 | + """Structural coverage — nested dicts still encode correctly.""" |
| 65 | + payload = { |
| 66 | + "section": { |
| 67 | + "key": "value", |
| 68 | + "control": "\033[31m", |
| 69 | + } |
| 70 | + } |
| 71 | + encoded = benedict(payload).to_toml() |
| 72 | + decoded = IODict.from_toml(encoded) |
| 73 | + self.assertEqual(decoded["section"]["key"], "value") |
| 74 | + self.assertEqual(decoded["section"]["control"], "\033[31m") |
14 | 75 |
|
15 | | - def test_encode_toml(self) -> None: |
16 | | - # TODO |
17 | | - pass |
| 76 | + def test_serializer_decode_roundtrip(self) -> None: |
| 77 | + """Direct serializer-level round-trip (bypasses IODict convenience layer).""" |
| 78 | + serializer = TOMLSerializer() |
| 79 | + payload = {"color": "\033[31m", "count": 42} |
| 80 | + encoded = serializer.encode(payload) |
| 81 | + decoded = serializer.decode(encoded) |
| 82 | + self.assertEqual(decoded, payload) |
0 commit comments