diff --git a/assets/scripts/app/controllers.coffee b/assets/scripts/app/controllers.coffee index 0db0ff54..7cbb408e 100644 --- a/assets/scripts/app/controllers.coffee +++ b/assets/scripts/app/controllers.coffee @@ -41,6 +41,7 @@ Travis.FirstSyncController = Em.Controller.extend isSyncing: Ember.computed.alias('user.isSyncing') Travis.IndexErrorController = Em.Controller.extend() +Travis.BuildsItemController = Em.ObjectController.extend(Travis.GithubUrlProperties) Travis.QueuesController = Em.ArrayController.extend content: (-> diff --git a/assets/scripts/app/controllers/build.coffee b/assets/scripts/app/controllers/build.coffee index 6e61ab6f..c8763418 100644 --- a/assets/scripts/app/controllers/build.coffee +++ b/assets/scripts/app/controllers/build.coffee @@ -1,4 +1,4 @@ -Travis.BuildController = Ember.Controller.extend +Travis.BuildController = Ember.Controller.extend Travis.GithubUrlProperties, needs: ['repo'] repoBinding: 'controllers.repo.repo' commitBinding: 'build.commit' @@ -10,7 +10,3 @@ Travis.BuildController = Ember.Controller.extend loading: (-> @get('build.isLoading') ).property('build.isLoading') - - urlGithubCommit: (-> - Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha')) - ).property('repo.slug', 'commit.sha') diff --git a/assets/scripts/app/controllers/builds.coffee b/assets/scripts/app/controllers/builds.coffee index 7339c3f5..1ebd215e 100644 --- a/assets/scripts/app/controllers/builds.coffee +++ b/assets/scripts/app/controllers/builds.coffee @@ -1,4 +1,6 @@ Travis.BuildsController = Em.ArrayController.extend + isPullRequestsList: false + sortAscending: false sortProperties: ['number'] diff --git a/assets/scripts/app/helpers.coffee b/assets/scripts/app/helpers.coffee index 98608e18..5c5b4f46 100644 --- a/assets/scripts/app/helpers.coffee +++ b/assets/scripts/app/helpers.coffee @@ -2,3 +2,4 @@ require 'helpers/handlebars' require 'helpers/helpers' require 'helpers/urls' require 'helpers/status_image_formatter' +require 'helpers/github_url_properties' diff --git a/assets/scripts/app/helpers/github_url_properties.coffee b/assets/scripts/app/helpers/github_url_properties.coffee new file mode 100644 index 00000000..6a19e21c --- /dev/null +++ b/assets/scripts/app/helpers/github_url_properties.coffee @@ -0,0 +1,8 @@ +Travis.GithubUrlProperties = Ember.Mixin.create + urlGithubCommit: (-> + Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha')) + ).property('repo.slug', 'commit.sha') + + urlGithubPullRequest: (-> + Travis.Urls.githubPullRequest(@get('repo.slug'), @get('build.pullRequestNumber')) + ).property('repo.slug', 'build.pullRequestNumber') diff --git a/assets/scripts/app/models/build.coffee b/assets/scripts/app/models/build.coffee index a5fb1809..a83fcf91 100644 --- a/assets/scripts/app/models/build.coffee +++ b/assets/scripts/app/models/build.coffee @@ -23,7 +23,14 @@ require 'travis/model' jobs: Ember.hasMany('Travis.Job') config: (-> - Travis.Helpers.compact(@get('_config')) + console.log('config') + if config = @get('_config') + Travis.Helpers.compact(config) + else + return if @get('isFetchingConfig') + @set 'isFetchingConfig', true + + @reload() ).property('_config') # TODO add eventType to the api for api build requests @@ -92,12 +99,6 @@ require 'travis/model' requeue: -> Travis.ajax.post "/builds/#{@get('id')}/restart" - isPropertyLoaded: (key) -> - if ['_duration', '_finishedAt'].contains(key) && !@get('isFinished') - return true - else - @_super(key) - formattedFinishedAt: (-> if finishedAt = @get('finishedAt') moment(finishedAt).format('lll') diff --git a/assets/scripts/app/models/env_var.coffee b/assets/scripts/app/models/env_var.coffee index 5ddd444c..168df98f 100644 --- a/assets/scripts/app/models/env_var.coffee +++ b/assets/scripts/app/models/env_var.coffee @@ -6,11 +6,3 @@ Travis.EnvVar = Travis.Model.extend public: Ember.attr('boolean') repo: Ember.belongsTo('Travis.Repo', key: 'repository_id') - - isPropertyLoaded: (key) -> - if key == 'value' - return true - else - @_super(key) - - diff --git a/assets/scripts/app/models/job.coffee b/assets/scripts/app/models/job.coffee index 088f5a19..ec8d3b00 100644 --- a/assets/scripts/app/models/job.coffee +++ b/assets/scripts/app/models/job.coffee @@ -42,7 +42,13 @@ require 'travis/model' ).property('repositorySlug') config: (-> - Travis.Helpers.compact(@get('_config')) + if config = @get('_config') + Travis.Helpers.compact(config) + else + return if @get('isFetchingConfig') + @set 'isFetchingConfig', true + + @reload() ).property('_config') isFinished: (-> @@ -113,14 +119,6 @@ require 'travis/model' @unsubscribe() if @get('state') == 'finished' && Travis.pusher ).observes('state') - isPropertyLoaded: (key) -> - if ['_finishedAt'].contains(key) && !@get('isFinished') - return true - else if key == '_startedAt' && @get('state') == 'created' - return true - else - @_super(key) - isFinished: (-> @get('state') in ['passed', 'failed', 'errored', 'canceled'] ).property('state') diff --git a/assets/scripts/app/models/ssh_key.coffee b/assets/scripts/app/models/ssh_key.coffee index 59f05b19..40d83fb0 100644 --- a/assets/scripts/app/models/ssh_key.coffee +++ b/assets/scripts/app/models/ssh_key.coffee @@ -3,11 +3,3 @@ Travis.SshKey = Travis.Model.extend value: Ember.attr('string') description: Ember.attr('string') fingerprint: Ember.attr('string') - - isPropertyLoaded: (key) -> - if key == 'value' - return true - else - @_super(key) - - diff --git a/assets/scripts/app/routes.coffee b/assets/scripts/app/routes.coffee index 8d86c8b8..b0e82ff5 100644 --- a/assets/scripts/app/routes.coffee +++ b/assets/scripts/app/routes.coffee @@ -245,8 +245,19 @@ Travis.AbstractBuildsRoute = Travis.Route.extend ).property('contentType') Travis.BuildsRoute = Travis.AbstractBuildsRoute.extend(contentType: 'builds') -Travis.PullRequestsRoute = Travis.AbstractBuildsRoute.extend(contentType: 'pull_requests') Travis.BranchesRoute = Travis.AbstractBuildsRoute.extend(contentType: 'branches') +Travis.PullRequestsRoute = Travis.AbstractBuildsRoute.extend( + contentType: 'pull_requests' + + # TODO: it would be better to have separate controller for branches and PRs list + setupController: (controller, model) -> + @_super(controller, model) + + this.controllerFor('builds').set('isPullRequestsList', true) + + deactivate: -> + this.controllerFor('builds').set('isPullRequestsList', false) +) Travis.BuildRoute = Travis.Route.extend serialize: (model, params) -> diff --git a/assets/scripts/app/templates/builds/list.hbs b/assets/scripts/app/templates/builds/list.hbs index ea2a408a..221b16eb 100644 --- a/assets/scripts/app/templates/builds/list.hbs +++ b/assets/scripts/app/templates/builds/list.hbs @@ -10,7 +10,7 @@ Committer - {{#if view.isPullRequestsList}} + {{#if isPullRequestsList}} PR @@ -21,7 +21,7 @@ - {{#each build in controller}} + {{#each build in controller itemController="buildsItem"}} {{#view Travis.BuildsItemView contextBinding="build"}} @@ -35,16 +35,16 @@ {{{formatMessage commit.message short="true" repoBinding=build.repo}}} - + {{formatCommit commit}} {{commit.committerName}} - {{#if view.isPullRequestsList}} + {{#if isPullRequestsList}} - + #{{pullRequestNumber}} diff --git a/assets/scripts/app/views/build.coffee b/assets/scripts/app/views/build.coffee index 6868b48c..58a464c9 100644 --- a/assets/scripts/app/views/build.coffee +++ b/assets/scripts/app/views/build.coffee @@ -3,10 +3,6 @@ Travis.reopen templateName: 'builds/list' buildsBinding: 'controller.builds' - isPullRequestsList: (-> - @get('controller.tab') == 'pull_requests' - ).property('controller.tab') - ShowMoreButton: Em.View.extend tagName: 'button' classNameBindings: ['isLoading', 'showMore'] @@ -37,14 +33,6 @@ Travis.reopen Travis.Helpers.colorForState(@get('build.state')) ).property('build.state') - urlGithubCommit: (-> - Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha')) - ).property('repo.slug', 'commit.sha') - - urlGithubPullRequest: (-> - Travis.Urls.githubPullRequest(@get('repo.slug'), @get('build.pullRequestNumber')) - ).property('repo.slug', 'build.pullRequestNumber') - BuildView: Travis.View.extend templateName: 'builds/show' classNameBindings: ['color', 'loading'] diff --git a/assets/scripts/lib/travis/model.coffee b/assets/scripts/lib/travis/model.coffee index 9226130b..d5e9ba91 100644 --- a/assets/scripts/lib/travis/model.coffee +++ b/assets/scripts/lib/travis/model.coffee @@ -34,84 +34,19 @@ Array.prototype.diff = (a) -> @_super(key) - load: (id, hash) -> - @loadedAttributes = [] - @loadedRelationships = [] - - attributes = this.constructor.getAttributes() || [] - relationships = this.constructor.getRelationships() || [] - - if hash - for key in attributes - dataKey = @dataKey(key) - if hash.hasOwnProperty(dataKey) - @loadedAttributes.pushObject(key) - - for key in relationships - dataKey = @dataKey(key) - if hash.hasOwnProperty(dataKey) - @loadedRelationships.pushObject(key) - - incomplete = Ember.EnumerableUtils.intersection(@loadedAttributes, attributes).length != attributes.length || - Ember.EnumerableUtils.intersection(@loadedRelationships, relationships).length != relationships.length - - #if incomplete - # properties = attributes.concat(relationships) - # loadedProperties = @loadedAttributes.concat(@loadedRelationships) - # diff = properties.diff(loadedProperties) - # #console.log(@constructor, 'with id', id, 'loaded as incomplete, info:', { diff: diff, attributes: loadedProperties, data: hash}) - - @set('incomplete', incomplete) - - @_super(id, hash) - - getAttr: (key, options) -> - @needsCompletionCheck(key) - @_super.apply this, arguments - getBelongsTo: (key, type, meta) -> unless key key = type.singularName() + '_id' - @needsCompletionCheck(key) @_super(key, type, meta) getHasMany: (key, type, meta) -> unless key key = type.singularName() + '_ids' - @needsCompletionCheck(key) @_super(key, type, meta) - needsCompletionCheck: (key) -> - if key && (@isAttribute(key) || @isRelationship(key)) && - @get('incomplete') && !@isPropertyLoaded(key) - @loadTheRest(key) - - isAttribute: (name) -> - this.constructor.getAttributes().contains(name) - - isRelationship: (name) -> - this.constructor.getRelationships().contains(name) - - loadTheRest: (key) -> - # for some weird reason key comes changed to a string and for some weird reason it even is called with - # undefined key - return if !key || key == 'undefined' - - message = "Load missing fields for #{@constructor.toString()} because of missing key '#{key}', cid: #{@get('clientId')}, id: #{@get('id')}" - if @isAttribute('state') && key != 'state' - message += ", in state: #{@get('state')}" - console.log message - return if @get('isCompleting') - @set 'isCompleting', true - - @reload() - select: -> @constructor.select(@get('id')) - isPropertyLoaded: (name) -> - @loadedAttributes.contains(name) || @loadedRelationships.contains(name) - @Travis.Model.reopenClass select: (id) -> @find().forEach (record) -> diff --git a/assets/scripts/spec/unit/build_spec.coffee b/assets/scripts/spec/unit/build_spec.coffee index c1b05fcc..c6d3c3fd 100644 --- a/assets/scripts/spec/unit/build_spec.coffee +++ b/assets/scripts/spec/unit/build_spec.coffee @@ -6,37 +6,6 @@ module "Travis.Build", Travis.Build.resetData() Travis.Job.resetData() -test 'it does not load record on duration, finishedAt and result if job is not in finished state', -> - Travis.Build.load [{ id: 1, state: 'started', started_at: null }] - - Ember.run -> - record = Travis.Build.find 1 - - record.loadTheRest = -> - ok(false, 'loadTheRest should not be called') - - record.get('duration') - record.get('finishedAt') - record.get('result') - - wait().then -> - ok(true, 'loadTheRest was not called') - -test 'it loads record on duration, finishedAt and result if job is in finished state', -> - expect(1) - - Travis.Build.load [{ id: 1, state: 'passed', started_at: null }] - - Ember.run -> - record = Travis.Build.find 1 - - record.loadTheRest = -> - ok(true, 'loadTheRest should be called') - - record.get('finishedAt') - - wait() - test 'it takes into account all the jobs when getting config keys', -> buildConfig = { rvm: ['1.9.3', '2.0.0'] } Travis.Build.load [{ id: '1', job_ids: ['1', '2', '3'], config: buildConfig }] diff --git a/assets/scripts/spec/unit/incomplete_spec.coffee b/assets/scripts/spec/unit/incomplete_spec.coffee deleted file mode 100644 index 6f81c325..00000000 --- a/assets/scripts/spec/unit/incomplete_spec.coffee +++ /dev/null @@ -1,83 +0,0 @@ -fullPostHash = null -Post = null -Author = null - -module "Travis.Model - incomplete", - setup: -> - fullPostHash = { - id: '1', - title: 'foo', - published_at: 'today', - - author_id: '1' - } - - Author = Travis.Model.extend() - - Post = Travis.Model.extend( - title: Ember.attr('string'), - publishedAt: Ember.attr('string', key: 'published_at'), - - author: Ember.belongsTo(Author, { key: 'author_id' }) - ) - - Post.adapter = Ember.FixtureAdapter.create() - -test "record is marked as incomplete if attributes are missing when loading a record", -> - Post.load([{ id: '1', title: 'foo' }]) - - record = Post.find('1') - ok(record.get('incomplete'), 'record should be incomplete') - equal(record.get('title'), 'foo', 'attributes should be accessible') - -test "record is marked as complete if missing attributes are loaded", -> - Post.load([{ id: '1', title: 'foo' }]) - - record = Post.find('1') - ok(record.get('incomplete'), 'record should be complete') - equal(record.get('title'), 'foo', 'attributes should be accessible') - - record.load('1', fullPostHash) - - ok(!record.get('incomplete'), 'record should be complete') - -test "record is marked as incomplete if belongsTo key is missing", -> - delete(fullPostHash.author_id) - Post.load([fullPostHash]) - - record = Post.find('1') - ok(record.get('incomplete'), 'record should be incomplete') - -test "proeperty can be loaded as null, which means that the property is still loaded", -> - fullPostHash.author_id = null - fullPostHash.title = null - - Post.load([fullPostHash]) - - record = Post.find('1') - ok(!record.get('incomplete'), 'record should be complete') - equal(record.get('title'), null, 'title should be null') - -test "when accessing missing property, record is loaded", -> - Post.FIXTURES = [fullPostHash] - Post.load([{ id: '1' }]) - - record = null - Ember.run -> record = Post.find('1') - - ok(record.get('incomplete'), 'record should be incomplete') - - publishedAt = null - Ember.run -> publishedAt = record.get('publishedAt') - - ok(!publishedAt, 'publishedAt should be missing') - - stop() - setTimeout( -> - start() - - Ember.run -> publishedAt = record.get('publishedAt') - equal(publishedAt, 'today', 'publishedAt should be loaded') - ok(!record.get('incomplete'), 'record should be complete') - , 50) - diff --git a/assets/scripts/spec/unit/incomplete_spec.js b/assets/scripts/spec/unit/incomplete_spec.js deleted file mode 100644 index 8b137891..00000000 --- a/assets/scripts/spec/unit/incomplete_spec.js +++ /dev/null @@ -1 +0,0 @@ - diff --git a/assets/scripts/spec/unit/job_spec.coffee b/assets/scripts/spec/unit/job_spec.coffee index fdf12984..a42409b6 100644 --- a/assets/scripts/spec/unit/job_spec.coffee +++ b/assets/scripts/spec/unit/job_spec.coffee @@ -36,37 +36,6 @@ test 'configKeys takes into account the keys of other jobs', -> deepEqual( configValues2, [ '2.0.0', undefined, 'Gemfile.1', undefined ] ) deepEqual( configValues3, [ '1.9.3', undefined, undefined, 'OpenJDK' ] ) -test 'it does not load record on duration, finishedAt and result if job is not in finished state', -> - Travis.Job.load [{ id: 1, state: 'started', started_at: null }] - - Ember.run -> - record = Travis.Job.find 1 - - record.loadTheRest = -> - ok(false, 'loadTheRest should not be called') - - record.get('_duration') - record.get('finishedAt') - record.get('result') - - wait().then -> - ok(true, 'loadTheRest was not called') - -test 'it loads record on duration, finishedAt and result if job is in finished state', -> - expect(1) - - Travis.Job.load [{ id: 1, state: 'passed', started_at: null }] - - Ember.run -> - record = Travis.Job.find 1 - - record.loadTheRest = -> - ok(true, 'loadTheRest should be called') - - record.get('finishedAt') - - wait() - test 'returns config values for all keys available on build with different number of config keys in sibling jobs', -> buildAttrs = id: 1 diff --git a/assets/scripts/spec/unit/log_chunks_spec.coffee b/assets/scripts/spec/unit/log_chunks_spec.coffee index 724ace17..70674720 100644 --- a/assets/scripts/spec/unit/log_chunks_spec.coffee +++ b/assets/scripts/spec/unit/log_chunks_spec.coffee @@ -6,13 +6,14 @@ test "it doesn't trigger downloading missing parts if they come in timely fashio callback = -> ok false, 'callback should not be called' - chunks = Travis.LogChunks.create(timeout: 15, missingPartsCallback: callback, content: []) + chunks = Travis.LogChunks.create(timeout: 20, missingPartsCallback: callback, content: []) - setTimeout (-> chunks.pushObject(number: 1, final: false)), 10 - setTimeout (-> chunks.pushObject(number: 2, final: false)), 20 + Ember.run.later (-> chunks.pushObject(number: 1, final: false)), 10 + Ember.run.later (-> chunks.pushObject(number: 2, final: false)), 20 setTimeout -> ok true - chunks.pushObject(number: 3, final: true) + Ember.run -> + chunks.pushObject(number: 3, final: true) start() equal(chunks.get('finalized'), true, 'log should be finalized') @@ -25,11 +26,11 @@ test "it triggers downloading missing parts if there is a missing part, even tho callback = (missingNumbers) -> deepEqual(missingNumbers, [2, 3], 'callback should be called with missing numbers') - chunks = Travis.LogChunks.create(timeout: 15, missingPartsCallback: callback, content: []) + chunks = Travis.LogChunks.create(timeout: 20, missingPartsCallback: callback, content: []) - chunks.pushObject(number: 1, final: false) + Ember.run -> chunks.pushObject(number: 1, final: false) setTimeout -> - chunks.pushObject(number: 4, final: true) + Ember.run -> chunks.pushObject(number: 4, final: true) ok(!chunks.get('finalized'), "log shouldn't be finalized") , 10 @@ -37,7 +38,7 @@ test "it triggers downloading missing parts if there is a missing part, even tho setTimeout -> Ember.run -> chunks.destroy() # destroy object to not fire more callbacks start() - , 40 + , 60 test "it triggers downloading next parts if there is no final part", -> expect(4) @@ -49,8 +50,9 @@ test "it triggers downloading next parts if there is no final part", -> chunks = Travis.LogChunks.create(timeout: 15, missingPartsCallback: callback, content: []) - chunks.pushObject(number: 1, final: false) - chunks.pushObject(number: 3, final: false) + Ember.run -> + chunks.pushObject(number: 1, final: false) + chunks.pushObject(number: 3, final: false) setTimeout -> Ember.run -> chunks.destroy() # destroy object to not fire more callbacks