|
1 """ |
|
2 Spanning tests for all the operations that F() expressions can perform. |
|
3 """ |
|
4 from django.test import TestCase, Approximate |
|
5 |
|
6 from django.conf import settings |
|
7 from django.db import models, DEFAULT_DB_ALIAS |
|
8 from django.db.models import F |
|
9 |
|
10 from regressiontests.expressions_regress.models import Number |
|
11 |
|
12 class ExpressionsRegressTests(TestCase): |
|
13 |
|
14 def setUp(self): |
|
15 Number(integer=-1).save() |
|
16 Number(integer=42).save() |
|
17 Number(integer=1337).save() |
|
18 self.assertEqual(Number.objects.update(float=F('integer')), 3) |
|
19 |
|
20 def test_fill_with_value_from_same_object(self): |
|
21 """ |
|
22 We can fill a value in all objects with an other value of the |
|
23 same object. |
|
24 """ |
|
25 self.assertQuerysetEqual( |
|
26 Number.objects.all(), |
|
27 [ |
|
28 '<Number: -1, -1.000>', |
|
29 '<Number: 42, 42.000>', |
|
30 '<Number: 1337, 1337.000>' |
|
31 ] |
|
32 ) |
|
33 |
|
34 def test_increment_value(self): |
|
35 """ |
|
36 We can increment a value of all objects in a query set. |
|
37 """ |
|
38 self.assertEqual( |
|
39 Number.objects.filter(integer__gt=0) |
|
40 .update(integer=F('integer') + 1), |
|
41 2) |
|
42 |
|
43 self.assertQuerysetEqual( |
|
44 Number.objects.all(), |
|
45 [ |
|
46 '<Number: -1, -1.000>', |
|
47 '<Number: 43, 42.000>', |
|
48 '<Number: 1338, 1337.000>' |
|
49 ] |
|
50 ) |
|
51 |
|
52 def test_filter_not_equals_other_field(self): |
|
53 """ |
|
54 We can filter for objects, where a value is not equals the value |
|
55 of an other field. |
|
56 """ |
|
57 self.assertEqual( |
|
58 Number.objects.filter(integer__gt=0) |
|
59 .update(integer=F('integer') + 1), |
|
60 2) |
|
61 self.assertQuerysetEqual( |
|
62 Number.objects.exclude(float=F('integer')), |
|
63 [ |
|
64 '<Number: 43, 42.000>', |
|
65 '<Number: 1338, 1337.000>' |
|
66 ] |
|
67 ) |
|
68 |
|
69 def test_complex_expressions(self): |
|
70 """ |
|
71 Complex expressions of different connection types are possible. |
|
72 """ |
|
73 n = Number.objects.create(integer=10, float=123.45) |
|
74 self.assertEqual(Number.objects.filter(pk=n.pk) |
|
75 .update(float=F('integer') + F('float') * 2), |
|
76 1) |
|
77 |
|
78 self.assertEqual(Number.objects.get(pk=n.pk).integer, 10) |
|
79 self.assertEqual(Number.objects.get(pk=n.pk).float, Approximate(256.900, places=3)) |
|
80 |
|
81 class ExpressionOperatorTests(TestCase): |
|
82 def setUp(self): |
|
83 self.n = Number.objects.create(integer=42, float=15.5) |
|
84 |
|
85 def test_lefthand_addition(self): |
|
86 # LH Addition of floats and integers |
|
87 Number.objects.filter(pk=self.n.pk).update( |
|
88 integer=F('integer') + 15, |
|
89 float=F('float') + 42.7 |
|
90 ) |
|
91 |
|
92 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 57) |
|
93 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(58.200, places=3)) |
|
94 |
|
95 def test_lefthand_subtraction(self): |
|
96 # LH Subtraction of floats and integers |
|
97 Number.objects.filter(pk=self.n.pk).update(integer=F('integer') - 15, |
|
98 float=F('float') - 42.7) |
|
99 |
|
100 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 27) |
|
101 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(-27.200, places=3)) |
|
102 |
|
103 def test_lefthand_multiplication(self): |
|
104 # Multiplication of floats and integers |
|
105 Number.objects.filter(pk=self.n.pk).update(integer=F('integer') * 15, |
|
106 float=F('float') * 42.7) |
|
107 |
|
108 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 630) |
|
109 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(661.850, places=3)) |
|
110 |
|
111 def test_lefthand_division(self): |
|
112 # LH Division of floats and integers |
|
113 Number.objects.filter(pk=self.n.pk).update(integer=F('integer') / 2, |
|
114 float=F('float') / 42.7) |
|
115 |
|
116 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 21) |
|
117 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(0.363, places=3)) |
|
118 |
|
119 def test_lefthand_modulo(self): |
|
120 # LH Modulo arithmetic on integers |
|
121 Number.objects.filter(pk=self.n.pk).update(integer=F('integer') % 20) |
|
122 |
|
123 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 2) |
|
124 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) |
|
125 |
|
126 def test_lefthand_bitwise_and(self): |
|
127 # LH Bitwise ands on integers |
|
128 Number.objects.filter(pk=self.n.pk).update(integer=F('integer') & 56) |
|
129 |
|
130 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 40) |
|
131 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) |
|
132 |
|
133 if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle': |
|
134 def test_lefthand_bitwise_or(self): |
|
135 # LH Bitwise or on integers |
|
136 Number.objects.filter(pk=self.n.pk).update(integer=F('integer') | 48) |
|
137 |
|
138 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 58) |
|
139 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) |
|
140 |
|
141 def test_right_hand_addition(self): |
|
142 # Right hand operators |
|
143 Number.objects.filter(pk=self.n.pk).update(integer=15 + F('integer'), |
|
144 float=42.7 + F('float')) |
|
145 |
|
146 # RH Addition of floats and integers |
|
147 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 57) |
|
148 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(58.200, places=3)) |
|
149 |
|
150 def test_right_hand_subtraction(self): |
|
151 Number.objects.filter(pk=self.n.pk).update(integer=15 - F('integer'), |
|
152 float=42.7 - F('float')) |
|
153 |
|
154 # RH Subtraction of floats and integers |
|
155 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, -27) |
|
156 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(27.200, places=3)) |
|
157 |
|
158 def test_right_hand_multiplication(self): |
|
159 # RH Multiplication of floats and integers |
|
160 Number.objects.filter(pk=self.n.pk).update(integer=15 * F('integer'), |
|
161 float=42.7 * F('float')) |
|
162 |
|
163 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 630) |
|
164 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(661.850, places=3)) |
|
165 |
|
166 def test_right_hand_division(self): |
|
167 # RH Division of floats and integers |
|
168 Number.objects.filter(pk=self.n.pk).update(integer=640 / F('integer'), |
|
169 float=42.7 / F('float')) |
|
170 |
|
171 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 15) |
|
172 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(2.755, places=3)) |
|
173 |
|
174 def test_right_hand_modulo(self): |
|
175 # RH Modulo arithmetic on integers |
|
176 Number.objects.filter(pk=self.n.pk).update(integer=69 % F('integer')) |
|
177 |
|
178 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 27) |
|
179 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) |
|
180 |
|
181 def test_right_hand_bitwise_and(self): |
|
182 # RH Bitwise ands on integers |
|
183 Number.objects.filter(pk=self.n.pk).update(integer=15 & F('integer')) |
|
184 |
|
185 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 10) |
|
186 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) |
|
187 |
|
188 if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.oracle': |
|
189 def test_right_hand_bitwise_or(self): |
|
190 # RH Bitwise or on integers |
|
191 Number.objects.filter(pk=self.n.pk).update(integer=15 | F('integer')) |
|
192 |
|
193 self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 47) |
|
194 self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) |
|
195 |