Skip to content

Commit

Permalink
exposes set methods and tests and fixes various dead-code-elimination…
Browse files Browse the repository at this point in the history
… patterns
  • Loading branch information
justinbmeyer committed Jul 22, 2018
1 parent 7ff1965 commit 7547e48
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 21 deletions.
22 changes: 21 additions & 1 deletion can-query-logic-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ QUnit.test("difference", function(){
}
});


});

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

assert.ok(pass, "Status is constructor like");
});

QUnit.test("can call low-level APIs from the outside", function(){
var gt1 = new QueryLogic.GreaterThan(1);
var lte1 = new QueryLogic.LessThanEqual(1);

QUnit.equal( QueryLogic.intersection(gt1, lte1), QueryLogic.EMPTY );
console.log(QueryLogic.EMPTY);


var isGtJustinAndGt35 = new QueryLogic.KeysAnd({
name: new QueryLogic.GreaterThan("Justin"),
age: new QueryLogic.GreaterThan(35)
});
var isGt25 = new QueryLogic.KeysAnd({
age: new QueryLogic.GreaterThan(25)
});

QUnit.deepEqual(QueryLogic.union(isGtJustinAndGt35, isGt25), isGt25, "fewer clauses");

});
19 changes: 9 additions & 10 deletions can-query-logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,24 +163,23 @@ canReflect.assign(QueryLogic.prototype,{

});

QueryLogic.UNIVERSAL = set.UNIVERSAL;
// Nothing
QueryLogic.EMPTY = set.EMPTY;
// The set exists, but we lack the language to represent it.
QueryLogic.UNDEFINABLE = set.UNDEFINABLE;
// Copy everything on `set` to QueryLogic
for(var prop in set) {
if(QueryLogic[prop] === undefined) {
QueryLogic[prop] = set[prop];
}
}


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

QueryLogic.makeEnum = function(values){
var Type = function(){};
Type[newSymbol] = function(val) { return val; };
makeEnum(Type, values);
return Type;
};
QueryLogic.defineComparison = set.defineComparison;
QueryLogic.isSpecial = set.isSpecial;
QueryLogic.isDefinedAndHasMembers = QueryLogic.isDefinedAndHasMembers;



QueryLogic.KeysAnd = BasicQuery.KeysAnd;
QueryLogic.ValuesOr = BasicQuery.Or;
Expand Down
27 changes: 27 additions & 0 deletions src/types/and-or-not-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var types = require("./and-or-not");
var QUnit = require("steal-qunit");
var set = require("../set");
var makeEnum = require("../types/make-enum");
var is = require("./comparisons");

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

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

});

QUnit.test("union with comparisons", function(){
var isGtJustinAndGt35 = new types.KeysAnd({
name: new is.GreaterThan("Justin"),
age: new is.GreaterThan(35)
});
var isGt25 = new types.KeysAnd({
age: new is.GreaterThan(25)
});
var result = set.union(isGtJustinAndGt35, isGt25);
QUnit.deepEqual(result, isGt25);

// if filtering in fewer dimensions is a superset, use that
var a = new types.KeysAnd({
name: new is.GreaterThan("Justin"),
age: new is.GreaterThan(35),
count: new is.GreaterThan(10)
});
var b = new types.KeysAnd({
age: new is.GreaterThan(25),
count: new is.GreaterThan(9)
});
result = set.union(b, a);
QUnit.deepEqual(result, b);

});
42 changes: 36 additions & 6 deletions src/types/comparisons-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,10 @@ var tests = {
a = new is.In([2, 4]);
b = new is.GreaterThan(2);

// TODO: this could actually just be new is.GreaterThan(2)
// TODO: this could actually just be new is.GreaterThanEqual(2)
assert.deepEqual(
set.union(a, b),
new is.Or([new is.In([2]), b])
new is.GreaterThanEqual(2)
);
},
intersection: function(assert) {
Expand Down Expand Up @@ -406,7 +406,7 @@ var tests = {
// TODO: this can be new is.LessThanEqual(4)
assert.deepEqual(
set.union(a, b),
new is.Or([new is.In([4]), b])
new is.LessThanEqual(4)
);
},
intersection: function(assert) {
Expand Down Expand Up @@ -631,6 +631,7 @@ var tests = {
set.union(a, b),
b
);

},
intersection: function(assert) {
var a = new is.In([5, 6]);
Expand Down Expand Up @@ -707,6 +708,16 @@ var tests = {
set.union(a, b),
b
);


var gt1 = new is.GreaterThan(1),
lt1 = new is.LessThan(1),
eq1 = new is.In([1]);

var intermediate = set.union(gt1,lt1);
var result = set.union( intermediate, eq1 );

QUnit.equal(result, set.UNIVERSAL, "foo > 1 || foo < 1 || foo === 1 => UNIVERSAL");
},
intersection: function(assert) {
var a = new is.In([5, 6]);
Expand Down Expand Up @@ -1545,6 +1556,14 @@ var tests = {
set.union(a, b),
new is.Or([a, b])
);

a = new is.GreaterThan(5);
b = new is.LessThan(5);

assert.deepEqual(
set.union(a, b),
new is.NotIn([5])
);
},
intersection: function(assert) {
var a = new is.GreaterThan(5),
Expand Down Expand Up @@ -3355,8 +3374,9 @@ var tests = {
},
And_Or: {
union: function(assert) {
var a = new is.Or([new is.LessThanEqual(0), new is.GreaterThanEqual(6)]),
b = new is.And([new is.GreaterThan(0), new is.LessThan(6)]);
var a, b;
a = new is.Or([new is.LessThanEqual(0), new is.GreaterThanEqual(6)]),
b = new is.And([new is.GreaterThan(0), new is.LessThan(6)]);

assert.deepEqual(
set.union(a, b),
Expand Down Expand Up @@ -3409,6 +3429,16 @@ var tests = {
new is.Or([b, a]),
"disjoint"
);

a = new is.Or([new is.LessThan(0), new is.GreaterThan(20)]);
b = new is.And([new is.GreaterThan(0), new is.LessThanEqual(20)]);
var result = set.union(a, b);

assert.deepEqual(
result,
new is.NotIn([0]),
"NotIn"
);
},
intersection: function(assert) {
var a = new is.Or([new is.LessThanEqual(0), new is.GreaterThanEqual(6)]);
Expand Down Expand Up @@ -3937,4 +3967,4 @@ QUnit.test("Able to do membership, union, difference with $in", function() {
QUnit.deepEqual(difference,
new is.And([gt1980, lte1990]),
"difference");*/
});
});
54 changes: 52 additions & 2 deletions src/types/comparisons.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,52 @@ function makeOr(ors) {

var is = comparisons;

function combineValueWithRangeCheck(inSet, rangeSet, RangeOrEqType){
var gte = new RangeOrEqType(rangeSet.value);
var leftValues = inSet.values.filter(function(value){
return !gte.isMember(value);
});
if(!leftValues.length) {
return gte;
}

if(leftValues.length < inSet.values.length) {
return makeOr([new is.In(leftValues), gte]);
} else {
return makeOr([inSet, rangeSet]);
}
}

// This tries to unify In([1]) with GT(1) -> GTE(1)
function makeOrWithInAndRange(inSet, rangeSet) {
if(rangeSet instanceof is.Or) {
var firstResult = makeOrWithInAndRange(inSet, rangeSet.values[0]);
if( !(firstResult instanceof is.Or) ) {
return set.union(firstResult, rangeSet.values[1]);
}
var secondResult = makeOrWithInAndRange(inSet, rangeSet.values[1]);
if( !(secondResult instanceof is.Or) ) {
return set.union(secondResult, rangeSet.values[0]);
}
return makeOr([inSet, rangeSet]);
} else {
if(rangeSet instanceof is.GreaterThan) {
return combineValueWithRangeCheck(inSet, rangeSet, is.GreaterThanEqual);
}
if(rangeSet instanceof is.LessThan) {
return combineValueWithRangeCheck(inSet, rangeSet, is.LessThanEqual);
}
return makeOr([inSet, rangeSet]);
}
}

var In_RANGE = {
union: combineFilterFirstValuesAgainstSecond({
values: makeNot(isMemberTest),
arePut: is.In,
combinedUsing: makeOr
combinedUsing: function(ors){
return makeOrWithInAndRange(ors[0], ors[1]);
}
}),
intersection: make_filterFirstValueAgainstSecond(isMemberTest, is.In, set.EMPTY),
difference: make_filterFirstValueAgainstSecond(makeNot(isMemberTest), is.In, set.EMPTY)
Expand Down Expand Up @@ -561,7 +602,16 @@ var comparators = {
},

GreaterThan_LessThan: {
union: makeOrUnless(is.LessThan),
union: (function(){
var makeOrUnlessLessThan = makeOrUnless(is.LessThan);
return function greaterThan_lessThan_union(a, b){
if( comparisons.In.test([a.value], b.value) ) {
return new is.NotIn([a.value]);
} else {
return makeOrUnlessLessThan(a, b);
}
}
})(),
intersection: makeAndUnless(is.GreaterThan),
difference: makeComplementSecondArgIf(is.LessThan)
},
Expand Down
25 changes: 23 additions & 2 deletions src/types/keys-and.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@ set.defineComparison(KeysAnd, KeysAnd, {
sameKeys[key] = objA.values[key];
}
});
var aUnequal = {}, bUnequal = {};
aAndBKeysThatAreNotEqual.forEach(function(key){
aUnequal[key] = objA.values[key];
bUnequal[key] = objB.values[key];
});

// if all keys are shared
if (!diff.aOnlyKeys.length && !diff.bOnlyKeys.length) {
Expand All @@ -303,7 +308,23 @@ set.defineComparison(KeysAnd, KeysAnd, {
return checkIfUniversalAndReturnUniversal(objA);
}
}

// (count > 5 && age > 25 ) || (count > 7 && age > 35 && name > "Justin" )
//
// ( age > 25 ) || ( name > "Justin" && age > 35) A U (B & C) => (A U B) & (A U C)
// ( age > 25 || name > "Justin" ) && (age > 25)
// lets see if one side is different
if (diff.aOnlyKeys.length > 0 && diff.bOnlyKeys.length === 0) {
// collect shared value
if( set.isSubset(new KeysAnd(aUnequal), new KeysAnd(bUnequal) )) {
return objB;
}
}
if (diff.bOnlyKeys.length > 0 && diff.aOnlyKeys.length === 0) {
// collect shared value
if( set.isSubset(new KeysAnd(bUnequal), new KeysAnd(aUnequal) )) {
return objA;
}
}

return new keysLogic.ValuesOr([objA, objB]);
},
Expand Down Expand Up @@ -350,4 +371,4 @@ set.defineComparison(set.UNIVERSAL, KeysAnd, {
});


module.exports = keysLogic.KeysAnd = KeysAnd;
module.exports = keysLogic.KeysAnd = KeysAnd;

0 comments on commit 7547e48

Please sign in to comment.