From 154be3b7edb837785e291169cca5ade598c55b89 Mon Sep 17 00:00:00 2001 From: Boetto Andrea Date: Wed, 17 May 2017 20:27:46 +0200 Subject: [PATCH 1/3] add newVals[key] !== undefined instead newVals[key] for handle boolean false change --- lib/changed.js | 2 +- .../simple-app/common/models/person.js | 8 +++++ .../simple-app/common/models/person.json | 6 ++-- test/test.js | 29 ++++++++++++++++--- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/changed.js b/lib/changed.js index 1e7d996..2b96f7e 100644 --- a/lib/changed.js +++ b/lib/changed.js @@ -394,7 +394,7 @@ module.exports = function(Model, options) { _.forEach(properties, function(key) { debug('getChangedProperties: - checking property %s ', key); - if (newVals[key]) { + if (newVals[key] !== undefined) { var newVal = newVals[key]; debug('getChangedProperties: - new value %s ', newVal); diff --git a/test/fixtures/simple-app/common/models/person.js b/test/fixtures/simple-app/common/models/person.js index a7ad1ec..beb92a1 100644 --- a/test/fixtures/simple-app/common/models/person.js +++ b/test/fixtures/simple-app/common/models/person.js @@ -21,6 +21,14 @@ module.exports = function(Person) { }); return cb.promise; }; + Person.changeFlag = function(args, cb) { + cb = cb || utils.createPromiseCallback(); + debug('this.changeFlag() called with %o', args); + process.nextTick(function() { + cb(null); + }); + return cb.promise; + }; // Define a function that should be called when a change is detected. Person.changeAge = function(args, cb) { diff --git a/test/fixtures/simple-app/common/models/person.json b/test/fixtures/simple-app/common/models/person.json index bf5cc3f..24ac6e7 100644 --- a/test/fixtures/simple-app/common/models/person.json +++ b/test/fixtures/simple-app/common/models/person.json @@ -9,7 +9,8 @@ "name": "String", "nickname": "String", "age": "Number", - "status": "String" + "status": "String", + "flag": "boolean" }, "validations": [], "relations": {}, @@ -20,7 +21,8 @@ "name": "changeName", "nickname": "changeName", "age": "changeAge", - "status": "changeStatus" + "status": "changeStatus", + "flag": "changeFlag" } } } diff --git a/test/test.js b/test/test.js index 4883058..f0f5bed 100644 --- a/test/test.js +++ b/test/test.js @@ -38,24 +38,26 @@ describe('loopback datasource changed property', function() { this.spyAge = this.sinon.spy(app.models.Person, 'changeAge'); this.spyStatus = this.sinon.spy(app.models.Person, 'changeStatus'); this.spyName = this.sinon.spy(app.models.Person, 'changeName'); + this.spyFlag = this.sinon.spy(app.models.Person, 'changeFlag'); }); lt.beforeEach.withApp(app); describe('when called internally', function() { lt.beforeEach.givenModel('Person', - {title: 'Mr', name:'Joe Blogs', nickname: 'joe', age: 21, status: 'active'}, 'joe'); + {title: 'Mr', name:'Joe Blogs', nickname: 'joe', age: 21, status: 'active', flag: true}, 'joe'); lt.beforeEach.givenModel('Person', - {title: 'Mr', name:'Bilbo Baggins', nickname: 'bilbo', age: 99, status: 'active'}, 'bilbo'); + {title: 'Mr', name:'Bilbo Baggins', nickname: 'bilbo', age: 99, status: 'active', flag: true}, 'bilbo'); lt.beforeEach.givenModel('Person', - {title: 'Miss', name:'Tina Turner', nickname: 'tina', age: 80, status: 'pending'}, 'tina'); + {title: 'Miss', name:'Tina Turner', nickname: 'tina', age: 80, status: 'pending', flag: false}, 'tina'); describe('Model.create', function() { it('should not run callback when creating new instances.', function(done) { var self = this; - expect(self.spyAge).not.to.have.been.called; + expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }); }); @@ -68,6 +70,7 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done); @@ -80,6 +83,7 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done); @@ -92,6 +96,7 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done); @@ -105,10 +110,25 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done); }); + + it('should run the callback after updating a watched property', function(done) { + var self = this; + this.joe.updateAttribute('flag', false) + .then(function(res) { + expect(res.flag).to.equal(false); + expect(self.spyAge).not.to.have.been.called; + expect(self.spyStatus).not.to.have.been.called; + expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).to.have.been.called; + done(); + }) + .catch(done); + }); }); describe('Model.updateAttributes', function() { @@ -119,6 +139,7 @@ describe('loopback datasource changed property', function() { expect(self.spyAge).not.to.have.been.called; expect(self.spyStatus).not.to.have.been.called; expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).not.to.have.been.called; done(); }) .catch(done); From 40d9a06bbc1ffc5cafbd544091d70bea6bc67ac4 Mon Sep 17 00:00:00 2001 From: Boetto Andrea Date: Wed, 17 May 2017 20:41:40 +0200 Subject: [PATCH 2/3] add test also for false to true transition --- test/test.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/test.js b/test/test.js index f0f5bed..ba23555 100644 --- a/test/test.js +++ b/test/test.js @@ -129,6 +129,19 @@ describe('loopback datasource changed property', function() { }) .catch(done); }); + it('should run the callback after updating a watched property', function(done) { + var self = this; + this.tina.updateAttribute('flag', true) + .then(function(res) { + expect(res.flag).to.equal(true); + expect(self.spyAge).not.to.have.been.called; + expect(self.spyStatus).not.to.have.been.called; + expect(self.spyName).not.to.have.been.called; + expect(self.spyFlag).to.have.been.called; + done(); + }) + .catch(done); + }); }); describe('Model.updateAttributes', function() { From 12fadfdc73bbcdbb00d3331d6804a570880b4a03 Mon Sep 17 00:00:00 2001 From: Boetto Andrea Date: Wed, 26 Jul 2017 15:52:49 +0200 Subject: [PATCH 3/3] changed callback not triggered if the value remain false --- lib/changed.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/changed.js b/lib/changed.js index 2b96f7e..af5b1aa 100644 --- a/lib/changed.js +++ b/lib/changed.js @@ -398,7 +398,7 @@ module.exports = function(Model, options) { var newVal = newVals[key]; debug('getChangedProperties: - new value %s ', newVal); - if (!oldVals[key] || !_.isEqual(oldVals[key], newVal)) { + if (oldVals[key] === undefined || !_.isEqual(oldVals[key], newVal)) { debug('getChangedProperties: - changed or new value: %s itemId: %s', newVal, itemId); changedProperties[itemId][key] = newVal;