From 59747f8424d861d8647eb4de51a8cc09a0d16394 Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Wed, 2 Mar 2016 12:42:39 +0100 Subject: [PATCH] Handle promises properly With API V3 we have some relationships (like lastBuild on branch) specified as asynchronuous, so sometimes we may deal with promises. This commit fixes the situation by handling both plain records and promises. --- app/components/repo-actions.js | 2 -- app/controllers/repo.js | 10 +++++--- app/services/update-times.js | 7 +++++- app/utils/eventually.js | 9 +++++++ .../repo-actions-item-component-mixin.js | 8 +++++- tests/unit/utils/eventually-test.js | 25 +++++++++++++++++++ 6 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 app/utils/eventually.js create mode 100644 tests/unit/utils/eventually-test.js diff --git a/app/components/repo-actions.js b/app/components/repo-actions.js index 9063460d..0ca81f70 100644 --- a/app/components/repo-actions.js +++ b/app/components/repo-actions.js @@ -1,7 +1,5 @@ import Ember from 'ember'; export default Ember.Component.extend({ - classNames: ['repo-main-tools'] - }); diff --git a/app/controllers/repo.js b/app/controllers/repo.js index 7b768291..1e27ebec 100644 --- a/app/controllers/repo.js +++ b/app/controllers/repo.js @@ -1,6 +1,7 @@ import Ember from 'ember'; import { githubRepo, statusImage } from 'travis/utils/urls'; import config from 'travis/config/environment'; +import eventually from 'travis/utils/eventually'; export default Ember.Controller.extend({ @@ -122,9 +123,12 @@ export default Ember.Controller.extend({ }, _lastBuildDidChange() { - var build; - build = this.get('repo.lastBuild'); - return this.set('build', build); + let lastBuild = this.get('repo.lastBuild'); + if(lastBuild) { + eventually(lastBuild, (build) => { + this.set('build', build); + }); + } }, stopObservingLastBuild() { diff --git a/app/services/update-times.js b/app/services/update-times.js index 5585ab38..0e0d6ec3 100644 --- a/app/services/update-times.js +++ b/app/services/update-times.js @@ -1,5 +1,6 @@ import Ember from 'ember'; import Config from 'travis/config/environment'; +import eventually from 'travis/utils/eventually'; export default Ember.Service.extend({ records: [], @@ -28,7 +29,11 @@ export default Ember.Service.extend({ records.filter((record) => { return this.get('allowFinishedBuilds') || !record.get('isFinished'); }).forEach((record) => { - record.updateTimes(); + eventually(record, function(resolvedRecord) { + if(resolvedRecord) { + resolvedRecord.updateTimes(); + } + }); }); this.set('records', []); diff --git a/app/utils/eventually.js b/app/utils/eventually.js new file mode 100644 index 00000000..b52f4b59 --- /dev/null +++ b/app/utils/eventually.js @@ -0,0 +1,9 @@ +export default function(anObjectOrAPromise, callback) { + if(anObjectOrAPromise.then) { + anObjectOrAPromise.then(function(result) { + callback(result); + }); + } else { + callback(anObjectOrAPromise); + } +} diff --git a/app/utils/repo-actions-item-component-mixin.js b/app/utils/repo-actions-item-component-mixin.js index e5539b67..a7785511 100644 --- a/app/utils/repo-actions-item-component-mixin.js +++ b/app/utils/repo-actions-item-component-mixin.js @@ -1,4 +1,5 @@ import Ember from 'ember'; +import eventually from 'travis/utils/eventually'; export default Ember.Mixin.create({ restarting: false, @@ -31,7 +32,12 @@ export default Ember.Mixin.create({ onFinished = () => { this.set('restarting', false); }; - return this.get('item').restart().then(onFinished, onFinished); + let restart = function(record) { + record.restart().then(onFinished, onFinished); + }; + eventually(this.get('item'), (item) => { + item.restart(); + }); }, cancel: function() { var type; diff --git a/tests/unit/utils/eventually-test.js b/tests/unit/utils/eventually-test.js new file mode 100644 index 00000000..07535c2c --- /dev/null +++ b/tests/unit/utils/eventually-test.js @@ -0,0 +1,25 @@ +import Ember from 'ember'; +import eventually from 'travis/utils/eventually'; + +module("eventually"); + +test("eventually runs a callback with passed item right away if it's not a promise", function() { + stop(); + expect(1); + + eventually({ foo: 'bar' }, function(result) { + equal(result.foo, 'bar'); + start(); + }); +}); + +test("eventually runs a callback when promise resolves if a passed object is a promise", function() { + stop(); + expect(1); + + let promise = { then: function(callback) { callback({ foo: 'bar'}); } }; + eventually(promise, function(result) { + equal(result.foo, 'bar'); + start(); + }); +});