From 5041e8204794a5eff458ba2bad7bc3dbbb6383df Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Fri, 19 Oct 2012 19:55:31 -0700 Subject: [PATCH 1/2] added changed() and previous to the collection save domain --- lib/resources/collection/index.js | 13 +++++++++++-- lib/script.js | 10 +++++++--- test-app/public/test/collection.test.js | 18 ++++++++++++++++++ test-app/resources/changed/config.json | 13 +++++++++++++ test-app/resources/changed/post.js | 3 +++ test-app/resources/changed/validate.js | 5 +++++ 6 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 test-app/resources/changed/config.json create mode 100644 test-app/resources/changed/post.js create mode 100644 test-app/resources/changed/validate.js diff --git a/lib/resources/collection/index.js b/lib/resources/collection/index.js index 1f24227..45353d7 100644 --- a/lib/resources/collection/index.js +++ b/lib/resources/collection/index.js @@ -470,13 +470,20 @@ Collection.prototype.save = function (ctx, fn) { protect: function(property) { delete item[property]; }, + changed: function (property) { + if(item.hasOwnProperty(property)) return true; + return false; + }, 'this': item, - data: item + data: item, + previous: {} }; function put() { var id = query.id - , sanitizedQuery = collection.sanitizeQuery(query); + , sanitizedQuery = collection.sanitizeQuery(query) + , prev = {}; + store.first(sanitizedQuery, function(err, obj) { if(!obj) { if (Object.keys(sanitizedQuery) === 1) { @@ -489,12 +496,14 @@ Collection.prototype.save = function (ctx, fn) { // merge changes Object.keys(item).forEach(function (key) { + prev[key] = obj[key]; obj[key] = item[key]; }); item = obj; domain['this'] = item; domain.data = item; + domain.previous = prev; collection.execCommands('update', item, commands); diff --git a/lib/script.js b/lib/script.js index 4140edb..311d266 100644 --- a/lib/script.js +++ b/lib/script.js @@ -13,7 +13,6 @@ function Script(src, path) { } catch(ex) { this.error = ex; } - } /** @@ -147,6 +146,7 @@ function wrapAsyncFunctions(asyncFunctions, sandbox, events, done, sandboxRoot) var args = _.toArray(arguments); var callback; var callbackIndex; + var result; for(var i = 0; i < args.length; i++) { if(typeof args[i] == 'function') { @@ -161,7 +161,7 @@ function wrapAsyncFunctions(asyncFunctions, sandbox, events, done, sandboxRoot) args[callbackIndex] = function() { if (sandboxRoot._error) return; try { - callback.apply(sandboxRoot._this, arguments); + result = callback.apply(sandboxRoot._this, arguments); events.emit('finishCallback'); } catch (err) { var wrappedErr = wrapError(err); @@ -176,12 +176,16 @@ function wrapAsyncFunctions(asyncFunctions, sandbox, events, done, sandboxRoot) }); } try { - asyncFunctions[k].apply(sandboxRoot._this, args); + result = asyncFunctions[k].apply(sandboxRoot._this, args); } catch(err) { var wrappedErr = wrapError(err); sandbox._error = wrappedErr; return done(wrappedErr); } + + if(result !== undefined) { + return result; + } }; } else if (typeof asyncFunctions[k] === 'object') { sandbox[k] = sandbox[k] || {}; diff --git a/test-app/public/test/collection.test.js b/test-app/public/test/collection.test.js index e36a383..3e83046 100644 --- a/test-app/public/test/collection.test.js +++ b/test-app/public/test/collection.test.js @@ -794,5 +794,23 @@ describe('Collection', function() { }); }); + describe('changed()', function(){ + it('should detect when a value has changed', function(done) { + dpd.changed.post({name: 'original'}, function (c) { + dpd.changed.put(c.id, {name: 'first name change'}, function (c) { + if(c.name !== 'saw first name changed previous original') { + throw Error('missed name change'); + } + done(); + }); + }); + }); + + afterEach(function (done) { + this.timeout(10000); + cleanCollection(dpd.changed, done); + }); + }); + }); diff --git a/test-app/resources/changed/config.json b/test-app/resources/changed/config.json new file mode 100644 index 0000000..7e0dbef --- /dev/null +++ b/test-app/resources/changed/config.json @@ -0,0 +1,13 @@ +{ + "type": "Collection", + "properties": { + "name": { + "name": "name", + "type": "string", + "typeLabel": "string", + "required": false, + "id": "name", + "order": 0 + } + } +} \ No newline at end of file diff --git a/test-app/resources/changed/post.js b/test-app/resources/changed/post.js new file mode 100644 index 0000000..c517de3 --- /dev/null +++ b/test-app/resources/changed/post.js @@ -0,0 +1,3 @@ +if(!(changed('name') && previous.name === undefined)) { + cancel('changed and/or previous are broken...'); +} \ No newline at end of file diff --git a/test-app/resources/changed/validate.js b/test-app/resources/changed/validate.js new file mode 100644 index 0000000..4ce1cd1 --- /dev/null +++ b/test-app/resources/changed/validate.js @@ -0,0 +1,5 @@ +if(this.name === 'first name change') { + if(changed('name')) { + this.name = 'saw first name changed previous ' + previous.name; + } +} \ No newline at end of file From bcd2981c7ae8021c7292acd69efec07b520cb489 Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Fri, 19 Oct 2012 20:03:23 -0700 Subject: [PATCH 2/2] added previous / changed docs --- docs/reference/collection-events.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/reference/collection-events.md b/docs/reference/collection-events.md index 033d24c..b4c3aac 100644 --- a/docs/reference/collection-events.md +++ b/docs/reference/collection-events.md @@ -96,6 +96,28 @@ Prevents a property from being updated. // Example: On Put // Protect a property protect('createdDate'); + + +### changed() + + changed(property) + +Returns whether a property has been updated. + + // Example: On Put + // Validate the title when it changes + if(changed('title') && this.title.length < 5) { + error('title', 'must be over 5 characters'); + } + +### previous + +An `Object` containing the previous values of the item to be updated. + + // Example: On Put + if(this.votes < previous.votes) { + emit('votes have decreased'); + } ### emit()