rally-jasmine 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. data/.gitignore +13 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +58 -0
  4. data/Gemfile +8 -0
  5. data/HOW_TO_TEST.markdown +9 -0
  6. data/MIT.LICENSE +20 -0
  7. data/README.markdown +77 -0
  8. data/RELEASE.markdown +22 -0
  9. data/RELEASE_NOTES.markdown +6 -0
  10. data/Rakefile +53 -0
  11. data/bin/jasmine +6 -0
  12. data/generators/jasmine/jasmine_generator.rb +24 -0
  13. data/generators/jasmine/templates/INSTALL +9 -0
  14. data/generators/jasmine/templates/jasmine-example/SpecRunner.html +54 -0
  15. data/generators/jasmine/templates/jasmine-example/spec/PlayerSpec.js +58 -0
  16. data/generators/jasmine/templates/jasmine-example/spec/SpecHelper.js +9 -0
  17. data/generators/jasmine/templates/jasmine-example/src/Player.js +22 -0
  18. data/generators/jasmine/templates/jasmine-example/src/Song.js +7 -0
  19. data/generators/jasmine/templates/lib/tasks/jasmine.rake +8 -0
  20. data/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml +81 -0
  21. data/generators/jasmine/templates/spec/javascripts/support/jasmine.yml +73 -0
  22. data/lib/generators/jasmine/examples/USAGE +11 -0
  23. data/lib/generators/jasmine/examples/examples_generator.rb +19 -0
  24. data/lib/generators/jasmine/examples/templates/app/assets/javascripts/jasmine_examples/Player.js +22 -0
  25. data/lib/generators/jasmine/examples/templates/app/assets/javascripts/jasmine_examples/Song.js +7 -0
  26. data/lib/generators/jasmine/examples/templates/spec/javascripts/helpers/SpecHelper.js +9 -0
  27. data/lib/generators/jasmine/examples/templates/spec/javascripts/jasmine_examples/PlayerSpec.js +58 -0
  28. data/lib/generators/jasmine/install/USAGE +11 -0
  29. data/lib/generators/jasmine/install/install_generator.rb +18 -0
  30. data/lib/generators/jasmine/install/templates/spec/javascripts/helpers/.gitkeep +0 -0
  31. data/lib/generators/jasmine/install/templates/spec/javascripts/support/jasmine.yml +76 -0
  32. data/lib/jasmine/application.rb +43 -0
  33. data/lib/jasmine/asset_pipeline_mapper.rb +19 -0
  34. data/lib/jasmine/base.rb +50 -0
  35. data/lib/jasmine/command_line_tool.rb +70 -0
  36. data/lib/jasmine/config.rb +121 -0
  37. data/lib/jasmine/dependencies.rb +59 -0
  38. data/lib/jasmine/firebug/firebug-1.6.2.xpi +0 -0
  39. data/lib/jasmine/firebug/firebug-1.7.0.xpi +0 -0
  40. data/lib/jasmine/firebug/firebug-license.txt +30 -0
  41. data/lib/jasmine/firebug/firebug.rb +30 -0
  42. data/lib/jasmine/page.rb +11 -0
  43. data/lib/jasmine/railtie.rb +21 -0
  44. data/lib/jasmine/results.rb +19 -0
  45. data/lib/jasmine/results_processor.rb +37 -0
  46. data/lib/jasmine/rspec_formatter.rb +92 -0
  47. data/lib/jasmine/run.html.erb +55 -0
  48. data/lib/jasmine/run_specs.rb +32 -0
  49. data/lib/jasmine/runner_config.rb +71 -0
  50. data/lib/jasmine/runners/http.rb +71 -0
  51. data/lib/jasmine/selenium_driver.rb +52 -0
  52. data/lib/jasmine/server.rb +20 -0
  53. data/lib/jasmine/sprockets_mapper.rb +13 -0
  54. data/lib/jasmine/tasks/jasmine.rake +56 -0
  55. data/lib/jasmine/tasks/jasmine_rails3.rake +1 -0
  56. data/lib/jasmine/version.rb +3 -0
  57. data/lib/jasmine.rb +23 -0
  58. data/lib/rack/jasmine/cache_control.rb +20 -0
  59. data/lib/rack/jasmine/focused_suite.rb +17 -0
  60. data/lib/rack/jasmine/redirect.rb +20 -0
  61. data/lib/rack/jasmine/runner.rb +27 -0
  62. data/spec/application_spec.rb +99 -0
  63. data/spec/asset_pipeline_mapper_spec.rb +18 -0
  64. data/spec/config_spec.rb +309 -0
  65. data/spec/dependencies_spec.rb +327 -0
  66. data/spec/fixture/Rakefile +4 -0
  67. data/spec/fixture/jasmine.erb.yml +4 -0
  68. data/spec/fixture/spec/example_spec.js +5 -0
  69. data/spec/fixture/src/example.js +3 -0
  70. data/spec/jasmine_command_line_tool_rakeless_spec.rb +20 -0
  71. data/spec/jasmine_command_line_tool_spec.rb +29 -0
  72. data/spec/jasmine_pojs_spec.rb +47 -0
  73. data/spec/jasmine_rails2_spec.rb +89 -0
  74. data/spec/jasmine_rails3_spec.rb +69 -0
  75. data/spec/jasmine_self_test_config.rb +19 -0
  76. data/spec/jasmine_self_test_spec.rb +22 -0
  77. data/spec/page_spec.rb +25 -0
  78. data/spec/rack/jasmine/runner_spec.rb +25 -0
  79. data/spec/results_processor_spec.rb +3 -0
  80. data/spec/results_spec.rb +27 -0
  81. data/spec/rspec_formatter_spec.rb +88 -0
  82. data/spec/runner_config_spec.rb +136 -0
  83. data/spec/server_spec.rb +48 -0
  84. data/spec/spec_helper.rb +55 -0
  85. data/spec/sprockets_mapper_spec.rb +17 -0
  86. 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]
@@ -0,0 +1,3 @@
1
+ module Jasmine
2
+ VERSION = "1.2.0"
3
+ end
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,20 @@
1
+ module Rack
2
+ module Jasmine
3
+
4
+ class Redirect
5
+ def initialize(url)
6
+ @url = url
7
+ end
8
+
9
+ def call(env)
10
+ [
11
+ 302,
12
+ { 'Location' => @url },
13
+ []
14
+ ]
15
+ end
16
+ end
17
+
18
+ end
19
+ end
20
+
@@ -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