Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make IDs unique based on existing items; fixes #102 #110

Merged
merged 2 commits into from
May 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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