Merge branch 'master' into rkh-better-login

This commit is contained in:
Konstantin Haase 2012-12-06 13:52:09 +01:00
commit 3eb4c04f11
6 changed files with 285 additions and 170 deletions

View File

@ -5,12 +5,7 @@
this should probably be refactored to use container view}}
{{#with view.job.log}}
{{#if id}}
{{#view view.PreView logBinding="view.context.log" logUrlBinding="view.logUrl"}}
<pre id="log" class="ansi"><a href="#" id="tail" {{action toggleTailing target="view"}}>
<span class="status"></span>
<label>Follow logs</label>
</a></pre>
{{/view}}
{{view Travis.PreView logBinding="view.context.log" logUrlBinding="view.logUrl"}}
{{/if}}
{{/with}}

View File

@ -0,0 +1,4 @@
<pre id="log" class="ansi"><a href="#" id="tail" {{action toggleTailing target="view"}}>
<span class="status"></span>
<label>Follow logs</label>
</a></pre>

View File

@ -101,10 +101,6 @@
jobBinding: 'context'
toggleTailing: (event) ->
Travis.app.tailing.toggle()
event.preventDefault()
logSubscriber: (->
# for some reason observing context does not work,
# TODO: find out why
@ -128,79 +124,115 @@
Travis.app.get('router').urlForEvent(event, repo, item)
).property('job.repo', 'parentView.currentItem')
PreView: Em.View.extend
init: ->
@_super.apply this, arguments
@set 'logManager', Travis.Log.create(target: this)
PreView: Em.View.extend
templateName: 'jobs/pre'
init: ->
@_super.apply this, arguments
@set 'logManager', Travis.Log.create(target: this)
didInsertElement: ->
@_super.apply this, arguments
toggleTailing: (event) ->
Travis.app.tailing.toggle()
event.preventDefault()
Ember.run.next this, ->
if @get 'log.isInitialized'
@logDidChange()
didInsertElement: ->
@_super.apply this, arguments
willDestroy: ->
@get('logManager').destroy()
@get('log.parts').removeArrayObserver this,
Ember.run.next this, ->
if @get 'log.isInitialized'
@logDidChange()
willDestroy: ->
@get('logManager').destroy()
@get('log.parts').removeArrayObserver this,
didChange: 'logContentsDidChange'
willChange: 'logContentsWillChange'
version: (->
@rerender()
@set 'logManager', Travis.Log.create(target: this)
).observes('log.version')
logDidChange: (->
if @get('log.isInitialized') && @state == 'inDOM'
@attachLogObservers()
).observes('log', 'log.isInitialized')
attachLogObservers: ->
return if @get('logPartsObserversAttached') == Ember.guidFor(@get('log'))
@set 'logPartsObserversAttached', Ember.guidFor(@get('log'))
Ember.run.next this, ->
@get('logManager').append @get('log.parts')
@get('log.parts').addArrayObserver this,
didChange: 'logContentsDidChange'
willChange: 'logContentsWillChange'
version: (->
@rerender()
@set 'logManager', Travis.Log.create(target: this)
).observes('log.version')
logContentsDidChange: (lines, index, removedCount, addedCount) ->
addedLines = lines.slice(index, index + addedCount)
@get('logManager').append addedLines
logDidChange: (->
if @get('log.isInitialized') && @state == 'inDOM'
@attachLogObservers()
).observes('log', 'log.isInitialized')
logContentsWillChange: (-> )
attachLogObservers: ->
return if @get('logPartsObserversAttached') == Ember.guidFor(@get('log'))
@set 'logPartsObserversAttached', Ember.guidFor(@get('log'))
appendLog: (payloads) ->
url = @get('logUrl')
Ember.run.next this, ->
@get('logManager').append @get('log.parts')
leftOut = []
fragment = document.createDocumentFragment()
@get('log.parts').addArrayObserver this,
didChange: 'logContentsDidChange'
willChange: 'logContentsWillChange'
# TODO: refactor this loop, it's getting messy
for payload in payloads
line = payload.content
number = payload.number
logContentsDidChange: (lines, index, removedCount, addedCount) ->
addedLines = lines.slice(index, index + addedCount)
@get('logManager').append addedLines
unless payload.append
pathWithNumber = "#{url}#L#{number}"
p = document.createElement('p')
p.innerHTML = '<a href="%@" id="L%@" class="log-line-number" name="L%@">%@</a>%@'.fmt(pathWithNumber, number, number, number, line)
line = p
logContentsWillChange: (-> )
if payload.fold && !payload.foldContinuation
div = document.createElement('div')
div.appendChild line
div.className = "fold #{payload.fold} show-first-line"
line = div
appendLog: (payloads) ->
url = @get('logUrl')
for payload in payloads
line = payload.content
number = payload.number
unless payload.append
pathWithNumber = "#{url}#L#{number}"
line = '<p><a href="%@" id="L%@" class="log-line-number" name="L%@">%@</a>%@</p>'.fmt(pathWithNumber, number, number, number, line)
if payload.fold && !payload.foldContinuation
line = "<div class='fold #{payload.fold} show-first-line'>#{line}</div>"
if payload.replace
this.$("#log #L#{number}").parent().replaceWith line
else if payload.append
this.$("#log #L#{number}").parent().append line
else if payload.foldContinuation
this.$("#log .fold.#{payload.fold}:last").append line
if payload.replace
if link = fragment.querySelector("#L#{number}")
link.parentElement.innerHTML = line.innerHTML
else
this.$('#log').append(line)
this.$("#L#{number}").parent().replaceWith line
else if payload.append
if link = fragment.querySelector("#L#{number}")
link.parentElement.innerHTML += line
else
this.$("#L#{number}").parent().append line
else if payload.foldContinuation
folds = fragment.querySelectorAll(".fold.#{payload.fold}")
if fold = folds[folds.length - 1]
fold.appendChild line
else
this.$("#log .fold.#{payload.fold}:last").append line
else
fragment.appendChild(line)
if payload.openFold
this.$("#log .fold.#{payload.openFold}:last").
removeClass('show-first-line').
addClass('open')
if payload.openFold
folds = fragment.querySelectorAll(".fold.#{payload.fold}")
if fold = folds[folds.length - 1]
fold = $(fold)
else
fold = this.$(".fold.#{payload.fold}:last")
if payload.foldEnd
this.$("#log .fold.#{payload.fold}:last").removeClass('show-first-line')
fold.removeClass('show-first-line').addClass('open')
if payload.foldEnd
folds = fragment.querySelectorAll(".fold.#{payload.fold}")
if fold = folds[folds.length - 1]
fold = $(fold)
else
fold = this.$(".fold.#{payload.fold}:last")
fold.removeClass('show-first-line')
this.$('#log')[0].appendChild fragment

View File

@ -76,8 +76,8 @@ describe 'Travis.Log', ->
{ 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 }, { number: 11 }]
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: /^\$/
@ -97,8 +97,8 @@ describe 'Travis.Log', ->
{ number: 1, fold: 'foo' },
{ number: 2, fold: 'foo', foldContinuation: true, foldEnd: true }]
expect( lines[1] ).toEqual ['$ bar', '']
expect( options[1]).toEqual [{ number: 3 }, { number: 4 }]
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: /^\$/
@ -124,8 +124,8 @@ describe 'Travis.Log', ->
{ number: 3, fold: 'foo' },
{ number: 4, fold: 'foo', foldContinuation: true, foldEnd: true }]
expect( lines[2] ).toEqual ['$ bar', '']
expect( options[2]).toEqual [{ number: 5 }, { number: 6 }]
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: /^\$/
@ -139,11 +139,10 @@ describe 'Travis.Log', ->
lines = target.get('calls').map (call) -> call.lines
options = target.get('calls').map (call) -> call.options
expect( lines[0] ).toEqual ['$ foo --foo', '1', '']
expect( lines[0] ).toEqual ['$ foo --foo', '1']
expect( options[0]).toEqual [
{ fold: 'foo', number: 1 },
{ fold: 'foo', number: 2, foldContinuation: true },
{ fold: 'foo', number: 3, foldContinuation: true }]
{ fold: 'foo', number: 2, foldContinuation: true }]
it 'allows to continue fold', ->
fold = Em.Object.create name: 'foo', startPattern: /^\$ foo/, endPattern: /^\$/
@ -164,25 +163,23 @@ describe 'Travis.Log', ->
lines = target.get('calls').map (call) -> call.lines
options = target.get('calls').map (call) -> call.options
expect( lines[0] ).toEqual ['$ foo --foo', '1', '']
expect( lines[0] ).toEqual ['$ foo --foo', '1']
expect( options[0]).toEqual [
{ fold: 'foo', number: 1 },
{ fold: 'foo', number: 2, foldContinuation: true },
{ fold: 'foo', number: 3, foldContinuation: true }]
{ fold: 'foo', number: 2, foldContinuation: true }]
expect( lines[1] ).toEqual ['2', '']
expect( lines[1] ).toEqual ['2']
expect( options[1]).toEqual [
{ fold: 'foo', number: 3, foldContinuation: true, append: true }
{ fold: 'foo', number: 4, foldContinuation: true }
{ fold: 'foo', number: 3, foldContinuation: true }
]
expect( lines[2] ).toEqual ['3']
expect( options[2]).toEqual [
{ fold: 'foo', number: 4, foldContinuation: true, append: true, foldEnd: true }
{ fold: 'foo', number: 4, foldContinuation: true, foldEnd: true }
]
expect( lines[3] ).toEqual ['$ bar', '']
expect( options[3]).toEqual [{ number: 5 }, { number: 6 }]
expect( lines[3] ).toEqual ['$ bar']
expect( options[3]).toEqual [{ number: 5 }]
it 'notifies that the line should be appended', ->
log.append '$ foo\n.'
@ -201,8 +198,8 @@ describe 'Travis.Log', ->
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 }, { number: 4 }]
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'
@ -216,17 +213,17 @@ describe 'Travis.Log', ->
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[0] ).toEqual ['$ foo']
expect( options[0]).toEqual [{ number: 1 }]
expect( lines[1] ).toEqual ['', 'Downloading 50%']
expect( options[1]).toEqual [{ number: 2, append: true }, { number: 2, replace: true }]
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 }, { number: 3 }]
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, append: true }, { number: 4 }]
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

@ -0,0 +1,161 @@
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

@ -1,74 +0,0 @@
view = null
store = null
record = null
describe 'Travis.LogView', ->
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' }
log = Travis.Artifact.find(1)
Ember.run ->
view = Travis.LogView.create(context: null)
view.append()
expect( $('#log').length ).toEqual 1
console.log $('#log')
job = Ember.Object.create log: log, subscribe: (-> )
Ember.run ->
view.set 'context', job
log.set 'isLoaded', true
expect( view.$('#log p').length ).toEqual 1
expect( view.$('#log p').text().trim() ).toEqual '1$ start'
Ember.run ->
log.append('$ end')
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' }
log = Travis.Artifact.find(1)
job = Ember.Object.create log: log, subscribe: (-> )
Ember.run ->
view = Travis.LogView.create()
view.set('context', job)
view.append()
Ember.run ->
log.append('end')
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' }
log = Travis.Artifact.find(1)
job = Ember.Object.create log: log, subscribe: (-> )
Ember.run ->
view = Travis.LogView.create()
view.set('context', job)
view.append()
Ember.run ->
log.append '$ bundle install\n1\n2'
Ember.run ->
log.append '3\n4\n$ something'
expect( view.$('#log > p').length ).toEqual 2
expect( view.$('#log .fold.bundle').length ).toEqual 1
expect( view.$('#log .fold.bundle > p').length ).toEqual 5