diff --git a/Assetfile b/Assetfile index 4eccd2fc..8c867331 100644 --- a/Assetfile +++ b/Assetfile @@ -31,6 +31,11 @@ input assets.scripts do end match 'vendor/**/*.js' do + if assets.production? + reject 'ember.js' + else + reject 'ember.prod.js' + end safe_concat assets.vendor_order, 'vendor.js' end diff --git a/Gemfile b/Gemfile index 2aa50f3a..a7922e0b 100644 --- a/Gemfile +++ b/Gemfile @@ -40,61 +40,3 @@ group :test do gem 'sinatra-contrib' end -require 'bundler/installer' - -module ::Bundler - class Installer < Environment - MAX_RETRIES = 3 - - def install_gem_from_spec(spec, standalone = false) - retries = 1 - # Download the gem to get the spec, because some specs that are returned - # by rubygems.org are broken and wrong. - Bundler::Fetcher.fetch(spec) if spec.source.is_a?(Bundler::Source::Rubygems) - - # Fetch the build settings, if there are any - settings = Bundler.settings["build.#{spec.name}"] - Bundler.rubygems.with_build_args [settings] do - spec.source.install(spec) - Bundler.ui.debug "from #{spec.loaded_from} " - end - - # newline comes after installing, some gems say "with native extensions" - Bundler.ui.info "" - if Bundler.settings[:bin] && standalone - generate_standalone_bundler_executable_stubs(spec) - elsif Bundler.settings[:bin] - generate_bundler_executable_stubs(spec, :force => true) - end - - FileUtils.rm_rf(Bundler.tmp) - rescue Gem::RemoteFetcher::FetchError => e - if retries <= MAX_RETRIES - Bundler.ui.warn "#{e.class}: #{e.message}" - Bundler.ui.warn "Installing #{spec.name} (#{spec.version}) failed." - Bundler.ui.warn "Retrying (#{retries}/#{MAX_RETRIES})" - retries += 1 - sleep retries - retry - else - Bundler.ui.warn "Installing #{spec.name} (#{spec.version}) failed after #{retries} retries: #{e.message}." - Bundler.ui.warn "Giving up" - msg = "An error, most likely because of network issues, has occurred trying to install #{spec.name} (#{spec.version}), " - msg << "and Bundler cannot continue." - raise Bundler::InstallError, msg - end - rescue Exception => e - # install hook failed - raise e if e.is_a?(Bundler::InstallHookError) || e.is_a?(Bundler::SecurityError) - - # other failure, likely a native extension build failure - Bundler.ui.info "" - Bundler.ui.warn "#{e.class}: #{e.message}" - msg = "An error occurred while installing #{spec.name} (#{spec.version})," - msg << " and Bundler cannot continue.\nMake sure that `gem install" - msg << " #{spec.name} -v '#{spec.version}'` succeeds before bundling." - Bundler.ui.debug e.backtrace.join("\n") - raise Bundler::InstallError, msg - end - end -end diff --git a/NOTES.txt b/NOTES.txt index 577dc5a8..1b2fc3b7 100644 --- a/NOTES.txt +++ b/NOTES.txt @@ -10,7 +10,7 @@ # Handlebars -* Can't {{bindAttr}} be just {{attr}}? Who cares it's "bound" in that context? +* Can't {{bind-attr}} be just {{attr}}? Who cares it's "bound" in that context? {{#each}} isn't {{#bindEach}} either. * Why is {{#collection contentBinding="foo"}} not just {{#collection foo}}? diff --git a/assets/scripts/app/app.coffee b/assets/scripts/app/app.coffee index 4e16be6f..3f5adc8e 100644 --- a/assets/scripts/app/app.coffee +++ b/assets/scripts/app/app.coffee @@ -33,7 +33,7 @@ unless window.TravisApplication @slider = new Travis.Slider() @pusher = new Travis.Pusher(Travis.config.pusher_key) if Travis.config.pusher_key - @tailing = new Travis.Tailing() + @tailing = new Travis.Tailing($(window), '#tail', '#log') @set('auth', Travis.Auth.create(app: this, endpoint: Travis.config.api_endpoint)) diff --git a/assets/scripts/app/controllers/build.coffee b/assets/scripts/app/controllers/build.coffee index 2446117b..6e61ab6f 100644 --- a/assets/scripts/app/controllers/build.coffee +++ b/assets/scripts/app/controllers/build.coffee @@ -2,7 +2,6 @@ Travis.BuildController = Ember.Controller.extend needs: ['repo'] repoBinding: 'controllers.repo.repo' commitBinding: 'build.commit' - lineNumberBinding: 'controllers.repo.lineNumber' currentUserBinding: 'controllers.repo.currentUser' tabBinding: 'controllers.repo.tab' @@ -15,11 +14,3 @@ Travis.BuildController = Ember.Controller.extend urlGithubCommit: (-> Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha')) ).property('repo.slug', 'commit.sha') - - urlAuthor: (-> - Travis.Urls.email(@get('commit.authorEmail')) - ).property('commit.authorEmail') - - urlCommitter: (-> - Travis.Urls.email(@get('commit.committerEmail')) - ).property('commit.committerEmail') diff --git a/assets/scripts/app/controllers/job.coffee b/assets/scripts/app/controllers/job.coffee index 417e3eb3..7365d06d 100644 --- a/assets/scripts/app/controllers/job.coffee +++ b/assets/scripts/app/controllers/job.coffee @@ -4,7 +4,6 @@ Travis.JobController = Em.Controller.extend jobBinding: 'controllers.repo.job' repoBinding: 'controllers.repo.repo' commitBinding: 'job.commit' - lineNumberBinding: 'controllers.repo.lineNumber' currentUserBinding: 'controllers.repo.currentUser' tabBinding: 'controllers.repo.tab' @@ -13,11 +12,3 @@ Travis.JobController = Em.Controller.extend urlGithubCommit: (-> Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha')) ).property('repo.slug', 'commit.sha') - - urlAuthor: (-> - Travis.Urls.email(@get('commit.authorEmail')) - ).property('commit.authorEmail') - - urlCommitter: (-> - Travis.Urls.email(@get('commit.committerEmail')) - ).property('commit.committerEmail') diff --git a/assets/scripts/app/helpers/helpers.coffee b/assets/scripts/app/helpers/helpers.coffee index 37791f1a..209f333f 100644 --- a/assets/scripts/app/helpers/helpers.coffee +++ b/assets/scripts/app/helpers/helpers.coffee @@ -75,19 +75,28 @@ require 'config/emoij' self._githubReferenceLink(reference, { owner: owner, repo: repo }, { owner: matchedOwner, repo: matchedRepo, number: matchedNumber } ) text = text.replace @_githubUserRegexp, (reference, username) -> self._githubUserLink(reference, username) + text = text.replace @_githubCommitReferenceRegexp, (reference, matchedOwner, matchedRepo, matchedSHA) -> + self._githubCommitReferenceLink(reference, { owner: owner, repo: repo }, { owner: matchedOwner, repo: matchedRepo, sha: matchedSHA }) text + _githubReferenceRegexp: new RegExp("([\\w-]+)?\\/?([\\w-]+)?(?:#|gh-)(\\d+)", 'g') + _githubReferenceLink: (reference, current, matched) -> owner = matched.owner || current.owner repo = matched.repo || current.repo - "#{reference}" - - _githubReferenceRegexp: new RegExp("([\\w-]+)?\\/?([\\w-]+)?(?:#|gh-)(\\d+)", 'g') + "#{reference}" _githubUserRegexp: new RegExp("\\B@([\\w-]+)", 'g') _githubUserLink: (reference, username) -> - "#{reference}" + "#{reference}" + + _githubCommitReferenceRegexp: new RegExp("([\\w-]+)?\\/([\\w-]+)?@([0-9A-Fa-f]+)", 'g') + + _githubCommitReferenceLink: (reference, current, matched) -> + owner = matched.owner || current.owner + repo = matched.repo || current.repo + "#{reference}" _normalizeDateString: (string) -> if window.JHW diff --git a/assets/scripts/app/helpers/urls.coffee b/assets/scripts/app/helpers/urls.coffee index 8af4d14e..17b75597 100644 --- a/assets/scripts/app/helpers/urls.coffee +++ b/assets/scripts/app/helpers/urls.coffee @@ -3,22 +3,22 @@ "#{Travis.config.api_endpoint}/jobs/#{id}/log.txt?deansi=true" githubPullRequest: (slug, pullRequestNumber) -> - "http://github.com/#{slug}/pull/#{pullRequestNumber}" + "https://github.com/#{slug}/pull/#{pullRequestNumber}" githubCommit: (slug, sha) -> - "http://github.com/#{slug}/commit/#{sha}" + "https://github.com/#{slug}/commit/#{sha}" githubRepo: (slug) -> - "http://github.com/#{slug}" + "https://github.com/#{slug}" githubWatchers: (slug) -> - "http://github.com/#{slug}/watchers" + "https://github.com/#{slug}/watchers" githubNetwork: (slug) -> - "http://github.com/#{slug}/network" + "https://github.com/#{slug}/network" githubAdmin: (slug) -> - "http://github.com/#{slug}/settings/hooks#travis_minibucket" + "https://github.com/#{slug}/settings/hooks#travis_minibucket" statusImage: (slug, branch) -> "#{location.protocol}//#{location.host}/#{slug}.png" + if branch then "?branch=#{branch}" else '' diff --git a/assets/scripts/app/models/account.coffee b/assets/scripts/app/models/account.coffee index 8fe049b6..03c29f79 100644 --- a/assets/scripts/app/models/account.coffee +++ b/assets/scripts/app/models/account.coffee @@ -7,7 +7,7 @@ require 'travis/model' _reposCount: Ember.attr(Number, key: 'repos_count') urlGithub: (-> - "http://github.com/#{@get('login')}" + "https://github.com/#{@get('login')}" ).property() # TODO: maybe it would be good to add a "default" value for Ember.attr diff --git a/assets/scripts/app/models/build.coffee b/assets/scripts/app/models/build.coffee index 779f7ad1..667daee9 100644 --- a/assets/scripts/app/models/build.coffee +++ b/assets/scripts/app/models/build.coffee @@ -45,7 +45,7 @@ require 'travis/model' ).property('jobs.@each.allowFailure') rawConfigKeys: (-> - keys = Travis.Helpers.configKeys(@get('config')) + keys = [] @get('jobs').forEach (job) -> Travis.Helpers.configKeys(job.get('config')).forEach (key) -> diff --git a/assets/scripts/app/models/hook.coffee b/assets/scripts/app/models/hook.coffee index 58fff636..4126292b 100644 --- a/assets/scripts/app/models/hook.coffee +++ b/assets/scripts/app/models/hook.coffee @@ -16,11 +16,11 @@ require 'travis/model' ).property('ownerName', 'name') urlGithub: (-> - "http://github.com/#{@get('slug')}" + "https://github.com/#{@get('slug')}" ).property() urlGithubAdmin: (-> - "http://github.com/#{@get('slug')}/settings/hooks#travis_minibucket" + "https://github.com/#{@get('slug')}/settings/hooks#travis_minibucket" ).property() toggle: -> diff --git a/assets/scripts/app/routes.coffee b/assets/scripts/app/routes.coffee index 06a20676..97f175a1 100644 --- a/assets/scripts/app/routes.coffee +++ b/assets/scripts/app/routes.coffee @@ -1,5 +1,4 @@ require 'travis/location' -require 'travis/line_number_parser' Ember.Router.reopen location: (if testMode? then Ember.NoneLocation.create() else Travis.Location.create()) @@ -60,7 +59,6 @@ Ember.Route.reopen if !@signedIn() && @get('needsAuth') Travis.auth.set('afterSignInTransition', transition) - transition.abort() Ember.RSVP.reject("needs-auth") else @_super.apply(this, arguments) @@ -116,12 +114,6 @@ Travis.Router.map -> @route 'index', path: '/' @route 'profile', path: '/profile' -Travis.ApplicationRoute = Ember.Route.extend Travis.LineNumberParser, - setupController: -> - @_super.apply this, arguments - - this.controllerFor('repo').set('lineNumber', @fetchLineNumber()) - Travis.SetupLastBuild = Ember.Mixin.create setupController: -> @repoDidLoad() diff --git a/assets/scripts/app/tailing.coffee b/assets/scripts/app/tailing.coffee index 276b18c7..3df8c872 100644 --- a/assets/scripts/app/tailing.coffee +++ b/assets/scripts/app/tailing.coffee @@ -1,12 +1,17 @@ -@Travis.Tailing = -> - @position = $(window).scrollTop() - $(window).scroll( $.throttle( 200, @onScroll.bind(this) ) ) - this - -$.extend Travis.Tailing.prototype, +class @Travis.Tailing options: timeout: 200 + tail: -> + $(@tail_selector) + log: -> + $(@log_selector) + + constructor: (@window, @tail_selector, @log_selector) -> + @position = @window.scrollTop() + @window.scroll( $.throttle( 200, @onScroll.bind(this) ) ) + this + run: -> @autoScroll() @positionButton() @@ -16,38 +21,43 @@ $.extend Travis.Tailing.prototype, if @active() then @stop() else @start() active: -> - $('#tail').hasClass('active') + @tail().hasClass('active') start: -> - $('#tail').addClass('active') + @tail().addClass('active') @run() stop: -> - $('#tail').removeClass('active') + @tail().removeClass('active') autoScroll: -> - return unless @active() - win = $(window) - log = $('#log') - logBottom = log.offset().top + log.outerHeight() + 40 - winBottom = win.scrollTop() + win.height() - win.scrollTop(logBottom - win.height()) if logBottom - winBottom > 0 + return false unless @active() + logBottom = @log().offset().top + @log().outerHeight() + 40 + winBottom = @window.scrollTop() + @window.height() + + if logBottom - winBottom > 0 + @window.scrollTop(logBottom - @window.height()) + true + else + false onScroll: -> @positionButton() - position = $(window).scrollTop() + position = @window.scrollTop() @stop() if position < @position @position = position positionButton: -> - tail = $('#tail') - return if tail.length is 0 - offset = $(window).scrollTop() - $('#log').offset().top - max = $('#log').height() - $('#tail').height() + 5 - offset = max if offset > max + return if @tail().length is 0 + offset = @window.scrollTop() - @log().offset().top + max = @log().height() - @tail().height() + 5 - if offset > 0 - tail.css(position: 'fixed', right: 32) + if offset > 0 && offset <= max + @tail().removeClass('bottom') + @tail().addClass('scrolling') else - tail.css(position: 'absolute', right: 2) - + if offset > max + @tail().addClass('bottom') + else + @tail().removeClass('bottom') + @tail().removeClass('scrolling') diff --git a/assets/scripts/app/templates/builds/list.hbs b/assets/scripts/app/templates/builds/list.hbs index 9e1baff4..5d73ca69 100644 --- a/assets/scripts/app/templates/builds/list.hbs +++ b/assets/scripts/app/templates/builds/list.hbs @@ -26,16 +26,16 @@
{{t builds.messages.sponsored_by}} - {{sponsor.name}} + {{sponsor.name}}
{{/if}} {{#if view.limited}}This log is too long to be displayed. Please reduce the verbosity of your - build or download the the raw log. + build or download the the raw log.
{{/if}} diff --git a/assets/scripts/app/templates/jobs/show.hbs b/assets/scripts/app/templates/jobs/show.hbs index ebee6825..0d3bd35e 100644 --- a/assets/scripts/app/templates/jobs/show.hbs +++ b/assets/scripts/app/templates/jobs/show.hbs @@ -1,5 +1,5 @@ {{#if job.isLoaded}} -Repositories: {{view.account.reposCount}} diff --git a/assets/scripts/app/templates/profile/tabs.hbs b/assets/scripts/app/templates/profile/tabs.hbs index 8f770575..6afb10c8 100644 --- a/assets/scripts/app/templates/profile/tabs.hbs +++ b/assets/scripts/app/templates/profile/tabs.hbs @@ -1,17 +1,17 @@
{{hook.description}}
@@ -54,8 +54,8 @@{{hook.description}}
- {{t repositories.duration}}: - {{formatDuration lastBuildDuration}} + {{t repositories.duration}}: + {{formatDuration lastBuildDuration}}
{{t repositories.finished_at}}: - {{formatTime lastBuildFinishedAt}} + {{formatTime lastBuildFinishedAt}}
Integrating Code Climate's test coverage reporting with your test suite on Travis CI allows to track changes in coverage over time. If you haven't tried it out already, sign - up today for to improve your code's quality. New customers get 20% off for the first three months! + {{bind-attr href="Travis.config.code_climate_url"}}" target="_blank">sign + up today to improve your code's quality. New customers get 20% off for the first three months!
diff --git a/assets/scripts/app/templates/status_images.hbs b/assets/scripts/app/templates/status_images.hbs index f5dc5c0a..0f832f2b 100644 --- a/assets/scripts/app/templates/status_images.hbs +++ b/assets/scripts/app/templates/status_images.hbs @@ -9,25 +9,25 @@
- +
- +
- +
- +
- +
- +
diff --git a/assets/scripts/app/templates/workers/list.hbs b/assets/scripts/app/templates/workers/list.hbs index 6f41d33e..a9387fe9 100644 --- a/assets/scripts/app/templates/workers/list.hbs +++ b/assets/scripts/app/templates/workers/list.hbs @@ -14,9 +14,9 @@ {{#if worker.isWorking}} {{#if worker.jobId}} - {{#linkTo "job" worker.repo worker.jobId}} + {{#link-to "job" worker.repo worker.jobId}} {{view.display}} - {{/linkTo}} + {{/link-to}} {{/if}} {{else}} {{view.display}} diff --git a/assets/scripts/app/views/job.coffee b/assets/scripts/app/views/job.coffee index 9027ebf7..1edaf375 100644 --- a/assets/scripts/app/views/job.coffee +++ b/assets/scripts/app/views/job.coffee @@ -29,11 +29,3 @@ Travis.reopen urlGithubCommit: (-> Travis.Urls.githubCommit(@get('repo.slug'), @get('commit.sha')) ).property('repo.slug', 'commit.sha') - - urlAuthor: (-> - Travis.Urls.email(@get('commit.authorEmail')) - ).property('commit.authorEmail') - - urlCommitter: (-> - Travis.Urls.email(@get('commit.committerEmail')) - ).property('commit.committerEmail') diff --git a/assets/scripts/app/views/log.coffee b/assets/scripts/app/views/log.coffee index 2bacdfe2..631765b3 100644 --- a/assets/scripts/app/views/log.coffee +++ b/assets/scripts/app/views/log.coffee @@ -1,4 +1,5 @@ require 'log' +require 'travis/lines_selector' Log.DEBUG = false Log.LIMIT = 10000 @@ -26,12 +27,12 @@ Travis.reopen console.log 'log view: did insert' if Log.DEBUG @_super.apply this, arguments @createEngine() - @lineNumberDidChange() willDestroyElement: -> console.log 'log view: will destroy' if Log.DEBUG parts = @get('log.parts') parts.removeArrayObserver(@, didChange: 'partsDidChange', willChange: 'noop') + @lineSelector?.willDestroy() versionDidChange: (-> @rerender() if @get('state') == 'inDOM' @@ -46,8 +47,8 @@ Travis.reopen console.log 'log view: create engine' if Log.DEBUG @scroll = new Log.Scroll @engine = Log.create(limit: Log.LIMIT, listeners: [@scroll]) + @lineSelector = new Travis.LinesSelector(@$().find('#log'), @scroll, window.location) @observeParts() - @numberLineOnHover() observeParts: -> parts = @get('log.parts') @@ -63,10 +64,6 @@ Travis.reopen @engine.set(part.number, part.content) @propertyDidChange('limited') - lineNumberDidChange: (-> - @scroll.set(number) if !@get('isDestroyed') && number = @get('controller.lineNumber') - ).observes('controller.lineNumber') - limited: (-> @engine?.limit?.limited ).property() @@ -79,24 +76,11 @@ Travis.reopen Travis.tailing.toggle() event.preventDefault() - numberLineOnHover: -> - $('#log').on 'mouseenter', 'a', -> - $(@).attr('href', '#L' + ($("#log p:visible").index(@parentNode) + 1)) - click: (event) -> - if (href = $(event.target).attr('href')) && matches = href?.match(/#L(\d+)$/) - @lineNumberClicked(matches[1]) - event.stopPropagation() - false - else - target = $(event.target) + target = $(event.target) + if target.prop('tagName') == 'P' target.closest('.fold').toggleClass('open') - lineNumberClicked: (number) -> - path = "#{window.location.pathname}#L#{number}" - window.history.pushState({ path: path }, null, path); - @set('controller.lineNumber', number) - actions: toTop: () -> $(window).scrollTop(0) @@ -105,25 +89,14 @@ Travis.reopen Log.Scroll = -> Log.Scroll.prototype = $.extend new Log.Listener, - set: (number) -> - return unless number - @number = number - @tryScroll() - insert: (log, data, pos) -> - @tryScroll() if @number + @tryScroll() if @numbers true tryScroll: -> - if element = $("#log p:visible")[@number - 1] + if element = $("#log p:visible.highlight:first") $('#main').scrollTop(0) - $('html, body').scrollTop($(element).offset()?.top) # weird, html works in chrome, body in firefox - @highlight(element) - @number = undefined - - highlight: (element) -> - $('#log p.highlight').removeClass('highlight') - $(element).addClass('highlight') + $('html, body').scrollTop(element.offset()?.top) # weird, html works in chrome, body in firefox # Log.Logger = -> # Log.Logger.prototype = $.extend new Log.Listener, diff --git a/assets/scripts/app/views/repo/show.coffee b/assets/scripts/app/views/repo/show.coffee index 1d008c24..95e6dc4f 100644 --- a/assets/scripts/app/views/repo/show.coffee +++ b/assets/scripts/app/views/repo/show.coffee @@ -37,7 +37,7 @@ Travis.reopen tabBinding: 'controller.tab' contextBinding: 'controller' - # hrm. how to parametrize bindAttr? + # hrm. how to parametrize bind-attr? classCurrent: (-> 'active' if @get('tab') == 'current' ).property('tab') diff --git a/assets/scripts/app/views/top.coffee b/assets/scripts/app/views/top.coffee index ac9e8d24..fe5d7aea 100644 --- a/assets/scripts/app/views/top.coffee +++ b/assets/scripts/app/views/top.coffee @@ -4,7 +4,7 @@ tabBinding: 'controller.tab' - # hrm. how to parametrize bindAttr? + # hrm. how to parametrize bind-attr? classHome: (-> 'active' if @get('tab') == 'home' ).property('tab') diff --git a/assets/scripts/lib/travis/line_number_parser.coffee b/assets/scripts/lib/travis/line_number_parser.coffee deleted file mode 100644 index 2abd54df..00000000 --- a/assets/scripts/lib/travis/line_number_parser.coffee +++ /dev/null @@ -1,3 +0,0 @@ -Travis.LineNumberParser = Ember.Mixin.create - fetchLineNumber: -> - match[1] if match = document.location.hash.match(/#L(\d+)$/) diff --git a/assets/scripts/lib/travis/lines_selector.coffee b/assets/scripts/lib/travis/lines_selector.coffee new file mode 100644 index 00000000..e49a456e --- /dev/null +++ b/assets/scripts/lib/travis/lines_selector.coffee @@ -0,0 +1,55 @@ +class Travis.LinesSelector + element: null + scroll: null + location: null + last_selected_line: null + + constructor: (@element, @scroll, @location) -> + Ember.run.scheduleOnce 'afterRender', this, -> + @last_selected_line = @getSelectedLines()?.first + @highlightLines() + + @element.on 'click', 'a', (event) => + element = $(event.target).parent('p') + @loadLineNumbers(element, event.shiftKey) + + event.preventDefault() + false + + willDestroy: -> + @location.hash = '' + + loadLineNumbers: (element, multiple) -> + @setHashValueWithLine(element, multiple) + @highlightLines() + + highlightLines: -> + @removeAllHighlights() + + if lines = @getSelectedLines() + @element.find('p:visible').slice(lines.first - 1, lines.last).addClass('highlight') + @scroll.tryScroll() + + setHashValueWithLine: (line, multiple) -> + line_number = @getLineNumberFromElement(line) + + if multiple && @last_selected_line? + lines = [line_number, @last_selected_line].sort (a,b) -> a - b + hash = "#L#{lines[0]}-L#{lines[1]}" + else + hash = "#L#{line_number}" + + @last_selected_line = line_number + @location.hash = hash + + getLineNumberFromElement: (element) -> + @element.find('p:visible').index(element) + 1 + + removeAllHighlights: -> + @element.find('p.highlight').removeClass('highlight') + + getSelectedLines: -> + if match = @location.hash.match(/#L(\d+)(-L(\d+))?$/) + first = match[1] + last = match[3] || match[1] + {first: first, last: last} diff --git a/assets/scripts/spec/integration/build_spec.coffee b/assets/scripts/spec/integration/build_spec.coffee index a8fd4d11..69f5ce14 100644 --- a/assets/scripts/spec/integration/build_spec.coffee +++ b/assets/scripts/spec/integration/build_spec.coffee @@ -66,7 +66,7 @@ test "updating current build", -> state: 'started' config: {} pull_request: false - compare_url: 'http://github.com/compare/0123456..1234567' + compare_url: 'https://github.com/compare/0123456..1234567' repository: id: 1 last_build_number: '3' diff --git a/assets/scripts/spec/support/expectations.coffee b/assets/scripts/spec/support/expectations.coffee index f16de344..0e3aa4f1 100644 --- a/assets/scripts/spec/support/expectations.coffee +++ b/assets/scripts/spec/support/expectations.coffee @@ -1,6 +1,6 @@ @displaysRepository = (repo) -> equal($('#repo h3 a').attr('href'), repo.href, 'repository title should link to repo page') - equal($('#repo .github-icon a').attr('href'), "http://github.com#{repo.href}", 'github icon should link to repo on github') + equal($('#repo .github-icon a').attr('href'), "https://github.com#{repo.href}", 'github icon should link to repo on github') @displaysTabs = (tabs) -> for name, tab of tabs @@ -27,13 +27,13 @@ equal(element.text(), data.duration) element = $('#summary .commit a') - equal(element.attr('href'), "http://github.com/#{data.repo}/commit/#{data.commit}") + equal(element.attr('href'), "https://github.com/#{data.repo}/commit/#{data.commit}") element = $('#summary .commit a') equal(element.text(), "#{data.commit} (#{data.branch})") element = $('#summary .compare a') - equal(element.attr('href'), "http://github.com/compare/#{data.compare}") + equal(element.attr('href'), "https://github.com/compare/#{data.compare}") element = $('#summary .compare a') equal(element.text(), data.compare) diff --git a/assets/scripts/spec/support/mocks.coffee b/assets/scripts/spec/support/mocks.coffee index 76f3b655..e4786764 100644 --- a/assets/scripts/spec/support/mocks.coffee +++ b/assets/scripts/spec/support/mocks.coffee @@ -24,10 +24,10 @@ builds = [ ] 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: 'https://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: 'https://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: 'https://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: 'https://github.com/compare/0123456..4567890' }, ] jobs = [ diff --git a/assets/scripts/spec/unit/helpers_spec.coffee b/assets/scripts/spec/unit/helpers_spec.coffee index fe049984..45781f20 100644 --- a/assets/scripts/spec/unit/helpers_spec.coffee +++ b/assets/scripts/spec/unit/helpers_spec.coffee @@ -3,53 +3,53 @@ module "Travis.Helpers.githubify" test 'replaces #Num with github issues link', -> message = 'Solved #11hey' result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') - expected = 'Solved #11hey' + expected = 'Solved #11hey' equal(result, expected, "#num should be converted to a link") test 'replaces User#Num with github issues link to forked repo', -> message = 'Solved test#11hey' result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') - expected = 'Solved test#11hey' + expected = 'Solved test#11hey' equal(result, expected, "user#num should be converted to a link") test 'replaces User/Project#Num with github issues link to another repo', -> message = 'Solved test_1-a2/test-a_11#11hey' result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') - expected = 'Solved test_1-a2/test-a_11#11hey' + expected = 'Solved test_1-a2/test-a_11#11hey' equal(result, expected, "owner/repo#num should be converted to a link") test 'replaces gh-Num with github issues link', -> message = 'Solved gh-22hey' result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') - expected = 'Solved gh-22hey' + expected = 'Solved gh-22hey' equal(result, expected, "gh-Num should be converted to a link") test 'replaces multiple references with github issues links', -> message = 'Try #1 and test#2 and test/testing#3' result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') - expected = 'Try #1 and ' - expected += 'test#2 and ' - expected += 'test/testing#3' + expected = 'Try #1 and ' + expected += 'test#2 and ' + expected += 'test/testing#3' equal(result, expected, "references should be converted to links") test 'replaces multiple references with github issues links', -> message = 'Try #1 and test#2 and test/testing#3' result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') - expected = 'Try #1 and ' - expected += 'test#2 and ' - expected += 'test/testing#3' + expected = 'Try #1 and ' + expected += 'test#2 and ' + expected += 'test/testing#3' equal(result, expected, "references should be converted to links") test 'replaces @user with github user link', -> message = 'It is for you @tender_love1' result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') - expected = 'It is for you @tender_love1' + expected = 'It is for you @tender_love1' equal(result, expected, "@user should be converted to a link") @@ -58,3 +58,17 @@ test 'does not replace @user if it is a sign-off', -> result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') equal(result, message, "@user should not be converted to a link if it matches an email") + +test 'replaces one commit reference with github commit link', -> + message = 'See travis-ci/travis-core@732fe00' + result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') + expected = 'See travis-ci/travis-core@732fe00' + + equal(result, expected, "Commit reference should be converted to a link") + +test 'replaces multiple commit references with github commit links', -> + message = 'See travis-ci/travis-core@732fe00 and travis-ci/travis-web@3b6aa17' + result = Travis.Helpers.githubify(message, 'travis-ci', 'travis-web') + expected = 'See travis-ci/travis-core@732fe00 and travis-ci/travis-web@3b6aa17' + + equal(result, expected, "Commit references should be converted to links") diff --git a/assets/scripts/spec/unit/line_selector_spec.coffee b/assets/scripts/spec/unit/line_selector_spec.coffee new file mode 100644 index 00000000..cbd4f12b --- /dev/null +++ b/assets/scripts/spec/unit/line_selector_spec.coffee @@ -0,0 +1,92 @@ +fakeLocation = {} +fakeScroll = + tryScroll: sinon.spy() + +element = jQuery('') + +module "Travis.LinesSelector", + setup: -> + fakeLocation.hash = '' + jQuery('body').append(element) + + teardown: -> + element.remove() + +test "defaults to no line selected", -> + Ember.run -> + new Travis.LinesSelector(element, fakeScroll, fakeLocation) + + wait().then -> + equal($('#fakeLog p.highlight').length, 0) + +test "defaults to a single line selected", -> + fakeLocation.hash = '#L2' + Ember.run -> + new Travis.LinesSelector(element, fakeScroll, fakeLocation) + + wait().then -> + equal($('#fakeLog p.highlight').length, 1) + equal($('#fakeLog p:nth-child(2)').hasClass('highlight'), true) + +test "defaults to multiple lines selected", -> + fakeLocation.hash = '#L2-L3' + Ember.run -> + new Travis.LinesSelector(element, fakeScroll, fakeLocation) + + wait().then -> + equal($('#fakeLog p.highlight').length, 2) + equal($('#fakeLog p:nth-child(2)').hasClass('highlight'), true) + equal($('#fakeLog p:nth-child(3)').hasClass('highlight'), true) + +test "selects a single line", -> + Ember.run -> + new Travis.LinesSelector(element, fakeScroll, fakeLocation) + + wait().then -> + equal($('#fakeLog p.highlight').length, 0) + $('#fakeLog p:first a').click() + equal($('#fakeLog p.highlight').length, 1) + equal($('#fakeLog p:nth-child(1)').hasClass('highlight'), true) + equal('#L1', fakeLocation.hash) + +test "selects multiple lines", -> + fakeLocation.hash = '#L2' + Ember.run -> + new Travis.LinesSelector(element, fakeScroll, fakeLocation) + + wait().then -> + equal($('#fakeLog p.highlight').length, 1) + + event = jQuery.Event('click') + event.shiftKey = true + $('#fakeLog p:first a').trigger(event) + + equal($('#fakeLog p.highlight').length, 2) + equal($('#fakeLog p:nth-child(1)').hasClass('highlight'), true) + equal($('#fakeLog p:nth-child(2)').hasClass('highlight'), true) + equal('#L1-L2', fakeLocation.hash) + +test "uses the last selected line as second selection line", -> + selector = null + Ember.run -> + selector = new Travis.LinesSelector(element, fakeScroll, fakeLocation) + + wait().then -> + $('#fakeLog p:last a').click() + equal($('#fakeLog p.highlight').length, 1) + equal(3, selector.last_selected_line) + + event = jQuery.Event('click') + event.shiftKey = true + $('#fakeLog p:first a').trigger(event) + + equal($('#fakeLog p.highlight').length, 3) + equal($('#fakeLog p:nth-child(1)').hasClass('highlight'), true) + equal($('#fakeLog p:nth-child(2)').hasClass('highlight'), true) + equal($('#fakeLog p:nth-child(3)').hasClass('highlight'), true) + equal('#L1-L3', fakeLocation.hash) + equal(1, selector.last_selected_line) diff --git a/assets/scripts/spec/unit/tailing_spec.coffee b/assets/scripts/spec/unit/tailing_spec.coffee new file mode 100644 index 00000000..18a836f0 --- /dev/null +++ b/assets/scripts/spec/unit/tailing_spec.coffee @@ -0,0 +1,89 @@ +fakeWindow = + scroll: sinon.spy() + scrollTop: sinon.stub().returns(0) + height: sinon.stub().returns(40) +element = jQuery('') +log = jQuery('') +tail = new Travis.Tailing(fakeWindow, '#specTail', '#specLog') +tail.tail = -> element +tail.log = -> log + +module "Travis.Tailing", + setup: -> + jQuery('body').append(element) + jQuery('body').append(log) + + teardown: -> + element.remove() + log.remove() + tail.stop() + +test "toggle", -> + equal(element.hasClass('active'), false) + tail.toggle() + equal(element.hasClass('active'), true) + tail.toggle() + stop() + + Ember.run.later -> + start() + equal(element.hasClass('active'), false) + , 300 + +test "active", -> + equal(tail.active(), false) + element.addClass('active') + equal(tail.active(), true) + +test "autoscroll when inactive", -> + tail.scrollTo = sinon.spy() + + equal(tail.active(), false) + equal(tail.autoScroll(), false) + equal(tail.scrollTo.called, false) + +test "autoscroll", -> + element.addClass('active') + log.offset = -> {top: 1} + log.outerHeight = -> 1 + + equal(tail.active(), true) + equal(tail.autoScroll(), true) + equal(fakeWindow.scrollTop.calledWith(2), true) + +test "autoscroll when we're at the bottom", -> + element.addClass('active') + log.offset = -> {top: 0} + log.outerHeight = -> 0 + + equal(tail.active(), true) + equal(tail.autoScroll(), false) + equal(fakeWindow.scrollTop.calledWith(0), false) + +test 'should stop scrolling if the position changed', -> + element.addClass('active') + tail.position = 100 + tail.onScroll() + equal(element.hasClass('active'), false) + +test 'positionButton adds the scrolling class', -> + log.offset = -> {top: -1} + + tail.positionButton() + equal(element.hasClass('scrolling'), true) + equal(element.hasClass('bottom'), false) + +test 'positionButton removes the scrolling class', -> + log.offset = -> {top: 1} + tail.positionButton() + equal(element.hasClass('scrolling'), false) + equal(element.hasClass('bottom'), false) + +test 'positionButton sets the button as bottom', -> + log.offset = -> {top: -100} + log.height = -> 50 + tail.height = -> 1 + + tail.positionButton() + equal(element.hasClass('scrolling'), false) + equal(element.hasClass('bottom'), true) diff --git a/assets/scripts/vendor/ember.js b/assets/scripts/vendor/ember.js index 735ee4b1..dc4bb500 100644 --- a/assets/scripts/vendor/ember.js +++ b/assets/scripts/vendor/ember.js @@ -1,15 +1,14 @@ -// ========================================================================== -// Project: Ember - JavaScript Application Framework -// Copyright: Copyright 2011-2013 Tilde Inc. and contributors -// Portions Copyright 2006-2011 Strobe Inc. -// Portions Copyright 2008-2011 Apple Inc. All rights reserved. -// License: Licensed under MIT license -// See https://raw.github.com/emberjs/ember.js/master/LICENSE -// ========================================================================== +/*! + * @overview Ember - JavaScript Application Framework + * @copyright Copyright 2011-2014 Tilde Inc. and contributors + * Portions Copyright 2006-2011 Strobe Inc. + * Portions Copyright 2008-2011 Apple Inc. All rights reserved. + * @license Licensed under MIT license + * See https://raw.github.com/emberjs/ember.js/master/LICENSE + * @version 1.3.1 + */ - // Version: 1.2.0 - (function() { /*global __fail__*/ @@ -32,7 +31,20 @@ if ('undefined' === typeof Ember) { } } -Ember.ENV = 'undefined' === typeof ENV ? {} : ENV; +// This needs to be kept in sync with the logic in +// `packages/ember-metal/lib/core.js`. +// +// This is duplicated here to ensure that `Ember.ENV` +// is setup even if `Ember` is not loaded yet. +if (Ember.ENV) { + // do nothing if Ember.ENV is already setup +} else if ('undefined' !== typeof EmberENV) { + Ember.ENV = EmberENV; +} else if('undefined' !== typeof ENV) { + Ember.ENV = ENV; +} else { + Ember.ENV = {}; +} if (!('MANDATORY_SETTER' in Ember.ENV)) { Ember.ENV.MANDATORY_SETTER = true; // default to true for debug dist @@ -184,20 +196,19 @@ if (!Ember.testing) { })(); -// ========================================================================== -// Project: Ember - JavaScript Application Framework -// Copyright: Copyright 2011-2013 Tilde Inc. and contributors -// Portions Copyright 2006-2011 Strobe Inc. -// Portions Copyright 2008-2011 Apple Inc. All rights reserved. -// License: Licensed under MIT license -// See https://raw.github.com/emberjs/ember.js/master/LICENSE -// ========================================================================== +/*! + * @overview Ember - JavaScript Application Framework + * @copyright Copyright 2011-2014 Tilde Inc. and contributors + * Portions Copyright 2006-2011 Strobe Inc. + * Portions Copyright 2008-2011 Apple Inc. All rights reserved. + * @license Licensed under MIT license + * See https://raw.github.com/emberjs/ember.js/master/LICENSE + * @version 1.3.1 + */ - // Version: 1.2.0 - (function() { -var define, requireModule; +var define, requireModule, require, requirejs; (function() { var registry = {}, seen = {}; @@ -206,36 +217,52 @@ var define, requireModule; registry[name] = { deps: deps, callback: callback }; }; - requireModule = function(name) { + requirejs = require = requireModule = function(name) { + requirejs._eak_seen = registry; + if (seen[name]) { return seen[name]; } seen[name] = {}; - var mod, deps, callback, reified, exports; - - mod = registry[name]; - - if (!mod) { - throw new Error("Module '" + name + "' not found."); + if (!registry[name]) { + throw new Error("Could not find module " + name); } - deps = mod.deps; - callback = mod.callback; - reified = []; + var mod = registry[name], + deps = mod.deps, + callback = mod.callback, + reified = [], + exports; for (var i=0, l=deps.length; i{{person.signature}}
``` - You can also use `yield` inside a template to - include the **contents** of the custom tag: + You can use `yield` inside a template to + include the **contents** of any block attached to + the component. The block will be executed in the + context of the surrounding context or outer controller: - ```html + ```handlebars {{#app-profile person=currentUser}}Admin mode
+ {{! Executed in the controllers context. }} {{/app-profile}} ``` - ```html + ```handlebars{{user.role.description}}
+{{description}}
+ {{/with}} +{{person.signature}}
+ ``` + + You can use `yield` inside a template to + include the **contents** of any block attached to + the component. The block will be executed in the + context of the surrounding context or outer controller: + + ```handlebars + {{#app-profile person=currentUser}} +Admin mode
+ {{! Executed in the controllers context. }} + {{/app-profile}} + ``` + + ```handlebars + +hi |
{{user.role.description}}
+{{description}}
+ {{/with}} +Howdy Dave
+Howdy Mary
+Howdy Sara
+Sorry, nobody is available for this task.
+ {{/each}} + ``` + ### Specifying a View class for items + If you provide an `itemViewClass` option that references a view class + with its own `template` you can omit the block. + + The following template: + + ```handlebars + {{#view App.MyView }} + {{each view.items itemViewClass="App.AnItemView"}} + {{/view}} + ``` + + And application code + + ```javascript + App = Ember.Application.create({ + MyView: Ember.View.extend({ + items: [ + Ember.Object.create({name: 'Dave'}), + Ember.Object.create({name: 'Mary'}), + Ember.Object.create({name: 'Sara'}) + ] + }) + }); + + App.AnItemView = Ember.View.extend({ + template: Ember.Handlebars.compile("Greetings {{name}}") + }); + ``` + + Will result in the HTML structure below + + ```html +