Skip to content

Instantly share code, notes, and snippets.

@raecoo
Created April 2, 2013 02:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raecoo/5289462 to your computer and use it in GitHub Desktop.
Save raecoo/5289462 to your computer and use it in GitHub Desktop.
JavaScript test suites for Rails project based on Jasmine with Sinon.JS.
# put this file in spec/javascripts/support/
@Factory = Factory = {}
ids = {}
sequences = {}
sequence = (name, callback) -> sequences[name] = callback
define = (name, defaults = {}) ->
Factory[name] = (attrs = {}) ->
result = $.extend {}, defaults, attrs
for k, v of result
if typeof v is 'function'
result[k] = v.call(result, result)
App[name].create result
next = (name) ->
->
ids[name] = (ids[name] ? 0) + 1
sequences[name]?(ids[name])
sequence 'id', (n) -> n
sequence 'username', (n) -> "User #{n}"
sequence 'email', (n) -> "user#{n}@meetgtd.com"
sequence 'nickname', (n) -> "user nickname #{n}"
one = (name) ->
->
Factory[name]()
many = (name, n = 1) ->
->
(Factory[name]() for i in [1..n])
define 'User',
id: next('id')
name: next('username')
email: next('email')
nickname: next('nickname')
guard 'jasmine', :timeout => 30000 do
watch(%r{app/assets/javascripts/(.+)\.(js\.coffee|js|coffee)$}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
watch(%r{spec/javascripts/(.+)_spec\.(js\.coffee|js|coffee)$}) { |m| puts m.inspect; "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
watch(%r{spec/javascripts/spec(_helper)?\.(js\.coffee|js|coffee)$}) { "spec/javascripts" }
watch(%r{spec/javascripts/support}) { "spec/javascripts" }
end
# put this file in spec/javascripts/support/
jasmine.Spec::fakeServer = ->
@server ||= sinon.fakeServer.create()
jasmine.Spec::respondWith = (args...) ->
@fakeServer().respondWith args...
jasmine.Spec::respond = ->
@server?.respond()
jasmine.Spec::spy = (args...) ->
@sinon.spy args...
jasmine.Spec::mock = (args...) ->
@sinon.mock args...
# gets event object from a callback spy
jasmine.Spec::getEvent = (spy, counter = 0) ->
spy.getCall(counter).args[0]
jasmine.Spec::stub = (args...) ->
@sinon.stub args...
beforeEach ->
@sinon = sinon.sandbox.create()
@fakeServer()
afterEach ->
@server?.restore()
@sinon.restore()
jasmine.Spec::stubAjax = ->
@ajax = @stub($, 'ajax')
@ajaxOption = (name, call = 0) -> @ajax.getCall(call).args[0][name]
@ajax
jasmine.Spec::stubAjaxCallback = ->
@errorSpy = @stub()
@successSpy = @stub()
@ajax.returns success: @successSpy
@successSpy.returns error: @errorSpy
@errorSpy.returns success: @successSpy
# put this file in spec/javascripts/support/
# src_files
#
# Return an array of filepaths relative to src_dir to include before jasmine specs.
# Default: []
#
# EXAMPLE:
#
# src_files:
# - lib/source1.js
# - lib/source2.js
# - dist/**/*.js
#
src_files:
- app/assets/javascripts/app/**/*.coffee
- lib/assets/javascripts/**/*.coffee
# stylesheets
#
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
# Default: []
#
# EXAMPLE:
#
# stylesheets:
# - css/style.css
# - stylesheets/*.css
#
stylesheets:
- app/assets/stylesheets/**/*.css
# helpers
#
# Return an array of filepaths relative to spec_dir to include before jasmine specs.
# Default: ["helpers/**/*.js"]
#
# EXAMPLE:
#
# helpers:
# - helpers/**/*.js
#
helpers:
- helpers/**/*.js
# spec_files
#
# Return an array of filepaths relative to spec_dir to include.
# Default: ["**/*[sS]pec.js"]
#
# EXAMPLE:
#
# spec_files:
# - **/*[sS]pec.js
#
spec_files:
- '**/*[sS]pec.js'
# src_dir
#
# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
# Default: project root
#
# EXAMPLE:
#
# src_dir: public
#
src_dir:
# spec_dir
#
# Spec directory path. Your spec_files must be returned relative to this path.
# Default: spec/javascripts
#
# EXAMPLE:
#
# spec_dir: spec/javascripts
#
spec_dir: spec/javascripts
# put this file in spec/javascripts/support/
module Jasmine
class Config
# Add your overrides or custom config code here
end
end
# Note - this is necessary for rspec2, which has removed the backtrace
module Jasmine
class SpecBuilder
def stop
save_coverage_report
@runner.stop
end
def declare_spec(parent, spec)
me = self
example_name = spec["name"]
@spec_ids << spec["id"]
backtrace = @example_locations[parent.description + " " + example_name]
parent.it example_name, {} do
me.report_spec(spec["id"])
end
end
def save_coverage_report
report_js = Pathname.new(File.join(@config.project_root, 'public/coverage/report/jscoverage-inject.js'))
report_js.parent.mkpath
jscoverage = eval_js "return JSON.stringify(window.jasmine.coverageReport());"
json = json_generate(jscoverage)
File.open(report_js, 'w') do |f|
f.write <<-JS.gsub(/^ {10}/, '')
jscoverage_isReport = true;
var jscoverage_reportJSON = #{json};
jscoverage_createRequest = function() {
return {
open: function() {},
send: function() {
var file;
for (file in jscoverage_reportJSON) {
if (!jscoverage_reportJSON.hasOwnProperty(file)) {
continue;
}
var fileCoverage = jscoverage_reportJSON[file];
_$jscoverage[file] = fileCoverage.coverage;
_$jscoverage[file].source = fileCoverage.source;
}
jscoverage_recalculateSummaryTab();
document.getElementById('summaryThrobber').style.visibility = 'hidden';
document.getElementById('warningDiv').style.visibility = 'hidden';
}
};
};
JS
end
end
end
end
# put this file in spec/javascripts/support/
$:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes
require 'rubygems'
require 'jasmine'
require 'rspec'
jasmine_config_overrides = File.expand_path(File.join(File.dirname(__FILE__), 'jasmine_config.rb'))
require jasmine_config_overrides if File.exists?(jasmine_config_overrides)
jasmine_config = Jasmine::Config.new
spec_builder = Jasmine::SpecBuilder.new(jasmine_config)
should_stop = false
RSpec.configuration.after(:suite) do
spec_builder.stop if should_stop
end
spec_builder.start
should_stop = true
spec_builder.declare_suites
/* put this file in spec/javascripts/ */
/*
*= require application
*/
# put this file in spec/javascripts/
#= require application
#= require sinon
#= require jasmine-sinon
#= require_tree ./
# put this file in spec/javascripts/
#= require support/jasmine
#= require support/factories
#= require_self
root = global ? window
beforeEach ->
# do something here
afterEach ->
# do something here
root.describeFunction = (func, name, testcases) ->
describe name, ->
for arg, expectation of testcases
do (arg, expectation) ->
describe "with arguments (#{arg})", ->
it "returns #{expectation}", ->
eval("var actual = func(#{arg});")
expect(actual).toEqual(expectation)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment