def test_deferred_fields(self):
        pre_save_changed.connect(func, sender=DeferredModel)

        obj = DeferredModel()
        post_init.send(instance=obj, sender=DeferredModel)

        assert list(obj._fieldsignals_originals.values()) == [{'a': 1}]
    def test_deferred_fields(self):
        pre_save_changed.connect(func, sender=DeferredModel)

        obj = DeferredModel()
        post_init.send(instance=obj, sender=DeferredModel)

        assert list(obj._fieldsignals_originals.values()) == [{'a': 1}]
    def test_pre_save_with_fields_unchanged(self):
        with must_be_called(False) as func:
            pre_save_changed.connect(func, sender=FakeModel, fields=('a_key',))

            obj = FakeModel()
            post_init.send(instance=obj, sender=FakeModel)

            obj.another = 'dont care about this field'
            pre_save.send(instance=obj, sender=FakeModel)
    def test_pre_save_with_fields_changed(self):
        with must_be_called(True) as func:
            pre_save_changed.connect(func, sender=FakeModel, fields=('a_key',))

            obj = FakeModel()
            post_init.send(instance=obj, sender=FakeModel)

            obj.a_key = 'change a field that we care about'
            pre_save.send(instance=obj, sender=FakeModel)
    def test_pre_save_unchanged(self):
        with must_be_called(False) as func:
            pre_save_changed.connect(func, sender=FakeModel)

            obj = FakeModel()

            # post_init sets list of initial values
            post_init.send(instance=obj, sender=FakeModel)
            # This *doesn't* call pre_save_changed, because we haven't changed anything.
            pre_save.send(instance=obj, sender=FakeModel)
    def test_pre_save_unchanged(self):
        with must_be_called(False) as func:
            pre_save_changed.connect(func, sender=FakeModel)

            obj = FakeModel()

            # post_init sets list of initial values
            post_init.send(instance=obj, sender=FakeModel)
            # This *doesn't* call pre_save_changed, because we haven't changed anything.
            pre_save.send(instance=obj, sender=FakeModel)
    def test_pre_save_changed(self):
        with must_be_called(True) as func:
            pre_save_changed.connect(func, sender=FakeModel)

            obj = FakeModel()

            # post_init sets list of initial values
            post_init.send(instance=obj, sender=FakeModel)

            obj.a_key = 'another value'
            pre_save.send(instance=obj, sender=FakeModel)
    def test_pre_save_with_fields_unchanged(self):
        with must_be_called(False) as func:
            pre_save_changed.connect(func,
                                     sender=FakeModel,
                                     fields=('a_key', ))

            obj = FakeModel()
            post_init.send(instance=obj, sender=FakeModel)

            obj.another = 'dont care about this field'
            pre_save.send(instance=obj, sender=FakeModel)
    def test_pre_save_with_fields_changed(self):
        with must_be_called(True) as func:
            pre_save_changed.connect(func,
                                     sender=FakeModel,
                                     fields=('a_key', ))

            obj = FakeModel()
            post_init.send(instance=obj, sender=FakeModel)

            obj.a_key = 'change a field that we care about'
            pre_save.send(instance=obj, sender=FakeModel)
    def test_pre_save_changed(self):
        with must_be_called(True) as func:
            pre_save_changed.connect(func, sender=FakeModel)

            obj = FakeModel()

            # post_init sets list of initial values
            post_init.send(instance=obj, sender=FakeModel)

            obj.a_key = 'another value'
            pre_save.send(instance=obj, sender=FakeModel)
    def test_pre_save_with_fields_changed(self):
        with must_be_called(True) as func:
            pre_save_changed.connect(func,
                                     sender=FakeModel,
                                     fields=("a_key", ))

            obj = FakeModel()
            post_init.send(instance=obj, sender=FakeModel)

            obj.a_key = "change a field that we care about"
            pre_save.send(instance=obj, sender=FakeModel)
        assert func.kwargs["changed_fields"] == {
            "a_key": ("a value", "change a field that we care about")
        }
    def test_pre_save_changed(self):
        with must_be_called(True) as func:
            pre_save_changed.connect(func, sender=FakeModel)

            obj = FakeModel()

            # post_init sets list of initial values
            post_init.send(instance=obj, sender=FakeModel)

            obj.a_key = "another value"
            pre_save.send(instance=obj, sender=FakeModel)

        assert func.kwargs["changed_fields"] == {
            "a_key": ("a value", "another value")
        }
    def test_compare_after_to_python(self):
        """
        Field values (e.g. datetimes) are equal even if set via string.
        Ensures that to_python() is called prior to comparison between old & new values.
        """
        with must_be_called(False) as func:
            pre_save_changed.connect(func, sender=FakeModel, fields=('a_datetime',))

            obj = FakeModel()
            obj.a_datetime = '2017-01-01T00:00:00.000000Z'
            post_init.send(instance=obj, sender=FakeModel)

            # This is identical to the above, even though the type is different,
            # so don't call the signal
            obj.a_datetime = datetime.datetime(2017, 1, 1, 0, 0, 0, 0, utc)
            pre_save.send(instance=obj, sender=FakeModel)
    def test_compare_after_to_python(self):
        """
        Field values (e.g. datetimes) are equal even if set via string.
        Ensures that to_python() is called prior to comparison between old & new values.
        """
        with must_be_called(False) as func:
            pre_save_changed.connect(func,
                                     sender=FakeModel,
                                     fields=('a_datetime', ))

            obj = FakeModel()
            obj.a_datetime = '2017-01-01T00:00:00.000000Z'
            post_init.send(instance=obj, sender=FakeModel)

            # This is identical to the above, even though the type is different,
            # so don't call the signal
            obj.a_datetime = datetime.datetime(2017, 1, 1, 0, 0, 0, 0, utc)
            pre_save.send(instance=obj, sender=FakeModel)