예제 #1
0
    def test_trait_dict_notification_compat(self):

        events = []

        def notifier(*args, **kwargs):
            event = dict_event_factory(*args, **kwargs)
            events.append(event)

        trait_dict = TraitDict(
            {
                "3": 3,
                "4": 4
            },
            notifiers=[notifier],
        )

        # when
        del trait_dict["4"]

        # then
        event, = events
        self.assertIs(event.object, trait_dict)
        self.assertEqual(event.removed, {"4": 4})

        # when
        events.clear()
        trait_dict.update({"3": None, "1": 1})

        # then
        event, = events
        self.assertEqual(event.removed, {"3": 3})
        self.assertEqual(event.added, {"3": None, "1": 1})
예제 #2
0
    def test_setdefault(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])

        result = td.setdefault("c", 3)
        self.assertEqual(result, 3)

        self.assertEqual(td.setdefault("a", 5), 1)
예제 #3
0
    def test_init_iterable(self):
        td = TraitDict([("a", 1), ("b", 2)], key_validator=str_validator,
                       value_validator=int_validator)
        self.assertEqual(td, {"a": 1, "b": 2})
        self.assertEqual(td.notifiers, [])

        with self.assertRaises(ValueError):
            TraitDict(["a", "b"], key_validator=str_validator,
                      value_validator=int_validator)
예제 #4
0
    def test_clear(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])

        td.clear()

        self.assertEqual(self.added, {})
        self.assertEqual(self.changed, {})
        self.assertEqual(self.removed, {"a": 1, "b": 2})
예제 #5
0
    def test_update_iterable(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])

        td.update([("a", 2), ("b", 4), ("c", 5)])

        self.assertEqual(self.added, {"c": 5})
        self.assertEqual(self.changed, {"a": 1, "b": 2})
        self.assertEqual(self.removed, {})
예제 #6
0
    def test_pop_key_error(self):
        python_dict = {}
        with self.assertRaises(KeyError) as python_e:
            python_dict.pop("a")

        td = TraitDict()
        with self.assertRaises(KeyError) as trait_e:
            td.pop("a")

        self.assertEqual(
            str(trait_e.exception),
            str(python_e.exception),
        )
예제 #7
0
    def test_clear_empty_dictionary(self):
        # Clearing an empty dictionary should not notify.
        td = TraitDict(
            {},
            key_validator=str_validator,
            value_validator=int_validator,
            notifiers=[self.notification_handler],
        )

        td.clear()

        self.assertIsNone(self.added)
        self.assertIsNone(self.changed)
        self.assertIsNone(self.removed)
예제 #8
0
    def test_update_with_empty_argument(self):
        td = TraitDict(
            {"1": 1, "2": 2},
            key_validator=str,
            notifiers=[self.notification_handler],
        )

        # neither of these should cause a notification to be emitted
        td.update([])
        td.update({})
        self.assertEqual(td, {"1": 1, "2": 2})
        self.assertIsNone(self.added)
        self.assertIsNone(self.changed)
        self.assertIsNone(self.removed)
예제 #9
0
    def test_pop(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])

        td.pop("b", "X")

        self.assertEqual(self.removed, {"b": 2})

        self.removed = None
        res = td.pop("x", "X")
        # Ensure no notification is fired.
        self.assertIsNone(self.removed)
        self.assertEqual(res, "X")
예제 #10
0
    def test_update_notifies_with_nonempty_argument(self):
        # Corner case: we don't want to get into the difficulties of
        # comparing values for equality, so we notify for a non-empty
        # argument even if the dictionary has not actually changed.
        td = TraitDict(
            {"1": 1, "2": 2},
            key_validator=str,
            notifiers=[self.notification_handler],
        )

        td.update({"1": 1})
        self.assertEqual(td, {"1": 1, "2": 2})
        self.assertEqual(self.added, {})
        self.assertEqual(self.changed, {"1": 1})
        self.assertEqual(self.removed, {})
예제 #11
0
    def test_update_with_transformation(self):
        td = TraitDict(
            {"1": 1, "2": 2},
            key_validator=str,
            notifiers=[self.notification_handler],
        )

        # when
        td.update({1: 2})

        # then
        self.assertEqual(td, {"1": 2, "2": 2})
        self.assertEqual(self.added, {})
        self.assertEqual(self.changed, {"1": 1})
        self.assertEqual(self.removed, {})
예제 #12
0
    def test_invalid_value(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])

        with self.assertRaises(TraitError):
            td["3"] = True
예제 #13
0
 def test_init(self):
     td = TraitDict({
         "a": 1,
         "b": 2
     },
                    key_validator=str_validator,
                    value_validator=int_validator)
     self.assertEqual(td, {"a": 1, "b": 2})
     self.assertEqual(td.notifiers, [])
예제 #14
0
    def test_delitem(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])
        del td["a"]

        self.assertEqual(self.added, {})
        self.assertEqual(self.changed, {})
        self.assertEqual(self.removed, {"a": 1})
예제 #15
0
 def test_ior(self):
     td = TraitDict(
         {"a": 1, "b": 2},
         key_validator=str_validator,
         value_validator=int_validator,
         notifiers=[self.notification_handler],
     )
     with self.assertRaises(TypeError):
         td |= {"a": 3, "d": 5}
예제 #16
0
    def test_deepcopy(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])
        td_copy = copy.deepcopy(td)

        self.assertEqual(td, td_copy)
        self.assertEqual(td_copy.notifiers, [])
        self.assertEqual(td_copy.value_validator, td.value_validator)
        self.assertEqual(td_copy.key_validator, td.key_validator)
예제 #17
0
    def test_pickle(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])

        for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
            td_unpickled = pickle.loads(pickle.dumps(td, protocol=protocol))

            self.assertIs(td_unpickled.key_validator, str_validator)
            self.assertIs(td_unpickled.value_validator, int_validator)
            self.assertEqual(td_unpickled.notifiers, [])
예제 #18
0
    def test_setitem(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])
        td["a"] = 5

        self.assertEqual(self.added, {})
        self.assertEqual(self.changed, {"a": 1})
        self.assertEqual(self.removed, {})

        with self.assertRaises(TraitError):
            td[5] = "a"
예제 #19
0
    def test_setdefault_with_casting(self):
        # If the validator does transformation, the containment
        # is checked before the transformation. This is more
        # consistent with the description of setdefault, which is
        # effectively a short-hand for ``__getitem__``,
        # followed by ``__setitem__`` (if get fails), followed by
        # another ``__getitem__``.
        # The notification should be factual about the actual
        # mutation on the dict.
        notifier = mock.Mock()
        td = TraitDict(
            key_validator=str,
            value_validator=str,
            notifiers=[notifier, self.notification_handler],
        )

        td.setdefault(1, 2)
        self.assertEqual(td, {"1": "2"})
        self.assertEqual(notifier.call_count, 1)
        self.assertEqual(self.removed, {})
        self.assertEqual(self.added, {"1": "2"})
        self.assertEqual(self.changed, {})

        notifier.reset_mock()
        td.setdefault(1, 4)
        self.assertEqual(td, {"1": "4"})
        self.assertEqual(notifier.call_count, 1)

        self.assertEqual(self.removed, {})
        self.assertEqual(self.added, {})
        self.assertEqual(self.changed, {"1": "2"})
예제 #20
0
    def test_popitem(self):
        td = TraitDict({"a": 1, "b": 2}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])

        items_cpy = td.copy().items()

        itm = td.popitem()

        self.assertIn(itm, items_cpy)
        self.assertNotIn(itm, td.items())

        td = TraitDict({}, key_validator=str_validator,
                       value_validator=int_validator,
                       notifiers=[self.notification_handler])

        with self.assertRaises(KeyError):
            td.popitem()
예제 #21
0
    def test_delitem_not_found(self):
        python_dict = dict()
        with self.assertRaises(KeyError) as python_e:
            del python_dict["x"]

        td = TraitDict()
        with self.assertRaises(KeyError) as trait_e:
            del td["x"]

        self.assertEqual(
            str(trait_e.exception),
            str(python_e.exception),
        )
예제 #22
0
        def test_ior(self):
            td = TraitDict(
                {"a": 1, "b": 2},
                key_validator=str_validator,
                value_validator=int_validator,
                notifiers=[self.notification_handler],
            )
            td |= {"a": 3, "d": 5}

            self.assertEqual(td, {"a": 3, "b": 2, "d": 5})
            self.assertEqual(self.added, {"d": 5})
            self.assertEqual(self.changed, {"a": 1})
            self.assertEqual(self.removed, {})
예제 #23
0
        def test_ior_is_quiet_if_no_change(self):
            td = TraitDict(
                {"a": 1, "b": 2},
                key_validator=str_validator,
                value_validator=int_validator,
                notifiers=[self.notification_handler],
            )

            td |= []

            self.assertEqual(td, {"a": 1, "b": 2})
            self.assertIsNone(self.added)
            self.assertIsNone(self.removed)
            self.assertIsNone(self.changed)