Skip to content

Commit 24f49b1

Browse files
committed
Added the remaining methods.
1 parent f4e6296 commit 24f49b1

File tree

22 files changed

+1977
-59
lines changed

22 files changed

+1977
-59
lines changed

dist/angular-data.js

+1,022-42
Large diffs are not rendered by default.

dist/angular-data.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

karma.conf.js

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// an example karma.conf.js
2+
module.exports = function (config) {
3+
config.set({
4+
// base path, that will be used to resolve files and exclude
5+
basePath: './',
6+
frameworks: ['sinon', 'chai', 'mocha'],
7+
plugins: [
8+
// these plugins will be require() by Karma
9+
'karma-sinon',
10+
'karma-mocha',
11+
'karma-chai',
12+
'karma-chrome-launcher',
13+
'karma-phantomjs-launcher',
14+
'karma-firefox-launcher',
15+
'karma-coverage'
16+
],
17+
autoWatch: false,
18+
browsers: ['Chrome'],
19+
20+
// list of files / patterns to load in the browser
21+
files: [
22+
'bower_components/angular/angular.js',
23+
'bower_components/angular-mocks/angular-mocks.js',
24+
'karma.start.js',
25+
'dist/angular-data.js',
26+
'test/**/*.js'
27+
],
28+
29+
reporters: ['progress', 'coverage'],
30+
31+
preprocessors: {
32+
'dist/angular-data.js': ['coverage']
33+
},
34+
35+
// optionally, configure the reporter
36+
coverageReporter: {
37+
type : 'html',
38+
dir : 'coverage/'
39+
},
40+
41+
// web server port
42+
port: 8080,
43+
44+
// cli runner port
45+
runnerPort: 9100,
46+
47+
// enable / disable colors in the output (reporters and logs)
48+
colors: true,
49+
50+
// level of logging
51+
logLevel: config.LOG_INFO,
52+
53+
// If browser does not capture in given timeout [ms], kill it
54+
captureTimeout: 30000,
55+
56+
// Continuous Integration mode
57+
// if true, it capture browsers, run tests and exit
58+
singleRun: false
59+
});
60+
};

karma.start.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Setup global test variables
2+
var $rootScope, $q, $log;
3+
4+
// Helper globals
5+
var fail = function (msg) {
6+
assert.equal('should not reach this!: ' + msg, 'failure');
7+
},
8+
TYPES_EXCEPT_STRING = [123, 123.123, null, undefined, {}, [], true, false, function () {}],
9+
TYPES_EXCEPT_STRING_OR_ARRAY = [123, 123.123, null, undefined, {}, true, false, function () {}],
10+
TYPES_EXCEPT_ARRAY = ['string', 123, 123.123, null, undefined, {}, true, false, function () {}],
11+
TYPES_EXCEPT_STRING_OR_NUMBER = [null, undefined, {}, [], true, false, function () {}],
12+
TYPES_EXCEPT_STRING_OR_ARRAY_OR_NUMBER = [null, undefined, {}, true, false, function () {}],
13+
TYPES_EXCEPT_NUMBER = ['string', null, undefined, {}, [], true, false, function () {}],
14+
TYPES_EXCEPT_OBJECT = ['string', 123, 123.123, null, undefined, true, false, function () {}],
15+
TYPES_EXCEPT_BOOLEAN = ['string', 123, 123.123, null, undefined, {}, [], function () {}],
16+
TYPES_EXCEPT_FUNCTION = ['string', 123, 123.123, null, undefined, {}, [], true, false];
17+
18+
angular.module('jmdobry.angular-data', ['ng', 'jmdobry.binary-heap', 'ngMock']);
19+
20+
beforeEach(module('jmdobry.angular-data'));
21+
22+
// Setup before each test
23+
beforeEach(inject(function (_$rootScope_, _$q_) {
24+
// Setup global mocks
25+
$q = _$q_;
26+
$rootScope = _$rootScope_;
27+
$log = {
28+
warn: function () {},
29+
log: function () {},
30+
info: function () {},
31+
error: function () {},
32+
debug: function () {}
33+
};
34+
35+
// Setup global spies
36+
sinon.spy($log, 'warn');
37+
sinon.spy($log, 'log');
38+
sinon.spy($log, 'info');
39+
sinon.spy($log, 'error');
40+
sinon.spy($log, 'debug');
41+
}));
42+
43+
// Clean up after each test
44+
afterEach(function () {
45+
// Tear down global spies
46+
$log.warn.restore();
47+
$log.log.restore();
48+
$log.info.restore();
49+
$log.error.restore();
50+
$log.debug.restore();
51+
});

package.json

+9-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,15 @@
2929
"mout": "0.8.0",
3030
"grunt-docular": "0.1.2",
3131
"grunt-contrib-uglify": "0.2.7",
32-
"grunt-contrib-jshint": "0.8.0"
32+
"grunt-contrib-jshint": "0.8.0",
33+
"karma": "0.11.12",
34+
"karma-phantomjs-launcher": "0.1.1",
35+
"karma-mocha": "0.1.1",
36+
"karma-chrome-launcher": "0.1.2",
37+
"karma-firefox-launcher": "0.1.3",
38+
"karma-sinon": "1.0.0",
39+
"karma-coverage": "0.1.4",
40+
"karma-chai": "0.0.2"
3341
},
3442
"scripts": {
3543
"test": "node node_modules/grunt-cli/bin/grunt build",

src/datastore/create/index.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
var utils = require('../../utils'),
2+
errors = require('../../errors'),
3+
store = require('../store'),
4+
services = require('../services'),
5+
POST = require('../HTTP').POST;
6+
7+
/**
8+
* @doc method
9+
* @id DS.async_methods:create
10+
* @name create(name, attrs)
11+
* @description
12+
* Create a new resource.
13+
*
14+
* Example:
15+
*
16+
* ```js
17+
* TODO: create(resourceName, attrs)
18+
* ```
19+
*
20+
* @param {string} resourceName The resource type, e.g. 'user', 'comment', etc.
21+
* @param {object} attrs The attributes with which to update the item of the type specified by `resourceName` that has
22+
* the primary key specified by `id`.
23+
* @returns {Promise} Promise produced by the `$q` service.
24+
*
25+
* ## ResolvesWith:
26+
*
27+
* - `{object}` - `item` - A reference to the newly created item.
28+
*
29+
* ## RejectsWith:
30+
*
31+
* - `{IllegalArgumentError}` - `err` - Argument `attrs` must be an object.
32+
* - `{RuntimeError}` - `err` - Argument `resourceName` must refer to an already registered resource.
33+
* - `{UnhandledError}` - `err` - Thrown for any uncaught exception.
34+
*/
35+
function create(resourceName, attrs) {
36+
var deferred = $q.defer();
37+
if (!store[resourceName]) {
38+
deferred.reject(new errors.RuntimeError('DS.create(resourceName, attrs): ' + resourceName + ' is not a registered resource!'));
39+
} else if (!utils.isObject(attrs)) {
40+
deferred.reject(new errors.IllegalArgumentError('DS.create(resourceName, attrs): attrs: Must be an object!', { attrs: { actual: typeof attrs, expected: 'object' } }));
41+
}
42+
43+
try {
44+
var resource = store[resourceName];
45+
46+
POST(resource.baseUrl + '/' + (resource.endpoint || resourceName), attrs, null).then(function (data) {
47+
try {
48+
var idAttribute = resource.idAttribute || 'id';
49+
if (!data[idAttribute]) {
50+
deferred.reject(new errors.RuntimeError('DS.create(resourceName, attrs): The server must return an object that has the idAttribute specified by the resource definition!'));
51+
} else {
52+
resource.index[data[idAttribute]] = data;
53+
resource.modified[data[idAttribute]] = utils.updateTimestamp(resource.modified[data[idAttribute]]);
54+
resource.collection.push(resource.index[data[idAttribute]]);
55+
resource.collectionModified = utils.updateTimestamp(resource.collectionModified);
56+
deferred.resolve(resource.index[data[idAttribute]]);
57+
}
58+
} catch (err) {
59+
deferred.reject(new errors.UnhandledError(err));
60+
}
61+
}, deferred.reject);
62+
} catch (err) {
63+
deferred.reject(new errors.UnhandledError(err));
64+
}
65+
66+
return deferred.promise;
67+
}
68+
69+
module.exports = create;

src/datastore/defineResource/index.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@ var utils = require('../../utils'),
44

55
/**
66
* @doc method
7-
* @id DS.methods:defineResource
7+
* @id DS.sync_methods:defineResource
88
* @name defineResource(definition)
99
* @description
1010
* Register a resource definition with the data store.
1111
*
12+
* Example:
13+
*
14+
* ```js
15+
* TODO: defineResource(definition)
16+
* ```
17+
*
1218
* ## Throws
1319
*
1420
* - `{IllegalArgumentError}` - Argument `definition` must be a string or an object.

src/datastore/destroy/index.js

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
var utils = require('../../utils'),
2+
errors = require('../../errors'),
3+
store = require('../store');
4+
5+
/**
6+
* @doc method
7+
* @id DS.async_methods:destroy
8+
* @name destroy(resourceName, id)
9+
* @description
10+
* Delete the item of the type specified by `resourceName` with the primary key specified by `id` from the data store
11+
* and the server.
12+
*
13+
* Example:
14+
*
15+
* ```js
16+
* TODO: destroy(name, id) example
17+
* ```
18+
*
19+
* @param {string} resourceName The resource type, e.g. 'user', 'comment', etc.
20+
* @param {string|number} id The primary key of the item to remove.
21+
* @returns {Promise} Promise produced by the `$q` service.
22+
*
23+
* ## ResolvesWith:
24+
*
25+
* - `{string|number}` - `id` - The primary key of the destroyed item.
26+
*
27+
* ## RejectsWith:
28+
*
29+
* - `{IllegalArgumentError}` - `err` - Argument `id` must be a string or a number.
30+
* - `{RuntimeError}` - `err` - Argument `resourceName` must refer to an already registered resource.
31+
* - `{UnhandledError}` - `err` - Thrown for any uncaught exception.
32+
*/
33+
function destroy(resourceName, id) {
34+
var deferred = $q.defer();
35+
if (!store[resourceName]) {
36+
deferred.reject(new errors.RuntimeError('DS.destroy(resourceName, id): ' + resourceName + ' is not a registered resource!'));
37+
} else if (!utils.isString(id) && !utils.isNumber(id)) {
38+
deferred.reject(new errors.IllegalArgumentError('DS.destroy(resourceName, id): id: Must be a string or a number!', { id: { actual: typeof id, expected: 'string|number' } }));
39+
}
40+
41+
try {
42+
var resource = store[resourceName];
43+
44+
this.DEL(resource.baseUrl + '/' + (resource.endpoint || resourceName + '/' + id), null).then(function (data) {
45+
try {
46+
delete resource.index[id];
47+
delete resource.modified[id];
48+
49+
for (var i = 0; i < resource.collection.length; i++) {
50+
if (resource.collection[i][resource.idAttribute || 'id'] == id) {
51+
break;
52+
}
53+
}
54+
resource.collection.splice(i, 1);
55+
resource.collectionModified = utils.updateTimestamp(resource.collectionModified);
56+
deferred.resolve(id);
57+
} catch (err) {
58+
deferred.reject(new errors.UnhandledError(err));
59+
}
60+
}, deferred.reject);
61+
} catch (err) {
62+
deferred.reject(new errors.UnhandledError(err));
63+
}
64+
65+
return deferred.promise;
66+
}
67+
68+
module.exports = destroy;

src/datastore/eject/index.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@ function _eject(resource, id) {
1818

1919
/**
2020
* @doc method
21-
* @id DS.methods:eject
22-
* @name eject(resourceName, id)
21+
* @id DS.sync_methods:eject
22+
* @name eject(name, id)
2323
* @description
2424
* Synchronously remove the item of type `resourceName` with the given primary key from the data store (not from the
2525
* server).
2626
*
27+
* Example:
28+
*
29+
* ```js
30+
* TODO: eject(resourceName, id) example
31+
* ```
32+
*
2733
* ## Throws
2834
*
2935
* - `{IllegalArgumentError}` - Argument `id` must be a string or a number.
@@ -37,7 +43,7 @@ function eject(resourceName, id) {
3743
if (!store[resourceName]) {
3844
throw new errors.RuntimeError('DS.eject(resourceName, id): ' + resourceName + ' is not a registered resource!');
3945
} else if (!utils.isString(id) && !utils.isNumber(id)) {
40-
throw new errors.IllegalArgumentError('DS.eject(resourceName, id): id: You must provide an id!', { id: { actual: typeof id, expected: 'string|number' } });
46+
throw new errors.IllegalArgumentError('DS.eject(resourceName, id): id: Must be a string or a number!', { id: { actual: typeof id, expected: 'string|number' } });
4147
}
4248

4349
try {

0 commit comments

Comments
 (0)