Skip to content

Instantly share code, notes, and snippets.

@MrAntix
Last active August 29, 2015 14:23
Show Gist options
  • Save MrAntix/cb7d6d20d904206ae64f to your computer and use it in GitHub Desktop.
Save MrAntix/cb7d6d20d904206ae64f to your computer and use it in GitHub Desktop.
Keyed Collection for AngularJS, tests using Jasmine in VS with Resharper
/// <reference path="~/Scripts/jasmine/jasmine.js" />
/// <reference path="~/Scripts/angular.js" />
/// <reference path="~/Scripts/angular-mocks.js" />
/// <reference path="~/Scripts/Common/Collections/keyed-collection.js" />
describe('keyed-collection', function () {
beforeEach(module('common.collections.keyedCollection'));
describe('keyed-collection service', function () {
var service,
item1 = { id: 'A', name: 'Name A' },
item1Update = { id: 'A', name: 'Name A UPDATE' },
item2 = { id: 'B', name: 'Name B' },
item3 = { id: 'C', name: 'Name C' },
getKey = function (item) { return item.id; };
beforeEach(inject(function ($injector) {
service = $injector.get('KeyedCollectionService');
}));
it('should create a keyed collection maintains insertion order', function () {
var collection = service
.new(getKey, item1, item2);
expect(collection[0]).toBe(item1);
expect(collection[1]).toBe(item2);
});
it('errors on duplicate', function () {
expect(function () {
service.new(getKey, item1, item1);
}).toThrow();
});
it('errors when not found', function () {
expect(function () {
service.new(getKey).$get('X');
}).toThrow();
});
it('should get item by key', function () {
var collection = service
.new(getKey, item1, item2);
expect(collection.$tryGet('A')).toBe(item1);
expect(collection.$tryGet('B')).toBe(item2);
});
it('can update existing and add new', function () {
var collection = service
.new(getKey, [item1, item2]);
collection.$update([item1Update, item3]);
expect(collection[0]).toBe(item1Update);
expect(collection[2]).toBe(item3);
});
it('can remove', function () {
var collection = service
.new(getKey, [item1, item2]);
collection.$remove(item1);
expect(collection.$tryGet('A')).toBe(undefined);
expect(collection.$get('B')).toBe(item2);
});
});
});
angular.module('common.collections.keyedCollection', [
])
.service('KeyedCollectionService', [
function() {
var paramArray = function(array, args, index) {
if (Array.isArray(array)) return array;
var argumentsArray = [];
for (var ai = index; ai < args.length; ai++) {
argumentsArray.push(args[ai]);
}
return argumentsArray;
},
add = function(collection, array) {
array = paramArray(array, arguments, 1);
for (var arrayIndex = 0; arrayIndex < array.length; arrayIndex++) {
var item = array[arrayIndex];
var key = collection.$getKey(item);
if (collection.$keys.indexOf(key) !== -1)
throw {
name: 'KeyExists',
message: 'key:\'' + key + '\' already exists in collection'
};
collection.$keys.push(key);
collection.push(item);
}
},
containsKey = function(collection, key) {
return collection.$keys.indexOf(key) !== -1;
},
get = function(collection, key) {
var item = collection.$tryGet(key);
if (item === undefined)
throw {
name: 'KeyNotFound',
message: 'key:\'' + key + '\' not found in collection'
};
return item;
},
tryGet = function(collection, key) {
var index = collection.$keys.indexOf(key);
return index === -1
? undefined
: collection[index];
},
update = function(collection, array) {
array = paramArray(array, arguments, 1);
for (var arrayIndex = 0; arrayIndex < array.length; arrayIndex++) {
var item = array[arrayIndex];
var key = collection.$getKey(item);
var index = collection.$keys.indexOf(key);
if (index === -1)
collection.$add(item);
else
collection[index] = item;
}
},
remove = function(collection, array) {
array = paramArray(array, arguments, 1);
for (var arrayIndex = 0; arrayIndex < array.length; arrayIndex++) {
var item = array[arrayIndex];
var key = collection.$getKey(item);
var index = collection.$keys.indexOf(key);
if (index === -1) continue;
collection.$keys.splice(index, 1);
collection.splice(index, 1);
}
};
return {
'new': function(getKey, array) {
var collection = [];
collection.$keys = [];
collection.$getKey = getKey;
collection.$add = function(a) { add(this, a); };
collection.$containsKey = function(key) { return containsKey(this, key); };
collection.$get = function(key) { return get(this, key); };
collection.$tryGet = function(key) { return tryGet(this, key); };
collection.$update = function(a) { update(this, a); };
collection.$remove = function(a) { remove(this, a); };
if (array)
collection.$add(paramArray(array, arguments, 1));
return collection;
}
};
}
]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment