示例#1
0
    def test_joint_conditions(self):
        """
        Test that joint conditions must be on the same aliased instance.

        In particular P(rel__attr1=val1, rel__attr2=val2) produces only a
        single join, so the two conditions must be jointly satisfied on the
        same database row.
        """
        self._assert_P_matches_Q(
            self.test_obj,
            p=P(m2ms__int_value=10, m2ms__char_value='bar'),
            q=Q(m2ms__int_value=10, m2ms__char_value='bar'),
        )
        self._assert_P_matches_Q(
            self.test_obj,
            p=P(m2ms__int_value=10, m2ms__char_value='foo'),
            q=Q(m2ms__int_value=10, m2ms__char_value='foo'),
        )
        self._assert_P_matches_Q(
            self.test_obj,
            p=P(m2ms__int_value=10) & OrmP(m2ms__char_value='bar'),
            q=Q(m2ms__int_value=10) & Q(m2ms__char_value='bar'),
        )

        self._assert_P_matches_Q(
            self.test_obj,
            p=P(m2ms__int_value=10) & OrmP(m2ms__char_value='foo'),
            q=Q(m2ms__int_value=10) & Q(m2ms__char_value='foo'),
        )
示例#2
0
 def test_follow_relationship(self):
     p1 = P(parent__int_value__gt=10)
     obj = TestObj.objects.filter(parent__int_value__gt=10)[0]
     self.assertTrue(p1.eval(obj))
     p2 = P(parent__parent__int_value__gt=10)
     obj = TestObj.objects.filter(parent__parent__int_value__gt=10)[0]
     self.assertTrue(p2.eval(obj))
示例#3
0
 def test_and(self):
     p1 = P(char_value__contains='hello')
     p2 = P(int_value=50)
     p3 = P(int_value__lt=20)
     pand1 = p1 & p2
     pand2 = p2 & p3
     self.assertTrue(pand1.eval(self.testobj))
     self.assertFalse(pand2.eval(self.testobj))
示例#4
0
 def test_or(self):
     p1 = P(char_value__contains='hello', int_value=50)
     p2 = P(int_value__gt=80)
     p3 = P(int_value__lt=20)
     por1 = p1 | p2
     por2 = p2 | p3
     self.assertTrue(por1.eval(self.testobj))
     self.assertFalse(por2.eval(self.testobj))
示例#5
0
 def test_or2(self):
     p1 = P(foo=True)
     p2 = P(bar=False)
     d = {'foo': True, 'bar': True}
     self.assertIn(d, p1)
     self.assertNotIn(d, p2)
     self.assertIn(d, (p1 | p1))
     self.assertIn(d, (p1 | p2))
     self.assertIn(d, (p1 | p2))
     self.assertIn(d, (p2 | p1))
     self.assertNotIn(d, (p2 | p2))
     self.assertNotIn(d, (p2 | P(foo=False)))
     self.assertNotIn(d, (P(foo=False) | p2))
示例#6
0
 def test_patch_with_orm_eval(self):
     """
     Tests that the debug patch_with_orm_eval() context works as expected.
     """
     with mock.patch('predicate.debug.original_eval',
                     return_value=False) as patched:
         self.assertIn(self.test_obj, P(int_value=10))
         self.assertFalse(patched.called)
         with patch_with_orm_eval():
             with self.assertRaises(AssertionError):
                 self.test_obj in P(int_value=10)
     self.assertTrue(patched.called)
     with patch_with_orm_eval():
         self.assertIn(self.test_obj, P(int_value=10))
示例#7
0
    def test_debug_orm_validations(self):
        self.assertIn(self.test_obj, P(int_value=10))
        with mock.patch('predicate.debug.original_eval',
                        return_value=False) as patched:
            with self.assertRaises(AssertionError):
                self.test_obj in OrmP(int_value=10)
        self.assertTrue(patched.called)

        with mock.patch('predicate.debug.original_eval',
                        return_value=True) as patched:
            self.assertIn(self.test_obj, OrmP(int_value=10))
        self.assertTrue(patched.called)
示例#8
0
    def test_dates(self):
        today = date.today()
        self.assertTrue(P(date_value__year=today.year).eval(self.testobj))
        self.assertTrue(P(date_value__month=today.month).eval(self.testobj))
        self.assertTrue(P(date_value__day=today.day).eval(self.testobj))
        self.assertTrue(
            P(date_value__week_day=today.weekday()).eval(self.testobj))

        self.assertFalse(P(date_value__year=today.year + 1).eval(self.testobj))
        self.assertFalse(
            P(date_value__month=today.month + 1).eval(self.testobj))
        self.assertFalse(P(date_value__day=today.day + 1).eval(self.testobj))
        self.assertFalse(
            P(date_value__week_day=today.weekday() + 1).eval(self.testobj))
示例#9
0
 def set_similar(self, my_obj=None):
     dlog("settings similar")
     if my_obj is None:
         my_obj = ColorChoice.objects.get(id=self.colorid)
     my_name = 'similar{}'.format(self.colorid)
     similar_color = P(hue__range=(max(0, my_obj.hue - 25),
                                   min(365, my_obj.hue + 25)),
                       saturation__range=(max(0, my_obj.saturation - 20),
                                          min(100, my_obj.saturation + 20)),
                       brightness__range=(max(0, my_obj.brightness - 20),
                                          min(100, my_obj.brightness + 20)))
     dlog(similar_color.children)
     collections[my_name] = Collection(my_name, similar_color)
     return my_name
示例#10
0
    def test_law_of_excluded_middle(self):
        """
        Django appears to obey the law of excluded middle p|~p is always
        satisfied.

        However, it's _not_ the case that p OR ~p is always satisfied, so the
        implementation in P does not match django's in some edge cases.
        """
        p = P(m2ms__int_value=10, m2ms__char_value='bar')
        q = Q(m2ms__int_value=10, m2ms__char_value='bar')
        self._assert_P_matches_Q(self.test_obj, p=p, q=q)

        self.assertNotIn(self.test_obj, p)
        self.assertNotIn(self.test_obj, ~p)
        # Since evaluation of the disjunction is just logical OR of the
        # disjuncts, since the
        self.assertNotIn(self.test_obj, p | ~p)

        self._assert_P_matches_Q(self.test_obj, p=p, q=q)
        self._assert_P_matches_Q(self.test_obj, p=(p | ~p), q=(q | ~q))
示例#11
0
    def test_dates(self):
        self.assertTrue(
            OrmP(date_value__year=self.date_obj.year).eval(self.testobj))
        self.assertTrue(
            OrmP(date_value__month=self.date_obj.month).eval(self.testobj))
        self.assertTrue(
            OrmP(date_value__day=self.date_obj.day).eval(self.testobj))

        orm_week_day = self.date_obj.isoweekday() % 7 + 1

        self.assertTrue(
            OrmP(date_value__week_day=orm_week_day).eval(self.testobj))

        self.assertFalse(
            OrmP(date_value__year=self.date_obj.year + 1).eval(self.testobj))
        self.assertFalse(
            OrmP(date_value__month=self.date_obj.month + 1).eval(self.testobj))
        self.assertFalse(
            OrmP(date_value__day=self.date_obj.day + 1).eval(self.testobj))
        self.assertFalse(
            P(date_value__week_day=orm_week_day + 1).eval(self.testobj))
示例#12
0
    def test_negation_joint_conditions(self):
        self._assert_P_matches_Q(
            self.test_obj,
            p=~P(m2ms__int_value=10, m2ms__char_value='bar'),
            q=~Q(m2ms__int_value=10, m2ms__char_value='bar'),
        )

        self.assertIn(
            self.test_obj,
            TestObj.objects.filter(
                ~~Q(m2ms__int_value=10, m2ms__char_value='bar')))
        self.assertIn(self.test_obj,
                      ~~P(m2ms__int_value=10, m2ms__char_value='bar'))
        self._assert_P_matches_Q(
            self.test_obj,
            p=~~P(m2ms__int_value=10, m2ms__char_value='bar'),
            q=~~Q(m2ms__int_value=10, m2ms__char_value='bar'),
        )

        self.assertNotIn(
            self.test_obj,
            TestObj.objects.filter(
                ~~~Q(m2ms__int_value=10, m2ms__char_value='bar')))
        self.assertNotIn(self.test_obj,
                         ~~~P(m2ms__int_value=10, m2ms__char_value='bar'))
        self._assert_P_matches_Q(
            self.test_obj,
            p=~~~P(m2ms__int_value=10, m2ms__char_value='bar'),
            q=~~~Q(m2ms__int_value=10, m2ms__char_value='bar'),
        )

        self.assertIn(self.test_obj,
                      ~~P(m2ms__int_value=10, m2ms__char_value='foo'))
        self._assert_P_matches_Q(
            self.test_obj,
            q=~~Q(m2ms__int_value=10, m2ms__char_value='foo'),
            p=~~P(m2ms__int_value=10, m2ms__char_value='foo'),
        )
示例#13
0
 def test_icontains(self):
     self.assertTrue(P(char_value__icontains='heLLo').eval(self.testobj))
示例#14
0
 def test_contains(self):
     self.assertTrue(P(char_value__contains='hello').eval(self.testobj))
     self.assertFalse(P(char_value__contains='foobar').eval(self.testobj))
示例#15
0
 def test_iexact(self):
     self.assertTrue(P(char_value__iexact='heLLo World').eval(self.testobj))
     self.assertFalse(P(char_value__iexact='hello worl').eval(self.testobj))
示例#16
0
    def test_de_morgan_law(self):
        """
        Tests De Morgan's law as it relates to the Django ORM.

        Surprisingly, the ORM does _not_ obey De Morgan's law in some cases,
        which this test manifests. See also:
            https://github.com/django/django/pull/6005#issuecomment-184016682
        since Django may start to obey De Morgan's law in Django >= 1.10.
        """
        expr = P(m2ms__int_value=10) & OrmP(m2ms__char_value='bar')
        transformed_expr = ~(~P(m2ms__int_value=10)
                             | ~P(m2ms__char_value='bar'))
        # By De Morgan's law, these expressions are equivalent:
        #     (A ∧ B) ⇔ ¬(¬A ∨ ¬B)
        # Translated into the ORM, and different queries are constructed for
        # expr and transformed_expr.
        #
        # The original expression compiles to the following SQL:
        #
        # SELECT "testapp_testobj"."id"
        # FROM "testapp_testobj"
        # INNER JOIN "testapp_testobj_m2ms"
        #       ON ("testapp_testobj"."id" = "testapp_testobj_m2ms"."testobj_id")
        # INNER JOIN "testapp_m2mmodel"
        #       ON ("testapp_testobj_m2ms"."m2mmodel_id" = "testapp_m2mmodel"."id")
        # WHERE ("testapp_m2mmodel"."int_value" = 10
        #        AND "testapp_m2mmodel"."char_value" = bar)
        #
        # The transformed version compiles to the following SQL, which is _not_
        # equivalent:
        #
        # SELECT "testapp_testobj"."id"
        # FROM "testapp_testobj"
        # WHERE NOT ((NOT ("testapp_testobj"."id" IN
        #                    (SELECT U1."testobj_id" AS Col1
        #                     FROM "testapp_testobj_m2ms" U1
        #                     INNER JOIN "testapp_m2mmodel" U2
        #                           ON (U1."m2mmodel_id" = U2."id")
        #                     WHERE U2."int_value" = 10))
        #             OR NOT ("testapp_testobj"."id" IN
        #                       (SELECT U1."testobj_id" AS Col1
        #                        FROM "testapp_testobj_m2ms" U1
        #                        INNER JOIN "testapp_m2mmodel" U2
        #                              ON (U1."m2mmodel_id" = U2."id")
        #                        WHERE U2."char_value" = bar))))

        # First show that these are not equivalent in the ORM, to verify that this
        # is not a bug in the predicate.P implementation.
        self.assertNotIn(
            self.test_obj,
            TestObj.objects.filter(
                Q(m2ms__int_value=10) & Q(m2ms__char_value='bar')))
        self.assertNotIn(self.test_obj, TestObj.objects.filter(expr))

        self.assertIn(
            self.test_obj,
            TestObj.objects.filter(~(~Q(m2ms__int_value=10)
                                     | ~Q(m2ms__char_value='bar'))))
        self.assertIn(self.test_obj, TestObj.objects.filter(transformed_expr))

        self.assertNotIn(self.test_obj, expr)
        self.assertIn(self.test_obj, transformed_expr)

        # Negate the queries, but weirdly, that doeesn't cause the answer to change.
        self._assert_P_matches_Q(
            self.test_obj,
            ~expr,
            ~(Q(m2ms__int_value=10) & Q(m2ms__char_value='bar')),
        )
        self.assertNotIn(self.test_obj, TestObj.objects.filter(~expr))

        # Test double negation still returns us to where we were originally.
        self._assert_P_matches_Q(
            self.test_obj, ~~expr,
            ~~(Q(m2ms__int_value=10) & Q(m2ms__char_value='bar'))),
        self.assertIn(self.test_obj, TestObj.objects.filter(~~expr))
示例#17
0
 def test_in_operator(self):
     p = P(int_value__lte=50)
     p2 = P(int_value__lt=10)
     self.assertTrue(self.testobj in p)
     self.assertFalse(self.testobj in p2)
示例#18
0
 def test_iregex(self):
     self.assertTrue(P(char_value__iregex='Hel*o').eval(self.testobj))
示例#19
0
 def test_istartswith(self):
     self.assertTrue(P(char_value__istartswith='heLLo').eval(self.testobj))
     self.assertFalse(P(char_value__startswith='world').eval(self.testobj))
示例#20
0
 def test_lt(self):
     self.assertFalse(P(int_value__lt=20).eval(self.testobj))
     self.assertTrue(P(int_value__lt=80).eval(self.testobj))
     self.assertFalse(P(int_value__lt=20.0).eval(self.testobj))
     self.assertTrue(P(int_value__lt=80.0).eval(self.testobj))
     self.assertFalse(P(int_value__lt=50).eval(self.testobj))
示例#21
0
 def test_iendswith(self):
     self.assertFalse(P(char_value__iendswith='hello').eval(self.testobj))
     self.assertTrue(P(char_value__iendswith='World').eval(self.testobj))
示例#22
0
 def test_lte(self):
     self.assertFalse(P(int_value__lte=20).eval(self.testobj))
     self.assertTrue(P(int_value__lte=50).eval(self.testobj))
示例#23
0
 def test_null(self):
     self.assertTrue(P(parent__isnull=True).eval(self.testobj))
     self.assertFalse(P(parent__isnull=False).eval(self.testobj))
示例#24
0
 def test_regex(self):
     self.assertTrue(P(char_value__regex='hel*o').eval(self.testobj))
     self.assertFalse(P(char_value__regex='Hel*o').eval(self.testobj))
示例#25
0
post_delete.connect(delete_color, ColorChoice)

# This is a global collections data structure accessed by all connected sockets
# it intially holds any commonly defined collections, but clients can add their
# own collections to wire into the signal-collection dispatching. If there were
# to be many user registered collections, the signal should be converted to a
# queued task instead of in the req/res cycle.
collections = {}

try:
    # We do this here in the try because we can't
    # access these models on startup if we are running in the syncdb
    # code. Could import this file in other-than-models.py to avoid that
    blue_colors = P(
        hue__range=(171, 264),
        saturation__range=(30,100),
        brightness__range=(30, 100)
        )

    django1 = P(
        hue__range=(145, 169),
        saturation__range=(30, 89),
        brightness__range=(10, 40)
        )

    django2 = P(
        hue__range=(75, 105),
        saturation__range=(65,99),
        brightness__range=(25,90)
        )