Skip to content

Commit 7547e48

Browse files
committed
exposes set methods and tests and fixes various dead-code-elimination patterns
1 parent 7ff1965 commit 7547e48

File tree

6 files changed

+168
-21
lines changed

6 files changed

+168
-21
lines changed

can-query-logic-test.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ QUnit.test("difference", function(){
6161
}
6262
});
6363

64-
64+
6565
});
6666

6767
QUnit.test("subset", function(){
@@ -242,3 +242,23 @@ QUnit.test("Value returned by makeEnum is constructorLike", function(assert){
242242

243243
assert.ok(pass, "Status is constructor like");
244244
});
245+
246+
QUnit.test("can call low-level APIs from the outside", function(){
247+
var gt1 = new QueryLogic.GreaterThan(1);
248+
var lte1 = new QueryLogic.LessThanEqual(1);
249+
250+
QUnit.equal( QueryLogic.intersection(gt1, lte1), QueryLogic.EMPTY );
251+
console.log(QueryLogic.EMPTY);
252+
253+
254+
var isGtJustinAndGt35 = new QueryLogic.KeysAnd({
255+
name: new QueryLogic.GreaterThan("Justin"),
256+
age: new QueryLogic.GreaterThan(35)
257+
});
258+
var isGt25 = new QueryLogic.KeysAnd({
259+
age: new QueryLogic.GreaterThan(25)
260+
});
261+
262+
QUnit.deepEqual(QueryLogic.union(isGtJustinAndGt35, isGt25), isGt25, "fewer clauses");
263+
264+
});

can-query-logic.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,23 @@ canReflect.assign(QueryLogic.prototype,{
163163

164164
});
165165

166-
QueryLogic.UNIVERSAL = set.UNIVERSAL;
167-
// Nothing
168-
QueryLogic.EMPTY = set.EMPTY;
169-
// The set exists, but we lack the language to represent it.
170-
QueryLogic.UNDEFINABLE = set.UNDEFINABLE;
166+
// Copy everything on `set` to QueryLogic
167+
for(var prop in set) {
168+
if(QueryLogic[prop] === undefined) {
169+
QueryLogic[prop] = set[prop];
170+
}
171+
}
172+
171173

172-
// We don't know if this exists. Intersection between two paginated sets.
173-
QueryLogic.UNKNOWABLE = set.UNKNOWABLE;
174174

175175
QueryLogic.makeEnum = function(values){
176176
var Type = function(){};
177177
Type[newSymbol] = function(val) { return val; };
178178
makeEnum(Type, values);
179179
return Type;
180180
};
181-
QueryLogic.defineComparison = set.defineComparison;
182-
QueryLogic.isSpecial = set.isSpecial;
183-
QueryLogic.isDefinedAndHasMembers = QueryLogic.isDefinedAndHasMembers;
181+
182+
184183

185184
QueryLogic.KeysAnd = BasicQuery.KeysAnd;
186185
QueryLogic.ValuesOr = BasicQuery.Or;

src/types/and-or-not-test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var types = require("./and-or-not");
22
var QUnit = require("steal-qunit");
33
var set = require("../set");
44
var makeEnum = require("../types/make-enum");
5+
var is = require("./comparisons");
56

67
QUnit.module("can-query-logic/and-or");
78

@@ -380,3 +381,29 @@ QUnit.test("And with nested ands", function(){
380381
);
381382

382383
});
384+
385+
QUnit.test("union with comparisons", function(){
386+
var isGtJustinAndGt35 = new types.KeysAnd({
387+
name: new is.GreaterThan("Justin"),
388+
age: new is.GreaterThan(35)
389+
});
390+
var isGt25 = new types.KeysAnd({
391+
age: new is.GreaterThan(25)
392+
});
393+
var result = set.union(isGtJustinAndGt35, isGt25);
394+
QUnit.deepEqual(result, isGt25);
395+
396+
// if filtering in fewer dimensions is a superset, use that
397+
var a = new types.KeysAnd({
398+
name: new is.GreaterThan("Justin"),
399+
age: new is.GreaterThan(35),
400+
count: new is.GreaterThan(10)
401+
});
402+
var b = new types.KeysAnd({
403+
age: new is.GreaterThan(25),
404+
count: new is.GreaterThan(9)
405+
});
406+
result = set.union(b, a);
407+
QUnit.deepEqual(result, b);
408+
409+
});

src/types/comparisons-test.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,10 @@ var tests = {
171171
a = new is.In([2, 4]);
172172
b = new is.GreaterThan(2);
173173

174-
// TODO: this could actually just be new is.GreaterThan(2)
174+
// TODO: this could actually just be new is.GreaterThanEqual(2)
175175
assert.deepEqual(
176176
set.union(a, b),
177-
new is.Or([new is.In([2]), b])
177+
new is.GreaterThanEqual(2)
178178
);
179179
},
180180
intersection: function(assert) {
@@ -406,7 +406,7 @@ var tests = {
406406
// TODO: this can be new is.LessThanEqual(4)
407407
assert.deepEqual(
408408
set.union(a, b),
409-
new is.Or([new is.In([4]), b])
409+
new is.LessThanEqual(4)
410410
);
411411
},
412412
intersection: function(assert) {
@@ -631,6 +631,7 @@ var tests = {
631631
set.union(a, b),
632632
b
633633
);
634+
634635
},
635636
intersection: function(assert) {
636637
var a = new is.In([5, 6]);
@@ -707,6 +708,16 @@ var tests = {
707708
set.union(a, b),
708709
b
709710
);
711+
712+
713+
var gt1 = new is.GreaterThan(1),
714+
lt1 = new is.LessThan(1),
715+
eq1 = new is.In([1]);
716+
717+
var intermediate = set.union(gt1,lt1);
718+
var result = set.union( intermediate, eq1 );
719+
720+
QUnit.equal(result, set.UNIVERSAL, "foo > 1 || foo < 1 || foo === 1 => UNIVERSAL");
710721
},
711722
intersection: function(assert) {
712723
var a = new is.In([5, 6]);
@@ -1545,6 +1556,14 @@ var tests = {
15451556
set.union(a, b),
15461557
new is.Or([a, b])
15471558
);
1559+
1560+
a = new is.GreaterThan(5);
1561+
b = new is.LessThan(5);
1562+
1563+
assert.deepEqual(
1564+
set.union(a, b),
1565+
new is.NotIn([5])
1566+
);
15481567
},
15491568
intersection: function(assert) {
15501569
var a = new is.GreaterThan(5),
@@ -3355,8 +3374,9 @@ var tests = {
33553374
},
33563375
And_Or: {
33573376
union: function(assert) {
3358-
var a = new is.Or([new is.LessThanEqual(0), new is.GreaterThanEqual(6)]),
3359-
b = new is.And([new is.GreaterThan(0), new is.LessThan(6)]);
3377+
var a, b;
3378+
a = new is.Or([new is.LessThanEqual(0), new is.GreaterThanEqual(6)]),
3379+
b = new is.And([new is.GreaterThan(0), new is.LessThan(6)]);
33603380

33613381
assert.deepEqual(
33623382
set.union(a, b),
@@ -3409,6 +3429,16 @@ var tests = {
34093429
new is.Or([b, a]),
34103430
"disjoint"
34113431
);
3432+
3433+
a = new is.Or([new is.LessThan(0), new is.GreaterThan(20)]);
3434+
b = new is.And([new is.GreaterThan(0), new is.LessThanEqual(20)]);
3435+
var result = set.union(a, b);
3436+
3437+
assert.deepEqual(
3438+
result,
3439+
new is.NotIn([0]),
3440+
"NotIn"
3441+
);
34123442
},
34133443
intersection: function(assert) {
34143444
var a = new is.Or([new is.LessThanEqual(0), new is.GreaterThanEqual(6)]);
@@ -3937,4 +3967,4 @@ QUnit.test("Able to do membership, union, difference with $in", function() {
39373967
QUnit.deepEqual(difference,
39383968
new is.And([gt1980, lte1990]),
39393969
"difference");*/
3940-
});
3970+
});

src/types/comparisons.js

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,52 @@ function makeOr(ors) {
331331

332332
var is = comparisons;
333333

334+
function combineValueWithRangeCheck(inSet, rangeSet, RangeOrEqType){
335+
var gte = new RangeOrEqType(rangeSet.value);
336+
var leftValues = inSet.values.filter(function(value){
337+
return !gte.isMember(value);
338+
});
339+
if(!leftValues.length) {
340+
return gte;
341+
}
342+
343+
if(leftValues.length < inSet.values.length) {
344+
return makeOr([new is.In(leftValues), gte]);
345+
} else {
346+
return makeOr([inSet, rangeSet]);
347+
}
348+
}
349+
350+
// This tries to unify In([1]) with GT(1) -> GTE(1)
351+
function makeOrWithInAndRange(inSet, rangeSet) {
352+
if(rangeSet instanceof is.Or) {
353+
var firstResult = makeOrWithInAndRange(inSet, rangeSet.values[0]);
354+
if( !(firstResult instanceof is.Or) ) {
355+
return set.union(firstResult, rangeSet.values[1]);
356+
}
357+
var secondResult = makeOrWithInAndRange(inSet, rangeSet.values[1]);
358+
if( !(secondResult instanceof is.Or) ) {
359+
return set.union(secondResult, rangeSet.values[0]);
360+
}
361+
return makeOr([inSet, rangeSet]);
362+
} else {
363+
if(rangeSet instanceof is.GreaterThan) {
364+
return combineValueWithRangeCheck(inSet, rangeSet, is.GreaterThanEqual);
365+
}
366+
if(rangeSet instanceof is.LessThan) {
367+
return combineValueWithRangeCheck(inSet, rangeSet, is.LessThanEqual);
368+
}
369+
return makeOr([inSet, rangeSet]);
370+
}
371+
}
372+
334373
var In_RANGE = {
335374
union: combineFilterFirstValuesAgainstSecond({
336375
values: makeNot(isMemberTest),
337376
arePut: is.In,
338-
combinedUsing: makeOr
377+
combinedUsing: function(ors){
378+
return makeOrWithInAndRange(ors[0], ors[1]);
379+
}
339380
}),
340381
intersection: make_filterFirstValueAgainstSecond(isMemberTest, is.In, set.EMPTY),
341382
difference: make_filterFirstValueAgainstSecond(makeNot(isMemberTest), is.In, set.EMPTY)
@@ -561,7 +602,16 @@ var comparators = {
561602
},
562603

563604
GreaterThan_LessThan: {
564-
union: makeOrUnless(is.LessThan),
605+
union: (function(){
606+
var makeOrUnlessLessThan = makeOrUnless(is.LessThan);
607+
return function greaterThan_lessThan_union(a, b){
608+
if( comparisons.In.test([a.value], b.value) ) {
609+
return new is.NotIn([a.value]);
610+
} else {
611+
return makeOrUnlessLessThan(a, b);
612+
}
613+
}
614+
})(),
565615
intersection: makeAndUnless(is.GreaterThan),
566616
difference: makeComplementSecondArgIf(is.LessThan)
567617
},

src/types/keys-and.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ set.defineComparison(KeysAnd, KeysAnd, {
277277
sameKeys[key] = objA.values[key];
278278
}
279279
});
280+
var aUnequal = {}, bUnequal = {};
281+
aAndBKeysThatAreNotEqual.forEach(function(key){
282+
aUnequal[key] = objA.values[key];
283+
bUnequal[key] = objB.values[key];
284+
});
280285

281286
// if all keys are shared
282287
if (!diff.aOnlyKeys.length && !diff.bOnlyKeys.length) {
@@ -303,7 +308,23 @@ set.defineComparison(KeysAnd, KeysAnd, {
303308
return checkIfUniversalAndReturnUniversal(objA);
304309
}
305310
}
306-
311+
// (count > 5 && age > 25 ) || (count > 7 && age > 35 && name > "Justin" )
312+
//
313+
// ( age > 25 ) || ( name > "Justin" && age > 35) A U (B & C) => (A U B) & (A U C)
314+
// ( age > 25 || name > "Justin" ) && (age > 25)
315+
// lets see if one side is different
316+
if (diff.aOnlyKeys.length > 0 && diff.bOnlyKeys.length === 0) {
317+
// collect shared value
318+
if( set.isSubset(new KeysAnd(aUnequal), new KeysAnd(bUnequal) )) {
319+
return objB;
320+
}
321+
}
322+
if (diff.bOnlyKeys.length > 0 && diff.aOnlyKeys.length === 0) {
323+
// collect shared value
324+
if( set.isSubset(new KeysAnd(bUnequal), new KeysAnd(aUnequal) )) {
325+
return objA;
326+
}
327+
}
307328

308329
return new keysLogic.ValuesOr([objA, objB]);
309330
},
@@ -350,4 +371,4 @@ set.defineComparison(set.UNIVERSAL, KeysAnd, {
350371
});
351372

352373

353-
module.exports = keysLogic.KeysAnd = KeysAnd;
374+
module.exports = keysLogic.KeysAnd = KeysAnd;

0 commit comments

Comments
 (0)