Skip to content

Commit

Permalink
Merge pull request #110 from canjs/102-id-unique
Browse files Browse the repository at this point in the history
Make IDs unique based on existing items; fixes #102
  • Loading branch information
andrejewski authored May 24, 2017
2 parents 978976b + ffd0b74 commit 12d8d39
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 27 deletions.
67 changes: 40 additions & 27 deletions helpers/legacyStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,26 @@ var isArrayLike = require("can-util/js/is-array-like/is-array-like");
var each = require("can-util/js/each/each");
var assign = require("can-util/js/assign/assign");

/*
Returns the initial ID all new item IDs will start from.
Assumption: the list items passed will not have their IDs modified.
*/
function getStartingId(items) {
var startingId = 0;
each(items, function (item) {
if (typeof item.id === 'number') {
startingId = Math.max(startingId, item.id + 1);
}
});
return startingId;
}

module.exports = function (count, make, filter) {
/*jshint eqeqeq:false */
var getUniqueId = (function () {
var i = 0;
return function () {
return i++;
}
})();
var nextItemId;
var getNextItemId = function () {
return nextItemId++;
}

var items,
findOne = function (id) {
Expand All @@ -25,20 +37,20 @@ module.exports = function (count, make, filter) {
types,
reset;

if(isArrayLike(count) && typeof count[0] === "string" ){
if (isArrayLike(count) && typeof count[0] === "string") {
types = count;
count = make;
make= filter;
make = filter;
filter = arguments[3];
} else if(typeof count === "string") {
} else if (typeof count === "string") {
types = [count + "s", count];
count = make;
make= filter;
make = filter;
filter = arguments[3];
}


if(typeof count === "number") {
if (typeof count === "number") {
nextItemId = 0;
items = [];
reset = function () {
items = [];
Expand All @@ -47,15 +59,16 @@ module.exports = function (count, make, filter) {
var item = make(i, items);

if (!item.id) {
item.id = getUniqueId();
item.id = getNextItemId();
}
items.push(item);
}
};
} else {
filter = make;
var initialItems = count;
reset = function(){
nextItemId = getStartingId(initialItems);
reset = function () {
items = initialItems.slice(0);
};
}
Expand Down Expand Up @@ -126,7 +139,7 @@ module.exports = function (count, make, filter) {
}
}

if ( typeof filter === "function" ) {
if (typeof filter === "function") {
i = 0;
while (i < retArr.length) {
if (!filter(retArr[i], request)) {
Expand All @@ -135,11 +148,11 @@ module.exports = function (count, make, filter) {
i++;
}
}
} else if( typeof filter === "object" ) {
} else if (typeof filter === "object") {
i = 0;
while (i < retArr.length) {
var subset = canSet.subset(retArr[i], request.data, filter);
if ( !subset ) {
if (!subset) {
retArr.splice(i, 1);
} else {
i++;
Expand All @@ -152,8 +165,8 @@ module.exports = function (count, make, filter) {
"count": retArr.length,
"data": retArr.slice(offset, offset + limit)
};
each(["limit","offset"], function(prop){
if(prop in request.data) {
each(["limit", "offset"], function (prop) {
if (prop in request.data) {
responseData[prop] = request.data[prop];
}
});
Expand Down Expand Up @@ -184,7 +197,7 @@ module.exports = function (count, make, filter) {
getData: function (request, response) {
var item = findOne(getId(request));

if(typeof item === "undefined") {
if (typeof item === "undefined") {
return response(404, 'Requested resource not found');
}

Expand All @@ -196,7 +209,7 @@ module.exports = function (count, make, filter) {
var id = getId(request),
item = findOne(id);

if(typeof item === "undefined") {
if (typeof item === "undefined") {
return response(404, 'Requested resource not found');
}

Expand All @@ -205,8 +218,8 @@ module.exports = function (count, make, filter) {
response({
id: id
}, {
location: request.url || "/" + getId(request)
});
location: request.url || "/" + getId(request)
});
},

/**
Expand All @@ -231,7 +244,7 @@ module.exports = function (count, make, filter) {
var id = getId(request),
item = findOne(id);

if(typeof item === "undefined") {
if (typeof item === "undefined") {
return response(404, 'Requested resource not found');
}

Expand All @@ -256,16 +269,16 @@ module.exports = function (count, make, filter) {
// If an ID wasn't passed into the request, we give the item
// a unique ID.
if (!item.id) {
item.id = getUniqueId();
item.id = getNextItemId();
}

// Push the new item into the store.
items.push(item);
response({
id: item.id
}, {
location: settings.url + "/" + item.id
});
location: settings.url + "/" + item.id
});
}
});
reset();
Expand Down
51 changes: 51 additions & 0 deletions test/fixture_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,57 @@ test('fixture.store fixtures should have unique IDs', function () {
});
});

test('fixture.store should assign unique IDs when fixtures provide IDs', function () {
/* NOTE: We are testing whether the unique ID we are assigning to a new
item will account for IDs which the user has provided.
*/

/* NOTE: These integers are used because IDs are created sequentially from 0.
Here, 0 1 and 2 must be skipped because they exist already.
If the implementation is changed this test will need updated.
*/
var store = fixture.store([
{id: 0, name: 'Object 0'},
{id: 1, name: 'Object 1'},
{id: 2, name: 'Object 2'}
]);

fixture('POST /models', store.createData);

function then (ajax, callback) {
ajax.then(callback, function (error) {
ok(false, 'ajax failure: ' + error);
start();
});
}

var request = $.ajax({
url: '/models',
dataType: 'json',
type: 'post',
data: {
name: 'My test object'
}
});

stop();
then(request, function (response) {
notEqual(response.id, 0);
notEqual(response.id, 1);
notEqual(response.id, 2);

/* NOTE: This check will fail if the underlying implementation changes.
This 3 is tightly coupled to the implementation.
If this is the only breaking assertion, update the provided IDs to
properly test the edge-case and update these assertions.
This check only serves to notify you to update the checks.
*/
equal(response.id, 3);

start();
});
});

test('simulating an error', function () {

fixture('/foo', function (request, response) {
Expand Down

0 comments on commit 12d8d39

Please sign in to comment.