Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce
This commit is contained in:
commit
2f3a11fed3
10
Gemfile
10
Gemfile
|
@ -253,11 +253,13 @@ group :development, :test do
|
|||
# PhantomJS driver for Capybara
|
||||
gem 'poltergeist', '~> 1.5.1'
|
||||
|
||||
gem 'jasmine-rails'
|
||||
gem 'teaspoon', '~> 1.0.0'
|
||||
gem 'teaspoon-jasmine'
|
||||
|
||||
gem "spring", '~> 1.3.1'
|
||||
gem "spring-commands-rspec", '1.0.4'
|
||||
gem "spring-commands-spinach", '1.0.0'
|
||||
gem 'spring', '~> 1.3.1'
|
||||
gem 'spring-commands-rspec', '~> 1.0.0'
|
||||
gem 'spring-commands-spinach', '~> 1.0.0'
|
||||
gem 'spring-commands-teaspoon', '~> 0.0.2'
|
||||
|
||||
gem "byebug"
|
||||
end
|
||||
|
|
21
Gemfile.lock
21
Gemfile.lock
|
@ -300,12 +300,6 @@ GEM
|
|||
i18n (0.7.0)
|
||||
ice_cube (0.11.1)
|
||||
ice_nine (0.10.0)
|
||||
jasmine-core (2.2.0)
|
||||
jasmine-rails (0.10.8)
|
||||
jasmine-core (>= 1.3, < 3.0)
|
||||
phantomjs (>= 1.9)
|
||||
railties (>= 3.2.0)
|
||||
sprockets-rails
|
||||
jquery-atwho-rails (1.0.1)
|
||||
jquery-rails (3.1.0)
|
||||
railties (>= 3.0, < 5.0)
|
||||
|
@ -400,7 +394,6 @@ GEM
|
|||
parser (2.2.0.2)
|
||||
ast (>= 1.1, < 3.0)
|
||||
pg (0.15.1)
|
||||
phantomjs (1.9.8.0)
|
||||
poltergeist (1.5.1)
|
||||
capybara (~> 2.1)
|
||||
cliver (~> 0.3.1)
|
||||
|
@ -594,6 +587,8 @@ GEM
|
|||
spring (>= 0.9.1)
|
||||
spring-commands-spinach (1.0.0)
|
||||
spring (>= 0.9.1)
|
||||
spring-commands-teaspoon (0.0.2)
|
||||
spring (>= 0.9.1)
|
||||
sprockets (2.11.0)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
|
@ -608,6 +603,10 @@ GEM
|
|||
stringex (2.5.2)
|
||||
task_list (1.0.2)
|
||||
html-pipeline
|
||||
teaspoon (1.0.2)
|
||||
railties (>= 3.2.5, < 5)
|
||||
teaspoon-jasmine (2.2.0)
|
||||
teaspoon (>= 1.0.0)
|
||||
temple (0.6.7)
|
||||
term-ansicolor (1.2.2)
|
||||
tins (~> 0.8)
|
||||
|
@ -737,7 +736,6 @@ DEPENDENCIES
|
|||
hipchat (~> 1.5.0)
|
||||
html-pipeline (~> 1.11.0)
|
||||
httparty
|
||||
jasmine-rails
|
||||
jquery-atwho-rails (~> 1.0.0)
|
||||
jquery-rails
|
||||
jquery-scrollto-rails
|
||||
|
@ -798,11 +796,14 @@ DEPENDENCIES
|
|||
slim
|
||||
spinach-rails
|
||||
spring (~> 1.3.1)
|
||||
spring-commands-rspec (= 1.0.4)
|
||||
spring-commands-spinach (= 1.0.0)
|
||||
spring-commands-rspec (~> 1.0.0)
|
||||
spring-commands-spinach (~> 1.0.0)
|
||||
spring-commands-teaspoon (~> 0.0.2)
|
||||
stamp
|
||||
state_machine
|
||||
task_list (= 1.0.2)
|
||||
teaspoon (~> 1.0.0)
|
||||
teaspoon-jasmine
|
||||
test_after_commit
|
||||
thin
|
||||
tinder (~> 1.9.2)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#= require jquery
|
||||
#= require jquery.waitforimages
|
||||
#= require task_list
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#= require jquery
|
||||
#= require bootstrap
|
||||
#= require jquery.waitforimages
|
||||
#= require task_list
|
||||
|
||||
class @MergeRequest
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#= require jquery
|
||||
#= require autosave
|
||||
#= require bootstrap
|
||||
#= require dropzone
|
||||
#= require dropzone_input
|
||||
#= require gfm_auto_complete
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#= require jquery
|
||||
#= require mousetrap
|
||||
|
||||
#= require shortcuts_navigation
|
||||
|
||||
class @ShortcutsIssuable extends ShortcutsNavigation
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#= require d3
|
||||
#= require jquery
|
||||
#= require stat_graph_contributors_util
|
||||
|
||||
class @ContributorsStatGraph
|
||||
|
|
|
@ -3,7 +3,8 @@ if Rails.env.development?
|
|||
|
||||
# initialization is skipped so trigger it
|
||||
Rack::MiniProfilerRails.initialize!(Rails.application)
|
||||
|
||||
Rack::MiniProfiler.config.position = 'right'
|
||||
Rack::MiniProfiler.config.start_hidden = true
|
||||
Rack::MiniProfiler.config.skip_paths << '/specs'
|
||||
Rack::MiniProfiler.config.skip_paths << '/teaspoon'
|
||||
end
|
||||
|
|
|
@ -2,7 +2,6 @@ require 'sidekiq/web'
|
|||
require 'api/api'
|
||||
|
||||
Gitlab::Application.routes.draw do
|
||||
mount JasmineRails::Engine => '/specs' if defined?(JasmineRails)
|
||||
use_doorkeeper do
|
||||
controllers applications: 'oauth/applications',
|
||||
authorized_applications: 'oauth/authorized_applications',
|
||||
|
|
|
@ -7,6 +7,6 @@ task jasmine: ['jasmine:ci']
|
|||
|
||||
namespace :jasmine do
|
||||
task :ci do
|
||||
Rake::Task['spec:javascript'].invoke
|
||||
Rake::Task['teaspoon'].invoke
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
%form.js-main-target-form
|
||||
%textarea#note_note
|
|
@ -0,0 +1,12 @@
|
|||
%ul
|
||||
%li.note
|
||||
.js-task-list-container
|
||||
.note-text
|
||||
%ul.task-list
|
||||
%li.task-list-item
|
||||
%input.task-list-item-checkbox{type: 'checkbox'}
|
||||
Task List Item
|
||||
.note-edit-form
|
||||
%form
|
||||
%textarea.js-task-list-field
|
||||
\- [ ] Task List Item
|
|
@ -0,0 +1,13 @@
|
|||
%a.btn-close
|
||||
|
||||
.issue-details
|
||||
.description.js-task-list-container
|
||||
.wiki
|
||||
%ul.task-list
|
||||
%li.task-list-item
|
||||
%input.task-list-item-checkbox{type: 'checkbox'}
|
||||
Task List Item
|
||||
%textarea.js-task-list-field
|
||||
\- [ ] Task List Item
|
||||
|
||||
%form.js-issue-update{action: '/foo'}
|
|
@ -0,0 +1,13 @@
|
|||
%a.btn-close
|
||||
|
||||
.merge-request-details
|
||||
.description.js-task-list-container
|
||||
.wiki
|
||||
%ul.task-list
|
||||
%li.task-list-item
|
||||
%input.task-list-item-checkbox{type: 'checkbox'}
|
||||
Task List Item
|
||||
%textarea.js-task-list-field
|
||||
\- [ ] Task List Item
|
||||
|
||||
%form.js-merge-request-update{action: '/foo'}
|
|
@ -1,34 +1,20 @@
|
|||
#= require jquery
|
||||
#= require jasmine-fixture
|
||||
#= require issue
|
||||
|
||||
describe 'Issue', ->
|
||||
describe 'task lists', ->
|
||||
selectors = {
|
||||
container: '.issue-details .description.js-task-list-container'
|
||||
item: '.wiki ul.task-list li.task-list-item input.task-list-item-checkbox[type=checkbox] {Task List Item}'
|
||||
textarea: '.wiki textarea.js-task-list-field{- [ ] Task List Item}'
|
||||
form: 'form.js-issue-update[action="/foo"]'
|
||||
close: 'a.btn-close'
|
||||
}
|
||||
fixture.preload('issues_show.html')
|
||||
|
||||
beforeEach ->
|
||||
$container = affix(selectors.container)
|
||||
|
||||
# # These two elements are siblings inside the container
|
||||
$container.find('.js-task-list-container').append(affix(selectors.item))
|
||||
$container.find('.js-task-list-container').append(affix(selectors.textarea))
|
||||
|
||||
# Task lists don't get initialized unless this button exists. Not ideal.
|
||||
$container.append(affix(selectors.close))
|
||||
|
||||
# This form is used to get the `update` URL. Not ideal.
|
||||
$container.append(affix(selectors.form))
|
||||
|
||||
fixture.load('issues_show.html')
|
||||
@issue = new Issue()
|
||||
|
||||
it 'modifies the Markdown field', ->
|
||||
spyOn(jQuery, 'ajax').and.stub()
|
||||
$('input[type=checkbox]').attr('checked', true).trigger('change')
|
||||
expect($('.js-task-list-field').val()).toBe('- [x] Task List Item')
|
||||
|
||||
it 'submits an ajax request on tasklist:changed', ->
|
||||
spyOn($, 'ajax').and.callFake (req) ->
|
||||
spyOn(jQuery, 'ajax').and.callFake (req) ->
|
||||
expect(req.type).toBe('PATCH')
|
||||
expect(req.url).toBe('/foo')
|
||||
expect(req.data.issue.description).not.toBe(null)
|
||||
|
|
|
@ -1,34 +1,23 @@
|
|||
#= require jquery
|
||||
#= require jasmine-fixture
|
||||
#= require merge_request
|
||||
|
||||
window.disableButtonIfEmptyField = -> null
|
||||
|
||||
describe 'MergeRequest', ->
|
||||
describe 'task lists', ->
|
||||
selectors = {
|
||||
container: '.merge-request-details .description.js-task-list-container'
|
||||
item: '.wiki ul.task-list li.task-list-item input.task-list-item-checkbox[type=checkbox] {Task List Item}'
|
||||
textarea: '.wiki textarea.js-task-list-field{- [ ] Task List Item}'
|
||||
form: 'form.js-merge-request-update[action="/foo"]'
|
||||
close: 'a.btn-close'
|
||||
}
|
||||
fixture.preload('merge_requests_show.html')
|
||||
|
||||
beforeEach ->
|
||||
$container = affix(selectors.container)
|
||||
|
||||
# # These two elements are siblings inside the container
|
||||
$container.find('.js-task-list-container').append(affix(selectors.item))
|
||||
$container.find('.js-task-list-container').append(affix(selectors.textarea))
|
||||
|
||||
# Task lists don't get initialized unless this button exists. Not ideal.
|
||||
$container.append(affix(selectors.close))
|
||||
|
||||
# This form is used to get the `update` URL. Not ideal.
|
||||
$container.append(affix(selectors.form))
|
||||
|
||||
fixture.load('merge_requests_show.html')
|
||||
@merge = new MergeRequest({})
|
||||
|
||||
it 'modifies the Markdown field', ->
|
||||
spyOn(jQuery, 'ajax').and.stub()
|
||||
|
||||
$('input[type=checkbox]').attr('checked', true).trigger('change')
|
||||
expect($('.js-task-list-field').val()).toBe('- [x] Task List Item')
|
||||
|
||||
it 'submits an ajax request on tasklist:changed', ->
|
||||
spyOn($, 'ajax').and.callFake (req) ->
|
||||
spyOn(jQuery, 'ajax').and.callFake (req) ->
|
||||
expect(req.type).toBe('PATCH')
|
||||
expect(req.url).toBe('/foo')
|
||||
expect(req.data.merge_request.description).not.toBe(null)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#= require jquery
|
||||
#= require jasmine-fixture
|
||||
#= require notes
|
||||
|
||||
window.gon = {}
|
||||
|
@ -7,21 +5,18 @@ window.disableButtonIfEmptyField = -> null
|
|||
|
||||
describe 'Notes', ->
|
||||
describe 'task lists', ->
|
||||
selectors = {
|
||||
container: 'li.note .js-task-list-container'
|
||||
item: '.note-text ul.task-list li.task-list-item input.task-list-item-checkbox[type=checkbox] {Task List Item}'
|
||||
textarea: '.note-edit-form form textarea.js-task-list-field{- [ ] Task List Item}'
|
||||
}
|
||||
fixture.preload('issue_note.html')
|
||||
|
||||
beforeEach ->
|
||||
$container = affix(selectors.container)
|
||||
|
||||
# These two elements are siblings inside the container
|
||||
$container.find('.js-task-list-container').append(affix(selectors.item))
|
||||
$container.find('.js-task-list-container').append(affix(selectors.textarea))
|
||||
fixture.load('issue_note.html')
|
||||
$('form').on 'submit', (e) -> e.preventDefault()
|
||||
|
||||
@notes = new Notes()
|
||||
|
||||
it 'modifies the Markdown field', ->
|
||||
$('input[type=checkbox]').attr('checked', true).trigger('change')
|
||||
expect($('.js-task-list-field').val()).toBe('- [x] Task List Item')
|
||||
|
||||
it 'submits the form on tasklist:changed', ->
|
||||
submitted = false
|
||||
$('form').on 'submit', (e) -> submitted = true; e.preventDefault()
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#= require jquery
|
||||
#= require jasmine-fixture
|
||||
|
||||
#= require shortcuts_issuable
|
||||
|
||||
describe 'ShortcutsIssuable', ->
|
||||
fixture.preload('issuable.html')
|
||||
|
||||
beforeEach ->
|
||||
fixture.load('issuable.html')
|
||||
@shortcut = new ShortcutsIssuable()
|
||||
|
||||
describe '#replyWithSelectedText', ->
|
||||
|
@ -14,7 +14,6 @@ describe 'ShortcutsIssuable', ->
|
|||
|
||||
beforeEach ->
|
||||
@selector = 'form.js-main-target-form textarea#note_note'
|
||||
affix(@selector)
|
||||
|
||||
describe 'with empty selection', ->
|
||||
it 'does nothing', ->
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# Teaspoon includes some support files, but you can use anything from your own
|
||||
# support path too.
|
||||
|
||||
# require support/jasmine-jquery-1.7.0
|
||||
# require support/jasmine-jquery-2.0.0
|
||||
# require support/jasmine-jquery-2.1.0
|
||||
# require support/sinon
|
||||
# require support/your-support-file
|
||||
|
||||
# PhantomJS (Teaspoons default driver) doesn't have support for
|
||||
# Function.prototype.bind, which has caused confusion. Use this polyfill to
|
||||
# avoid the confusion.
|
||||
|
||||
#= require support/bind-poly
|
||||
|
||||
# You can require your own javascript files here. By default this will include
|
||||
# everything in application, however you may get better load performance if you
|
||||
# require the specific files that are being used in the spec that tests them.
|
||||
|
||||
#= require jquery
|
||||
#= require bootstrap
|
||||
#= require underscore
|
||||
|
||||
# Deferring execution
|
||||
|
||||
# If you're using CommonJS, RequireJS or some other asynchronous library you can
|
||||
# defer execution. Call Teaspoon.execute() after everything has been loaded.
|
||||
# Simple example of a timeout:
|
||||
|
||||
# Teaspoon.defer = true
|
||||
# setTimeout(Teaspoon.execute, 1000)
|
||||
|
||||
# Matching files
|
||||
|
||||
# By default Teaspoon will look for files that match
|
||||
# _spec.{js,js.coffee,.coffee}. Add a filename_spec.js file in your spec path
|
||||
# and it'll be included in the default suite automatically. If you want to
|
||||
# customize suites, check out the configuration in teaspoon_env.rb
|
||||
|
||||
# Manifest
|
||||
|
||||
# If you'd rather require your spec files manually (to control order for
|
||||
# instance) you can disable the suite matcher in the configuration and use this
|
||||
# file as a manifest.
|
||||
|
||||
# For more information: http://github.com/modeset/teaspoon
|
|
@ -1,15 +0,0 @@
|
|||
# path to parent directory of spec_files
|
||||
# relative path from Rails.root
|
||||
#
|
||||
# Alternatively accept an array of directory to include external spec files
|
||||
# spec_dir:
|
||||
# - spec/javascripts
|
||||
# - ../engine/spec/javascripts
|
||||
#
|
||||
# defaults to spec/javascripts
|
||||
spec_dir: spec/javascripts
|
||||
|
||||
# list of file expressions to include as specs into spec runner
|
||||
# relative path from spec_dir
|
||||
spec_files:
|
||||
- "**/*[Ss]pec.{js.coffee,js,coffee}"
|
|
@ -1,15 +0,0 @@
|
|||
#Use this file to set/override Jasmine configuration options
|
||||
#You can remove it if you don't need it.
|
||||
#This file is loaded *after* jasmine.yml is interpreted.
|
||||
#
|
||||
#Example: using a different boot file.
|
||||
#Jasmine.configure do |config|
|
||||
# config.boot_dir = '/absolute/path/to/boot_dir'
|
||||
# config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] }
|
||||
#end
|
||||
#
|
||||
#Example: prevent PhantomJS auto install, uses PhantomJS already on your path.
|
||||
#Jasmine.configure do |config|
|
||||
# config.prevent_phantom_js_auto_install = true
|
||||
#end
|
||||
#
|
|
@ -0,0 +1,178 @@
|
|||
Teaspoon.configure do |config|
|
||||
# Determines where the Teaspoon routes will be mounted. Changing this to "/jasmine" would allow you to browse to
|
||||
# `http://localhost:3000/jasmine` to run your tests.
|
||||
config.mount_at = "/teaspoon"
|
||||
|
||||
# Specifies the root where Teaspoon will look for files. If you're testing an engine using a dummy application it can
|
||||
# be useful to set this to your engines root (e.g. `Teaspoon::Engine.root`).
|
||||
# Note: Defaults to `Rails.root` if nil.
|
||||
config.root = nil
|
||||
|
||||
# Paths that will be appended to the Rails assets paths
|
||||
# Note: Relative to `config.root`.
|
||||
config.asset_paths = ["spec/javascripts", "spec/javascripts/stylesheets"]
|
||||
|
||||
# Fixtures are rendered through a controller, which allows using HAML, RABL/JBuilder, etc. Files in these paths will
|
||||
# be rendered as fixtures.
|
||||
config.fixture_paths = ["spec/javascripts/fixtures"]
|
||||
|
||||
# SUITES
|
||||
#
|
||||
# You can modify the default suite configuration and create new suites here. Suites are isolated from one another.
|
||||
#
|
||||
# When defining a suite you can provide a name and a block. If the name is left blank, :default is assumed. You can
|
||||
# omit various directives and the ones defined in the default suite will be used.
|
||||
#
|
||||
# To run a specific suite
|
||||
# - in the browser: http://localhost/teaspoon/[suite_name]
|
||||
# - with the rake task: rake teaspoon suite=[suite_name]
|
||||
# - with the cli: teaspoon --suite=[suite_name]
|
||||
config.suite do |suite|
|
||||
# Specify the framework you would like to use. This allows you to select versions, and will do some basic setup for
|
||||
# you -- which you can override with the directives below. This should be specified first, as it can override other
|
||||
# directives.
|
||||
# Note: If no version is specified, the latest is assumed.
|
||||
#
|
||||
# Versions: 1.3.1, 2.0.3, 2.1.3, 2.2.0
|
||||
suite.use_framework :jasmine, "2.2.0"
|
||||
|
||||
# Specify a file matcher as a regular expression and all matching files will be loaded when the suite is run. These
|
||||
# files need to be within an asset path. You can add asset paths using the `config.asset_paths`.
|
||||
suite.matcher = "{spec/javascripts,app/assets}/**/*_spec.{js,js.coffee,coffee}"
|
||||
|
||||
# Load additional JS files, but requiring them in your spec helper is the preferred way to do this.
|
||||
#suite.javascripts = []
|
||||
|
||||
# You can include your own stylesheets if you want to change how Teaspoon looks.
|
||||
# Note: Spec related CSS can and should be loaded using fixtures.
|
||||
#suite.stylesheets = ["teaspoon"]
|
||||
|
||||
# This suites spec helper, which can require additional support files. This file is loaded before any of your test
|
||||
# files are loaded.
|
||||
suite.helper = "spec_helper"
|
||||
|
||||
# Partial to be rendered in the head tag of the runner. You can use the provided ones or define your own by creating
|
||||
# a `_boot.html.erb` in your fixtures path, and adjust the config to `"/boot"` for instance.
|
||||
#
|
||||
# Available: boot, boot_require_js
|
||||
suite.boot_partial = "boot"
|
||||
|
||||
# Partial to be rendered in the body tag of the runner. You can define your own to create a custom body structure.
|
||||
suite.body_partial = "body"
|
||||
|
||||
# Hooks allow you to use `Teaspoon.hook("fixtures")` before, after, or during your spec run. This will make a
|
||||
# synchronous Ajax request to the server that will call all of the blocks you've defined for that hook name.
|
||||
#suite.hook :fixtures, &proc{}
|
||||
|
||||
# Determine whether specs loaded into the test harness should be embedded as individual script tags or concatenated
|
||||
# into a single file. Similar to Rails' asset `debug: true` and `config.assets.debug = true` options. By default,
|
||||
# Teaspoon expands all assets to provide more valuable stack traces that reference individual source files.
|
||||
#suite.expand_assets = true
|
||||
end
|
||||
|
||||
# Example suite. Since we're just filtering to files already within the root test/javascripts, these files will also
|
||||
# be run in the default suite -- but can be focused into a more specific suite.
|
||||
#config.suite :targeted do |suite|
|
||||
# suite.matcher = "spec/javascripts/targeted/*_spec.{js,js.coffee,coffee}"
|
||||
#end
|
||||
|
||||
# CONSOLE RUNNER SPECIFIC
|
||||
#
|
||||
# These configuration directives are applicable only when running via the rake task or command line interface. These
|
||||
# directives can be overridden using the command line interface arguments or with ENV variables when using the rake
|
||||
# task.
|
||||
#
|
||||
# Command Line Interface:
|
||||
# teaspoon --driver=phantomjs --server-port=31337 --fail-fast=true --format=junit --suite=my_suite /spec/file_spec.js
|
||||
#
|
||||
# Rake:
|
||||
# teaspoon DRIVER=phantomjs SERVER_PORT=31337 FAIL_FAST=true FORMATTERS=junit suite=my_suite
|
||||
|
||||
# Specify which headless driver to use. Supports PhantomJS and Selenium Webdriver.
|
||||
#
|
||||
# Available: :phantomjs, :selenium, :capybara_webkit
|
||||
# PhantomJS: https://github.com/modeset/teaspoon/wiki/Using-PhantomJS
|
||||
# Selenium Webdriver: https://github.com/modeset/teaspoon/wiki/Using-Selenium-WebDriver
|
||||
# Capybara Webkit: https://github.com/modeset/teaspoon/wiki/Using-Capybara-Webkit
|
||||
#config.driver = :phantomjs
|
||||
|
||||
# Specify additional options for the driver.
|
||||
#
|
||||
# PhantomJS: https://github.com/modeset/teaspoon/wiki/Using-PhantomJS
|
||||
# Selenium Webdriver: https://github.com/modeset/teaspoon/wiki/Using-Selenium-WebDriver
|
||||
# Capybara Webkit: https://github.com/modeset/teaspoon/wiki/Using-Capybara-Webkit
|
||||
#config.driver_options = nil
|
||||
|
||||
# Specify the timeout for the driver. Specs are expected to complete within this time frame or the run will be
|
||||
# considered a failure. This is to avoid issues that can arise where tests stall.
|
||||
#config.driver_timeout = 180
|
||||
|
||||
# Specify a server to use with Rack (e.g. thin, mongrel). If nil is provided Rack::Server is used.
|
||||
#config.server = nil
|
||||
|
||||
# Specify a port to run on a specific port, otherwise Teaspoon will use a random available port.
|
||||
#config.server_port = nil
|
||||
|
||||
# Timeout for starting the server in seconds. If your server is slow to start you may have to bump this, or you may
|
||||
# want to lower this if you know it shouldn't take long to start.
|
||||
#config.server_timeout = 20
|
||||
|
||||
# Force Teaspoon to fail immediately after a failing suite. Can be useful to make Teaspoon fail early if you have
|
||||
# several suites, but in environments like CI this may not be desirable.
|
||||
#config.fail_fast = true
|
||||
|
||||
# Specify the formatters to use when outputting the results.
|
||||
# Note: Output files can be specified by using `"junit>/path/to/output.xml"`.
|
||||
#
|
||||
# Available: :dot, :clean, :documentation, :json, :junit, :pride, :rspec_html, :snowday, :swayze_or_oprah, :tap, :tap_y, :teamcity
|
||||
#config.formatters = [:dot]
|
||||
|
||||
# Specify if you want color output from the formatters.
|
||||
#config.color = true
|
||||
|
||||
# Teaspoon pipes all console[log/debug/error] to $stdout. This is useful to catch places where you've forgotten to
|
||||
# remove them, but in verbose applications this may not be desirable.
|
||||
#config.suppress_log = false
|
||||
|
||||
# COVERAGE REPORTS / THRESHOLD ASSERTIONS
|
||||
#
|
||||
# Coverage reports requires Istanbul (https://github.com/gotwarlost/istanbul) to add instrumentation to your code and
|
||||
# display coverage statistics.
|
||||
#
|
||||
# Coverage configurations are similar to suites. You can define several, and use different ones under different
|
||||
# conditions.
|
||||
#
|
||||
# To run with a specific coverage configuration
|
||||
# - with the rake task: rake teaspoon USE_COVERAGE=[coverage_name]
|
||||
# - with the cli: teaspoon --coverage=[coverage_name]
|
||||
|
||||
# Specify that you always want a coverage configuration to be used. Otherwise, specify that you want coverage
|
||||
# on the CLI.
|
||||
# Set this to "true" or the name of your coverage config.
|
||||
#config.use_coverage = nil
|
||||
|
||||
# You can have multiple coverage configs by passing a name to config.coverage.
|
||||
# e.g. config.coverage :ci do |coverage|
|
||||
# The default coverage config name is :default.
|
||||
config.coverage do |coverage|
|
||||
# Which coverage reports Istanbul should generate. Correlates directly to what Istanbul supports.
|
||||
#
|
||||
# Available: text-summary, text, html, lcov, lcovonly, cobertura, teamcity
|
||||
#coverage.reports = ["text-summary", "html"]
|
||||
|
||||
# The path that the coverage should be written to - when there's an artifact to write to disk.
|
||||
# Note: Relative to `config.root`.
|
||||
#coverage.output_path = "coverage"
|
||||
|
||||
# Assets to be ignored when generating coverage reports. Accepts an array of filenames or regular expressions. The
|
||||
# default excludes assets from vendor, gems and support libraries.
|
||||
#coverage.ignore = [%r{/lib/ruby/gems/}, %r{/vendor/assets/}, %r{/support/}, %r{/(.+)_helper.}]
|
||||
|
||||
# Various thresholds requirements can be defined, and those thresholds will be checked at the end of a run. If any
|
||||
# aren't met the run will fail with a message. Thresholds can be defined as a percentage (0-100), or nil.
|
||||
#coverage.statements = nil
|
||||
#coverage.functions = nil
|
||||
#coverage.branches = nil
|
||||
#coverage.lines = nil
|
||||
end
|
||||
end
|
|
@ -1,433 +0,0 @@
|
|||
/* jasmine-fixture - 1.3.1
|
||||
* Makes injecting HTML snippets into the DOM easy & clean!
|
||||
* https://github.com/searls/jasmine-fixture
|
||||
*/
|
||||
(function() {
|
||||
var createHTMLBlock,
|
||||
__slice = [].slice;
|
||||
|
||||
(function($) {
|
||||
var ewwSideEffects, jasmineFixture, originalAffix, originalJasmineDotFixture, originalJasmineFixture, root, _, _ref;
|
||||
root = (1, eval)('this');
|
||||
originalJasmineFixture = root.jasmineFixture;
|
||||
originalJasmineDotFixture = (_ref = root.jasmine) != null ? _ref.fixture : void 0;
|
||||
originalAffix = root.affix;
|
||||
_ = function(list) {
|
||||
return {
|
||||
inject: function(iterator, memo) {
|
||||
var item, _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
||||
item = list[_i];
|
||||
_results.push(memo = iterator(memo, item));
|
||||
}
|
||||
return _results;
|
||||
}
|
||||
};
|
||||
};
|
||||
root.jasmineFixture = function($) {
|
||||
var $whatsTheRootOf, affix, create, jasmineFixture, noConflict;
|
||||
affix = function(selectorOptions) {
|
||||
return create.call(this, selectorOptions, true);
|
||||
};
|
||||
create = function(selectorOptions, attach) {
|
||||
var $top;
|
||||
$top = null;
|
||||
_(selectorOptions.split(/[ ](?![^\{]*\})(?=[^\]]*?(?:\[|$))/)).inject(function($parent, elementSelector) {
|
||||
var $el;
|
||||
if (elementSelector === ">") {
|
||||
return $parent;
|
||||
}
|
||||
$el = createHTMLBlock($, elementSelector);
|
||||
if (attach || $top) {
|
||||
$el.appendTo($parent);
|
||||
}
|
||||
$top || ($top = $el);
|
||||
return $el;
|
||||
}, $whatsTheRootOf(this));
|
||||
return $top;
|
||||
};
|
||||
noConflict = function() {
|
||||
var currentJasmineFixture, _ref1;
|
||||
currentJasmineFixture = jasmine.fixture;
|
||||
root.jasmineFixture = originalJasmineFixture;
|
||||
if ((_ref1 = root.jasmine) != null) {
|
||||
_ref1.fixture = originalJasmineDotFixture;
|
||||
}
|
||||
root.affix = originalAffix;
|
||||
return currentJasmineFixture;
|
||||
};
|
||||
$whatsTheRootOf = function(that) {
|
||||
if (that.jquery != null) {
|
||||
return that;
|
||||
} else if ($('#jasmine_content').length > 0) {
|
||||
return $('#jasmine_content');
|
||||
} else {
|
||||
return $('<div id="jasmine_content"></div>').appendTo('body');
|
||||
}
|
||||
};
|
||||
jasmineFixture = {
|
||||
affix: affix,
|
||||
create: create,
|
||||
noConflict: noConflict
|
||||
};
|
||||
ewwSideEffects(jasmineFixture);
|
||||
return jasmineFixture;
|
||||
};
|
||||
ewwSideEffects = function(jasmineFixture) {
|
||||
var _ref1;
|
||||
if ((_ref1 = root.jasmine) != null) {
|
||||
_ref1.fixture = jasmineFixture;
|
||||
}
|
||||
$.fn.affix = root.affix = jasmineFixture.affix;
|
||||
return afterEach(function() {
|
||||
return $('#jasmine_content').remove();
|
||||
});
|
||||
};
|
||||
if ($) {
|
||||
return jasmineFixture = root.jasmineFixture($);
|
||||
} else {
|
||||
return root.affix = function() {
|
||||
var nowJQueryExists;
|
||||
nowJQueryExists = window.jQuery || window.$;
|
||||
if (nowJQueryExists != null) {
|
||||
jasmineFixture = root.jasmineFixture(nowJQueryExists);
|
||||
return affix.call.apply(affix, [this].concat(__slice.call(arguments)));
|
||||
} else {
|
||||
throw new Error("jasmine-fixture requires jQuery to be defined at window.jQuery or window.$");
|
||||
}
|
||||
};
|
||||
}
|
||||
})(window.jQuery || window.$);
|
||||
|
||||
createHTMLBlock = (function() {
|
||||
var bindData, bindEvents, parseAttributes, parseClasses, parseContents, parseEnclosure, parseReferences, parseVariableScope, regAttr, regAttrDfn, regAttrs, regCBrace, regClass, regClasses, regData, regDatas, regEvent, regEvents, regExclamation, regId, regReference, regTag, regTagNotContent, regZenTagDfn;
|
||||
createHTMLBlock = function($, ZenObject, data, functions, indexes) {
|
||||
var ZenCode, arr, block, blockAttrs, blockClasses, blockHTML, blockId, blockTag, blocks, el, el2, els, forScope, indexName, inner, len, obj, origZenCode, paren, result, ret, zc, zo;
|
||||
if ($.isPlainObject(ZenObject)) {
|
||||
ZenCode = ZenObject.main;
|
||||
} else {
|
||||
ZenCode = ZenObject;
|
||||
ZenObject = {
|
||||
main: ZenCode
|
||||
};
|
||||
}
|
||||
origZenCode = ZenCode;
|
||||
if (indexes === undefined) {
|
||||
indexes = {};
|
||||
}
|
||||
if (ZenCode.charAt(0) === "!" || $.isArray(data)) {
|
||||
if ($.isArray(data)) {
|
||||
forScope = ZenCode;
|
||||
} else {
|
||||
obj = parseEnclosure(ZenCode, "!");
|
||||
obj = obj.substring(obj.indexOf(":") + 1, obj.length - 1);
|
||||
forScope = parseVariableScope(ZenCode);
|
||||
}
|
||||
while (forScope.charAt(0) === "@") {
|
||||
forScope = parseVariableScope("!for:!" + parseReferences(forScope, ZenObject));
|
||||
}
|
||||
zo = ZenObject;
|
||||
zo.main = forScope;
|
||||
el = $();
|
||||
if (ZenCode.substring(0, 5) === "!for:" || $.isArray(data)) {
|
||||
if (!$.isArray(data) && obj.indexOf(":") > 0) {
|
||||
indexName = obj.substring(0, obj.indexOf(":"));
|
||||
obj = obj.substr(obj.indexOf(":") + 1);
|
||||
}
|
||||
arr = ($.isArray(data) ? data : data[obj]);
|
||||
zc = zo.main;
|
||||
if ($.isArray(arr) || $.isPlainObject(arr)) {
|
||||
$.map(arr, function(value, index) {
|
||||
var next;
|
||||
zo.main = zc;
|
||||
if (indexName !== undefined) {
|
||||
indexes[indexName] = index;
|
||||
}
|
||||
if (!$.isPlainObject(value)) {
|
||||
value = {
|
||||
value: value
|
||||
};
|
||||
}
|
||||
next = createHTMLBlock($, zo, value, functions, indexes);
|
||||
if (el.length !== 0) {
|
||||
return $.each(next, function(index, value) {
|
||||
return el.push(value);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!$.isArray(data)) {
|
||||
ZenCode = ZenCode.substr(obj.length + 6 + forScope.length);
|
||||
} else {
|
||||
ZenCode = "";
|
||||
}
|
||||
} else if (ZenCode.substring(0, 4) === "!if:") {
|
||||
result = parseContents("!" + obj + "!", data, indexes);
|
||||
if (result !== "undefined" || result !== "false" || result !== "") {
|
||||
el = createHTMLBlock($, zo, data, functions, indexes);
|
||||
}
|
||||
ZenCode = ZenCode.substr(obj.length + 5 + forScope.length);
|
||||
}
|
||||
ZenObject.main = ZenCode;
|
||||
} else if (ZenCode.charAt(0) === "(") {
|
||||
paren = parseEnclosure(ZenCode, "(", ")");
|
||||
inner = paren.substring(1, paren.length - 1);
|
||||
ZenCode = ZenCode.substr(paren.length);
|
||||
zo = ZenObject;
|
||||
zo.main = inner;
|
||||
el = createHTMLBlock($, zo, data, functions, indexes);
|
||||
} else {
|
||||
blocks = ZenCode.match(regZenTagDfn);
|
||||
block = blocks[0];
|
||||
if (block.length === 0) {
|
||||
return "";
|
||||
}
|
||||
if (block.indexOf("@") >= 0) {
|
||||
ZenCode = parseReferences(ZenCode, ZenObject);
|
||||
zo = ZenObject;
|
||||
zo.main = ZenCode;
|
||||
return createHTMLBlock($, zo, data, functions, indexes);
|
||||
}
|
||||
block = parseContents(block, data, indexes);
|
||||
blockClasses = parseClasses($, block);
|
||||
if (regId.test(block)) {
|
||||
blockId = regId.exec(block)[1];
|
||||
}
|
||||
blockAttrs = parseAttributes(block, data);
|
||||
blockTag = (block.charAt(0) === "{" ? "span" : "div");
|
||||
if (ZenCode.charAt(0) !== "#" && ZenCode.charAt(0) !== "." && ZenCode.charAt(0) !== "{") {
|
||||
blockTag = regTag.exec(block)[1];
|
||||
}
|
||||
if (block.search(regCBrace) !== -1) {
|
||||
blockHTML = block.match(regCBrace)[1];
|
||||
}
|
||||
blockAttrs = $.extend(blockAttrs, {
|
||||
id: blockId,
|
||||
"class": blockClasses,
|
||||
html: blockHTML
|
||||
});
|
||||
el = $("<" + blockTag + ">", blockAttrs);
|
||||
el.attr(blockAttrs);
|
||||
el = bindEvents(block, el, functions);
|
||||
el = bindData(block, el, data);
|
||||
ZenCode = ZenCode.substr(blocks[0].length);
|
||||
ZenObject.main = ZenCode;
|
||||
}
|
||||
if (ZenCode.length > 0) {
|
||||
if (ZenCode.charAt(0) === ">") {
|
||||
if (ZenCode.charAt(1) === "(") {
|
||||
zc = parseEnclosure(ZenCode.substr(1), "(", ")");
|
||||
ZenCode = ZenCode.substr(zc.length + 1);
|
||||
} else if (ZenCode.charAt(1) === "!") {
|
||||
obj = parseEnclosure(ZenCode.substr(1), "!");
|
||||
forScope = parseVariableScope(ZenCode.substr(1));
|
||||
zc = obj + forScope;
|
||||
ZenCode = ZenCode.substr(zc.length + 1);
|
||||
} else {
|
||||
len = Math.max(ZenCode.indexOf("+"), ZenCode.length);
|
||||
zc = ZenCode.substring(1, len);
|
||||
ZenCode = ZenCode.substr(len);
|
||||
}
|
||||
zo = ZenObject;
|
||||
zo.main = zc;
|
||||
els = $(createHTMLBlock($, zo, data, functions, indexes));
|
||||
els.appendTo(el);
|
||||
}
|
||||
if (ZenCode.charAt(0) === "+") {
|
||||
zo = ZenObject;
|
||||
zo.main = ZenCode.substr(1);
|
||||
el2 = createHTMLBlock($, zo, data, functions, indexes);
|
||||
$.each(el2, function(index, value) {
|
||||
return el.push(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
ret = el;
|
||||
return ret;
|
||||
};
|
||||
bindData = function(ZenCode, el, data) {
|
||||
var datas, i, split;
|
||||
if (ZenCode.search(regDatas) === 0) {
|
||||
return el;
|
||||
}
|
||||
datas = ZenCode.match(regDatas);
|
||||
if (datas === null) {
|
||||
return el;
|
||||
}
|
||||
i = 0;
|
||||
while (i < datas.length) {
|
||||
split = regData.exec(datas[i]);
|
||||
if (split[3] === undefined) {
|
||||
$(el).data(split[1], data[split[1]]);
|
||||
} else {
|
||||
$(el).data(split[1], data[split[3]]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return el;
|
||||
};
|
||||
bindEvents = function(ZenCode, el, functions) {
|
||||
var bindings, fn, i, split;
|
||||
if (ZenCode.search(regEvents) === 0) {
|
||||
return el;
|
||||
}
|
||||
bindings = ZenCode.match(regEvents);
|
||||
if (bindings === null) {
|
||||
return el;
|
||||
}
|
||||
i = 0;
|
||||
while (i < bindings.length) {
|
||||
split = regEvent.exec(bindings[i]);
|
||||
if (split[2] === undefined) {
|
||||
fn = functions[split[1]];
|
||||
} else {
|
||||
fn = functions[split[2]];
|
||||
}
|
||||
$(el).bind(split[1], fn);
|
||||
i++;
|
||||
}
|
||||
return el;
|
||||
};
|
||||
parseAttributes = function(ZenBlock, data) {
|
||||
var attrStrs, attrs, i, parts;
|
||||
if (ZenBlock.search(regAttrDfn) === -1) {
|
||||
return undefined;
|
||||
}
|
||||
attrStrs = ZenBlock.match(regAttrDfn);
|
||||
attrs = {};
|
||||
i = 0;
|
||||
while (i < attrStrs.length) {
|
||||
parts = regAttr.exec(attrStrs[i]);
|
||||
attrs[parts[1]] = "";
|
||||
if (parts[3] !== undefined) {
|
||||
attrs[parts[1]] = parseContents(parts[3], data);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return attrs;
|
||||
};
|
||||
parseClasses = function($, ZenBlock) {
|
||||
var classes, clsString, i;
|
||||
ZenBlock = ZenBlock.match(regTagNotContent)[0];
|
||||
if (ZenBlock.search(regClasses) === -1) {
|
||||
return undefined;
|
||||
}
|
||||
classes = ZenBlock.match(regClasses);
|
||||
clsString = "";
|
||||
i = 0;
|
||||
while (i < classes.length) {
|
||||
clsString += " " + regClass.exec(classes[i])[1];
|
||||
i++;
|
||||
}
|
||||
return $.trim(clsString);
|
||||
};
|
||||
parseContents = function(ZenBlock, data, indexes) {
|
||||
var html;
|
||||
if (indexes === undefined) {
|
||||
indexes = {};
|
||||
}
|
||||
html = ZenBlock;
|
||||
if (data === undefined) {
|
||||
return html;
|
||||
}
|
||||
while (regExclamation.test(html)) {
|
||||
html = html.replace(regExclamation, function(str, str2) {
|
||||
var begChar, fn, val;
|
||||
begChar = "";
|
||||
if (str.indexOf("!for:") > 0 || str.indexOf("!if:") > 0) {
|
||||
return str;
|
||||
}
|
||||
if (str.charAt(0) !== "!") {
|
||||
begChar = str.charAt(0);
|
||||
str = str.substring(2, str.length - 1);
|
||||
}
|
||||
fn = new Function("data", "indexes", "var r=undefined;" + "with(data){try{r=" + str + ";}catch(e){}}" + "with(indexes){try{if(r===undefined)r=" + str + ";}catch(e){}}" + "return r;");
|
||||
val = unescape(fn(data, indexes));
|
||||
return begChar + val;
|
||||
});
|
||||
}
|
||||
html = html.replace(/\\./g, function(str) {
|
||||
return str.charAt(1);
|
||||
});
|
||||
return unescape(html);
|
||||
};
|
||||
parseEnclosure = function(ZenCode, open, close, count) {
|
||||
var index, ret;
|
||||
if (close === undefined) {
|
||||
close = open;
|
||||
}
|
||||
index = 1;
|
||||
if (count === undefined) {
|
||||
count = (ZenCode.charAt(0) === open ? 1 : 0);
|
||||
}
|
||||
if (count === 0) {
|
||||
return;
|
||||
}
|
||||
while (count > 0 && index < ZenCode.length) {
|
||||
if (ZenCode.charAt(index) === close && ZenCode.charAt(index - 1) !== "\\") {
|
||||
count--;
|
||||
} else {
|
||||
if (ZenCode.charAt(index) === open && ZenCode.charAt(index - 1) !== "\\") {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
ret = ZenCode.substring(0, index);
|
||||
return ret;
|
||||
};
|
||||
parseReferences = function(ZenCode, ZenObject) {
|
||||
ZenCode = ZenCode.replace(regReference, function(str) {
|
||||
var fn;
|
||||
str = str.substr(1);
|
||||
fn = new Function("objs", "var r=\"\";" + "with(objs){try{" + "r=" + str + ";" + "}catch(e){}}" + "return r;");
|
||||
return fn(ZenObject, parseReferences);
|
||||
});
|
||||
return ZenCode;
|
||||
};
|
||||
parseVariableScope = function(ZenCode) {
|
||||
var forCode, rest, tag;
|
||||
if (ZenCode.substring(0, 5) !== "!for:" && ZenCode.substring(0, 4) !== "!if:") {
|
||||
return undefined;
|
||||
}
|
||||
forCode = parseEnclosure(ZenCode, "!");
|
||||
ZenCode = ZenCode.substr(forCode.length);
|
||||
if (ZenCode.charAt(0) === "(") {
|
||||
return parseEnclosure(ZenCode, "(", ")");
|
||||
}
|
||||
tag = ZenCode.match(regZenTagDfn)[0];
|
||||
ZenCode = ZenCode.substr(tag.length);
|
||||
if (ZenCode.length === 0 || ZenCode.charAt(0) === "+") {
|
||||
return tag;
|
||||
} else if (ZenCode.charAt(0) === ">") {
|
||||
rest = "";
|
||||
rest = parseEnclosure(ZenCode.substr(1), "(", ")", 1);
|
||||
return tag + ">" + rest;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
regZenTagDfn = /([#\.\@]?[\w-]+|\[([\w-!?=:"']+(="([^"]|\\")+")? {0,})+\]|\~[\w$]+=[\w$]+|&[\w$]+(=[\w$]+)?|[#\.\@]?!([^!]|\\!)+!){0,}(\{([^\}]|\\\})+\})?/i;
|
||||
regTag = /(\w+)/i;
|
||||
regId = /(?:^|\b)#([\w-!]+)/i;
|
||||
regTagNotContent = /((([#\.]?[\w-]+)?(\[([\w!]+(="([^"]|\\")+")? {0,})+\])?)+)/i;
|
||||
/*
|
||||
See lookahead syntax (?!) at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
|
||||
*/
|
||||
|
||||
regClasses = /(\.[\w-]+)(?!["\w])/g;
|
||||
regClass = /\.([\w-]+)/i;
|
||||
regReference = /(@[\w$_][\w$_\d]+)/i;
|
||||
regAttrDfn = /(\[([\w-!]+(="?([^"]|\\")+"?)? {0,})+\])/ig;
|
||||
regAttrs = /([\w-!]+(="([^"]|\\")+")?)/g;
|
||||
regAttr = /([\w-!]+)(="?((([\w]+(\[.*?\])+)|[^"\]]|\\")+)"?)?/i;
|
||||
regCBrace = /\{(([^\}]|\\\})+)\}/i;
|
||||
regExclamation = /(?:([^\\]|^))!([^!]|\\!)+!/g;
|
||||
regEvents = /\~[\w$]+(=[\w$]+)?/g;
|
||||
regEvent = /\~([\w$]+)=([\w$]+)/i;
|
||||
regDatas = /&[\w$]+(=[\w$]+)?/g;
|
||||
regData = /&([\w$]+)(=([\w$]+))?/i;
|
||||
return createHTMLBlock;
|
||||
})();
|
||||
|
||||
}).call(this);
|
Loading…
Reference in New Issue