rally-jasmine 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.travis.yml +58 -0
- data/Gemfile +8 -0
- data/HOW_TO_TEST.markdown +9 -0
- data/MIT.LICENSE +20 -0
- data/README.markdown +77 -0
- data/RELEASE.markdown +22 -0
- data/RELEASE_NOTES.markdown +6 -0
- data/Rakefile +53 -0
- data/bin/jasmine +6 -0
- data/generators/jasmine/jasmine_generator.rb +24 -0
- data/generators/jasmine/templates/INSTALL +9 -0
- data/generators/jasmine/templates/jasmine-example/SpecRunner.html +54 -0
- data/generators/jasmine/templates/jasmine-example/spec/PlayerSpec.js +58 -0
- data/generators/jasmine/templates/jasmine-example/spec/SpecHelper.js +9 -0
- data/generators/jasmine/templates/jasmine-example/src/Player.js +22 -0
- data/generators/jasmine/templates/jasmine-example/src/Song.js +7 -0
- data/generators/jasmine/templates/lib/tasks/jasmine.rake +8 -0
- data/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml +81 -0
- data/generators/jasmine/templates/spec/javascripts/support/jasmine.yml +73 -0
- data/lib/generators/jasmine/examples/USAGE +11 -0
- data/lib/generators/jasmine/examples/examples_generator.rb +19 -0
- data/lib/generators/jasmine/examples/templates/app/assets/javascripts/jasmine_examples/Player.js +22 -0
- data/lib/generators/jasmine/examples/templates/app/assets/javascripts/jasmine_examples/Song.js +7 -0
- data/lib/generators/jasmine/examples/templates/spec/javascripts/helpers/SpecHelper.js +9 -0
- data/lib/generators/jasmine/examples/templates/spec/javascripts/jasmine_examples/PlayerSpec.js +58 -0
- data/lib/generators/jasmine/install/USAGE +11 -0
- data/lib/generators/jasmine/install/install_generator.rb +18 -0
- data/lib/generators/jasmine/install/templates/spec/javascripts/helpers/.gitkeep +0 -0
- data/lib/generators/jasmine/install/templates/spec/javascripts/support/jasmine.yml +76 -0
- data/lib/jasmine/application.rb +43 -0
- data/lib/jasmine/asset_pipeline_mapper.rb +19 -0
- data/lib/jasmine/base.rb +50 -0
- data/lib/jasmine/command_line_tool.rb +70 -0
- data/lib/jasmine/config.rb +121 -0
- data/lib/jasmine/dependencies.rb +59 -0
- data/lib/jasmine/firebug/firebug-1.6.2.xpi +0 -0
- data/lib/jasmine/firebug/firebug-1.7.0.xpi +0 -0
- data/lib/jasmine/firebug/firebug-license.txt +30 -0
- data/lib/jasmine/firebug/firebug.rb +30 -0
- data/lib/jasmine/page.rb +11 -0
- data/lib/jasmine/railtie.rb +21 -0
- data/lib/jasmine/results.rb +19 -0
- data/lib/jasmine/results_processor.rb +37 -0
- data/lib/jasmine/rspec_formatter.rb +92 -0
- data/lib/jasmine/run.html.erb +55 -0
- data/lib/jasmine/run_specs.rb +32 -0
- data/lib/jasmine/runner_config.rb +71 -0
- data/lib/jasmine/runners/http.rb +71 -0
- data/lib/jasmine/selenium_driver.rb +52 -0
- data/lib/jasmine/server.rb +20 -0
- data/lib/jasmine/sprockets_mapper.rb +13 -0
- data/lib/jasmine/tasks/jasmine.rake +56 -0
- data/lib/jasmine/tasks/jasmine_rails3.rake +1 -0
- data/lib/jasmine/version.rb +3 -0
- data/lib/jasmine.rb +23 -0
- data/lib/rack/jasmine/cache_control.rb +20 -0
- data/lib/rack/jasmine/focused_suite.rb +17 -0
- data/lib/rack/jasmine/redirect.rb +20 -0
- data/lib/rack/jasmine/runner.rb +27 -0
- data/spec/application_spec.rb +99 -0
- data/spec/asset_pipeline_mapper_spec.rb +18 -0
- data/spec/config_spec.rb +309 -0
- data/spec/dependencies_spec.rb +327 -0
- data/spec/fixture/Rakefile +4 -0
- data/spec/fixture/jasmine.erb.yml +4 -0
- data/spec/fixture/spec/example_spec.js +5 -0
- data/spec/fixture/src/example.js +3 -0
- data/spec/jasmine_command_line_tool_rakeless_spec.rb +20 -0
- data/spec/jasmine_command_line_tool_spec.rb +29 -0
- data/spec/jasmine_pojs_spec.rb +47 -0
- data/spec/jasmine_rails2_spec.rb +89 -0
- data/spec/jasmine_rails3_spec.rb +69 -0
- data/spec/jasmine_self_test_config.rb +19 -0
- data/spec/jasmine_self_test_spec.rb +22 -0
- data/spec/page_spec.rb +25 -0
- data/spec/rack/jasmine/runner_spec.rb +25 -0
- data/spec/results_processor_spec.rb +3 -0
- data/spec/results_spec.rb +27 -0
- data/spec/rspec_formatter_spec.rb +88 -0
- data/spec/runner_config_spec.rb +136 -0
- data/spec/server_spec.rb +48 -0
- data/spec/spec_helper.rb +55 -0
- data/spec/sprockets_mapper_spec.rb +17 -0
- metadata +319 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class Results
|
3
|
+
|
4
|
+
attr_reader :suites
|
5
|
+
def initialize(result_hash, suite_hash, example_locations)
|
6
|
+
@suites = suite_hash
|
7
|
+
@results = result_hash
|
8
|
+
@example_locations = example_locations
|
9
|
+
end
|
10
|
+
|
11
|
+
def for_spec_id(id)
|
12
|
+
@results[id]
|
13
|
+
end
|
14
|
+
|
15
|
+
def example_location_for(spec_description)
|
16
|
+
@example_locations[spec_description]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class ResultsProcessor
|
3
|
+
|
4
|
+
def initialize(config)
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
def process(results_hash, suites_hash)
|
9
|
+
return Jasmine::Results.new(results_hash, suites_hash, example_locations)
|
10
|
+
end
|
11
|
+
|
12
|
+
def example_locations
|
13
|
+
example_locations = {}
|
14
|
+
example_name_parts = []
|
15
|
+
previous_indent_level = 0
|
16
|
+
@config.spec_files_full_paths.each do |filename|
|
17
|
+
line_number = 1
|
18
|
+
File.open(filename, "r") do |file|
|
19
|
+
file.readlines.each do |line|
|
20
|
+
match = /^(\s*)(describe|it)\s*\(\s*["'](.*)["']\s*,\s*function/.match(line)
|
21
|
+
if (match)
|
22
|
+
indent_level = match[1].length / 2
|
23
|
+
example_name = match[3]
|
24
|
+
example_name_parts[indent_level] = example_name
|
25
|
+
|
26
|
+
full_example_name = example_name_parts.slice(0, indent_level + 1).join(" ")
|
27
|
+
example_locations[full_example_name] = "#{filename}:#{line_number}: in `it'"
|
28
|
+
end
|
29
|
+
line_number += 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
example_locations
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'enumerator'
|
2
|
+
|
3
|
+
module Jasmine
|
4
|
+
class RspecFormatter
|
5
|
+
|
6
|
+
def format_results(results)
|
7
|
+
@results = results
|
8
|
+
declare_suites(@results.suites)
|
9
|
+
end
|
10
|
+
|
11
|
+
def declare_suites(suites)
|
12
|
+
suites.each do |suite|
|
13
|
+
#empty block for rspec 1
|
14
|
+
group = example_group(suite["name"]) {}
|
15
|
+
process_children(group, suite["children"])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def process_children(parent, children)
|
20
|
+
children.each do |suite_or_spec|
|
21
|
+
type = suite_or_spec["type"]
|
22
|
+
if type == "suite"
|
23
|
+
process_children(parent.describe(suite_or_spec["name"]), suite_or_spec["children"])
|
24
|
+
elsif type == "spec"
|
25
|
+
declare_spec(parent, suite_or_spec)
|
26
|
+
else
|
27
|
+
raise "unknown type #{type} for #{suite_or_spec.inspect}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def declare_spec(parent, spec)
|
33
|
+
me = self
|
34
|
+
example_name = spec["name"]
|
35
|
+
backtrace = @results.example_location_for(parent.description + " " + example_name)
|
36
|
+
if Jasmine::Dependencies.rspec2?
|
37
|
+
parent.it example_name, {} do
|
38
|
+
me.report_spec(spec["id"])
|
39
|
+
end
|
40
|
+
else
|
41
|
+
parent.it example_name, {}, backtrace do
|
42
|
+
me.report_spec(spec["id"])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def report_spec(spec_id)
|
48
|
+
spec_results = results_for(spec_id)
|
49
|
+
out = ""
|
50
|
+
messages = spec_results['messages'].each do |message|
|
51
|
+
case
|
52
|
+
when message["type"] == "log"
|
53
|
+
puts message["text"]
|
54
|
+
puts "\n"
|
55
|
+
else
|
56
|
+
unless message["message"] =~ /^Passed.$/
|
57
|
+
STDERR << message["message"]
|
58
|
+
STDERR << "\n"
|
59
|
+
|
60
|
+
out << message["message"]
|
61
|
+
out << "\n"
|
62
|
+
end
|
63
|
+
|
64
|
+
if !message["passed"] && message["trace"]["stack"]
|
65
|
+
stack_trace = message["trace"]["stack"].gsub(/<br \/>/, "\n").gsub(/<\/?b>/, " ")
|
66
|
+
STDERR << stack_trace.gsub(/\(.*\)@http:\/\/localhost:[0-9]+\/specs\//, "/spec/")
|
67
|
+
STDERR << "\n"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
fail out unless spec_results['result'] == 'passed'
|
73
|
+
puts out unless out.empty?
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def example_group(*args, &block)
|
79
|
+
if Jasmine::Dependencies.rspec2?
|
80
|
+
RSpec::Core::ExampleGroup.describe(*args, &block).register
|
81
|
+
else
|
82
|
+
Spec::Example::ExampleGroupFactory.create_example_group(*args, &block)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def results_for(spec_id)
|
87
|
+
@results.for_spec_id(spec_id.to_s)
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
2
|
+
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
3
|
+
<head>
|
4
|
+
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
|
5
|
+
<title>Jasmine suite</title>
|
6
|
+
<link rel="shortcut icon" type="image/png" href="/__JASMINE_ROOT__/images/jasmine_favicon.png">
|
7
|
+
<% css_files.each do |css_file| %>
|
8
|
+
<link rel="stylesheet" href="<%= css_file %>" type="text/css" media="screen"/>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<% jasmine_files.each do |jasmine_file| %>
|
12
|
+
<script src="<%= jasmine_file %>" type="text/javascript"></script>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<script type="text/javascript">
|
16
|
+
//TODO: make this a js file that gets passed in, then iterate over only js_files
|
17
|
+
var jsApiReporter;
|
18
|
+
(function() {
|
19
|
+
var jasmineEnv = jasmine.getEnv();
|
20
|
+
|
21
|
+
jsApiReporter = new jasmine.JsApiReporter();
|
22
|
+
var htmlReporter = new jasmine.HtmlReporter();
|
23
|
+
|
24
|
+
jasmineEnv.addReporter(jsApiReporter);
|
25
|
+
jasmineEnv.addReporter(htmlReporter);
|
26
|
+
|
27
|
+
jasmineEnv.specFilter = function(spec) {
|
28
|
+
return htmlReporter.specFilter(spec);
|
29
|
+
};
|
30
|
+
|
31
|
+
var currentWindowOnload = window.onload;
|
32
|
+
|
33
|
+
window.onload = function() {
|
34
|
+
if (currentWindowOnload) {
|
35
|
+
currentWindowOnload();
|
36
|
+
}
|
37
|
+
execJasmine();
|
38
|
+
};
|
39
|
+
|
40
|
+
function execJasmine() {
|
41
|
+
jasmineEnv.execute();
|
42
|
+
}
|
43
|
+
|
44
|
+
})();
|
45
|
+
</script>
|
46
|
+
|
47
|
+
<% js_files.each do |js_file| %>
|
48
|
+
<script src="<%= js_file %>" type="text/javascript"></script>
|
49
|
+
<% end %>
|
50
|
+
|
51
|
+
</head>
|
52
|
+
<body>
|
53
|
+
<div id="jasmine_content"></div>
|
54
|
+
</body>
|
55
|
+
</html>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'jasmine'
|
5
|
+
jasmine_config_overrides = File.expand_path(File.join(Dir.pwd, 'spec', 'javascripts', 'support', 'jasmine_config.rb'))
|
6
|
+
require jasmine_config_overrides if File.exist?(jasmine_config_overrides)
|
7
|
+
if Jasmine::Dependencies.rspec2?
|
8
|
+
require 'rspec'
|
9
|
+
else
|
10
|
+
require 'spec'
|
11
|
+
end
|
12
|
+
|
13
|
+
jasmine_runner_config = Jasmine::RunnerConfig.new
|
14
|
+
server = Jasmine::Server.new(jasmine_runner_config.port, Jasmine::Application.app(jasmine_runner_config))
|
15
|
+
client = Jasmine::SeleniumDriver.new(jasmine_runner_config.browser, jasmine_runner_config.jasmine_server_url)
|
16
|
+
|
17
|
+
t = Thread.new do
|
18
|
+
begin
|
19
|
+
server.start
|
20
|
+
rescue ChildProcess::TimeoutError
|
21
|
+
end
|
22
|
+
# # ignore bad exits
|
23
|
+
end
|
24
|
+
t.abort_on_exception = true
|
25
|
+
Jasmine::wait_for_listener(jasmine_runner_config.port, "jasmine server")
|
26
|
+
puts "jasmine server started."
|
27
|
+
|
28
|
+
results_processor = Jasmine::ResultsProcessor.new(jasmine_runner_config)
|
29
|
+
results = Jasmine::Runners::HTTP.new(client, results_processor, jasmine_runner_config.result_batch_size).run
|
30
|
+
formatter = Jasmine::RspecFormatter.new
|
31
|
+
formatter.format_results(results)
|
32
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class RunnerConfig
|
3
|
+
def initialize(config = Jasmine::Config.new)
|
4
|
+
@config = config
|
5
|
+
end
|
6
|
+
|
7
|
+
def css_files
|
8
|
+
@config.jasmine_stylesheets + @config.user_stylesheets
|
9
|
+
end
|
10
|
+
|
11
|
+
def jasmine_files
|
12
|
+
@config.jasmine_javascripts
|
13
|
+
end
|
14
|
+
|
15
|
+
def js_files
|
16
|
+
@config.js_files
|
17
|
+
end
|
18
|
+
|
19
|
+
def spec_files
|
20
|
+
@config.spec_files
|
21
|
+
end
|
22
|
+
|
23
|
+
def spec_files_full_paths
|
24
|
+
@config.spec_files_full_paths
|
25
|
+
end
|
26
|
+
|
27
|
+
def spec_path
|
28
|
+
@config.spec_path
|
29
|
+
end
|
30
|
+
|
31
|
+
def spec_dir
|
32
|
+
@config.spec_dir
|
33
|
+
end
|
34
|
+
|
35
|
+
def src_dir
|
36
|
+
@config.src_dir
|
37
|
+
end
|
38
|
+
|
39
|
+
def project_root
|
40
|
+
@config.project_root
|
41
|
+
end
|
42
|
+
|
43
|
+
def root_path
|
44
|
+
@config.root_path
|
45
|
+
end
|
46
|
+
|
47
|
+
def browser
|
48
|
+
ENV["JASMINE_BROWSER"] || 'firefox'
|
49
|
+
end
|
50
|
+
|
51
|
+
def port
|
52
|
+
@config.port
|
53
|
+
end
|
54
|
+
|
55
|
+
def jasmine_server_url
|
56
|
+
"#{@config.jasmine_host}:#{@config.port}/"
|
57
|
+
end
|
58
|
+
|
59
|
+
def src_mapper=(context)
|
60
|
+
@config.src_mapper = context
|
61
|
+
end
|
62
|
+
|
63
|
+
def src_mapper
|
64
|
+
@config.src_mapper
|
65
|
+
end
|
66
|
+
|
67
|
+
def result_batch_size
|
68
|
+
ENV["JASMINE_RESULT_BATCH_SIZE"] ? ENV["JASMINE_RESULT_BATCH_SIZE"].to_i : 50
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Jasmine
|
2
|
+
module Runners
|
3
|
+
class HTTP
|
4
|
+
attr_accessor :suites
|
5
|
+
|
6
|
+
def initialize(client, results_processor, result_batch_size)
|
7
|
+
@client = client
|
8
|
+
@results_processor = results_processor
|
9
|
+
@result_batch_size = result_batch_size
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
@client.connect
|
14
|
+
load_suite_info
|
15
|
+
wait_for_suites_to_finish_running
|
16
|
+
results = @results_processor.process(results_hash, suites)
|
17
|
+
@client.disconnect
|
18
|
+
results
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def load_suite_info
|
24
|
+
started = Time.now
|
25
|
+
while !eval_js('return jsApiReporter && jsApiReporter.started') do
|
26
|
+
raise "couldn't connect to Jasmine after 60 seconds" if (started + 60 < Time.now)
|
27
|
+
sleep 0.1
|
28
|
+
end
|
29
|
+
|
30
|
+
@suites = eval_js("var result = jsApiReporter.suites(); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }")
|
31
|
+
end
|
32
|
+
|
33
|
+
def results_hash
|
34
|
+
spec_results = {}
|
35
|
+
spec_ids.each_slice(@result_batch_size) do |slice|
|
36
|
+
spec_results.merge!(eval_js("var result = jsApiReporter.resultsForSpecs(#{json_generate(slice)}); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }"))
|
37
|
+
end
|
38
|
+
spec_results
|
39
|
+
end
|
40
|
+
|
41
|
+
def spec_ids
|
42
|
+
map_spec_ids = lambda do |suites|
|
43
|
+
suites.map do |suite_or_spec|
|
44
|
+
if suite_or_spec['type'] == 'spec'
|
45
|
+
suite_or_spec['id']
|
46
|
+
else
|
47
|
+
map_spec_ids.call(suite_or_spec['children'])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
map_spec_ids.call(@suites).compact.flatten
|
52
|
+
end
|
53
|
+
|
54
|
+
def wait_for_suites_to_finish_running
|
55
|
+
puts "Waiting for suite to finish in browser ..."
|
56
|
+
while !eval_js('return jsApiReporter.finished') do
|
57
|
+
sleep 0.1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def eval_js(script)
|
62
|
+
@client.eval_js(script)
|
63
|
+
end
|
64
|
+
|
65
|
+
def json_generate(obj)
|
66
|
+
@client.json_generate(obj)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class SeleniumDriver
|
3
|
+
def initialize(browser, http_address)
|
4
|
+
require 'selenium-webdriver'
|
5
|
+
|
6
|
+
::Selenium::WebDriver::Driver.send(:attr_accessor, :bridge)
|
7
|
+
::Selenium::WebDriver::Remote::Bridge.send(:attr_accessor, :http)
|
8
|
+
::Selenium::WebDriver::Remote::Http::Default.send(:attr_accessor, :server_url)
|
9
|
+
|
10
|
+
selenium_server = if ENV['SELENIUM_SERVER']
|
11
|
+
ENV['SELENIUM_SERVER']
|
12
|
+
elsif ENV['SELENIUM_SERVER_PORT']
|
13
|
+
"http://localhost:#{ENV['SELENIUM_SERVER_PORT']}/wd/hub"
|
14
|
+
end
|
15
|
+
options = if browser == "firefox" && ENV["JASMINE_FIREBUG"]
|
16
|
+
require File.join(File.dirname(__FILE__), "firebug/firebug")
|
17
|
+
profile = Selenium::WebDriver::Firefox::Profile.new
|
18
|
+
profile.enable_firebug
|
19
|
+
{:profile => profile}
|
20
|
+
end || {}
|
21
|
+
@driver = if selenium_server
|
22
|
+
Selenium::WebDriver.for :remote, :url => selenium_server, :desired_capabilities => browser.to_sym
|
23
|
+
else
|
24
|
+
Selenium::WebDriver.for browser.to_sym, options
|
25
|
+
end
|
26
|
+
@http_address = http_address
|
27
|
+
end
|
28
|
+
|
29
|
+
def connect
|
30
|
+
wdsid = @driver.bridge.session_id
|
31
|
+
wduri = @driver.bridge.http.server_url
|
32
|
+
|
33
|
+
wdurl = "#{wduri.scheme}://#{wduri.host}:#{wduri.port}/wd/hub"
|
34
|
+
url = "#{@http_address}?wdurl=#{URI.encode(wdurl)}&wdsid=#{URI.encode(wdsid)}"
|
35
|
+
@driver.navigate.to url
|
36
|
+
url
|
37
|
+
end
|
38
|
+
|
39
|
+
def disconnect
|
40
|
+
@driver.quit
|
41
|
+
end
|
42
|
+
|
43
|
+
def eval_js(script)
|
44
|
+
result = @driver.execute_script(script)
|
45
|
+
JSON.parse("{\"result\":#{result}}", :max_nesting => false)["result"]
|
46
|
+
end
|
47
|
+
|
48
|
+
def json_generate(obj)
|
49
|
+
JSON.generate(obj)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Jasmine
|
2
|
+
class Server
|
3
|
+
def initialize(port = 8888, application = Jasmine::Application.app)
|
4
|
+
@port = port
|
5
|
+
@application = application
|
6
|
+
end
|
7
|
+
|
8
|
+
def start
|
9
|
+
if Jasmine::Dependencies.legacy_rack?
|
10
|
+
handler = Rack::Handler.get('webrick')
|
11
|
+
handler.run(@application, :Port => @port, :AccessLog => [])
|
12
|
+
else
|
13
|
+
server = Rack::Server.new(:Port => @port, :AccessLog => [])
|
14
|
+
# workaround for Rack bug, when Rack > 1.2.1 is released Rack::Server.start(:app => Jasmine.app(self)) will work
|
15
|
+
server.instance_variable_set(:@app, @application)
|
16
|
+
server.start
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Jasmine::SprocketsMapper
|
2
|
+
def initialize(context, mount_point = 'assets')
|
3
|
+
@context = context
|
4
|
+
@mount_point = mount_point
|
5
|
+
end
|
6
|
+
|
7
|
+
def files(src_files)
|
8
|
+
src_files.map do |src_file|
|
9
|
+
filename = src_file.gsub(/^assets\//, '').gsub(/\.js$/, '')
|
10
|
+
@context.find_asset(filename).to_a.map(&:logical_path).map(&:to_s)
|
11
|
+
end.flatten.uniq.map{|path| File.join(@mount_point, path).to_s + "?body=true"}
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
namespace :jasmine do
|
2
|
+
task :require do
|
3
|
+
require 'jasmine'
|
4
|
+
end
|
5
|
+
|
6
|
+
task :require_json do
|
7
|
+
begin
|
8
|
+
require 'json'
|
9
|
+
rescue LoadError
|
10
|
+
puts "You must have a JSON library installed to run jasmine:ci. Try \"gem install json\""
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Run continuous integration tests"
|
16
|
+
task :ci => ["jasmine:require_json", "jasmine:require"] do
|
17
|
+
if Jasmine::Dependencies.rspec2?
|
18
|
+
require "rspec"
|
19
|
+
require "rspec/core/rake_task"
|
20
|
+
else
|
21
|
+
require "spec"
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
end
|
24
|
+
|
25
|
+
if Jasmine::Dependencies.rspec2?
|
26
|
+
RSpec::Core::RakeTask.new(:jasmine_continuous_integration_runner) do |t|
|
27
|
+
t.rspec_opts = ["--colour", "--format", ENV['JASMINE_SPEC_FORMAT'] || "progress"]
|
28
|
+
t.verbose = true
|
29
|
+
if Jasmine::Dependencies.rails_3_asset_pipeline?
|
30
|
+
t.rspec_opts += ["-r #{File.expand_path(File.join(::Rails.root, 'config', 'environment'))}"]
|
31
|
+
end
|
32
|
+
t.pattern = [Jasmine.runner_filepath]
|
33
|
+
end
|
34
|
+
else
|
35
|
+
Spec::Rake::SpecTask.new(:jasmine_continuous_integration_runner) do |t|
|
36
|
+
t.spec_opts = ["--color", "--format", ENV['JASMINE_SPEC_FORMAT'] || "specdoc"]
|
37
|
+
t.verbose = true
|
38
|
+
t.spec_files = [Jasmine.runner_filepath]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
Rake::Task["jasmine_continuous_integration_runner"].invoke
|
42
|
+
end
|
43
|
+
|
44
|
+
task :server => "jasmine:require" do
|
45
|
+
jasmine_config_overrides = File.join(Jasmine::Config.new.project_root, 'spec', 'javascripts' ,'support' ,'jasmine_config.rb')
|
46
|
+
require jasmine_config_overrides if File.exist?(jasmine_config_overrides)
|
47
|
+
|
48
|
+
port = ENV['JASMINE_PORT'] || 8888
|
49
|
+
puts "your tests are here:"
|
50
|
+
puts " http://localhost:#{port}/"
|
51
|
+
Jasmine::Server.new(port).start
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "Run specs via server"
|
56
|
+
task :jasmine => ['jasmine:server']
|
@@ -0,0 +1 @@
|
|
1
|
+
task "jasmine:require" => [:environment]
|
data/lib/jasmine.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
jasmine_files = ['base',
|
2
|
+
'dependencies',
|
3
|
+
'runner_config',
|
4
|
+
'config',
|
5
|
+
'application',
|
6
|
+
'server',
|
7
|
+
'selenium_driver',
|
8
|
+
'rspec_formatter',
|
9
|
+
'command_line_tool',
|
10
|
+
'page',
|
11
|
+
'asset_pipeline_mapper',
|
12
|
+
'sprockets_mapper',
|
13
|
+
'results_processor',
|
14
|
+
'results',
|
15
|
+
File.join('runners', 'http')]
|
16
|
+
|
17
|
+
jasmine_files.each do |file|
|
18
|
+
require File.join('jasmine', file)
|
19
|
+
end
|
20
|
+
|
21
|
+
require File.join('jasmine', "railtie") if Jasmine::Dependencies.rails3?
|
22
|
+
|
23
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rack
|
2
|
+
module Jasmine
|
3
|
+
|
4
|
+
class CacheControl
|
5
|
+
def initialize(app)
|
6
|
+
@app, @content_type = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
status, headers, body = @app.call(env)
|
11
|
+
headers = Rack::Utils::HeaderHash.new(headers)
|
12
|
+
headers['Cache-Control'] ||= "max-age=0, private, must-revalidate"
|
13
|
+
headers['Pragma'] ||= "no-cache"
|
14
|
+
[status, headers, body]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Rack
|
2
|
+
module Jasmine
|
3
|
+
|
4
|
+
class FocusedSuite
|
5
|
+
def initialize(runner_config)
|
6
|
+
@runner_config = runner_config
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
run_adapter = Rack::Jasmine::RunAdapter.new(@runner_config)
|
11
|
+
run_adapter.run(env["PATH_INFO"])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Rack
|
2
|
+
module Jasmine
|
3
|
+
|
4
|
+
class Runner
|
5
|
+
def initialize(page)
|
6
|
+
@page = page
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
@path = env["PATH_INFO"]
|
11
|
+
return not_found if @path != "/"
|
12
|
+
[
|
13
|
+
200,
|
14
|
+
{ 'Content-Type' => 'text/html'},
|
15
|
+
[@page.render]
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
def not_found
|
20
|
+
[404, {"Content-Type" => "text/plain",
|
21
|
+
"X-Cascade" => "pass"},
|
22
|
+
["File not found: #{@path}\n"]]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|