From 154fcd5c89f3cd3c9c3437384f499e164a0fef61 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Wed, 28 May 2025 21:31:20 +0000 Subject: [PATCH 01/11] GitHub + PyTest --- .github/workflows/test.yml | 31 +++++++++++++++++++++++++++++++ pyproject.toml | 4 +--- tests/test_hello.py | 2 ++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/test.yml create mode 100644 tests/test_hello.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..662219c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,31 @@ +name: Test + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + cache: "pip" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Test with pytest + run: | + pytest tests/ diff --git a/pyproject.toml b/pyproject.toml index 9a05b97..7b06530 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,9 +21,7 @@ dependencies = [ [project.optional-dependencies] dev = [ - "mkdocs==1.6.1", - "mkdocs-material==9.5.49", - "mkdocstrings-python==1.13.0" + "pytest==8.3.5" ] [project.urls] diff --git a/tests/test_hello.py b/tests/test_hello.py new file mode 100644 index 0000000..fa77e7b --- /dev/null +++ b/tests/test_hello.py @@ -0,0 +1,2 @@ +def test_answer(): + assert True From b7ead3cf7511d5996d6239c1ecfb128eff278f56 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Wed, 28 May 2025 21:37:35 +0000 Subject: [PATCH 02/11] Don't cache, apparently GitHub doesn't like that --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 662219c..cba6730 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,6 @@ jobs: uses: actions/setup-python@v3 with: python-version: "3.10" - cache: "pip" - name: Install dependencies run: | python -m pip install --upgrade pip From 1d360fe9f46ab2c6b2af84322484a6d8345dae26 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Thu, 29 May 2025 09:27:09 +0000 Subject: [PATCH 03/11] Add test/lint dependencies to .toml and use that in actions --- .github/workflows/test.yml | 4 ++-- pyproject.toml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cba6730..98688b7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,8 +23,8 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pytest - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + pip install . + pip install .[dev] - name: Test with pytest run: | pytest tests/ diff --git a/pyproject.toml b/pyproject.toml index 7b06530..f13ba62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,8 @@ dependencies = [ [project.optional-dependencies] dev = [ - "pytest==8.3.5" + "pytest==8.3.5", + "ruff==0.6.7" ] [project.urls] From a7c9af94c969e2c7fd5b985be956797c0363d04a Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Thu, 29 May 2025 09:37:32 +0000 Subject: [PATCH 04/11] An actual test with coverage reporting --- .coverage | Bin 0 -> 53248 bytes .github/workflows/test.yml | 2 +- pyproject.toml | 6 ++++++ python_thingset/encoders/text.py | 2 +- tests/test_hello.py | 2 -- tests/test_text_encoder.py | 9 +++++++++ 6 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 .coverage delete mode 100644 tests/test_hello.py create mode 100644 tests/test_text_encoder.py diff --git a/.coverage b/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..6044be02935f0663091aaf3642571608fc47a2ac GIT binary patch literal 53248 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 bytes: + def encode_fetch(self, parent_id: str, ids: List[str]) -> bytes: children = "null" if len(ids) > 0: diff --git a/tests/test_hello.py b/tests/test_hello.py deleted file mode 100644 index fa77e7b..0000000 --- a/tests/test_hello.py +++ /dev/null @@ -1,2 +0,0 @@ -def test_answer(): - assert True diff --git a/tests/test_text_encoder.py b/tests/test_text_encoder.py new file mode 100644 index 0000000..8101b57 --- /dev/null +++ b/tests/test_text_encoder.py @@ -0,0 +1,9 @@ +from python_thingset.encoders import ThingSetTextEncoder + + +encoder = ThingSetTextEncoder() + + +def test_root(): + encoded = encoder.encode_get("") + assert encoded == "thingset ?\n".encode() From 64c10f8daed39e5061e7d47dbcaa731c5227862f Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Thu, 29 May 2025 10:49:09 +0000 Subject: [PATCH 05/11] Don't track .coverage --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6fb8897..ab85883 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,7 @@ __pycache__ # build metadata / files *build -python_thingset.egg-info \ No newline at end of file +*egg-info + +# test metadata +.coverage \ No newline at end of file From dc1f1eada6cfcf7b59c95b4ce39426e52a837e94 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Thu, 29 May 2025 10:49:43 +0000 Subject: [PATCH 06/11] Refactor float/int handling --- python_thingset/encoders/text.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/python_thingset/encoders/text.py b/python_thingset/encoders/text.py index 060d3f4..447b469 100644 --- a/python_thingset/encoders/text.py +++ b/python_thingset/encoders/text.py @@ -26,25 +26,19 @@ def encode_fetch(self, parent_id: str, ids: List[str]) -> bytes: def encode_get(self, value_id: str) -> bytes: return f"thingset ?{value_id}\n".encode() - def encode_exec(self, value_id: str, args: Union[Any, None]) -> bytes: + def encode_exec(self, value_id: str, args: List[Union[Any, None]]) -> bytes: """properly format strings for transmission, add args to stringified list""" processed_args = "[" """ leave numeric values as is, surround strings with escape chars """ for a in args: - try: - int(a) + if isinstance(a, int): processed_args += f"{a}," continue - except ValueError: - pass - - try: - float(a) + + if isinstance(a, float): processed_args += f"{a}," continue - except ValueError: - pass processed_args += f'\\"{a}\\",' @@ -58,16 +52,11 @@ def encode_update(self, parent_id: None, value_id: str, value: Any) -> bytes: val = None - try: + if isinstance(value, int): val = int(value) - except ValueError: - pass - if val is None: - try: - val = float(value) - except ValueError: - pass + if isinstance(value, float): + val = float(value) if val is None: val = f'\\"{value}\\"' From de2b5c57b38c9c4f46fde63b425dcdbec0a555a7 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Thu, 29 May 2025 10:50:06 +0000 Subject: [PATCH 07/11] Fix missing return in ThingSetSerial._recv --- python_thingset/backends/serial.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_thingset/backends/serial.py b/python_thingset/backends/serial.py index dddc6f9..213b04c 100644 --- a/python_thingset/backends/serial.py +++ b/python_thingset/backends/serial.py @@ -105,7 +105,7 @@ def _send(self, data: bytes, _: Union[int, None]) -> None: self._serial.send(data) def _recv(self) -> bytes: - self._serial.get_message() + return self._serial.get_message() @property def port(self) -> str: From 17d8bc9879136eacadc7999254ae26d19387de56 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Thu, 29 May 2025 10:50:21 +0000 Subject: [PATCH 08/11] Implement ThingSetTextEncoder tests --- tests/encoders/text/test_enc_txt_exec.py | 25 ++++++++++++++++++++++ tests/encoders/text/test_enc_txt_fetch.py | 21 ++++++++++++++++++ tests/encoders/text/test_enc_txt_get.py | 17 +++++++++++++++ tests/encoders/text/test_enc_txt_update.py | 25 ++++++++++++++++++++++ tests/test_text_encoder.py | 9 -------- 5 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 tests/encoders/text/test_enc_txt_exec.py create mode 100644 tests/encoders/text/test_enc_txt_fetch.py create mode 100644 tests/encoders/text/test_enc_txt_get.py create mode 100644 tests/encoders/text/test_enc_txt_update.py delete mode 100644 tests/test_text_encoder.py diff --git a/tests/encoders/text/test_enc_txt_exec.py b/tests/encoders/text/test_enc_txt_exec.py new file mode 100644 index 0000000..4642154 --- /dev/null +++ b/tests/encoders/text/test_enc_txt_exec.py @@ -0,0 +1,25 @@ +from python_thingset.encoders import ThingSetTextEncoder + + +encoder = ThingSetTextEncoder() + + +def test_exec_no_args(): + encoded = encoder.encode_exec("Func", []) + assert encoded == "thingset !Func []\n".encode() + +def test_exec_int_arg(): + encoded = encoder.encode_exec("Func", [7]) + assert encoded == "thingset !Func [7,]\n".encode() + +def test_exec_float_arg(): + encoded = encoder.encode_exec("Func", [3.14]) + assert encoded == "thingset !Func [3.14,]\n".encode() + +def test_exec_str_arg(): + encoded = encoder.encode_exec("Func", ["a_text-arg"]) + assert encoded == """thingset !Func [\\"a_text-arg\\",]\n""".encode() + +def test_exec_one_of_each_arg(): + encoded = encoder.encode_exec("Func", [1, 2.34, "moretext"]) + assert encoded == """thingset !Func [1,2.34,\\"moretext\\",]\n""".encode() diff --git a/tests/encoders/text/test_enc_txt_fetch.py b/tests/encoders/text/test_enc_txt_fetch.py new file mode 100644 index 0000000..c40a1ac --- /dev/null +++ b/tests/encoders/text/test_enc_txt_fetch.py @@ -0,0 +1,21 @@ +from python_thingset.encoders import ThingSetTextEncoder + + +encoder = ThingSetTextEncoder() + + +def test_fetch_root(): + encoded = encoder.encode_fetch("", []) + assert encoded == "thingset ? null\n".encode() + +def test_fetch_root_one_child(): + encoded = encoder.encode_fetch("", ["One"]) + assert encoded == """thingset ? [\\"One\\",]\n""".encode() + +def test_fetch_root_two_children(): + encoded = encoder.encode_fetch("", ["One", "Two"]) + assert encoded == """thingset ? [\\"One\\",\\"Two\\",]\n""".encode() + +def test_fetch_not_root_one_child(): + encoded = encoder.encode_fetch("NotRoot", ["One"]) + assert encoded == """thingset ?NotRoot [\\"One\\",]\n""".encode() diff --git a/tests/encoders/text/test_enc_txt_get.py b/tests/encoders/text/test_enc_txt_get.py new file mode 100644 index 0000000..d8d209e --- /dev/null +++ b/tests/encoders/text/test_enc_txt_get.py @@ -0,0 +1,17 @@ +from python_thingset.encoders import ThingSetTextEncoder + + +encoder = ThingSetTextEncoder() + + +def test_get_root(): + encoded = encoder.encode_get("") + assert encoded == "thingset ?\n".encode() + +def test_get_depth_one(): + encoded = encoder.encode_get("One") + assert encoded == "thingset ?One\n".encode() + +def test_get_depth_two(): + encoded = encoder.encode_get("One/Two") + assert encoded == "thingset ?One/Two\n".encode() diff --git a/tests/encoders/text/test_enc_txt_update.py b/tests/encoders/text/test_enc_txt_update.py new file mode 100644 index 0000000..bce5328 --- /dev/null +++ b/tests/encoders/text/test_enc_txt_update.py @@ -0,0 +1,25 @@ +from python_thingset.encoders import ThingSetTextEncoder + + +encoder = ThingSetTextEncoder() + + +def test_update_value_at_root_int(): + encoded = encoder.encode_update(None, "Value", [1]) + assert encoded == """thingset = {\\"Value\\":1}\n""".encode() + +def test_update_value_at_root_float(): + encoded = encoder.encode_update(None, "Value", [3.14]) + assert encoded == """thingset = {\\"Value\\":3.14}\n""".encode() + +def test_update_value_at_root_str(): + encoded = encoder.encode_update(None, "Value", ["sometext"]) + assert encoded == """thingset = {\\"Value\\":\\"sometext\\"}\n""".encode() + +def test_update_value_at_depth_one(): + encoded = encoder.encode_update(None, "One/Value", [1]) + assert encoded == """thingset =One {\\"Value\\":1}\n""".encode() + +def test_update_value_at_depth_two(): + encoded = encoder.encode_update(None, "One/Two/Value", [1]) + assert encoded == """thingset =One/Two {\\"Value\\":1}\n""".encode() diff --git a/tests/test_text_encoder.py b/tests/test_text_encoder.py deleted file mode 100644 index 8101b57..0000000 --- a/tests/test_text_encoder.py +++ /dev/null @@ -1,9 +0,0 @@ -from python_thingset.encoders import ThingSetTextEncoder - - -encoder = ThingSetTextEncoder() - - -def test_root(): - encoded = encoder.encode_get("") - assert encoded == "thingset ?\n".encode() From a6ac402a69a7eb70d253db16760faab16189fe29 Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Thu, 29 May 2025 13:45:43 +0000 Subject: [PATCH 09/11] Add binary encoder tests --- python_thingset/encoders/binary.py | 4 +-- tests/encoders/binary/test_enc_bin_exec.py | 33 +++++++++++++++++++ tests/encoders/binary/test_enc_bin_fetch.py | 17 ++++++++++ tests/encoders/binary/test_enc_bin_get.py | 9 +++++ .../encoders/binary/test_enc_bin_get_paths.py | 9 +++++ 5 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 tests/encoders/binary/test_enc_bin_exec.py create mode 100644 tests/encoders/binary/test_enc_bin_fetch.py create mode 100644 tests/encoders/binary/test_enc_bin_get.py create mode 100644 tests/encoders/binary/test_enc_bin_get_paths.py diff --git a/python_thingset/encoders/binary.py b/python_thingset/encoders/binary.py index 3abe3ff..2f0db07 100644 --- a/python_thingset/encoders/binary.py +++ b/python_thingset/encoders/binary.py @@ -28,7 +28,7 @@ def __init__(self): 18 41 # CBOR uint: 0x41 (object ID) """ - def encode_fetch(self, parent_id: int, value_ids: List[int]) -> bytes: + def encode_fetch(self, parent_id: int, value_ids: List[Union[int, None]]) -> bytes: req = bytearray() req.append(ThingSetRequest.FETCH) req += cbor2.dumps(parent_id, canonical=True) @@ -43,7 +43,7 @@ def encode_fetch(self, parent_id: int, value_ids: List[int]) -> bytes: def encode_get(self, value_id: int) -> bytes: return bytes([ThingSetRequest.GET] + list(cbor2.dumps(value_id))) - def encode_exec(self, value_id: int, args: Union[Any, None]) -> bytes: + def encode_exec(self, value_id: int, args: List[Union[Any, None]]) -> bytes: p_args = list() for a in args: diff --git a/tests/encoders/binary/test_enc_bin_exec.py b/tests/encoders/binary/test_enc_bin_exec.py new file mode 100644 index 0000000..55f63e9 --- /dev/null +++ b/tests/encoders/binary/test_enc_bin_exec.py @@ -0,0 +1,33 @@ +from python_thingset.encoders import ThingSetBinaryEncoder + + +encoder = ThingSetBinaryEncoder() + + +def test_exec_no_args(): + encoded = encoder.encode_exec(0xF09, []) + assert encoded == b'\x02\x19\x0f\t\x80' + +def test_exec_one_int(): + encoded = encoder.encode_exec(0xF09, [2]) + assert encoded == b'\x02\x19\x0f\t\x81\x02' + +def test_exec_one_float(): + encoded = encoder.encode_exec(0xF09, [3.14]) + assert encoded == b'\x02\x19\x0f\t\x81\xfa@H\xf5\xc3' + +def test_exec_one_str(): + encoded = encoder.encode_exec(0xF09, ["hello"]) + assert encoded == b'\x02\x19\x0f\t\x81ehello' + +def test_exec_one_bool_true(): + encoded = encoder.encode_exec(0xF09, ["true"]) + assert encoded == b'\x02\x19\x0f\t\x81\xf5' + +def test_exec_one_bool_false(): + encoded = encoder.encode_exec(0xF09, ["false"]) + assert encoded == b'\x02\x19\x0f\t\x81\xf4' + +def test_exec_multiple_args(): + encoded = encoder.encode_exec(0xF09, ["false", 5, "age", 7.89, "true"]) + assert encoded == b'\x02\x19\x0f\t\x85\xf4\x05cage\xfa@\xfcz\xe1\xf5' diff --git a/tests/encoders/binary/test_enc_bin_fetch.py b/tests/encoders/binary/test_enc_bin_fetch.py new file mode 100644 index 0000000..c495d89 --- /dev/null +++ b/tests/encoders/binary/test_enc_bin_fetch.py @@ -0,0 +1,17 @@ +from python_thingset.encoders import ThingSetBinaryEncoder + + +encoder = ThingSetBinaryEncoder() + + +def test_fetch_no_children(): + encoded = encoder.encode_fetch(0xF01, []) + assert encoded == b'\x05\x19\x0f\x01\xf6' + +def test_fetch_one_child(): + encoded = encoder.encode_fetch(0xF, [0xF01]) + assert encoded == b'\x05\x0f\x81\x19\x0f\x01' + +def test_fetch_two_children(): + encoded = encoder.encode_fetch(0xF, [0xF01, 0xF02]) + assert encoded == b'\x05\x0f\x82\x19\x0f\x01\x19\x0f\x02' diff --git a/tests/encoders/binary/test_enc_bin_get.py b/tests/encoders/binary/test_enc_bin_get.py new file mode 100644 index 0000000..ed914be --- /dev/null +++ b/tests/encoders/binary/test_enc_bin_get.py @@ -0,0 +1,9 @@ +from python_thingset.encoders import ThingSetBinaryEncoder + + +encoder = ThingSetBinaryEncoder() + + +def test_get(): + encoded = encoder.encode_get(0xF01) + assert encoded == b'\x01\x19\x0f\x01' diff --git a/tests/encoders/binary/test_enc_bin_get_paths.py b/tests/encoders/binary/test_enc_bin_get_paths.py new file mode 100644 index 0000000..ae6d46f --- /dev/null +++ b/tests/encoders/binary/test_enc_bin_get_paths.py @@ -0,0 +1,9 @@ +from python_thingset.encoders import ThingSetBinaryEncoder + + +encoder = ThingSetBinaryEncoder() + + +def test_enc_get_paths(): + encoded = encoder.encode_get_path(0xF) + assert encoded == b'\x05\x17\x81\x0f' From 68130a684dcbb9b34ea5e0e87cabef69106180cf Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Thu, 29 May 2025 13:46:35 +0000 Subject: [PATCH 10/11] Add update test --- tests/encoders/binary/test_enc_bin_update.py | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/encoders/binary/test_enc_bin_update.py diff --git a/tests/encoders/binary/test_enc_bin_update.py b/tests/encoders/binary/test_enc_bin_update.py new file mode 100644 index 0000000..63dfd9b --- /dev/null +++ b/tests/encoders/binary/test_enc_bin_update.py @@ -0,0 +1,25 @@ +from python_thingset.encoders import ThingSetBinaryEncoder + + +encoder = ThingSetBinaryEncoder() + + +def test_update_int(): + encoded = encoder.encode_update(0x0, 0x4F, 1) + assert encoded == b'\x07\x00\xa1\x18O\x01' + +def test_update_float(): + encoded = encoder.encode_update(0x0, 0x4F, 3.14) + assert encoded == b'\x07\x00\xa1\x18O\xfa@H\xf5\xc3' + +def test_update_str(): + encoded = encoder.encode_update(0x0, 0x4F, "hello") + assert encoded == b'\x07\x00\xa1\x18Oehello' + +def test_update_bool_true(): + encoded = encoder.encode_update(0x0, 0x4F, "true") + assert encoded == b'\x07\x00\xa1\x18O\xf5' + +def test_update_bool_false(): + encoded = encoder.encode_update(0x0, 0x4F, "false") + assert encoded == b'\x07\x00\xa1\x18O\xf4' From 01c00656fc2b814456042bbc787f275b4046cf1d Mon Sep 17 00:00:00 2001 From: Adam Mitchell Date: Thu, 29 May 2025 13:51:39 +0000 Subject: [PATCH 11/11] Format with ruff --- python_thingset/encoders/text.py | 2 +- tests/encoders/binary/test_enc_bin_exec.py | 20 ++++++++++++------- tests/encoders/binary/test_enc_bin_fetch.py | 8 +++++--- tests/encoders/binary/test_enc_bin_get.py | 2 +- .../encoders/binary/test_enc_bin_get_paths.py | 2 +- tests/encoders/binary/test_enc_bin_update.py | 14 ++++++++----- tests/encoders/text/test_enc_txt_exec.py | 4 ++++ tests/encoders/text/test_enc_txt_fetch.py | 3 +++ tests/encoders/text/test_enc_txt_get.py | 2 ++ tests/encoders/text/test_enc_txt_update.py | 4 ++++ 10 files changed, 43 insertions(+), 18 deletions(-) diff --git a/python_thingset/encoders/text.py b/python_thingset/encoders/text.py index 447b469..afa5b75 100644 --- a/python_thingset/encoders/text.py +++ b/python_thingset/encoders/text.py @@ -35,7 +35,7 @@ def encode_exec(self, value_id: str, args: List[Union[Any, None]]) -> bytes: if isinstance(a, int): processed_args += f"{a}," continue - + if isinstance(a, float): processed_args += f"{a}," continue diff --git a/tests/encoders/binary/test_enc_bin_exec.py b/tests/encoders/binary/test_enc_bin_exec.py index 55f63e9..b5a2fb3 100644 --- a/tests/encoders/binary/test_enc_bin_exec.py +++ b/tests/encoders/binary/test_enc_bin_exec.py @@ -6,28 +6,34 @@ def test_exec_no_args(): encoded = encoder.encode_exec(0xF09, []) - assert encoded == b'\x02\x19\x0f\t\x80' + assert encoded == b"\x02\x19\x0f\t\x80" + def test_exec_one_int(): encoded = encoder.encode_exec(0xF09, [2]) - assert encoded == b'\x02\x19\x0f\t\x81\x02' + assert encoded == b"\x02\x19\x0f\t\x81\x02" + def test_exec_one_float(): encoded = encoder.encode_exec(0xF09, [3.14]) - assert encoded == b'\x02\x19\x0f\t\x81\xfa@H\xf5\xc3' + assert encoded == b"\x02\x19\x0f\t\x81\xfa@H\xf5\xc3" + def test_exec_one_str(): encoded = encoder.encode_exec(0xF09, ["hello"]) - assert encoded == b'\x02\x19\x0f\t\x81ehello' + assert encoded == b"\x02\x19\x0f\t\x81ehello" + def test_exec_one_bool_true(): encoded = encoder.encode_exec(0xF09, ["true"]) - assert encoded == b'\x02\x19\x0f\t\x81\xf5' + assert encoded == b"\x02\x19\x0f\t\x81\xf5" + def test_exec_one_bool_false(): encoded = encoder.encode_exec(0xF09, ["false"]) - assert encoded == b'\x02\x19\x0f\t\x81\xf4' + assert encoded == b"\x02\x19\x0f\t\x81\xf4" + def test_exec_multiple_args(): encoded = encoder.encode_exec(0xF09, ["false", 5, "age", 7.89, "true"]) - assert encoded == b'\x02\x19\x0f\t\x85\xf4\x05cage\xfa@\xfcz\xe1\xf5' + assert encoded == b"\x02\x19\x0f\t\x85\xf4\x05cage\xfa@\xfcz\xe1\xf5" diff --git a/tests/encoders/binary/test_enc_bin_fetch.py b/tests/encoders/binary/test_enc_bin_fetch.py index c495d89..79525e0 100644 --- a/tests/encoders/binary/test_enc_bin_fetch.py +++ b/tests/encoders/binary/test_enc_bin_fetch.py @@ -6,12 +6,14 @@ def test_fetch_no_children(): encoded = encoder.encode_fetch(0xF01, []) - assert encoded == b'\x05\x19\x0f\x01\xf6' + assert encoded == b"\x05\x19\x0f\x01\xf6" + def test_fetch_one_child(): encoded = encoder.encode_fetch(0xF, [0xF01]) - assert encoded == b'\x05\x0f\x81\x19\x0f\x01' + assert encoded == b"\x05\x0f\x81\x19\x0f\x01" + def test_fetch_two_children(): encoded = encoder.encode_fetch(0xF, [0xF01, 0xF02]) - assert encoded == b'\x05\x0f\x82\x19\x0f\x01\x19\x0f\x02' + assert encoded == b"\x05\x0f\x82\x19\x0f\x01\x19\x0f\x02" diff --git a/tests/encoders/binary/test_enc_bin_get.py b/tests/encoders/binary/test_enc_bin_get.py index ed914be..5c9cfba 100644 --- a/tests/encoders/binary/test_enc_bin_get.py +++ b/tests/encoders/binary/test_enc_bin_get.py @@ -6,4 +6,4 @@ def test_get(): encoded = encoder.encode_get(0xF01) - assert encoded == b'\x01\x19\x0f\x01' + assert encoded == b"\x01\x19\x0f\x01" diff --git a/tests/encoders/binary/test_enc_bin_get_paths.py b/tests/encoders/binary/test_enc_bin_get_paths.py index ae6d46f..3d95a49 100644 --- a/tests/encoders/binary/test_enc_bin_get_paths.py +++ b/tests/encoders/binary/test_enc_bin_get_paths.py @@ -6,4 +6,4 @@ def test_enc_get_paths(): encoded = encoder.encode_get_path(0xF) - assert encoded == b'\x05\x17\x81\x0f' + assert encoded == b"\x05\x17\x81\x0f" diff --git a/tests/encoders/binary/test_enc_bin_update.py b/tests/encoders/binary/test_enc_bin_update.py index 63dfd9b..c2dd17f 100644 --- a/tests/encoders/binary/test_enc_bin_update.py +++ b/tests/encoders/binary/test_enc_bin_update.py @@ -6,20 +6,24 @@ def test_update_int(): encoded = encoder.encode_update(0x0, 0x4F, 1) - assert encoded == b'\x07\x00\xa1\x18O\x01' + assert encoded == b"\x07\x00\xa1\x18O\x01" + def test_update_float(): encoded = encoder.encode_update(0x0, 0x4F, 3.14) - assert encoded == b'\x07\x00\xa1\x18O\xfa@H\xf5\xc3' + assert encoded == b"\x07\x00\xa1\x18O\xfa@H\xf5\xc3" + def test_update_str(): encoded = encoder.encode_update(0x0, 0x4F, "hello") - assert encoded == b'\x07\x00\xa1\x18Oehello' + assert encoded == b"\x07\x00\xa1\x18Oehello" + def test_update_bool_true(): encoded = encoder.encode_update(0x0, 0x4F, "true") - assert encoded == b'\x07\x00\xa1\x18O\xf5' + assert encoded == b"\x07\x00\xa1\x18O\xf5" + def test_update_bool_false(): encoded = encoder.encode_update(0x0, 0x4F, "false") - assert encoded == b'\x07\x00\xa1\x18O\xf4' + assert encoded == b"\x07\x00\xa1\x18O\xf4" diff --git a/tests/encoders/text/test_enc_txt_exec.py b/tests/encoders/text/test_enc_txt_exec.py index 4642154..6a52612 100644 --- a/tests/encoders/text/test_enc_txt_exec.py +++ b/tests/encoders/text/test_enc_txt_exec.py @@ -8,18 +8,22 @@ def test_exec_no_args(): encoded = encoder.encode_exec("Func", []) assert encoded == "thingset !Func []\n".encode() + def test_exec_int_arg(): encoded = encoder.encode_exec("Func", [7]) assert encoded == "thingset !Func [7,]\n".encode() + def test_exec_float_arg(): encoded = encoder.encode_exec("Func", [3.14]) assert encoded == "thingset !Func [3.14,]\n".encode() + def test_exec_str_arg(): encoded = encoder.encode_exec("Func", ["a_text-arg"]) assert encoded == """thingset !Func [\\"a_text-arg\\",]\n""".encode() + def test_exec_one_of_each_arg(): encoded = encoder.encode_exec("Func", [1, 2.34, "moretext"]) assert encoded == """thingset !Func [1,2.34,\\"moretext\\",]\n""".encode() diff --git a/tests/encoders/text/test_enc_txt_fetch.py b/tests/encoders/text/test_enc_txt_fetch.py index c40a1ac..0ebfc9c 100644 --- a/tests/encoders/text/test_enc_txt_fetch.py +++ b/tests/encoders/text/test_enc_txt_fetch.py @@ -8,14 +8,17 @@ def test_fetch_root(): encoded = encoder.encode_fetch("", []) assert encoded == "thingset ? null\n".encode() + def test_fetch_root_one_child(): encoded = encoder.encode_fetch("", ["One"]) assert encoded == """thingset ? [\\"One\\",]\n""".encode() + def test_fetch_root_two_children(): encoded = encoder.encode_fetch("", ["One", "Two"]) assert encoded == """thingset ? [\\"One\\",\\"Two\\",]\n""".encode() + def test_fetch_not_root_one_child(): encoded = encoder.encode_fetch("NotRoot", ["One"]) assert encoded == """thingset ?NotRoot [\\"One\\",]\n""".encode() diff --git a/tests/encoders/text/test_enc_txt_get.py b/tests/encoders/text/test_enc_txt_get.py index d8d209e..1b4832f 100644 --- a/tests/encoders/text/test_enc_txt_get.py +++ b/tests/encoders/text/test_enc_txt_get.py @@ -8,10 +8,12 @@ def test_get_root(): encoded = encoder.encode_get("") assert encoded == "thingset ?\n".encode() + def test_get_depth_one(): encoded = encoder.encode_get("One") assert encoded == "thingset ?One\n".encode() + def test_get_depth_two(): encoded = encoder.encode_get("One/Two") assert encoded == "thingset ?One/Two\n".encode() diff --git a/tests/encoders/text/test_enc_txt_update.py b/tests/encoders/text/test_enc_txt_update.py index bce5328..b4318d1 100644 --- a/tests/encoders/text/test_enc_txt_update.py +++ b/tests/encoders/text/test_enc_txt_update.py @@ -8,18 +8,22 @@ def test_update_value_at_root_int(): encoded = encoder.encode_update(None, "Value", [1]) assert encoded == """thingset = {\\"Value\\":1}\n""".encode() + def test_update_value_at_root_float(): encoded = encoder.encode_update(None, "Value", [3.14]) assert encoded == """thingset = {\\"Value\\":3.14}\n""".encode() + def test_update_value_at_root_str(): encoded = encoder.encode_update(None, "Value", ["sometext"]) assert encoded == """thingset = {\\"Value\\":\\"sometext\\"}\n""".encode() + def test_update_value_at_depth_one(): encoded = encoder.encode_update(None, "One/Value", [1]) assert encoded == """thingset =One {\\"Value\\":1}\n""".encode() + def test_update_value_at_depth_two(): encoded = encoder.encode_update(None, "One/Two/Value", [1]) assert encoded == """thingset =One/Two {\\"Value\\":1}\n""".encode()