# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt

"""Tests for coverage.py's bytecode analysis."""

from __future__ import annotations

import dis

from textwrap import dedent

from tests.coveragetest import CoverageTest

from coverage import env
from coverage.bytecode import code_objects, op_set


class BytecodeTest(CoverageTest):
    """Tests for bytecode.py"""

    def test_code_objects(self) -> None:
        code = compile(
            dedent("""\
                def f(x):
                    def g(y):
                        return {z for z in range(10)}
                    def j():
                        return [z for z in range(10)]
                    return g(x)
                def h(x):
                    return x+1
                """),
            "<string>",
            "exec"
        )

        objs = list(code_objects(code))
        assert code in objs

        expected = {"<module>", "f", "g", "j", "h"}
        if env.PYVERSION < (3, 12):
            # Comprehensions were compiled as implicit functions in earlier
            # versions of Python.
            expected.update({"<setcomp>", "<listcomp>"})
        assert {c.co_name for c in objs} == expected

    def test_op_set(self) -> None:
        opcodes = op_set("LOAD_CONST", "NON_EXISTENT_OPCODE", "RETURN_VALUE")
        assert opcodes == {dis.opmap["LOAD_CONST"], dis.opmap["RETURN_VALUE"]}
