'Ensure that Q-objects handle ORing ANDed ORed components. :)'

def test_or_and_or_combination(self):

    class TestDoc(Document, ):
        x = IntField()
        y = BooleanField()
    TestDoc.drop_collection()
    TestDoc(x=(-1), y=True).save()
    TestDoc(x=101, y=True).save()
    TestDoc(x=99, y=False).save()
    TestDoc(x=101, y=False).save()
    q1 = (Q(x__gt=0) & (Q(y=True) | Q(y__exists=False)))
    q2 = (Q(x__lt=100) & (Q(y=False) | Q(y__exists=False)))
    query = (q1 | q2).to_query(TestDoc)
    self.assertEqual(query, {'$or': [{'$and': [{'x': {'$gt': 0}}, {'$or': [{'y': True}, {'y': {'$exists': False}}]}]}, {'$and': [{'x': {'$lt': 100}}, {'$or': [{'y': False}, {'y': {'$exists': False}}]}]}]})
    self.assertEqual(2, TestDoc.objects((q1 | q2)).count())
