-
-
Notifications
You must be signed in to change notification settings - Fork 874
/
Copy pathQueryPredicateUnitTests.m
121 lines (90 loc) · 5.69 KB
/
QueryPredicateUnitTests.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
* Copyright (c) 2015-present, Parse, LLC.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "PFQuery.h"
#import "PFQueryUtilities.h"
#import "PFTestCase.h"
@interface QueryPredicateUnitTests : PFTestCase
@end
@implementation QueryPredicateUnitTests
///--------------------------------------
#pragma mark - Helpers
///--------------------------------------
- (void)assertPredicate:(NSPredicate *)predicate hasNormalForm:(NSPredicate *)expectedDNF {
NSPredicate *actualDNF = [PFQueryUtilities predicateByNormalizingPredicate:predicate];
XCTAssertEqualObjects([expectedDNF predicateFormat], [actualDNF predicateFormat]);
}
- (void)assertUnsupportedPredicate:(NSPredicate *)predicate {
PFAssertThrowsInconsistencyException([PFQuery queryWithClassName:@"TestObject" predicate:predicate]);
}
///--------------------------------------
#pragma mark - Tests
///--------------------------------------
- (void)testDisjunctiveNormalForm {
[self assertPredicate:[NSPredicate predicateWithFormat:@"A = B"]
hasNormalForm:[NSPredicate predicateWithFormat:@"A = B"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"!(3 <= X)"]
hasNormalForm:[NSPredicate predicateWithFormat:@"X < 3"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"A BETWEEN {3, 5}"]
hasNormalForm:[NSPredicate predicateWithFormat:@"A >= 3 AND A <= 5"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"A BETWEEN %@", @[@3, @5]]
hasNormalForm:[NSPredicate predicateWithFormat:@"A >= 3 AND A <= 5"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"A = B AND C = D"]
hasNormalForm:[NSPredicate predicateWithFormat:@"A = B AND C = D"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"A = B OR C = D"]
hasNormalForm:[NSPredicate predicateWithFormat:@"A = B OR C = D"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"(A = B AND C = D) OR (E = F AND G = H)"]
hasNormalForm:[NSPredicate predicateWithFormat:@"(A = B AND C = D) OR (E = F AND G = H)"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"(A = B OR C = D) AND (E = F OR G = H)"]
hasNormalForm:[NSPredicate predicateWithFormat:@"(A = B AND E = F) OR (A = B AND G = H) OR "
"(C = D AND E = F) OR (C = D AND G = H)"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"NOT ((A = B AND C = D) OR (E = F AND G = H))"]
hasNormalForm:[NSPredicate predicateWithFormat:@"(A != B AND E != F) OR (A != B AND G != H) OR "
"(C != D AND E != F) OR (C != D AND G != H)"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"NOT (A <= B)"]
hasNormalForm:[NSPredicate predicateWithFormat:@"A > B"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"NOT (NOT (A = B))"]
hasNormalForm:[NSPredicate predicateWithFormat:@"A = B"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"NOT (A BETWEEN %@ OR A BETWEEN %@)",
@[@3, @5], @[@7, @9]]
hasNormalForm:[NSPredicate predicateWithFormat:@"(A < 3 AND A < 7) OR (A < 3 AND A > 9) OR "
"(A > 5 and A < 7) OR (A > 5 AND A > 9)"]];
}
- (void)testUnsupportedPredicates {
[self assertUnsupportedPredicate:[NSPredicate predicateWithFormat:@"x = y"]];
[self assertUnsupportedPredicate:[NSPredicate predicateWithFormat:@"NOT (text CONTAINS 'word')"]];
[self assertUnsupportedPredicate:[NSPredicate predicateWithFormat:@"ANY x = 3"]];
[self assertUnsupportedPredicate:[NSPredicate predicateWithFormat:@"text LIKE 'foo'"]];
[self assertUnsupportedPredicate:[NSPredicate predicateWithFormat:@"A=1 OR B=2 OR C=3 OR D=4 OR E=5"]];
[self assertUnsupportedPredicate:[NSPredicate predicateWithFormat:@"$foo = 'bar'"]];
}
- (void)testHoistedCommonPredicates {
// These queries don't end up in DNF, because we can make them more efficient.
[self assertPredicate:[NSPredicate predicateWithFormat:@"(A = B OR C = D) AND E = F"]
hasNormalForm:[NSPredicate predicateWithFormat:@"(A = B OR C = D) AND E = F"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"(A = B AND E = F) OR (C = D AND E = F)"]
hasNormalForm:[NSPredicate predicateWithFormat:@"(A = B OR C = D) AND E = F"]];
}
- (void)testNormalizeYodaConditions {
[self assertPredicate:[NSPredicate predicateWithFormat:@"3 <= X"]
hasNormalForm:[NSPredicate predicateWithFormat:@"X >= 3"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"%@ != number", @[@3, @5, @7, @9, @11]]
hasNormalForm:[NSPredicate predicateWithFormat:@"number != %@", @[@3, @5, @7, @9, @11]]];
}
- (void)testNormalizeContainedIn {
[self assertPredicate:[NSPredicate predicateWithFormat:@"number IN %@", @[@3, @5, @7, @9, @11]]
hasNormalForm:[NSPredicate predicateWithFormat:@"number IN %@", @[@3, @5, @7, @9, @11]]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"NOT (number IN %@)", @[@3, @5, @7, @9, @11]]
hasNormalForm:[NSPredicate predicateWithFormat:@"number notContainedIn: %@", @[@3, @5, @7, @9, @11]]];
// These rely on Mongo's conflation of containment with equality.
[self assertPredicate:[NSPredicate predicateWithFormat:@"3 IN Y"]
hasNormalForm:[NSPredicate predicateWithFormat:@"Y = 3"]];
[self assertPredicate:[NSPredicate predicateWithFormat:@"NOT (3 IN Y)"]
hasNormalForm:[NSPredicate predicateWithFormat:@"Y != 3"]];
}
@end