import jsii
import pytest

from jsii.errors import JSIIError
import jsii_calc


class TestErrorHandling:
    def test_jsii_error(self):
        obj = jsii_calc.Calculator()

        with pytest.raises(
            JSIIError, match="Class jsii-calc.Calculator doesn't have a method"
        ):
            jsii.kernel.invoke(obj, "nonexistentMethod")

    def test_inheritance_maintained(self):
        """Check that for JSII struct types we can get the inheritance tree in some way."""
        # inspect.getmro() won't work because of TypedDict, but we add another annotation
        bases = find_struct_bases(jsii_calc.DerivedStruct)

        base_names = [b.__name__ for b  in bases]

        assert base_names == ['DerivedStruct', 'MyFirstStruct']

    def test_descriptive_error_when_passing_function(self):
        obj = jsii_calc.Calculator()

        with pytest.raises(JSIIError, match="Cannot pass function as argument here.*"):
            obj.add(self.test_descriptive_error_when_passing_function)


def find_struct_bases(x):
    ret = []
    seen = set([])

    def recurse(s):
        if s not in seen:
            ret.append(s)
            seen.add(s)
            bases = getattr(s, '__jsii_struct_bases__', [])
            for base in bases:
                recurse(base)

    recurse(x)
    return ret
import jsii
import pytest

from jsii.errors import JSIIError
import jsii_calc


class TestErrorHandling:
    def test_jsii_error(self):
        obj = jsii_calc.Calculator()

        with pytest.raises(
            JSIIError, match="Class jsii-calc.Calculator doesn't have a method"
        ):
            jsii.kernel.invoke(obj, "nonexistentMethod")

    def test_inheritance_maintained(self):
        """Check that for JSII struct types we can get the inheritance tree in some way."""
        # inspect.getmro() won't work because of TypedDict, but we add another annotation
        bases = find_struct_bases(jsii_calc.DerivedStruct)

        base_names = [b.__name__ for b  in bases]

        assert base_names == ['DerivedStruct', 'MyFirstStruct']

    def test_descriptive_error_when_passing_function(self):
        obj = jsii_calc.Calculator()

        with pytest.raises(JSIIError, match="Cannot pass function as argument here.*"):
            obj.add(self.test_descriptive_error_when_passing_function)


def find_struct_bases(x):
    ret = []
    seen = set([])

    def recurse(s):
        if s not in seen:
            ret.append(s)
            seen.add(s)
            bases = getattr(s, '__jsii_struct_bases__', [])
            for base in bases:
                recurse(base)

    recurse(x)
    return ret
Check that for JSII struct types we can get the inheritance tree in some way. # inspect.getmro() won't work because of TypedDict, but we add another annotation