1
0
Fork 0

Merge pull request #912 from triAGENS/foxx-generator-new-methods

Add the new Foxx.Repository methods
This commit is contained in:
Lucas Dohmen 2014-06-19 11:53:37 +02:00
commit dcf8ea97bf
2 changed files with 122 additions and 51 deletions

View File

@ -34,11 +34,7 @@ var Repository,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_initializer /// @startDocuBlock JSF_foxx_repository_initializer
/// Create a new instance of Repository /// Create a new instance of Repository with `new FoxxRepository(collection, opts)`
///
/// `new FoxxRepository(collection, opts)`
///
/// Create a new instance of Repository
/// ///
/// A Foxx Repository is always initialized with a collection object. You can get /// A Foxx Repository is always initialized with a collection object. You can get
/// your collection object by asking your Foxx.Controller for it: the /// your collection object by asking your Foxx.Controller for it: the
@ -108,9 +104,7 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_save /// @startDocuBlock JSF_foxx_repository_save
/// `save(model)` /// Save a model into the database with `save(model)`
///
/// Save a model into the database
/// ///
/// Expects a model. Will set the ID and Rev on the model. /// Expects a model. Will set the ID and Rev on the model.
/// Returns the model. /// Returns the model.
@ -135,9 +129,7 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_byId /// @startDocuBlock JSF_foxx_repository_byId
/// `byId(id)` /// Find a model by its ID with `byId(id)`
///
/// Find a model by its ID
/// ///
/// Returns the model for the given ID. /// Returns the model for the given ID.
/// ///
@ -157,9 +149,7 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_byExample /// @startDocuBlock JSF_foxx_repository_byExample
/// `byExample(example)` /// Find all models by an example with `byExample(example)`
///
/// Find all models by an example
/// ///
/// Returns an array of models for the given ID. /// Returns an array of models for the given ID.
/// ///
@ -181,9 +171,7 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_firstExample /// @startDocuBlock JSF_foxx_repository_firstExample
/// `firstExample(example)` /// Find the first model that matches the example with `firstExample(example)`
///
/// Find the first model that matches the example.
/// ///
/// Returns a model that matches the given example. /// Returns a model that matches the given example.
/// ///
@ -203,23 +191,24 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_all /// @startDocuBlock JSF_foxx_repository_all
/// `all()` /// Find all entries in the collection with `all()`
/// ///
/// Returns an array of models that matches the given example. /// Returns an array of models that matches the given example. You need to provide
/// both a skip and a limit value.
/// **Warning:** ArangoDB doesn't guarantee a specific order in this case, to make /// **Warning:** ArangoDB doesn't guarantee a specific order in this case, to make
/// this really useful we have to explicitly provide something to order by. /// this really useful we have to explicitly provide something to order by.
/// ///
/// *Examples* /// *Examples*
/// ///
/// ```javascript /// ```javascript
/// var myModel = repository.all(); /// var myModel = repository.all({ skip: 4, limit: 2 });
/// myModel[0].get('name'); /// myModel[0].get('name');
/// ``` /// ```
/// @endDocuBlock /// @endDocuBlock
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
all: function () { all: function (options) {
'use strict'; 'use strict';
var rawDocuments = this.collection.all().skip(4).limit(2).toArray(); var rawDocuments = this.collection.all().skip(options.skip).limit(options.limit).toArray();
return _.map(rawDocuments, function (rawDocument) { return _.map(rawDocuments, function (rawDocument) {
return (new this.modelPrototype(rawDocument)); return (new this.modelPrototype(rawDocument));
}, this); }, this);
@ -231,9 +220,8 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_remove /// @startDocuBlock JSF_foxx_repository_remove
/// `remove(model)` /// Remove the model from the repository with `remove(model)`
/// ///
/// Remove the model from the repository
/// ///
/// Expects a model /// Expects a model
/// ///
@ -244,12 +232,15 @@ _.extend(Repository.prototype, {
/// ``` /// ```
/// @endDocuBlock /// @endDocuBlock
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
remove: function (model) {
'use strict';
var id = model.get('_id');
this.collection.remove(id);
},
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_removeById /// @startDocuBlock JSF_foxx_repository_removeById
/// `removeById(id)` /// Remove the document with the given ID with `removeById(id)`
///
/// Remove the document with the given ID
/// ///
/// Expects an ID of an existing document. /// Expects an ID of an existing document.
/// ///
@ -267,9 +258,7 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_removeByExample /// @startDocuBlock JSF_foxx_repository_removeByExample
/// `removeByExample(example)` /// Remove all documents that match the example with `removeByExample(example)`
///
/// Remove all documents that match the example
/// ///
/// Find all documents that fit this example and remove them. /// Find all documents that fit this example and remove them.
/// ///
@ -291,7 +280,7 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_replace /// @startDocuBlock JSF_foxx_repository_replace
/// `replace(model)` /// Replace an entry in the collection with its new version via `replace(model)`
/// ///
/// Find the model in the database by its `_id` and replace it with this version. /// Find the model in the database by its `_id` and replace it with this version.
/// Expects a model. Sets the Revision of the model. /// Expects a model. Sets the Revision of the model.
@ -316,9 +305,7 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_replaceById /// @startDocuBlock JSF_foxx_repository_replaceById
/// `replaceById(id, model)` /// Find an item by ID and replace it with the given model with `replaceById(id, model)`
///
/// Find an item by ID and replace it with the given model
/// ///
/// Find the model in the database by the given ID and replace it with the given. /// Find the model in the database by the given ID and replace it with the given.
/// model. /// model.
@ -337,13 +324,11 @@ _.extend(Repository.prototype, {
id_and_rev = this.collection.replace(id, data); id_and_rev = this.collection.replace(id, data);
model.set(id_and_rev); model.set(id_and_rev);
return model; return model;
} },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_replaceByExample /// @startDocuBlock JSF_foxx_repository_replaceByExample
/// `replaceByExample(example, model)` /// Find an item by example and replace it with the given model with `replaceByExample(example, model)`
///
/// Find an item by example and replace it with the given model
/// ///
/// Find the model in the database by the given example and replace it with the given. /// Find the model in the database by the given example and replace it with the given.
/// model. /// model.
@ -356,6 +341,13 @@ _.extend(Repository.prototype, {
/// ``` /// ```
/// @endDocuBlock /// @endDocuBlock
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
replaceByExample: function (example, model) {
'use strict';
var data = model.forDB(),
idAndRev = this.collection.replaceByExample(example, data);
model.set(idAndRev);
return model;
},
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SUBSECTION-- Updating Entries // --SUBSECTION-- Updating Entries
@ -363,9 +355,8 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_updateById /// @startDocuBlock JSF_foxx_repository_updateById
/// `updateById(id, object)` /// Find an item by ID and update it with the attributes in the provided object with `updateById(id, object)`
/// ///
/// Find an item by ID and update it with the attributes in the provided object.
/// Returns the updated model. /// Returns the updated model.
/// ///
/// *Examples* /// *Examples*
@ -375,12 +366,16 @@ _.extend(Repository.prototype, {
/// ``` /// ```
/// @endDocuBlock /// @endDocuBlock
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
updateById: function (id, updates) {
'use strict';
this.collection.update(id, updates);
},
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_updateByExample /// @startDocuBlock JSF_foxx_repository_updateByExample
/// `updateByExample(example, object)` /// Find an item by example and update it with the attributes in the provided object
/// with `updateByExample(example, object)`
/// ///
/// Find an item by example and update it with the attributes in the provided object.
/// Returns the updated model. /// Returns the updated model.
/// ///
/// *Examples* /// *Examples*
@ -390,6 +385,10 @@ _.extend(Repository.prototype, {
/// ``` /// ```
/// @endDocuBlock /// @endDocuBlock
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
updateByExample: function (example, updates) {
'use strict';
this.collection.updateByExample(example, updates);
},
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SUBSECTION-- Counting Entries // --SUBSECTION-- Counting Entries
@ -397,9 +396,8 @@ _.extend(Repository.prototype, {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_repository_count /// @startDocuBlock JSF_foxx_repository_count
/// `count()` /// Return the number of entries in this collection with `count()`
/// ///
/// Return the number of entries in this collection
/// ///
/// *Examples* /// *Examples*
/// ///
@ -408,6 +406,10 @@ _.extend(Repository.prototype, {
/// ``` /// ```
/// @endDocuBlock /// @endDocuBlock
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
count: function () {
'use strict';
return this.collection.count();
}
}); });
Repository.extend = backbone_helpers.extend; Repository.extend = backbone_helpers.extend;

View File

@ -66,13 +66,18 @@ describe('Repository Methods', function () {
beforeEach(function () { beforeEach(function () {
collection = createSpyObj('collection', [ collection = createSpyObj('collection', [
'all',
'save', 'save',
'count',
'document', 'document',
'byExample', 'byExample',
'firstExample', 'firstExample',
'remove', 'remove',
'removeByExample', 'removeByExample',
'replace' 'update',
'updateByExample',
'replace',
'replaceByExample'
]); ]);
instance = new FoxxRepository(collection, { model: Model }); instance = new FoxxRepository(collection, { model: Model });
}); });
@ -139,11 +144,36 @@ describe('Repository Methods', function () {
expect(collection.firstExample.calls.argsFor(0)).toEqual([example]); expect(collection.firstExample.calls.argsFor(0)).toEqual([example]);
}); });
it('should find all'); it('should find all', function () {
var cursor = createSpyObj('cursor', ['skip', 'limit', 'toArray']),
result = [{}],
models;
collection.all.and.returnValue(cursor);
cursor.skip.and.returnValue(cursor);
cursor.limit.and.returnValue(cursor);
cursor.toArray.and.returnValue(result);
// TODO: Would prefer to mock the constructor and check for the specific instance
models = instance.all({ skip: 4, limit: 2 });
expect(models[0] instanceof Model).toBe(true);
expect(cursor.skip.calls.argsFor(0)).toEqual([4]);
expect(cursor.limit.calls.argsFor(0)).toEqual([2]);
});
}); });
describe('for removing entries', function () { describe('for removing entries', function () {
it('should allow to remove a model'); it('should allow to remove a model', function () {
var model = new Model(),
id = createSpy('id');
spyOn(model, 'get').and.returnValue(id);
instance.remove(model);
expect(collection.remove.calls.argsFor(0)).toEqual([id]);
expect(model.get.calls.argsFor(0)).toEqual(['_id']);
});
it('should allow to remove by ID', function () { it('should allow to remove by ID', function () {
var id = createSpy('id'); var id = createSpy('id');
@ -202,15 +232,54 @@ describe('Repository Methods', function () {
expect(collection.replace.calls.argsFor(0)).toEqual([id, data]); expect(collection.replace.calls.argsFor(0)).toEqual([id, data]);
}); });
it('should replace by example'); it('should replace by example', function () {
var model = new Model({}),
idAndRev = createSpy('idAndRev'),
example = createSpy('example'),
data = createSpy('data'),
result;
spyOn(model, 'forDB').and.returnValue(data);
spyOn(model, 'set');
collection.replaceByExample.and.returnValue(idAndRev);
result = instance.replaceByExample(example, model);
expect(result).toBe(model);
expect(model.set.calls.argsFor(0)).toEqual([idAndRev]);
expect(collection.replaceByExample.calls.argsFor(0)).toEqual([example, data]);
});
}); });
describe('for updating entries', function () { describe('for updating entries', function () {
it('should update by id'); it('should update by id', function () {
it('should update by example'); var id = createSpy('id'),
updates = createSpy('updates'),
idAndRev = createSpy('idAndRev');
collection.update.and.returnValue(idAndRev);
instance.updateById(id, updates);
expect(collection.update.calls.argsFor(0)).toEqual([id, updates]);
});
it('should update by example', function () {
var example = createSpy('example'),
updates = createSpy('updates'),
idAndRev = createSpy('idAndRev');
collection.updateByExample.and.returnValue(idAndRev);
instance.updateByExample(example, updates);
expect(collection.updateByExample.calls.argsFor(0)).toEqual([example, updates]);
});
}); });
describe('for counting entries', function () { describe('for counting entries', function () {
it('should count all'); it('should count all', function () {
var count = createSpy('count');
collection.count.and.returnValue(count);
expect(instance.count()).toBe(count);
});
}); });
}); });