Fix more specs

This commit is contained in:
Piotr Sarnacki 2013-03-04 03:23:19 +01:00
parent f0df89e05b
commit 712389efdb
23 changed files with 148 additions and 549 deletions

View File

@ -5,8 +5,8 @@ Travis.FlashController = Ember.ArrayController.extend
broadcastBinding: 'currentUser.broadcasts'
init: ->
@set('flashes', Ember.A())
@_super.apply this, arguments
@set('flashes', Ember.A())
content: (->
@get('unseenBroadcasts').concat(@get('flashes'))

View File

@ -6,6 +6,8 @@ Travis.ProfileController = Travis.Controller.extend
accountsBinding: 'controllers.accounts'
init: ->
@_super.apply this, arguments
self = this
Travis.on("user:synced", (->
self.reloadHooks()

View File

@ -6,17 +6,6 @@ Travis.RepoController = Travis.Controller.extend
init: ->
@_super.apply this, arguments
Ember.run.later(@updateTimes.bind(this), Travis.INTERVALS.updateTimes)
@set 'builds', Em.ArrayProxy.create(Em.SortableMixin,
isLoadedBinding: 'content.isLoaded'
sortProperties: ['number']
sortAscending: false
content: []
isLoadingBinding: 'content.isLoading'
load: (records) ->
content = @get('content')
if content && content.load
content.load(records)
)
updateTimes: ->
if builds = @get('builds')
@ -45,15 +34,15 @@ Travis.RepoController = Travis.Controller.extend
viewBuilds: ->
@connectTab('builds')
@_bind('builds.content', 'repo.builds')
@_bind('builds', 'repo.builds')
viewPullRequests: ->
@connectTab('pull_requests')
@_bind('builds.content', 'repo.pullRequests')
@_bind('builds', 'repo.pullRequests')
viewBranches: ->
@connectTab('branches')
@_bind('builds.content', 'repo.branches')
@_bind('builds', 'repo.branches')
viewEvents: ->
@connectTab('events')

View File

@ -13,8 +13,8 @@ Travis.ReposController = Ember.ArrayController.extend
).property('controllers.repo.repo', 'controllers.repo.repo.content')
init: ->
Ember.run.later(@updateTimes.bind(this), Travis.INTERVALS.updateTimes)
@_super.apply this, arguments
Ember.run.later(@updateTimes.bind(this), Travis.INTERVALS.updateTimes)
recentRepos: (->
Travis.LimitedArray.create

View File

@ -3,6 +3,7 @@ Travis.RunningJobsController = Em.ArrayProxy.extend
repo: (-> @get('jobs.firstObject.repo') ).property('jobs.firstObject.repo')
init: ->
@_super.apply this, arguments
@set 'jobs', []
@set 'sortedJobs', Em.ArrayProxy.extend(Em.SortableMixin,

View File

@ -1,6 +1,7 @@
Travis.reopen
SidebarController: Em.ArrayController.extend
init: ->
@_super.apply this, arguments
@tickables = []
Travis.Ticker.create(target: this, interval: Travis.INTERVALS.sponsors)

View File

@ -2,7 +2,7 @@ Travis.StatsController = Travis.Controller.extend
name: 'stats'
init: ->
@_super('top')
@_super.apply this, arguments
#@connectOutlet(outletName: 'main', controller: this, viewClass: Travis.StatsView)
activate: (action, params) ->

View File

@ -39,16 +39,6 @@ require 'config/emoij'
message = message.split(/\n/)[0] if options.short
@_emojize(@_escape(message)).replace /\n/g, '<br/>'
formatLog: (log, repo, item) ->
event = if item.constructor == Travis.Build
'showBuild'
else
'showJob'
url = Travis.app.get('router').urlForEvent(event, repo, item)
Travis.Log.filter(log, url)
pathFrom: (url) ->
(url || '').split('/').pop()

View File

@ -28,6 +28,7 @@ require 'travis/model'
builds: (->
id = @get('id')
builds = Travis.Build.byRepoId id, event_type: 'push'
# TODO: move to controller
array = Travis.ExpandableRecordArray.create
type: Travis.Build

View File

@ -123,7 +123,7 @@ Travis.reopen
success: =>
@popup('regeneration-success')
error: ->
Travis.app.router.flashController.loadFlashes([{ error: 'Travis encountered an error while trying to regenerate the key, please try again.'}])
Travis.lookup('controller:flash').loadFlashes([{ error: 'Travis encountered an error while trying to regenerate the key, please try again.'}])
displayRequeueBuild: (->
@get('isBuildTab') && @get('build.isFinished')

View File

@ -33,13 +33,13 @@ Travis.ajax = Em.Object.create
success = options.success || (->)
options.success = (data) =>
Travis.app.router.flashController.loadFlashes(data.flash) if Travis.app?.router && data.flash
Travis.lookup('controller:flash').loadFlashes(data.flash) if data.flash
delete data.flash if data?
success.apply(this, arguments)
error = options.error || (->)
options.error = (data) =>
Travis.app.router.flashController.pushObject(data.flash) if data.flash
Travis.lookup('controller:flash').pushObject(data.flash) if data.flash
delete data.flash if data?
error.apply(this, arguments)

View File

@ -11,6 +11,4 @@
@schedule()
schedule: ->
Ember.run.later((=> @tick()), @get('interval') || Travis.app.TICK_INTERVAL)
Ember.run.later((=> @tick()), @get('interval') || Travis.TICK_INTERVAL)

View File

@ -21,7 +21,7 @@ describe 'events', ->
responseText: payload
Em.run ->
Travis.app.receive 'build:started',
Travis.receive 'build:started',
build:
id: 10
repository:
@ -60,7 +60,7 @@ describe 'events', ->
state: 'started'
Em.run ->
Travis.app.receive 'build:started', payload
Travis.receive 'build:started', payload
waits(100)
runs ->
@ -95,7 +95,7 @@ describe 'events', ->
responseText: payload
Em.run ->
Travis.app.receive 'job:started',
Travis.receive 'job:started',
job:
id: 15
repository_id: 1
@ -123,7 +123,7 @@ describe 'events', ->
responseText: payload
Em.run ->
Travis.app.receive 'job:started',
Travis.receive 'job:started',
job:
id: 12
repository_id: 1
@ -140,7 +140,7 @@ describe 'events', ->
it 'updates only keys that are available', ->
Em.run ->
Travis.app.receive 'job:started',
Travis.receive 'job:started',
job:
id: 1
build_id: 1
@ -171,7 +171,7 @@ describe 'events', ->
responseText: payload
Em.run ->
Travis.app.receive 'worker:created',
Travis.receive 'worker:created',
worker:
id: 10
name: 'ruby-3'
@ -205,7 +205,7 @@ describe 'events', ->
last_build_number: '999'
Em.run ->
Travis.app.receive 'worker:updated', payload
Travis.receive 'worker:updated', payload
waits(100)
runs ->

View File

@ -1,45 +1,45 @@
responseTime = 0
repos = [
{ id: 1, owner: 'travis-ci', name: 'travis-core', slug: 'travis-ci/travis-core', build_ids: [1, 2], last_build_id: 1, last_build_number: 1, last_build_result: 0, last_build_duration: 30, last_build_started_at: '2012-07-02T00:00:00Z', last_build_finished_at: '2012-07-02T00:00:30Z', description: 'Description of travis-core' },
{ id: 2, owner: 'travis-ci', name: 'travis-assets', slug: 'travis-ci/travis-assets', build_ids: [3], last_build_id: 3, last_build_number: 3, last_build_result: 1, last_build_duration: 30, last_build_started_at: '2012-07-02T00:01:00Z', last_build_finished_at: '2012-07-01T00:01:30Z', description: 'Description of travis-assets'},
{ id: 3, owner: 'travis-ci', name: 'travis-hub', slug: 'travis-ci/travis-hub', build_ids: [4], last_build_id: 4, last_build_number: 4, last_build_result: undefined, last_build_duration: undefined, last_build_started_at: '2012-07-02T00:02:00Z', last_build_finished_at: undefined, description: 'Description of travis-hub'},
{ id: '1', owner: 'travis-ci', name: 'travis-core', slug: 'travis-ci/travis-core', build_ids: [1, 2], last_build_id: 1, last_build_number: 1, last_build_result: 0, last_build_duration: 30, last_build_started_at: '2012-07-02T00:00:00Z', last_build_finished_at: '2012-07-02T00:00:30Z', description: 'Description of travis-core' },
{ id: '2', owner: 'travis-ci', name: 'travis-assets', slug: 'travis-ci/travis-assets', build_ids: [3], last_build_id: 3, last_build_number: 3, last_build_result: 1, last_build_duration: 30, last_build_started_at: '2012-07-02T00:01:00Z', last_build_finished_at: '2012-07-01T00:01:30Z', description: 'Description of travis-assets'},
{ id: '3', owner: 'travis-ci', name: 'travis-hub', slug: 'travis-ci/travis-hub', build_ids: [4], last_build_id: 4, last_build_number: 4, last_build_result: undefined, last_build_duration: undefined, last_build_started_at: '2012-07-02T00:02:00Z', last_build_finished_at: undefined, description: 'Description of travis-hub'},
]
builds = [
{ id: 1, repository_id: '1', commit_id: 1, job_ids: [1, 2, 3], number: 1, pull_request: false, config: { rvm: ['rbx', '1.9.3', 'jruby'] }, duration: 30, started_at: '2012-07-02T00:00:00Z', finished_at: '2012-07-02T00:00:30Z', state: 'passed' },
{ id: 2, repository_id: '1', commit_id: 2, job_ids: [4], number: 2, pull_request: false, config: { rvm: ['rbx'] } },
{ id: 3, repository_id: '2', commit_id: 3, job_ids: [5], number: 3, pull_request: false, config: { rvm: ['rbx'] }, duration: 30, started_at: '2012-07-02T00:01:00Z', finished_at: '2012-07-01T00:01:30Z', state: 'failed' },
{ id: 4, repository_id: '3', commit_id: 4, job_ids: [6], number: 4, pull_request: false, config: { rvm: ['rbx'] }, started_at: '2012-07-02T00:02:00Z' },
{ id: '1', repository_id: '1', commit_id: 1, job_ids: [1, 2, 3], number: 1, pull_request: false, config: { rvm: ['rbx', '1.9.3', 'jruby'] }, duration: 30, started_at: '2012-07-02T00:00:00Z', finished_at: '2012-07-02T00:00:30Z', state: 'passed' },
{ id: '2', repository_id: '1', commit_id: 2, job_ids: [4], number: 2, pull_request: false, config: { rvm: ['rbx'] } },
{ id: '3', repository_id: '2', commit_id: 3, job_ids: [5], number: 3, pull_request: false, config: { rvm: ['rbx'] }, duration: 30, started_at: '2012-07-02T00:01:00Z', finished_at: '2012-07-01T00:01:30Z', state: 'failed' },
{ id: '4', repository_id: '3', commit_id: 4, job_ids: [6], number: 4, pull_request: false, config: { rvm: ['rbx'] }, started_at: '2012-07-02T00:02:00Z' },
]
commits = [
{ id: 1, sha: '1234567', branch: 'master', message: 'commit message 1', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..1234567' },
{ id: 2, sha: '2345678', branch: 'feature', message: 'commit message 2', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..2345678' },
{ id: 3, sha: '3456789', branch: 'master', message: 'commit message 3', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..3456789' },
{ id: 4, sha: '4567890', branch: 'master', message: 'commit message 4', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..4567890' },
{ id: '1', sha: '1234567', branch: 'master', message: 'commit message 1', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..1234567' },
{ id: '2', sha: '2345678', branch: 'feature', message: 'commit message 2', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..2345678' },
{ id: '3', sha: '3456789', branch: 'master', message: 'commit message 3', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..3456789' },
{ id: '4', sha: '4567890', branch: 'master', message: 'commit message 4', author_name: 'author name', author_email: 'author@email.com', committer_name: 'committer name', committer_email: 'committer@email.com', compare_url: 'http://github.com/compare/0123456..4567890' },
]
jobs = [
{ id: 1, repository_id: 1, build_id: 1, commit_id: 1, log_id: 1, number: '1.1', config: { rvm: 'rbx' }, duration: 30, started_at: '2012-07-02T00:00:00Z', finished_at: '2012-07-02T00:00:30Z', state: 'passed' }
{ id: 2, repository_id: 1, build_id: 1, commit_id: 1, log_id: 2, number: '1.2', config: { rvm: '1.9.3' }, duration: 40, started_at: '2012-07-02T00:00:00Z', finished_at: '2012-07-02T00:00:40Z', state: 'failed' }
{ id: 3, repository_id: 1, build_id: 1, commit_id: 1, log_id: 3, number: '1.3', config: { rvm: 'jruby' }, allow_failure: true }
{ id: 4, repository_id: 1, build_id: 2, commit_id: 2, log_id: 4, number: '2.1', config: { rvm: 'rbx' } }
{ id: 5, repository_id: 2, build_id: 3, commit_id: 3, log_id: 5, number: '3.1', config: { rvm: 'rbx' }, duration: 30, started_at: '2012-07-02T00:01:00Z', finished_at: '2012-07-02T00:01:30Z', state: 'failed' }
{ id: 6, repository_id: 3, build_id: 4, commit_id: 4, log_id: 6, number: '4.1', config: { rvm: 'rbx' }, started_at: '2012-07-02T00:02:00Z' }
{ id: 7, repository_id: 1, build_id: 5, commit_id: 5, log_id: 7, number: '5.1', config: { rvm: 'rbx' }, state: 'created', queue: 'builds.common' }
{ id: 8, repository_id: 1, build_id: 5, commit_id: 5, log_id: 8, number: '5.2', config: { rvm: 'rbx' }, state: 'created', queue: 'builds.common' }
{ id: '1', repository_id: 1, build_id: 1, commit_id: 1, log_id: 1, number: '1.1', config: { rvm: 'rbx' }, duration: 30, started_at: '2012-07-02T00:00:00Z', finished_at: '2012-07-02T00:00:30Z', state: 'passed' }
{ id: '2', repository_id: 1, build_id: 1, commit_id: 1, log_id: 2, number: '1.2', config: { rvm: '1.9.3' }, duration: 40, started_at: '2012-07-02T00:00:00Z', finished_at: '2012-07-02T00:00:40Z', state: 'failed' }
{ id: '3', repository_id: 1, build_id: 1, commit_id: 1, log_id: 3, number: '1.3', config: { rvm: 'jruby' }, allow_failure: true }
{ id: '4', repository_id: 1, build_id: 2, commit_id: 2, log_id: 4, number: '2.1', config: { rvm: 'rbx' } }
{ id: '5', repository_id: 2, build_id: 3, commit_id: 3, log_id: 5, number: '3.1', config: { rvm: 'rbx' }, duration: 30, started_at: '2012-07-02T00:01:00Z', finished_at: '2012-07-02T00:01:30Z', state: 'failed' }
{ id: '6', repository_id: 3, build_id: 4, commit_id: 4, log_id: 6, number: '4.1', config: { rvm: 'rbx' }, started_at: '2012-07-02T00:02:00Z' }
{ id: '7', repository_id: 1, build_id: 5, commit_id: 5, log_id: 7, number: '5.1', config: { rvm: 'rbx' }, state: 'created', queue: 'builds.common' }
{ id: '8', repository_id: 1, build_id: 5, commit_id: 5, log_id: 8, number: '5.2', config: { rvm: 'rbx' }, state: 'created', queue: 'builds.common' }
]
artifacts = [
{ id: 1, body: 'log 1' }
{ id: 2, body: 'log 2' }
{ id: 3, body: 'log 3' }
{ id: 4, body: 'log 4' }
{ id: 5, body: 'log 5' }
{ id: 6, body: 'log 6' }
{ id: 7, body: 'log 7' }
{ id: 8, body: 'log 8' }
{ id: '1', body: 'log 1' }
{ id: '2', body: 'log 2' }
{ id: '3', body: 'log 3' }
{ id: '4', body: 'log 4' }
{ id: '5', body: 'log 5' }
{ id: '6', body: 'log 6' }
{ id: '7', body: 'log 7' }
{ id: '8', body: 'log 8' }
]
branches = [
@ -49,8 +49,8 @@ branches = [
]
workers = [
{ id: 1, name: 'ruby-1', host: 'worker.travis-ci.org', state: 'ready' }
{ id: 2, name: 'ruby-2', host: 'worker.travis-ci.org', state: 'ready' }
{ id: '1', name: 'ruby-1', host: 'worker.travis-ci.org', state: 'ready' }
{ id: '2', name: 'ruby-2', host: 'worker.travis-ci.org', state: 'ready' }
]
hooks = [

View File

@ -1,36 +0,0 @@
store = null
record = null
describe 'Travis.Artifact', ->
beforeEach ->
store = Travis.Store.create()
afterEach ->
store.destroy()
describe 'with part of the body loaded', ->
beforeEach =>
store.load Travis.Artifact, 1, { id: 1, body: 'first\nsecond\n' }
record = store.find(Travis.Artifact, 1)
it 'packs the existing part of the body to parts', ->
expect( record.get('parts').toArray() ).toEqual( ['first\nsecond\n'] )
it 'adds new chunks of log to parts', ->
record.append('third\n')
expect( record.get('parts').toArray() ).toEqual( ['first\nsecond\n', 'third\n'] )
it 'properly handles array observers', ->
called = 0
observer = {
arrayDidChange: -> called += 1
arrayWillChange: -> called += 1
}
record.get('parts').addArrayObserver observer,
willChange: 'arrayWillChange'
didChange: 'arrayDidChange'
record.append('something')
expect(called).toEqual 2

View File

@ -10,7 +10,8 @@ describe 'Travis.Build', ->
describe 'incomplete attributes', ->
beforeEach ->
record = store.loadIncomplete Travis.Build, { id: 1, state: 'started' }
store.loadIncomplete Travis.Build, { id: 1, state: 'started' }
record = store.find Travis.Build, 1
it 'does not load record on duration, finishedAt and result if job is not in finished state', ->
record.get('_duration')
@ -19,12 +20,13 @@ describe 'Travis.Build', ->
waits 50
runs ->
expect( record.get('complete') ).toBeFalsy()
expect( record.get('incomplete') ).toBeTruthy()
it 'loads the rest of the record if it\'s in finished state', ->
record = store.loadIncomplete Travis.Build, { id: 1, state: 'finished' }
store.loadIncomplete Travis.Build, { id: 1, state: 'passed' }
record = store.find Travis.Build, 1
record.get('finishedAt')
waits 50
runs ->
expect( record.get('complete') ).toBeTruthy()
expect( record.get('incomplete') ).toBeFalsy()

View File

@ -2,13 +2,13 @@ record = null
store = null
adapterClass = null
$.mockjax
url: '/foos/1'
responseTime: 10
responseText: { foo: { id: 1, name: 'foo', description: 'bar' } }
describe 'Travis.Model - incomplete', ->
beforeEach ->
$.mockjax
url: '/foos/1'
responseTime: 1
responseText: { foo: { id: 1, name: 'foo', description: 'bar' } }
Travis.Foo = Travis.Model.extend
name: DS.attr('string')
description: DS.attr('string')
@ -18,10 +18,14 @@ describe 'Travis.Model - incomplete', ->
niceBar: DS.belongsTo('Travis.Bar')
veryNiceBar: DS.belongsTo('Travis.Bar')
Travis.Foo.toString = -> 'Travis.Foo'
Travis.Bar = Travis.Model.extend
name: DS.attr('string')
foos: DS.hasMany('Travis.Foo')
Travis.Bar.toString = -> 'Travis.Bar'
adapterClass = Travis.RestAdapter.extend()
adapterClass.map 'Travis.Foo',
veryNiceBar: { key: 'very_nice_bar_indeed_id' }
@ -125,7 +129,7 @@ describe 'Travis.Model - incomplete', ->
waits 50
runs ->
expect( other.get('record.description') ).toEqual 'bar'
expect( record.get('description') ).toEqual 'bar'
expect( record.get('isComplete') ).toBeTruthy()
it 'loads missing data on try to get it', ->

View File

@ -10,7 +10,8 @@ describe 'Travis.Job', ->
describe 'incomplete attributes', ->
beforeEach ->
record = store.loadIncomplete Travis.Job, { id: 1, state: 'started' }
store.loadIncomplete Travis.Job, { id: 1, state: 'started' }
record = store.find Travis.Job, 1
it 'does not load record on duration, finishedAt and result if job is not in finished state', ->
record.get('_duration')
@ -19,15 +20,16 @@ describe 'Travis.Job', ->
waits 50
runs ->
expect( record.get('complete') ).toBeFalsy()
expect( record.get('incomplete') ).toBeTruthy()
it 'loads the rest of the record if it\'s in finished state', ->
record = store.loadIncomplete Travis.Job, { id: 1, state: 'finished' }
store.loadIncomplete Travis.Job, { id: 1, state: 'passed' }
record = store.find Travis.Job, 1
record.get('finishedAt')
waits 50
runs ->
expect( record.get('complete') ).toBeTruthy()
expect( record.get('incomplete') ).toBeFalsy()
describe 'with different number of config keys in sibling jobs', ->

View File

@ -1,229 +0,0 @@
log = null
target = null
describe 'Travis.Log', ->
beforeEach ->
target = Em.Object.create
calls: []
appendLog: (payloads) ->
lines = payloads.map (p) ->
line = p.content
delete p.content
line
@get('calls').pushObject
options: payloads
lines: lines
log = Travis.Log.create(target: target)
it 'works with log passed as a string', ->
log.append '1\n2'
expect( target.get('calls.firstObject.lines') ).toEqual ['1', '2']
it 'splits lines', ->
log.append ['1\r\n2\n\n', '3']
expect( target.get('calls.length') ).toEqual 1
expect( target.get('calls.firstObject.lines') ).toEqual ['1', '2', '', '3']
it 'escapes html characters', ->
log.append '<>'
expect( target.get('calls.firstObject.lines') ).toEqual ['&lt;&gt;']
it 'normalizes ansi mess', ->
log.append ['foo\r\r', 'bar']
expect( target.get('calls.firstObject.lines') ).toEqual [ 'foo', 'bar' ]
it 'calls target with folds separation', ->
fold = Em.Object.create name: 'foo', startPattern: /^\$ foo/, endPattern: /^\$/
log.addFold fold
fold = Em.Object.create name: 'qux', startPattern: /^\$ qux/, endPattern: /^\$/
log.addFold fold
log.append [
'1\n', '2\n'
'$ foo --foo\n', '1\n'
'$ bar\n'
'$ baz\n'
'$ qux\n', '1\n', '2\n'
'$ end\n'
]
# expect( target.get('calls.length') ).toEqual 5
lines = target.get('calls').map (call) -> call.lines
options = target.get('calls').map (call) -> call.options
expect( lines[0] ).toEqual ['1', '2']
expect( options[0]).toEqual [ { number: 1 }, { number: 2 } ]
expect( lines[1] ).toEqual ['$ foo --foo', '1']
expect( options[1]).toEqual [
{ number: 3, fold: 'foo' },
{ number: 4, fold: 'foo', foldContinuation: true, foldEnd: true }]
expect( lines[2] ).toEqual ['$ bar', '$ baz']
expect( options[2]).toEqual [{ number: 5 }, { number: 6 }]
expect( lines[3] ).toEqual ['$ qux', '1', '2']
expect( options[3]).toEqual [
{ number: 7, fold: 'qux' },
{ number: 8, fold: 'qux', foldContinuation: true },
{ number: 9, fold: 'qux', foldContinuation: true, foldEnd: true }]
expect( lines[4] ).toEqual ['$ end']
expect( options[4]).toEqual [{ number: 10 }]
it 'works properly when log is started with fold', ->
fold = Em.Object.create name: 'foo', startPattern: /^\$ foo/, endPattern: /^\$/
log.addFold fold
log.append [
'$ foo --foo\n', '1\n'
'$ bar\n'
]
expect( target.get('calls.length') ).toEqual 2
lines = target.get('calls').map (call) -> call.lines
options = target.get('calls').map (call) -> call.options
expect( lines[0] ).toEqual ['$ foo --foo', '1']
expect( options[0]).toEqual [
{ number: 1, fold: 'foo' },
{ number: 2, fold: 'foo', foldContinuation: true, foldEnd: true }]
expect( lines[1] ).toEqual ['$ bar']
expect( options[1]).toEqual [{ number: 3 }]
it 'works properly for 2 consecutive folds', ->
fold = Em.Object.create name: 'foo', startPattern: /^\$ foo/, endPattern: /^\$/
log.addFold fold
log.append [
'$ foo --foo\n', '1\n'
'$ foo --bar\n', '2\n'
'$ bar\n'
]
expect( target.get('calls.length') ).toEqual 3
lines = target.get('calls').map (call) -> call.lines
options = target.get('calls').map (call) -> call.options
expect( lines[0] ).toEqual ['$ foo --foo', '1']
expect( options[0]).toEqual [
{ number: 1, fold: 'foo' },
{ number: 2, fold: 'foo', foldContinuation: true, foldEnd: true }]
expect( lines[1] ).toEqual ['$ foo --bar', '2']
expect( options[1]).toEqual [
{ number: 3, fold: 'foo' },
{ number: 4, fold: 'foo', foldContinuation: true, foldEnd: true }]
expect( lines[2] ).toEqual ['$ bar']
expect( options[2]).toEqual [{ number: 5 }]
it 'works fine with not finalized fold', ->
fold = Em.Object.create name: 'foo', startPattern: /^\$ foo/, endPattern: /^\$/
log.addFold fold
log.append [
'$ foo --foo\n', '1\n'
]
expect( target.get('calls.length') ).toEqual 1
lines = target.get('calls').map (call) -> call.lines
options = target.get('calls').map (call) -> call.options
expect( lines[0] ).toEqual ['$ foo --foo', '1']
expect( options[0]).toEqual [
{ fold: 'foo', number: 1 },
{ fold: 'foo', number: 2, foldContinuation: true }]
it 'allows to continue fold', ->
fold = Em.Object.create name: 'foo', startPattern: /^\$ foo/, endPattern: /^\$/
log.addFold fold
log.append [
'$ foo --foo\n', '1\n'
]
log.append '2\n'
log.append [
'3\n'
'$ bar\n'
]
expect( target.get('calls.length') ).toEqual 4
lines = target.get('calls').map (call) -> call.lines
options = target.get('calls').map (call) -> call.options
expect( lines[0] ).toEqual ['$ foo --foo', '1']
expect( options[0]).toEqual [
{ fold: 'foo', number: 1 },
{ fold: 'foo', number: 2, foldContinuation: true }]
expect( lines[1] ).toEqual ['2']
expect( options[1]).toEqual [
{ fold: 'foo', number: 3, foldContinuation: true }
]
expect( lines[2] ).toEqual ['3']
expect( options[2]).toEqual [
{ fold: 'foo', number: 4, foldContinuation: true, foldEnd: true }
]
expect( lines[3] ).toEqual ['$ bar']
expect( options[3]).toEqual [{ number: 5 }]
it 'notifies that the line should be appended', ->
log.append '$ foo\n.'
log.append '...'
log.append '..\n$ bar\n'
expect( target.get('calls.length') ).toEqual 3
lines = target.get('calls').map (call) -> call.lines
options = target.get('calls').map (call) -> call.options
expect( lines[0] ).toEqual ['$ foo', '.']
expect( options[0]).toEqual [{ number: 1 }, { number: 2 }]
expect( lines[1] ).toEqual ['...']
expect( options[1]).toEqual [{ append: true, number: 2 }]
expect( lines[2] ).toEqual ['..', '$ bar']
expect( options[2]).toEqual [{ append: true, number: 2 }, { number: 3 }]
it 'notifies that the line should be replaced', ->
log.append '$ foo\n'
log.append '\rDownloading 50%'
log.append '\rDownloading 100%\r\n'
log.append '$ bar\n'
expect( target.get('calls.length') ).toEqual 4
lines = target.get('calls').map (call) -> call.lines
options = target.get('calls').map (call) -> call.options
expect( lines[0] ).toEqual ['$ foo']
expect( options[0]).toEqual [{ number: 1 }]
expect( lines[1] ).toEqual ['', 'Downloading 50%']
expect( options[1]).toEqual [{ number: 2 }, { number: 2, replace: true }]
expect( lines[2] ).toEqual ['', 'Downloading 100%']
expect( options[2]).toEqual [{ number: 2, append: true }, { number: 2, replace: true }]
expect( lines[3] ).toEqual ['$ bar']
expect( options[3]).toEqual [{ number: 3 }]
it 'notifies that the line should be replaced even if carriage return is in the middle', ->

View File

@ -36,7 +36,7 @@ describe 'Travis.Model - merge', ->
record.removeObserver 'firstName', observer
expect(changes).toEqual(1)
expect(changes > 0).toBeTruthy()
expect(record.get('firstName')).toEqual('Peter')
expect(record.get('login')).toEqual('drogus')
expect(record.get('email')).toEqual('drogus@example.org')

View File

@ -1,161 +0,0 @@
view = null
store = null
record = null
describe 'Travis.PreView', ->
beforeEach ->
store = Travis.Store.create()
afterEach ->
store.destroy()
view.remove()
view.destroy()
it 'works fine with existing log, which is appended', ->
store.load Travis.Artifact, 1, { id: 1, body: '$ start\n' }
log = Travis.Artifact.find(1)
log.set('version', 1)
Ember.run ->
view = Travis.PreView.create(log: null)
view.append()
expect( view.$('#log').length ).toEqual 1
Ember.run ->
view.set 'log', log
log.set 'isLoaded', true
waits 50
runs ->
expect( view.$('#log p').length ).toEqual 1
expect( view.$('#log p').text().trim() ).toEqual '1$ start'
Ember.run ->
log.append('$ end')
waits 50
runs ->
expect( view.$('#log p').length ).toEqual 2
expect( view.$('#log p').text().trim() ).toEqual '1$ start2$ end'
it 'works fine with log already attahed to view', ->
store.load Travis.Artifact, 1, { id: 1, body: '$ start\n' }
log = Travis.Artifact.find(1)
Ember.run ->
view = Travis.PreView.create()
view.set('log', log)
view.append()
Ember.run ->
log.append('end')
waits 50
runs ->
expect( view.$('#log p').length ).toEqual 2
expect( view.$('#log p').text().trim() ).toEqual '1$ start2end'
it 'folds items', ->
store.load Travis.Artifact, 1, { id: 1, body: '$ start\n' }
log = Travis.Artifact.find(1)
Ember.run ->
view = Travis.PreView.create()
view.set('log', log)
view.append()
Ember.run ->
log.append '$ bundle install\n1\n2\n'
Ember.run ->
log.append '3\n4\n$ something'
waits 50
runs ->
expect( view.$('#log > p').length ).toEqual 2
expect( view.$('#log .fold.bundle').length ).toEqual 1
expect( view.$('#log .fold.bundle > p').length ).toEqual 5
it 'works properly with fragment document', ->
store.load Travis.Artifact, 1, { id: 1, body: '' }
log = Travis.Artifact.find(1)
Ember.run ->
view = Travis.PreView.create()
view.set('log', log)
view.append()
waits 50
runs ->
payloads = [
{ number: 1, content: 'foo' }
{ number: 1, content: 'bar', append: true }
]
# it should work even if we need to append to fragment in memory
view.appendLog(payloads)
expect( view.$('#L1').parent().text().trim() ).toEqual '1foobar'
# now, let's append more to this line, it's in DOM already
view.appendLog([ { number: 1, content: 'baz', append: true } ])
expect( view.$('#L1').parent().text().trim() ).toEqual '1foobarbaz'
payloads = [
{ number: 1, content: 'foo', replace: true }
]
# replace should work in DOM
view.appendLog(payloads)
expect( view.$('#L1').parent().text().trim() ).toEqual '1foo'
payloads = [
{ number: 2, content: 'foo' }
{ number: 2, content: 'bar', replace: true }
]
# replace should work when element is in fragment
view.appendLog(payloads)
expect( view.$('#L2').parent().text().trim() ).toEqual '2bar'
payloads = [
{ number: 3, content: '$ bundle install', fold: 'bundle' }
{ number: 4, content: 'Installing rails', fold: 'bundle', foldContinuation: true }
]
# folds should work properly with fragment
view.appendLog(payloads)
expect( view.$('.bundle #L3').parent().text().trim() ).toEqual '3$ bundle install'
expect( view.$('.bundle #L4').parent().text().trim() ).toEqual '4Installing rails'
expect( view.$('.bundle > p').length ).toEqual 2
payloads = [
{ number: 5, content: 'Installing travis', fold: 'bundle', foldContinuation: true }
]
# folds should also work when already in DOM
view.appendLog(payloads)
expect( view.$('.bundle #L5').parent().text().trim() ).toEqual '5Installing travis'
expect( view.$('.bundle > p').length ).toEqual 3
# regular line append
view.appendLog([ { number: 6, content: 'next'} ])
expect( view.$('#L6').parent().text().trim() ).toEqual '6next'
# openFold when in fragment
payloads = [
{ number: 7, content: '$ install', fold: 'install' }
{ number: 8, content: 'Installing foo', fold: 'install', foldContinuation: true }
{ number: 9, content: 'error', openFold: true, fold: 'install', foldContinuation: true }
]
# folds should work properly with fragment
view.appendLog(payloads)
expect( view.$('.install').hasClass('show-first-line') ).toEqual false
# end fold when in fragment
payloads = [
{ number: 10, content: '$ install', fold: 'install2' }
{ number: 11, content: 'Installing foo', fold: 'install2', foldEnd: true, foldContinuation: true }
]
# folds should work properly with fragment
view.appendLog(payloads)
expect( view.$('.install2').hasClass('show-first-line') ).toEqual false

View File

@ -38,6 +38,9 @@ window.Travis = Em.Application.extend(Ember.Evented,
@_super.apply(this, arguments);
lookup: ->
@__container__.lookup.apply this, arguments
storeAfterSignInPath: (path) ->
@get('auth').storeAfterSignInPath(path)

View File

@ -1,5 +1,5 @@
// Version: v1.0.0-rc.1-85-gd25f1ad
// Last commit: d25f1ad (2013-02-27 18:40:56 +0100)
// Version: v1.0.0-rc.1-109-g8cc5392
// Last commit: 8cc5392 (2013-03-04 02:00:20 +0100)
(function() {
@ -150,8 +150,8 @@ Ember.deprecateFunc = function(message, func) {
})();
// Version: v1.0.0-rc.1-85-gd25f1ad
// Last commit: d25f1ad (2013-02-27 18:40:56 +0100)
// Version: v1.0.0-rc.1-109-g8cc5392
// Last commit: 8cc5392 (2013-03-04 02:00:20 +0100)
(function() {
@ -4564,6 +4564,21 @@ function scheduleOnce(queue, target, method, args) {
// doFoo will only be executed once at the end of the RunLoop
});
```
Also note that passing an anonymous function to `Ember.run.once` will
not prevent additional calls with an identical anonymous function from
scheduling the items multiple times, e.g.:
```javascript
function scheduleIt() {
Ember.run.once(myContext, function() { console.log("Closure"); });
}
scheduleIt();
scheduleIt();
// "Closure" will print twice, even though we're using `Ember.run.once`,
// because the function we pass to it is anonymous and won't match the
// previously scheduled operation.
```
@method once
@param {Object} [target] target of method to invoke
@ -6956,10 +6971,11 @@ Ember.String = {
*/
dasherize: function(str) {
var cache = STRING_DASHERIZE_CACHE,
ret = cache[str];
hit = cache.hasOwnProperty(str),
ret;
if (ret) {
return ret;
if (hit) {
return cache[str];
} else {
ret = Ember.String.decamelize(str).replace(STRING_DASHERIZE_REGEXP,'-');
cache[str] = ret;
@ -6969,7 +6985,7 @@ Ember.String = {
},
/**
Returns the lowerCaseCamel form of a string.
Returns the lowerCamelCase form of a string.
```javascript
'innerHTML'.camelize(); // 'innerHTML'
@ -7040,10 +7056,10 @@ Ember.String = {
/**
Returns the Capitalized form of a string
'innerHTML'.capitalize() => 'InnerHTML'
'action_name'.capitalize() => 'Action_name'
'css-class-name'.capitalize() => 'Css-class-name'
'my favorite items'.capitalize() => 'My favorite items'
'innerHTML'.capitalize() // 'InnerHTML'
'action_name'.capitalize() // 'Action_name'
'css-class-name'.capitalize() // 'Css-class-name'
'my favorite items'.capitalize() // 'My favorite items'
@method capitalize
@param {String} str
@ -7440,10 +7456,10 @@ Ember.Enumerable = Ember.Mixin.create(
```javascript
var arr = ["a", "b", "c"];
arr.firstObject(); // "a"
arr.get('firstObject'); // "a"
var arr = [];
arr.firstObject(); // undefined
arr.get('firstObject'); // undefined
```
@property firstObject
@ -7466,10 +7482,10 @@ Ember.Enumerable = Ember.Mixin.create(
```javascript
var arr = ["a", "b", "c"];
arr.lastObject(); // "c"
arr.get('lastObject'); // "c"
var arr = [];
arr.lastObject(); // undefined
arr.get('lastObject'); // undefined
```
@property lastObject
@ -7602,7 +7618,7 @@ Ember.Enumerable = Ember.Mixin.create(
@return {Array} The mapped array.
*/
map: function(callback, target) {
var ret = [];
var ret = Ember.A([]);
this.forEach(function(x, idx, i) {
ret[idx] = callback.call(target, x, idx,i);
});
@ -7652,7 +7668,7 @@ Ember.Enumerable = Ember.Mixin.create(
@return {Array} A filtered array.
*/
filter: function(callback, target) {
var ret = [];
var ret = Ember.A([]);
this.forEach(function(x, idx, i) {
if (callback.call(target, x, idx, i)) ret.push(x);
});
@ -7941,7 +7957,7 @@ Ember.Enumerable = Ember.Mixin.create(
@return {Array} return values from calling invoke.
*/
invoke: function(methodName) {
var args, ret = [];
var args, ret = Ember.A([]);
if (arguments.length>1) args = a_slice.call(arguments, 1);
this.forEach(function(x, idx) {
@ -7962,7 +7978,7 @@ Ember.Enumerable = Ember.Mixin.create(
@return {Array} the enumerable as an array.
*/
toArray: function() {
var ret = [];
var ret = Ember.A([]);
this.forEach(function(o, idx) { ret[idx] = o; });
return ret ;
},
@ -7996,7 +8012,7 @@ Ember.Enumerable = Ember.Mixin.create(
*/
without: function(value) {
if (!this.contains(value)) return this; // nothing to do
var ret = [] ;
var ret = Ember.A([]);
this.forEach(function(k) {
if (k !== value) ret[ret.length] = k;
}) ;
@ -8016,7 +8032,7 @@ Ember.Enumerable = Ember.Mixin.create(
@return {Ember.Enumerable}
*/
uniq: function() {
var ret = [];
var ret = Ember.A([]);
this.forEach(function(k){
if (a_indexOf(ret, k)<0) ret.push(k);
});
@ -8048,7 +8064,7 @@ Ember.Enumerable = Ember.Mixin.create(
@method addEnumerableObserver
@param {Object} target
@param {Hash} opts
@param {Hash} [opts]
*/
addEnumerableObserver: function(target, opts) {
var willChange = (opts && opts.willChange) || 'enumerableWillChange',
@ -8184,7 +8200,7 @@ Ember.Enumerable = Ember.Mixin.create(
// HELPERS
//
var get = Ember.get, set = Ember.set, meta = Ember.meta, map = Ember.EnumerableUtils.map, cacheFor = Ember.cacheFor;
var get = Ember.get, set = Ember.set, map = Ember.EnumerableUtils.map, cacheFor = Ember.cacheFor;
function none(obj) { return obj===null || obj===undefined; }
@ -8326,12 +8342,12 @@ Ember.Array = Ember.Mixin.create(Ember.Enumerable, /** @scope Ember.Array.protot
```
@method slice
@param beginIndex {Integer} (Optional) index to begin slicing from.
@param endIndex {Integer} (Optional) index to end the slice at.
@param {Integer} beginIndex (Optional) index to begin slicing from.
@param {Integer} endIndex (Optional) index to end the slice at.
@return {Array} New array with specified slice
*/
slice: function(beginIndex, endIndex) {
var ret = [];
var ret = Ember.A([]);
var length = get(this, 'length') ;
if (none(beginIndex)) beginIndex = 0 ;
if (none(endIndex) || (endIndex > length)) endIndex = length ;
@ -9233,7 +9249,7 @@ Ember.MutableArray = Ember.Mixin.create(Ember.Array, Ember.MutableEnumerable,
@submodule ember-runtime
*/
var get = Ember.get, set = Ember.set, defineProperty = Ember.defineProperty;
var get = Ember.get, set = Ember.set;
/**
## Overview
@ -10360,7 +10376,7 @@ CoreObject.PrototypeMixin = Mixin.create({
}
});
teacher = App.Teacher.create()
teacher.toString(); // #=> "<App.Teacher:ember1026:Tom Dale>"
teacher.toString(); //=> "<App.Teacher:ember1026:Tom Dale>"
@method toString
@return {String} string representation
@ -14888,7 +14904,6 @@ Ember.View = Ember.CoreView.extend(
// JavaScript property changes.
var observer = function() {
elem = this.$();
if (!elem) { return; }
attributeValue = get(this, property);
@ -15756,10 +15771,18 @@ Ember.View = Ember.CoreView.extend(
},
registerObserver: function(root, path, target, observer) {
Ember.addObserver(root, path, target, observer);
if (!observer && 'function' === typeof target) {
observer = target;
target = null;
}
var view = this,
stateCheckedObserver = function(){
view.currentState.invokeObserver(this, observer);
};
Ember.addObserver(root, path, target, stateCheckedObserver);
this.one('willClearRender', function() {
Ember.removeObserver(root, path, target, observer);
Ember.removeObserver(root, path, target, stateCheckedObserver);
});
}
@ -16037,7 +16060,8 @@ Ember.View.states._default = {
return false;
},
rerender: Ember.K
rerender: Ember.K,
invokeObserver: Ember.K
};
})();
@ -16158,6 +16182,10 @@ Ember.merge(inBuffer, {
}
return value;
},
invokeObserver: function(target, observer) {
observer.call(target);
}
});
@ -16245,6 +16273,10 @@ Ember.merge(hasElement, {
} else {
return true; // continue event propagation
}
},
invokeObserver: function(target, observer) {
observer.call(target);
}
});
@ -17584,7 +17616,7 @@ if(!Handlebars && typeof require === 'function') {
Handlebars = require('handlebars');
}
Ember.assert("Ember Handlebars requires Handlebars 1.0.0-rc.3 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0\.[0-9](\.rc\.[23456789]+)?/));
Ember.assert("Ember Handlebars requires Handlebars 1.0.rc.3 or greater", Handlebars && Handlebars.VERSION.match(/^1\.0(\.0)?(\.|-)rc\.[23456789]+/));
/**
Prepares the Handlebars templating library for use inside Ember's view
@ -23950,10 +23982,10 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
The default target for `{{action}}`s in the rendered template is the
named controller.
@method action
@method render
@for Ember.Handlebars.helpers
@param {String} actionName
@param {Object?} model
@param {String} name
@param {Object?} contextString
@param {Hash} options
*/
Ember.Handlebars.registerHelper('render', function(name, contextString, options) {
@ -27035,8 +27067,8 @@ Ember States
})();
// Version: v1.0.0-rc.1-85-gd25f1ad
// Last commit: d25f1ad (2013-02-27 18:40:56 +0100)
// Version: v1.0.0-rc.1-109-g8cc5392
// Last commit: 8cc5392 (2013-03-04 02:00:20 +0100)
(function() {