jasmine 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/.travis.yml +1 -0
- data/Gemfile +1 -8
- data/RELEASE_NOTES.markdown +6 -0
- data/lib/jasmine.rb +8 -2
- data/lib/jasmine/application.rb +40 -0
- data/lib/jasmine/asset_pipeline_mapper.rb +20 -0
- data/lib/jasmine/base.rb +1 -1
- data/lib/jasmine/config.rb +12 -73
- data/lib/jasmine/dependencies.rb +4 -0
- data/lib/jasmine/page.rb +1 -1
- 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 +1 -0
- data/lib/jasmine/run_specs.rb +33 -0
- data/lib/jasmine/runner_config.rb +60 -0
- data/lib/jasmine/runners/http.rb +70 -0
- data/lib/jasmine/selenium_driver.rb +0 -14
- data/lib/jasmine/server.rb +14 -35
- data/lib/jasmine/tasks/jasmine.rake +2 -2
- data/lib/jasmine/version.rb +1 -1
- data/lib/rack/jasmine/focused_suite.rb +3 -3
- data/spec/application_spec.rb +99 -0
- data/spec/asset_pipeline_mapper_spec.rb +18 -0
- data/spec/config_spec.rb +32 -67
- data/spec/dependencies_spec.rb +14 -3
- data/spec/jasmine_self_test_spec.rb +16 -16
- data/spec/page_spec.rb +1 -1
- 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 +131 -0
- data/spec/server_spec.rb +34 -81
- metadata +44 -24
- data/lib/jasmine/runner.rb +0 -32
- data/lib/jasmine/spec_builder.rb +0 -162
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -3,13 +3,6 @@ gemspec
|
|
3
3
|
|
4
4
|
unless ENV["TRAVIS"]
|
5
5
|
group :debug do
|
6
|
-
|
7
|
-
# curl -OL http://rubyforge.org/frs/download.php/75415/ruby-debug-base19-0.11.26.gem
|
8
|
-
# # Replace with your ruby path if necessary
|
9
|
-
# gem install linecache19-0.5.13.gem ruby-debug-base19-0.11.26.gem -- --with-ruby-include=$rvm_path/src/ruby-1.9.3-p125/
|
10
|
-
# rm linecache19-0.5.13.gem ruby-debug-base19-0.11.26.gem
|
11
|
-
gem 'linecache19', '0.5.13'
|
12
|
-
gem 'ruby-debug-base19', '0.11.26'
|
13
|
-
gem 'ruby-debug19', :require => 'ruby-debug'
|
6
|
+
gem 'debugger'
|
14
7
|
end
|
15
8
|
end
|
data/lib/jasmine.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
jasmine_files = ['base',
|
2
2
|
'dependencies',
|
3
|
+
'runner_config',
|
3
4
|
'config',
|
5
|
+
'application',
|
4
6
|
'server',
|
5
7
|
'selenium_driver',
|
6
|
-
'
|
8
|
+
'rspec_formatter',
|
7
9
|
'command_line_tool',
|
8
|
-
'page'
|
10
|
+
'page',
|
11
|
+
'asset_pipeline_mapper',
|
12
|
+
'results_processor',
|
13
|
+
'results',
|
14
|
+
File.join('runners', 'http')]
|
9
15
|
|
10
16
|
jasmine_files.each do |file|
|
11
17
|
require File.join('jasmine', file)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rack'
|
2
|
+
require 'rack/utils'
|
3
|
+
require 'jasmine-core'
|
4
|
+
require 'rack/jasmine/runner'
|
5
|
+
require 'rack/jasmine/focused_suite'
|
6
|
+
require 'rack/jasmine/redirect'
|
7
|
+
require 'rack/jasmine/cache_control'
|
8
|
+
require 'ostruct'
|
9
|
+
|
10
|
+
module Jasmine
|
11
|
+
class Application
|
12
|
+
def self.app(config = Jasmine::RunnerConfig.new)
|
13
|
+
page = Jasmine::Page.new(config)
|
14
|
+
Rack::Builder.app do
|
15
|
+
use Rack::Head
|
16
|
+
use Rack::Jasmine::CacheControl
|
17
|
+
if Jasmine::Dependencies.rails_3_asset_pipeline?
|
18
|
+
map('/assets') do
|
19
|
+
run Rails.application.assets
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
map('/run.html') { run Rack::Jasmine::Redirect.new('/') }
|
24
|
+
map('/__suite__') { run Rack::Jasmine::FocusedSuite.new(config) }
|
25
|
+
|
26
|
+
#TODO: These path mappings should come from the config.
|
27
|
+
map('/__JASMINE_ROOT__') { run Rack::File.new(Jasmine::Core.path) }
|
28
|
+
map(config.spec_path) { run Rack::File.new(config.spec_dir) }
|
29
|
+
map(config.root_path) { run Rack::File.new(config.project_root) }
|
30
|
+
|
31
|
+
map('/') do
|
32
|
+
run Rack::Cascade.new([
|
33
|
+
Rack::URLMap.new('/' => Rack::File.new(config.src_dir)),
|
34
|
+
Rack::Jasmine::Runner.new(page)
|
35
|
+
])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Jasmine::AssetPipelineMapper
|
2
|
+
|
3
|
+
def self.context
|
4
|
+
context = ::Rails.application.assets.context_class
|
5
|
+
context.extend(::Sprockets::Helpers::IsolatedHelper)
|
6
|
+
context.extend(::Sprockets::Helpers::RailsHelper)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(src_files, context = Jasmine::AssetPipelineMapper.context)
|
10
|
+
@src_files = src_files
|
11
|
+
@context = context
|
12
|
+
end
|
13
|
+
|
14
|
+
def files
|
15
|
+
@src_files.map do |src_file|
|
16
|
+
filename = src_file.gsub(/^assets\//, '').gsub(/\.js$/, '')
|
17
|
+
@context.asset_paths.asset_for(filename, 'js').to_a.map { |p| @context.asset_path(p).gsub(/^\//, '') + "?body=true" }
|
18
|
+
end.flatten.uniq
|
19
|
+
end
|
20
|
+
end
|
data/lib/jasmine/base.rb
CHANGED
data/lib/jasmine/config.rb
CHANGED
@@ -3,77 +3,6 @@ module Jasmine
|
|
3
3
|
require 'yaml'
|
4
4
|
require 'erb'
|
5
5
|
|
6
|
-
def browser
|
7
|
-
ENV["JASMINE_BROWSER"] || 'firefox'
|
8
|
-
end
|
9
|
-
|
10
|
-
def jasmine_host
|
11
|
-
ENV["JASMINE_HOST"] || 'http://localhost'
|
12
|
-
end
|
13
|
-
|
14
|
-
def jasmine_port
|
15
|
-
ENV["JASMINE_PORT"] || Jasmine::find_unused_port
|
16
|
-
end
|
17
|
-
|
18
|
-
def start_server(port = 8888)
|
19
|
-
if defined? Rack::Server # Rack ~>1.0 compatibility
|
20
|
-
server = Rack::Server.new(:Port => port, :AccessLog => [])
|
21
|
-
server.instance_variable_set(:@app, Jasmine.app(self)) # workaround for Rack bug, when Rack > 1.2.1 is released Rack::Server.start(:app => Jasmine.app(self)) will work
|
22
|
-
server.start
|
23
|
-
else
|
24
|
-
handler = Rack::Handler.get('webrick')
|
25
|
-
handler.run(Jasmine.app(self), :Port => port, :AccessLog => [])
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def start
|
30
|
-
start_jasmine_server
|
31
|
-
@client = Jasmine::SeleniumDriver.new(browser, "#{jasmine_host}:#{@jasmine_server_port}/")
|
32
|
-
@client.connect
|
33
|
-
end
|
34
|
-
|
35
|
-
def stop
|
36
|
-
@client.disconnect
|
37
|
-
end
|
38
|
-
|
39
|
-
def start_jasmine_server
|
40
|
-
require 'json'
|
41
|
-
@jasmine_server_port = jasmine_port
|
42
|
-
t = Thread.new do
|
43
|
-
begin
|
44
|
-
start_server(@jasmine_server_port)
|
45
|
-
rescue ChildProcess::TimeoutError; end
|
46
|
-
#ignore bad exits
|
47
|
-
end
|
48
|
-
t.abort_on_exception = true
|
49
|
-
Jasmine::wait_for_listener(@jasmine_server_port, "jasmine server")
|
50
|
-
puts "jasmine server started."
|
51
|
-
end
|
52
|
-
|
53
|
-
def windows?
|
54
|
-
require 'rbconfig'
|
55
|
-
::RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
|
56
|
-
end
|
57
|
-
|
58
|
-
def run
|
59
|
-
begin
|
60
|
-
start
|
61
|
-
puts "servers are listening on their ports -- running the test script..."
|
62
|
-
tests_passed = @client.run
|
63
|
-
ensure
|
64
|
-
stop
|
65
|
-
end
|
66
|
-
return tests_passed
|
67
|
-
end
|
68
|
-
|
69
|
-
def eval_js(script)
|
70
|
-
@client.eval_js(script)
|
71
|
-
end
|
72
|
-
|
73
|
-
def json_generate(obj)
|
74
|
-
@client.json_generate(obj)
|
75
|
-
end
|
76
|
-
|
77
6
|
def match_files(dir, patterns)
|
78
7
|
dir = File.expand_path(dir)
|
79
8
|
negative, positive = patterns.partition {|pattern| /^!/ =~ pattern}
|
@@ -105,7 +34,7 @@ module Jasmine
|
|
105
34
|
src_files.collect {|f| "/" + f } + helpers.collect {|f| File.join(spec_path, f) } + spec_files_to_include.collect {|f| File.join(spec_path, f) }
|
106
35
|
end
|
107
36
|
|
108
|
-
def
|
37
|
+
def user_stylesheets
|
109
38
|
stylesheets.collect {|f| "/" + f }
|
110
39
|
end
|
111
40
|
|
@@ -146,7 +75,9 @@ module Jasmine
|
|
146
75
|
end
|
147
76
|
|
148
77
|
def src_files
|
149
|
-
if simple_config['src_files']
|
78
|
+
if simple_config['src_files'] && Jasmine::Dependencies.rails_3_asset_pipeline?
|
79
|
+
Jasmine::AssetPipelineMapper.new(simple_config['src_files']).files
|
80
|
+
elsif simple_config['src_files']
|
150
81
|
match_files(src_dir, simple_config['src_files'])
|
151
82
|
else
|
152
83
|
[]
|
@@ -168,5 +99,13 @@ module Jasmine
|
|
168
99
|
[]
|
169
100
|
end
|
170
101
|
end
|
102
|
+
|
103
|
+
def jasmine_stylesheets
|
104
|
+
::Jasmine::Core.css_files.map {|f| "/__JASMINE_ROOT__/#{f}"}
|
105
|
+
end
|
106
|
+
|
107
|
+
def jasmine_javascripts
|
108
|
+
::Jasmine::Core.js_files.map {|f| "/__JASMINE_ROOT__/#{f}" }
|
109
|
+
end
|
171
110
|
end
|
172
111
|
end
|
data/lib/jasmine/dependencies.rb
CHANGED
@@ -18,6 +18,10 @@ module Jasmine
|
|
18
18
|
safe_gem_check("rails", ">= 3.0")
|
19
19
|
end
|
20
20
|
|
21
|
+
def legacy_rack?
|
22
|
+
!Rack.constants.include?(:Server)
|
23
|
+
end
|
24
|
+
|
21
25
|
def rails_3_asset_pipeline?
|
22
26
|
rails3? && Rails.respond_to?(:application) && Rails.application.respond_to?(:assets) && Rails.application.assets
|
23
27
|
end
|
data/lib/jasmine/page.rb
CHANGED
@@ -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
|
data/lib/jasmine/run.html.erb
CHANGED
@@ -0,0 +1,33 @@
|
|
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,
|
16
|
+
"#{jasmine_runner_config.jasmine_host}:#{jasmine_runner_config.port}/")
|
17
|
+
|
18
|
+
t = Thread.new do
|
19
|
+
begin
|
20
|
+
server.start
|
21
|
+
rescue ChildProcess::TimeoutError
|
22
|
+
end
|
23
|
+
# # ignore bad exits
|
24
|
+
end
|
25
|
+
t.abort_on_exception = true
|
26
|
+
Jasmine::wait_for_listener(jasmine_runner_config.port, "jasmine server")
|
27
|
+
puts "jasmine server started."
|
28
|
+
|
29
|
+
results_processor = Jasmine::ResultsProcessor.new(jasmine_runner_config)
|
30
|
+
results = Jasmine::Runners::HTTP.new(client, results_processor).run
|
31
|
+
formatter = Jasmine::RspecFormatter.new
|
32
|
+
formatter.format_results(results)
|
33
|
+
|