Skip to content

Commit a1bcbc0

Browse files
committed
Fix tests
2 parents f923681 + 0f6e70a commit a1bcbc0

File tree

8 files changed

+170
-65
lines changed

8 files changed

+170
-65
lines changed

can-query-logic-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require("./src/set-test");
2+
require("./src/helpers-test");
23
require("./src/types/make-real-number-range-inclusive-test");
34
require("./src/types/comparisons-test");
45
require("./src/types/and-or-not-test");

doc/can-query-logic.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
@group can-query-logic.prototype 1 prototype
55
@group can-query-logic/query-format 2 query format
66
@group can-query-logic.static 3 static methods
7+
@package ../package.json
78

89
@group can-query-logic.static-types 4 static types
910
@outline 3

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "can-query-logic",
3-
"version": "1.1.10",
3+
"version": "1.1.13",
44
"description": "query data",
55
"homepage": "",
66
"repository": {

src/helpers-test.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
var QUnit = require("steal-qunit");
2+
var helpers = require("./helpers");
3+
var canReflect = require("can-reflect");
4+
5+
QUnit.module("can-query-logic/helpers");
6+
7+
8+
QUnit.test('.getIdentityIndex', function(assert){
9+
var items = [
10+
{id: 1, name: "Item 0"},
11+
{id: 2, name: "Item 1"},
12+
{id: 3, name: "Item 1"},
13+
{id: 4, name: "Item 1"},
14+
{id: 5, name: "Item 2"}
15+
];
16+
17+
canReflect.eachIndex(items, function(item) {
18+
canReflect.assignSymbols(item, {
19+
"can.getSchema": function() {
20+
return {
21+
type: "map",
22+
identity: ["id"],
23+
keys: {
24+
id: Number,
25+
name: String
26+
}
27+
};
28+
}
29+
});
30+
});
31+
32+
var props = {id:2, name: "Item 1"};
33+
canReflect.assignSymbols(props,{
34+
"can.getSchema": function() {
35+
return {
36+
type: "map",
37+
identity: ["id"],
38+
keys: {
39+
id: Number,
40+
name: String
41+
}
42+
};
43+
}
44+
});
45+
var compare = helpers.sorter("name", {});
46+
var res = helpers.getIdentityIndex(compare, items, props, 1);
47+
assert.deepEqual(res, 1);
48+
});
49+
50+
QUnit.test(".getIndex should not sort unchanged items #33", function(assert) {
51+
52+
var items = [
53+
{id: 1, name: "Item 0"},
54+
{id: 2, name: "Item 1"},
55+
{id: 3, name: "Item 1"},
56+
{id: 4, name: "Item 1"},
57+
{id: 5, name: "Item 2"}
58+
];
59+
60+
canReflect.eachIndex(items, function(item) {
61+
canReflect.assignSymbols(item, {
62+
"can.getSchema": function() {
63+
return {
64+
type: "map",
65+
identity: ["id"],
66+
keys: {
67+
id: Number,
68+
name: String
69+
}
70+
};
71+
}
72+
});
73+
});
74+
75+
var compare = helpers.sorter("name", {});
76+
77+
var res1 = helpers.getIndex(compare,items, items[0]);
78+
var res2 = helpers.getIndex(compare,items, items[1]);
79+
var res3 = helpers.getIndex(compare,items, items[2]);
80+
var res4 = helpers.getIndex(compare,items, items[3]);
81+
82+
83+
assert.equal(res1, 0);
84+
assert.equal(res2, 1);
85+
assert.equal(res3, 2);
86+
assert.equal(res4, 3);
87+
});
88+
89+
QUnit.test("Missed schema on helper.getIndex #45", function(assert) {
90+
var items = [
91+
{id: 1, name: "Item 0"},
92+
{id: 2, name: "Item 1"},
93+
{id: 3, name: "Item 2"},
94+
{id: 4, name: "Item 3"},
95+
{id: 5, name: "Item 4"}
96+
];
97+
98+
var compare = helpers.sorter("name", {});
99+
var schema = { keys: {}, identity: ["id"] };
100+
101+
assert.equal(helpers.getIndex(compare,items, {id: 2, name: "Item 1"}, schema), 1);
102+
});

src/helpers.js

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,58 @@ var helpers = {
4949
}
5050
});
5151
},
52+
// Get the index of an item by it's identity
53+
// Starting from the middle of the items
54+
// return the index of match in the right direction
55+
// or in the left direction
56+
// otherwise return the last index
57+
// see getIdentityIndexByDirection
58+
getIdentityIndex: function(compare, items, props, startIndex, schema) {
59+
var identity = canReflect.getIdentity(props, schema),
60+
starterItem = items[startIndex];
61+
// check if the middle has a match
62+
if (compare(props, starterItem) === 0) {
63+
if (identity === canReflect.getIdentity(starterItem, schema)) {
64+
return startIndex;
65+
}
66+
}
67+
68+
var rightResult = this.getIdentityIndexByDirection(compare, items, props, startIndex+1, 1, schema),
69+
leftResult;
70+
if(rightResult.index) {
71+
return rightResult.index;
72+
} else {
73+
leftResult = this.getIdentityIndexByDirection(compare, items, props, startIndex-1, -1, schema);
74+
}
75+
if(leftResult.index !== undefined) {
76+
return leftResult.index;
77+
}
78+
// put at the last index item that doesn't match an identity
79+
return rightResult.lastIndex;
80+
},
81+
// Get the index of an item by it's identity
82+
// for a given direction (right or left)
83+
// 1 for right
84+
// -1 for left
85+
getIdentityIndexByDirection: function(compare, items, props, startIndex, direction, schema) {
86+
var currentIndex = startIndex;
87+
var identity = canReflect.getIdentity(props, schema);
88+
while(currentIndex >= 0 && currentIndex < items.length) {
89+
var currentItem = items[currentIndex];
90+
var computed = compare(props, currentItem);
91+
if(computed === 0) {
92+
if( identity === canReflect.getIdentity(currentItem, schema)) {
93+
return {index: currentIndex};
94+
}
95+
} else {
96+
return {lastIndex: currentIndex - direction};
97+
}
98+
currentIndex = currentIndex + direction;
99+
}
100+
return {lastIndex: currentIndex - direction};
101+
},
52102
//
53-
getIndex: function(compare, items, props) {
103+
getIndex: function(compare, items, props, schema) {
54104
if (!items || !items.length) {
55105
return undefined;
56106
}
@@ -62,35 +112,22 @@ var helpers = {
62112
}
63113

64114
var low = 0,
65-
high = items.length,
66-
range = [];
115+
high = items.length;
67116

68117
// From lodash lodash 4.6.1 <https://lodash.com/>
69118
// Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
70119
while (low < high) {
71120
var mid = (low + high) >>> 1,
72121
item = items[mid],
73122
computed = compare(props, item);
74-
75123
if (computed === 0) {
76-
range.push(item);
77-
low++;
124+
return this.getIdentityIndex(compare, items, props, mid, schema);
78125
} else if (computed === -1) {
79126
high = mid;
80127
} else {
81128
low = mid + 1;
82129
}
83130
}
84-
if (range.length > 0) {
85-
for (var i = 0; i < range.length; i++) {
86-
var itemInRange = range[i],
87-
id = canReflect.getSchema(itemInRange).identity[0];
88-
if (canReflect.hasOwnKey(props, id) && props[id] === itemInRange[id]) {
89-
high = items.indexOf(itemInRange);
90-
break;
91-
}
92-
}
93-
}
94131
return high;
95132
// bisect by calling sortFunc
96133
},

src/serializers/basic-query.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ module.exports = function(schema) {
281281

282282

283283
// Makes a sort type that can make a compare function using the SetType
284-
var Sort = BasicQuery.makeSort(keys, hydrateAndValue);
284+
var Sort = BasicQuery.makeSort(schema, hydrateAndValue);
285285
var serializer = new Serializer(serializeMap);
286286
serializer.add(comparisonsConverter.serializer);
287287

src/types/basic-query-sorting-test.js

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -357,51 +357,13 @@ QUnit.test("index uses can-reflect", function(assert) {
357357
[true, true, true, true], "read everything");
358358
});
359359

360-
361-
QUnit.test("index should not sort unchanged items #33", function(assert) {
362-
canReflect.assignSymbols({},{
363-
"can.getSchema": function() {
364-
return {
365-
type: "map",
366-
identity: ["id"],
367-
keys: {
368-
id: Number,
369-
name: String
370-
}
371-
};
372-
}
373-
});
374-
375-
var items = [
376-
{id: 1, name: "Item 0"},
377-
{id: 2, name: "Item 1"},
378-
{id: 3, name: "Item 1"},
379-
{id: 4, name: "Item 1"},
380-
{id: 5, name: "Item 2"}
381-
];
382-
383-
canReflect.eachIndex(items, function(item, i) {
384-
canReflect.assignSymbols(item, {
385-
"can.getSchema": function() {
386-
return {
387-
type: "map",
388-
identity: ["id"],
389-
keys: {
390-
id: Number,
391-
name: String
392-
}
393-
};
394-
}
395-
});
396-
});
397-
398-
399-
360+
QUnit.test(".index should work with literal objects", function(assert) {
400361
var query = new BasicQuery({
401-
sort: "name"
362+
sort: "name"
402363
});
403-
404-
var res = query.index({id:4, name: "Item 1"}, items);
405364

406-
assert.equal(res, 3);
365+
var items = [{id: 1, name: "Item 0"}, {id: 2, name: "Item 1"}];
366+
var res = query.index({id: 1, name: "Item 1"}, items);
367+
368+
assert.equal(res, 1, "Item index at 1");
407369
});

src/types/basic-query.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ var RecordRange = makeRealNumberRangeInclusive(0, Infinity);
3737
// That compare function will read the right property and return `-1` or `1`
3838

3939
// WILL MAKE A TYPE FOR SORTING
40-
function makeSort(schemaKeys, hydrateAndValue) {
40+
function makeSort(schema, hydrateAndValue) {
41+
var schemaKeys = schema.keys;
4142
// Makes gt and lt functions that `helpers.sorter` can use
4243
// to make a `compare` function for `Array.sort(compare)`.`
4344
var sorters = {};
@@ -107,6 +108,7 @@ function makeSort(schemaKeys, hydrateAndValue) {
107108

108109
function Sort(key) {
109110
this.key = key;
111+
this.schema = schema;
110112
this.compare = helpers.sorter(key, sorters);
111113
}
112114

@@ -129,7 +131,7 @@ function makeSort(schemaKeys, hydrateAndValue) {
129131
return Sort;
130132
}
131133

132-
var DefaultSort = makeSort({});
134+
var DefaultSort = makeSort({ keys: {}, identity: ["id"] });
133135

134136

135137
// Define the BasicQuery type
@@ -234,7 +236,7 @@ canReflect.assignMap(BasicQuery.prototype, {
234236
return undefined;
235237
}
236238
// use the passed sort's compare function
237-
return helpers.getIndex(this.sort.compare, items, props);
239+
return helpers.getIndex(this.sort.compare, items, props, this.sort.schema);
238240
},
239241
isMember: function(props) {
240242
// Use the AND type for it's isMember method

0 commit comments

Comments
 (0)