Repository: redis/redis-py
File: tests/test_asyncio/test_commands.py (Python)

Code before:

    @skip_if_server_version_lt("8.3.224")
    @pytest.mark.parametrize(
        "value", [b"", b"abc", b"The quick brown fox jumps over the lazy dog"]
    )
    async def test_local_digest_matches_server(self, r, value):
        key = "k:digest"
        await r.delete(key)
        await r.set(key, value)

        res_server = await r.digest(key)

        # Caution! This one is not executing execute_command and it not async
        res_local = r.digest_local(value)

        # got is str if decode_responses=True; ensure bytes->str for comparison
        if isinstance(res_server, bytes):
            assert isinstance(res_local, bytes)

        assert res_server is not None
        assert len(res_server) == 16
        assert res_local is not None
        assert len(res_local) == 16
        assert res_server == res_local

    @skip_if_server_version_lt("8.3.224")
    async def test_pipeline_digest(self, r):
        k1, k2 = "k:d1{42}", "k:d2{42}"
        await r.mset({k1: b"A", k2: b"B"})
        p = r.pipeline()
        p.digest(k1)
        p.digest(k2)
        out = await p.execute()
        assert len(out) == 2
        for d in out:
            if isinstance(d, bytes):
                d = d.decode()
            assert d is None or len(d) == 16

    async def test_get_and_set(self, r: redis.Redis):
        # get and set can't be tested independently of each other
        assert await r.get("a") is None
        byte_string = b"value"
        integer = 5
        unicode_string = chr(3456) + "abcd" + chr(3421)
        assert await r.set("byte_string", byte_string)
        assert await r.set("integer", 5)
        assert await r.set("unicode_string", unicode_string)
        assert await r.get("byte_string") == byte_string
        assert await r.get("integer") == str(integer).encode()
        assert (await r.get("unicode_string")).decode("utf-8") == unicode_string

Review comment (suggestion):
The test only verifies that res_local is bytes when res_server is bytes, but doesn't verify the opposite case when decode_responses=True. Consider adding an else clause to assert that both are strings when decode_responses=True, ensuring type consistency between server and local digest in both modes.

Code after:

    @skip_if_server_version_lt("8.3.224")
    @pytest.mark.parametrize(
        "value",
        [
            b"",
            b"abc",
            b"The quick brown fox jumps over the lazy dog",
            "",
            "abc",
            "The quick brown fox jumps over the lazy dog",
        ],
    )
    async def test_local_digest_matches_server(self, r, value):
        key = "k:digest"
        await r.delete(key)
        await r.set(key, value)

        res_server = await r.digest(key)

        # Caution! This one is not executing execute_command and it is not async
        res_local = r.digest_local(value)

        # Verify type consistency between server and local digest
        if isinstance(res_server, bytes):
            assert isinstance(res_local, bytes)
        else:
            assert isinstance(res_local, str)

        assert res_server is not None
        assert len(res_server) == 16
        assert res_local is not None
        assert len(res_local) == 16
        assert res_server == res_local

    @skip_if_server_version_lt("8.3.224")
    async def test_pipeline_digest(self, r):
        k1, k2 = "k:d1{42}", "k:d2{42}"
        await r.mset({k1: b"A", k2: b"B"})
        p = r.pipeline()
        p.digest(k1)
        p.digest(k2)
        out = await p.execute()
        assert len(out) == 2
        for d in out:
            if isinstance(d, bytes):
                d = d.decode()
            assert d is None or len(d) == 16

    async def test_get_and_set(self, r: redis.Redis):
        # get and set can't be tested independently of each other