# Path: microcosm_pubsub/chain/context.py
# class SafeContext(MutableMapping):
#     """
#     Dictionary that raises on overwriting keys.
# 
#     """
#     def __init__(self, *args, **kwargs):
#         self.store = dict(*args, **kwargs)
# 
#     def __getitem__(self, key):
#         # enable context self-references
#         if key == CONTEXT:
#             return self
#         return self.store[key]
# 
#     def __setitem__(self, key, value):
#         # do not allow overwrite of context self-references
#         if key == CONTEXT:
#             raise ValueError("May not reassign 'context' key")
# 
#         if key in self.store:
#             raise ValueError(f"Key '{key}' already set")
# 
#         self.store[key] = value
# 
#     def assign(self, key, value):
#         # do not allow overwrite of context self-references
#         if key == CONTEXT:
#             raise ValueError("May not reassign 'context' key")
# 
#         # Skip validation
#         self.store[key] = value
#         return self
# 
#     def __delitem__(self, key):
#         del self.store[key]
# 
#     def __iter__(self):
#         return iter(self.store)
# 
#     def __len__(self):
#         return len(self.store)
# 
#     def __getattr__(self, key):
#         return self[key]
# 
#     def local(self, *args, **kwargs):
#         """
#         Create a locally scoped child context.
# 
#         """
#         return ScopedSafeContext(self, *args, **kwargs)


from hamcrest import (
    assert_that,
    calling,
    contains_exactly,
    has_length,
    is_,
    raises,
)
from microcosm_pubsub.chain.context import SafeContext



class TestSafeContext:

    def test_can_set(self):
        context = SafeContext()
        context["arg"] = 20
        assert_that(context["arg"], is_(20))
        assert_that(context.arg, is_(20))

    def test_cannot_overwrite(self):
        context = SafeContext()
        context["arg"] = 20
        assert_that(
            calling(context.update).with_args(arg=21),
            raises(ValueError),
        )


class TestScopedSafeContext:

    def setup(self):

# Path: microcosm_pubsub/chain/context.py
# class SafeContext(MutableMapping):
#     """
#     Dictionary that raises on overwriting keys.
# 
#     """
#     def __init__(self, *args, **kwargs):
#         self.store = dict(*args, **kwargs)
# 
#     def __getitem__(self, key):
#         # enable context self-references
#         if key == CONTEXT:
#             return self
#         return self.store[key]
# 
#     def __setitem__(self, key, value):
#         # do not allow overwrite of context self-references
#         if key == CONTEXT:
#             raise ValueError("May not reassign 'context' key")
# 
#         if key in self.store:
#             raise ValueError(f"Key '{key}' already set")
# 
#         self.store[key] = value
# 
#     def assign(self, key, value):
#         # do not allow overwrite of context self-references
#         if key == CONTEXT:
#             raise ValueError("May not reassign 'context' key")
# 
#         # Skip validation
#         self.store[key] = value
#         return self
# 
#     def __delitem__(self, key):
#         del self.store[key]
# 
#     def __iter__(self):
#         return iter(self.store)
# 
#     def __len__(self):
#         return len(self.store)
# 
#     def __getattr__(self, key):
#         return self[key]
# 
#     def local(self, *args, **kwargs):
#         """
#         Create a locally scoped child context.
# 
#         """
#         return ScopedSafeContext(self, *args, **kwargs)


# Path: microcosm_pubsub/tests/chain/test_context.py
from hamcrest import (
    assert_that,
    calling,
    contains_exactly,
    has_length,
    is_,
    raises,
)
from microcosm_pubsub.chain.context import SafeContext




class TestSafeContext:

    def test_can_set(self):
        context = SafeContext()
        context["arg"] = 20
        assert_that(context["arg"], is_(20))
        assert_that(context.arg, is_(20))

    def test_cannot_overwrite(self):
        context = SafeContext()
        context["arg"] = 20
        assert_that(
            calling(context.update).with_args(arg=21),
            raises(ValueError),
        )


class TestScopedSafeContext:

    def setup(self):

        self.parent = SafeContext()