summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-05-29 09:10:46 +0000
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-05-29 09:10:46 +0000
commitacb7721fe807a75860f4be0a3bb50146232fa229 (patch)
treee4d5d3eaf5102b6ac9770bc42d44a058143a8d47
parentac584d6b086691ad6b496c082a80bc78b8f08a22 (diff)
parentbd12ca5eb3c8b6ca9de28cbbb074ff1e29c661f2 (diff)
downloadgitlab-ce-acb7721fe807a75860f4be0a3bb50146232fa229.tar.gz
Merge branch 'rs-teaspoon' into 'master'
Add Teaspoon for Javascript testing Looking to expand our Javascript unit tests, and this gem makes things a bit better in that respect. See https://github.com/modeset/teaspoon See merge request !715
-rw-r--r--Gemfile10
-rw-r--r--Gemfile.lock21
-rw-r--r--app/assets/javascripts/issue.js.coffee1
-rw-r--r--app/assets/javascripts/merge_request.js.coffee3
-rw-r--r--app/assets/javascripts/notes.js.coffee2
-rw-r--r--app/assets/javascripts/shortcuts_issuable.coffee2
-rw-r--r--app/assets/javascripts/stat_graph_contributors.js.coffee1
-rw-r--r--config/initializers/6_rack_profiler.rb3
-rw-r--r--config/routes.rb1
-rw-r--r--lib/tasks/jasmine.rake2
-rw-r--r--spec/javascripts/fixtures/issuable.html.haml2
-rw-r--r--spec/javascripts/fixtures/issue_note.html.haml12
-rw-r--r--spec/javascripts/fixtures/issues_show.html.haml13
-rw-r--r--spec/javascripts/fixtures/merge_requests_show.html.haml13
-rw-r--r--spec/javascripts/issue_spec.js.coffee30
-rw-r--r--spec/javascripts/merge_request_spec.js.coffee31
-rw-r--r--spec/javascripts/notes_spec.js.coffee19
-rw-r--r--spec/javascripts/shortcuts_issuable_spec.js.coffee7
-rw-r--r--spec/javascripts/spec_helper.coffee46
-rw-r--r--spec/javascripts/support/jasmine.yml15
-rw-r--r--spec/javascripts/support/jasmine_helper.rb15
-rw-r--r--spec/teaspoon_env.rb178
-rwxr-xr-xvendor/assets/javascripts/jasmine-fixture.js433
23 files changed, 313 insertions, 547 deletions
diff --git a/Gemfile b/Gemfile
index c51941b1e35..d0fd205a378 100644
--- a/Gemfile
+++ b/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
diff --git a/Gemfile.lock b/Gemfile.lock
index f479ca7ed53..d1e311c2d49 100644
--- a/Gemfile.lock
+++ b/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)
diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee
index 86ad3d03bac..74d6b80be5e 100644
--- a/app/assets/javascripts/issue.js.coffee
+++ b/app/assets/javascripts/issue.js.coffee
@@ -1,4 +1,3 @@
-#= require jquery
#= require jquery.waitforimages
#= require task_list
diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee
index a5a2caf1263..19967ebb2e5 100644
--- a/app/assets/javascripts/merge_request.js.coffee
+++ b/app/assets/javascripts/merge_request.js.coffee
@@ -1,5 +1,4 @@
-#= require jquery
-#= require bootstrap
+#= require jquery.waitforimages
#= require task_list
class @MergeRequest
diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee
index f186fec2a0c..b9bd5c730bf 100644
--- a/app/assets/javascripts/notes.js.coffee
+++ b/app/assets/javascripts/notes.js.coffee
@@ -1,6 +1,4 @@
-#= require jquery
#= require autosave
-#= require bootstrap
#= require dropzone
#= require dropzone_input
#= require gfm_auto_complete
diff --git a/app/assets/javascripts/shortcuts_issuable.coffee b/app/assets/javascripts/shortcuts_issuable.coffee
index 6b534f29218..bb532194682 100644
--- a/app/assets/javascripts/shortcuts_issuable.coffee
+++ b/app/assets/javascripts/shortcuts_issuable.coffee
@@ -1,6 +1,4 @@
-#= require jquery
#= require mousetrap
-
#= require shortcuts_navigation
class @ShortcutsIssuable extends ShortcutsNavigation
diff --git a/app/assets/javascripts/stat_graph_contributors.js.coffee b/app/assets/javascripts/stat_graph_contributors.js.coffee
index ed12bdcef22..3be14cb43dd 100644
--- a/app/assets/javascripts/stat_graph_contributors.js.coffee
+++ b/app/assets/javascripts/stat_graph_contributors.js.coffee
@@ -1,5 +1,4 @@
#= require d3
-#= require jquery
#= require stat_graph_contributors_util
class @ContributorsStatGraph
diff --git a/config/initializers/6_rack_profiler.rb b/config/initializers/6_rack_profiler.rb
index 38a5fa98dc2..5312fd8e89a 100644
--- a/config/initializers/6_rack_profiler.rb
+++ b/config/initializers/6_rack_profiler.rb
@@ -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
diff --git a/config/routes.rb b/config/routes.rb
index 3f8f920963d..b7380254abb 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -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',
diff --git a/lib/tasks/jasmine.rake b/lib/tasks/jasmine.rake
index 9e2cceffa19..ac307a9e929 100644
--- a/lib/tasks/jasmine.rake
+++ b/lib/tasks/jasmine.rake
@@ -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
diff --git a/spec/javascripts/fixtures/issuable.html.haml b/spec/javascripts/fixtures/issuable.html.haml
new file mode 100644
index 00000000000..42ab4aa68b1
--- /dev/null
+++ b/spec/javascripts/fixtures/issuable.html.haml
@@ -0,0 +1,2 @@
+%form.js-main-target-form
+ %textarea#note_note
diff --git a/spec/javascripts/fixtures/issue_note.html.haml b/spec/javascripts/fixtures/issue_note.html.haml
new file mode 100644
index 00000000000..0aecc7334fd
--- /dev/null
+++ b/spec/javascripts/fixtures/issue_note.html.haml
@@ -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
diff --git a/spec/javascripts/fixtures/issues_show.html.haml b/spec/javascripts/fixtures/issues_show.html.haml
new file mode 100644
index 00000000000..db5abe0cae3
--- /dev/null
+++ b/spec/javascripts/fixtures/issues_show.html.haml
@@ -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'}
diff --git a/spec/javascripts/fixtures/merge_requests_show.html.haml b/spec/javascripts/fixtures/merge_requests_show.html.haml
new file mode 100644
index 00000000000..c4329b8f94a
--- /dev/null
+++ b/spec/javascripts/fixtures/merge_requests_show.html.haml
@@ -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'}
diff --git a/spec/javascripts/issue_spec.js.coffee b/spec/javascripts/issue_spec.js.coffee
index 13b25862f57..268e4c68c31 100644
--- a/spec/javascripts/issue_spec.js.coffee
+++ b/spec/javascripts/issue_spec.js.coffee
@@ -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)
diff --git a/spec/javascripts/merge_request_spec.js.coffee b/spec/javascripts/merge_request_spec.js.coffee
index 3ebc4a4eed5..a4735af0343 100644
--- a/spec/javascripts/merge_request_spec.js.coffee
+++ b/spec/javascripts/merge_request_spec.js.coffee
@@ -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))
+ fixture.load('merge_requests_show.html')
+ @merge = new MergeRequest({})
- # This form is used to get the `update` URL. Not ideal.
- $container.append(affix(selectors.form))
+ it 'modifies the Markdown field', ->
+ spyOn(jQuery, 'ajax').and.stub()
- @merge = new MergeRequest({})
+ $('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)
diff --git a/spec/javascripts/notes_spec.js.coffee b/spec/javascripts/notes_spec.js.coffee
index de2e8e7f6c8..050b6e362c6 100644
--- a/spec/javascripts/notes_spec.js.coffee
+++ b/spec/javascripts/notes_spec.js.coffee
@@ -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()
diff --git a/spec/javascripts/shortcuts_issuable_spec.js.coffee b/spec/javascripts/shortcuts_issuable_spec.js.coffee
index 57dcc2161d3..a01ad7140dd 100644
--- a/spec/javascripts/shortcuts_issuable_spec.js.coffee
+++ b/spec/javascripts/shortcuts_issuable_spec.js.coffee
@@ -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', ->
diff --git a/spec/javascripts/spec_helper.coffee b/spec/javascripts/spec_helper.coffee
new file mode 100644
index 00000000000..892a539d96b
--- /dev/null
+++ b/spec/javascripts/spec_helper.coffee
@@ -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
diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml
deleted file mode 100644
index 168c9618643..00000000000
--- a/spec/javascripts/support/jasmine.yml
+++ /dev/null
@@ -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}"
diff --git a/spec/javascripts/support/jasmine_helper.rb b/spec/javascripts/support/jasmine_helper.rb
deleted file mode 100644
index 4d73aec5a31..00000000000
--- a/spec/javascripts/support/jasmine_helper.rb
+++ /dev/null
@@ -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
-#
diff --git a/spec/teaspoon_env.rb b/spec/teaspoon_env.rb
new file mode 100644
index 00000000000..58f45ff8610
--- /dev/null
+++ b/spec/teaspoon_env.rb
@@ -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
diff --git a/vendor/assets/javascripts/jasmine-fixture.js b/vendor/assets/javascripts/jasmine-fixture.js
deleted file mode 100755
index 9980aec6ddb..00000000000
--- a/vendor/assets/javascripts/jasmine-fixture.js
+++ /dev/null
@@ -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);