satisfaction-jasmine 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/README.markdown +37 -0
  2. data/bin/jasmine +58 -0
  3. data/generators/jasmine/jasmine_generator.rb +25 -0
  4. data/generators/jasmine/templates/INSTALL +9 -0
  5. data/generators/jasmine/templates/lib/tasks/jasmine.rake +23 -0
  6. data/generators/jasmine/templates/spec/javascripts/ExampleSpec.js +11 -0
  7. data/generators/jasmine/templates/spec/javascripts/SpecHelper.js +1 -0
  8. data/generators/jasmine/templates/spec/javascripts/support/jasmine-rails-with-src-base-url.yml +23 -0
  9. data/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml +20 -0
  10. data/generators/jasmine/templates/spec/javascripts/support/jasmine.yml +20 -0
  11. data/generators/jasmine/templates/spec/javascripts/support/jasmine_config.rb +61 -0
  12. data/generators/jasmine/templates/spec/javascripts/support/jasmine_runner.rb +17 -0
  13. data/jasmine/contrib/ruby/jasmine_runner.rb +334 -0
  14. data/jasmine/contrib/ruby/jasmine_spec_builder.rb +153 -0
  15. data/jasmine/contrib/ruby/run.html +47 -0
  16. data/jasmine/lib/TrivialReporter.js +117 -0
  17. data/jasmine/lib/consolex.js +28 -0
  18. data/jasmine/lib/jasmine-0.10.0.js +2261 -0
  19. data/jasmine/lib/jasmine.css +86 -0
  20. data/jasmine/lib/json2.js +478 -0
  21. data/lib/jasmine.rb +6 -0
  22. data/lib/jasmine/base.rb +63 -0
  23. data/lib/jasmine/config.rb +166 -0
  24. data/lib/jasmine/run.html.erb +43 -0
  25. data/lib/jasmine/selenium_driver.rb +44 -0
  26. data/lib/jasmine/server.rb +125 -0
  27. data/lib/jasmine/spec_builder.rb +152 -0
  28. data/spec/config_spec.rb +138 -0
  29. data/spec/jasmine_self_test_config.rb +15 -0
  30. data/spec/jasmine_self_test_spec.rb +18 -0
  31. data/spec/server_spec.rb +65 -0
  32. data/spec/spec_helper.rb +4 -0
  33. metadata +145 -0
@@ -0,0 +1,152 @@
1
+ require 'enumerator'
2
+
3
+ module Jasmine
4
+ class SpecBuilder
5
+ attr_accessor :suites
6
+
7
+ def initialize(config)
8
+ @config = config
9
+ @spec_files = config.spec_files
10
+ @runner = config
11
+ @spec_ids = []
12
+ end
13
+
14
+ def start
15
+ guess_example_locations
16
+
17
+ @runner.start
18
+ load_suite_info
19
+ wait_for_suites_to_finish_running
20
+ end
21
+
22
+ def stop
23
+ @runner.stop
24
+ end
25
+
26
+ def script_path
27
+ File.expand_path(__FILE__)
28
+ end
29
+
30
+ def guess_example_locations
31
+ @example_locations = {}
32
+
33
+ example_name_parts = []
34
+ previous_indent_level = 0
35
+ @config.spec_files_full_paths.each do |filename|
36
+ line_number = 1
37
+ File.open(filename, "r") do |file|
38
+ file.readlines.each do |line|
39
+ match = /^(\s*)(describe|it)\s*\(\s*["'](.*)["']\s*,\s*function/.match(line)
40
+ if (match)
41
+ indent_level = match[1].length / 2
42
+ example_name = match[3]
43
+ example_name_parts[indent_level] = example_name
44
+
45
+ full_example_name = example_name_parts.slice(0, indent_level + 1).join(" ")
46
+ @example_locations[full_example_name] = "#{filename}:#{line_number}: in `it'"
47
+ end
48
+ line_number += 1
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def load_suite_info
55
+ started = Time.now
56
+ while !eval_js('jsApiReporter && jsApiReporter.started') do
57
+ raise "couldn't connect to Jasmine after 60 seconds" if (started + 60 < Time.now)
58
+ sleep 0.1
59
+ end
60
+
61
+ @suites = eval_js("var result = jsApiReporter.suites(); if (window.Prototype && Object.toJSON) { Object.toJSON(result) } else { JSON.stringify(result) }")
62
+ end
63
+
64
+ def results_for(spec_id)
65
+ @spec_results ||= load_results
66
+ @spec_results[spec_id.to_s]
67
+ end
68
+
69
+ def load_results
70
+ @spec_results = {}
71
+ @spec_ids.each_slice(50) do |slice|
72
+ @spec_results.merge!(eval_js("var result = jsApiReporter.resultsForSpecs(#{JSON.generate(slice)}); if (window.Prototype && Object.toJSON) { Object.toJSON(result) } else { JSON.stringify(result) }"))
73
+ end
74
+ @spec_results
75
+ end
76
+
77
+ def wait_for_suites_to_finish_running
78
+ puts "Waiting for suite to finish in browser ..."
79
+ while !eval_js('jsApiReporter.finished') do
80
+ sleep 0.1
81
+ end
82
+ end
83
+
84
+ def declare_suites
85
+ me = self
86
+ suites.each do |suite|
87
+ declare_suite(self, suite)
88
+ end
89
+ end
90
+
91
+ def declare_suite(parent, suite)
92
+ me = self
93
+ parent.describe suite["name"] do
94
+ suite["children"].each do |suite_or_spec|
95
+ type = suite_or_spec["type"]
96
+ if type == "suite"
97
+ me.declare_suite(self, suite_or_spec)
98
+ elsif type == "spec"
99
+ me.declare_spec(self, suite_or_spec)
100
+ else
101
+ raise "unknown type #{type} for #{suite_or_spec.inspect}"
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ def declare_spec(parent, spec)
108
+ me = self
109
+ example_name = spec["name"]
110
+ @spec_ids << spec["id"]
111
+ backtrace = @example_locations[parent.description + " " + example_name]
112
+ parent.it example_name, {}, backtrace do
113
+ me.report_spec(spec["id"])
114
+ end
115
+ end
116
+
117
+ def report_spec(spec_id)
118
+ spec_results = results_for(spec_id)
119
+ out = ""
120
+ messages = spec_results['messages'].each do |message|
121
+ case
122
+ when message["type"] == "MessageResult"
123
+ puts message["text"]
124
+ puts "\n"
125
+ else
126
+ unless message["message"] =~ /^Passed.$/
127
+ STDERR << message["message"]
128
+ STDERR << "\n"
129
+
130
+ out << message["message"]
131
+ out << "\n"
132
+ end
133
+
134
+ if !message["passed"] && message["trace"]["stack"]
135
+ stack_trace = message["trace"]["stack"].gsub(/<br \/>/, "\n").gsub(/<\/?b>/, " ")
136
+ STDERR << stack_trace.gsub(/\(.*\)@http:\/\/localhost:[0-9]+\/specs\//, "/spec/")
137
+ STDERR << "\n"
138
+ end
139
+ end
140
+
141
+ end
142
+ fail out unless spec_results['result'] == 'passed'
143
+ puts out unless out.empty?
144
+ end
145
+
146
+ private
147
+
148
+ def eval_js(js)
149
+ @runner.eval_js(js)
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,138 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ describe Jasmine::Config do
4
+ before(:each) do
5
+ @template_dir = File.expand_path(File.join(File.dirname(__FILE__), "../generators/jasmine/templates"))
6
+ @config = Jasmine::Config.new
7
+ end
8
+
9
+ describe "configuration" do
10
+ before(:each) do
11
+ @config.stub!(:src_dir).and_return(File.join(@template_dir, "public"))
12
+ @config.stub!(:spec_dir).and_return(File.join(@template_dir, "spec"))
13
+ end
14
+
15
+ it "if sources.yaml not found" do
16
+ File.stub!(:exist?).and_return(false)
17
+ @config.src_files.should == []
18
+ @config.stylesheets.should == []
19
+ @config.spec_files.should == ['/javascripts/ExampleSpec.js', '/javascripts/SpecHelper.js']
20
+ @config.mappings.should == {
21
+ '/__root__' => @config.project_root,
22
+ '/__spec__' => @config.spec_dir
23
+ }
24
+ end
25
+
26
+ it "if jasmine.yml is empty" do
27
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
28
+ YAML.stub!(:load).and_return(false)
29
+ @config.src_files.should == []
30
+ @config.stylesheets.should == []
31
+ @config.spec_files.should == ['/javascripts/ExampleSpec.js', '/javascripts/SpecHelper.js']
32
+ @config.mappings.should == {
33
+ '/__root__' => @config.project_root,
34
+ '/__spec__' => @config.spec_dir
35
+ }
36
+ end
37
+
38
+ it "using default jasmine.yml" do
39
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
40
+ @config.src_files.should == []
41
+ @config.spec_files.should == ['/javascripts/ExampleSpec.js', '/javascripts/SpecHelper.js']
42
+ @config.mappings.should == {
43
+ '/__root__' => @config.project_root,
44
+ '/__spec__' => @config.spec_dir
45
+ }
46
+ end
47
+
48
+ it "simple_config stylesheets" do
49
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
50
+ YAML.stub!(:load).and_return({'stylesheets' => ['/foo.css', '/bar.css']})
51
+ Dir.stub!(:glob).and_return do |glob_string|
52
+ glob_string
53
+ end
54
+ @config.stylesheets.should == ['/foo.css', '/bar.css']
55
+ end
56
+
57
+ describe "using rails jasmine.yml" do
58
+ before do
59
+ original_glob = Dir.method(:glob)
60
+ Dir.stub!(:glob).and_return do |glob_string|
61
+ if glob_string =~ /public/
62
+ glob_string
63
+ else
64
+ original_glob.call(glob_string)
65
+ end
66
+ end
67
+ end
68
+ describe "with a src_base_url defined" do
69
+ it "loads src over http" do
70
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine-rails-with-src-base-url.yml'))
71
+ @config.src_files.should == ['http://localhost:3000/javascripts/prototype.js',
72
+ 'http://localhost:3000/javascripts/effects.js',
73
+ 'http://localhost:3000/javascripts/controls.js',
74
+ 'http://localhost:3000/javascripts/dragdrop.js',
75
+ 'http://localhost:3000/javascripts/application.js']
76
+ @config.js_files.should == [
77
+ 'http://localhost:3000/javascripts/prototype.js',
78
+ 'http://localhost:3000/javascripts/effects.js',
79
+ 'http://localhost:3000/javascripts/controls.js',
80
+ 'http://localhost:3000/javascripts/dragdrop.js',
81
+ 'http://localhost:3000/javascripts/application.js',
82
+ '/__spec__/javascripts/ExampleSpec.js',
83
+ '/__spec__/javascripts/SpecHelper.js',
84
+ ]
85
+ end
86
+ end
87
+ describe "without a src_base_url defined" do
88
+ it "loads src files from the file system" do
89
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine-rails.yml'))
90
+ @config.spec_files.should == ['/javascripts/ExampleSpec.js', '/javascripts/SpecHelper.js']
91
+ @config.src_files.should == ['/javascripts/prototype.js',
92
+ '/javascripts/effects.js',
93
+ '/javascripts/controls.js',
94
+ '/javascripts/dragdrop.js',
95
+ '/javascripts/application.js']
96
+ @config.js_files.should == [
97
+ '/javascripts/prototype.js',
98
+ '/javascripts/effects.js',
99
+ '/javascripts/controls.js',
100
+ '/javascripts/dragdrop.js',
101
+ '/javascripts/application.js',
102
+ '/__spec__/javascripts/ExampleSpec.js',
103
+ '/__spec__/javascripts/SpecHelper.js',
104
+ ]
105
+ end
106
+ end
107
+ end
108
+
109
+ it "should provide a list of all spec files with full paths" do
110
+ @config.spec_files_full_paths.should == [
111
+ File.join(@template_dir, 'spec/javascripts/ExampleSpec.js'),
112
+ File.join(@template_dir, 'spec/javascripts/SpecHelper.js')
113
+ ]
114
+ end
115
+
116
+ end
117
+
118
+ it "src_dir uses root when src dir is blank" do
119
+ @config.stub!(:project_root).and_return('some_project_root')
120
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
121
+ YAML.stub!(:load).and_return({'src_dir' => nil})
122
+ @config.src_dir.should == 'some_project_root'
123
+ end
124
+
125
+ it "should use correct default yaml config" do
126
+ @config.stub!(:project_root).and_return('some_project_root')
127
+ @config.simple_config_file.should == (File.join('some_project_root', 'spec/javascripts/support/jasmine.yml'))
128
+ end
129
+
130
+
131
+ it "should provide dir mappings" do
132
+ @config.mappings.should == {
133
+ '/__root__' => @config.project_root,
134
+ '/__spec__' => @config.spec_dir
135
+ }
136
+ end
137
+
138
+ end
@@ -0,0 +1,15 @@
1
+ require 'jasmine'
2
+
3
+ class JasmineSelfTestConfig < Jasmine::Config
4
+ def project_root
5
+ File.expand_path(File.join(File.dirname(__FILE__), ".."))
6
+ end
7
+
8
+ def src_dir
9
+ File.join(project_root, 'src')
10
+ end
11
+
12
+ def spec_dir
13
+ File.join(project_root, 'jasmine/spec')
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ require 'jasmine_self_test_config'
4
+
5
+ jasmine_config = JasmineSelfTestConfig.new
6
+ spec_builder = Jasmine::SpecBuilder.new(jasmine_config)
7
+
8
+ should_stop = false
9
+
10
+ Spec::Runner.configure do |config|
11
+ config.after(:suite) do
12
+ spec_builder.stop if should_stop
13
+ end
14
+ end
15
+
16
+ spec_builder.start
17
+ should_stop = true
18
+ spec_builder.declare_suites
@@ -0,0 +1,65 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ def read(body)
4
+ return body if body.is_a?(String)
5
+ out = ""
6
+ body.each {|data| out += data }
7
+ out
8
+ end
9
+
10
+ describe Jasmine::Server do
11
+ before(:each) do
12
+ config = Jasmine::Config.new
13
+ config.stub!(:mappings).and_return({
14
+ "/src" => File.join(Jasmine.root, "src"),
15
+ "/spec" => File.join(Jasmine.root, "spec")
16
+ })
17
+
18
+ config.stub!(:js_files).and_return(["/src/file1.js", "/spec/file2.js"])
19
+
20
+ @server = Jasmine::Server.new(0, config)
21
+ @thin_app = @server.thin.app
22
+ end
23
+
24
+ after(:each) do
25
+ @server.thin.stop if @server && @server.thin.running?
26
+ end
27
+
28
+ it "should serve static files" do
29
+ code, headers, body = @thin_app.call("PATH_INFO" => "/spec/suites/EnvSpec.js", "SCRIPT_NAME" => "xxx")
30
+ code.should == 200
31
+ headers["Content-Type"].should == "application/javascript"
32
+ read(body).should == File.read(File.join(Jasmine.root, "spec/suites/EnvSpec.js"))
33
+ end
34
+
35
+ it "should serve Jasmine static files under /__JASMINE_ROOT__/" do
36
+ code, headers, body = @thin_app.call("PATH_INFO" => "/__JASMINE_ROOT__/lib/jasmine.css", "SCRIPT_NAME" => "xxx")
37
+ code.should == 200
38
+ headers["Content-Type"].should == "text/css"
39
+ read(body).should == File.read(File.join(Jasmine.root, "lib/jasmine.css"))
40
+ end
41
+
42
+ it "should redirect /run.html to /" do
43
+ code, headers, body = @thin_app.call("PATH_INFO" => "/run.html", "SCRIPT_NAME" => "xxx")
44
+ code.should == 302
45
+ headers["Location"].should == "/"
46
+ end
47
+
48
+ describe "/ page" do
49
+ it "should load each js file in order" do
50
+ code, headers, body = @thin_app.call("PATH_INFO" => "/", "SCRIPT_NAME" => "xxx")
51
+ code.should == 200
52
+ body = read(body)
53
+ body.should include("\"/src/file1.js")
54
+ body.should include("\"/spec/file2.js")
55
+ body.should satisfy {|s| s.index("/src/file1.js") < s.index("/spec/file2.js") }
56
+ end
57
+ end
58
+
59
+ it "should display an error using JS for 404's" do
60
+ code, headers, body = @thin_app.call("PATH_INFO" => "/spec/NonExistantFile.js", "SCRIPT_NAME" => "xxx")
61
+ code.should == 200 # todo: shouldn't this be 404? will that work with all browsers?
62
+ headers["Content-Type"].should == "application/javascript"
63
+ read(body).should == "document.write('<p>Couldn\\'t load /spec/NonExistantFile.js!</p>');"
64
+ end
65
+ end
@@ -0,0 +1,4 @@
1
+ require "#{File.dirname(__FILE__)}/../vendor/gems/environment"
2
+ require 'spec'
3
+
4
+ require File.expand_path(File.join(File.dirname(__FILE__), "../lib/jasmine"))
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: satisfaction-jasmine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.3
5
+ platform: ruby
6
+ authors:
7
+ - Rajan Agaskar
8
+ - Christian Williams
9
+ - Satisfactioneers
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2010-02-02 00:00:00 -08:00
15
+ default_executable: jasmine
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: rspec
19
+ type: :runtime
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 1.1.5
26
+ version:
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ type: :runtime
30
+ version_requirement:
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 1.1.9
36
+ version:
37
+ - !ruby/object:Gem::Dependency
38
+ name: rack
39
+ type: :runtime
40
+ version_requirement:
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: 1.0.0
46
+ version:
47
+ - !ruby/object:Gem::Dependency
48
+ name: thin
49
+ type: :runtime
50
+ version_requirement:
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 1.2.4
56
+ version:
57
+ - !ruby/object:Gem::Dependency
58
+ name: selenium-rc
59
+ type: :runtime
60
+ version_requirement:
61
+ version_requirements: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: 2.1.0
66
+ version:
67
+ - !ruby/object:Gem::Dependency
68
+ name: selenium-client
69
+ type: :runtime
70
+ version_requirement:
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 1.2.17
76
+ version:
77
+ description: Javascript BDD test framework
78
+ email: nerds@getsatisfaction.com
79
+ executables:
80
+ - jasmine
81
+ extensions: []
82
+
83
+ extra_rdoc_files:
84
+ - README.markdown
85
+ files:
86
+ - generators/jasmine/jasmine_generator.rb
87
+ - generators/jasmine/templates/INSTALL
88
+ - generators/jasmine/templates/lib/tasks/jasmine.rake
89
+ - generators/jasmine/templates/spec/javascripts/ExampleSpec.js
90
+ - generators/jasmine/templates/spec/javascripts/SpecHelper.js
91
+ - generators/jasmine/templates/spec/javascripts/support/jasmine-rails-with-src-base-url.yml
92
+ - generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml
93
+ - generators/jasmine/templates/spec/javascripts/support/jasmine.yml
94
+ - generators/jasmine/templates/spec/javascripts/support/jasmine_config.rb
95
+ - generators/jasmine/templates/spec/javascripts/support/jasmine_runner.rb
96
+ - jasmine/contrib/ruby/jasmine_runner.rb
97
+ - jasmine/contrib/ruby/jasmine_spec_builder.rb
98
+ - jasmine/contrib/ruby/run.html
99
+ - jasmine/lib/TrivialReporter.js
100
+ - jasmine/lib/consolex.js
101
+ - jasmine/lib/jasmine-0.10.0.js
102
+ - jasmine/lib/jasmine.css
103
+ - jasmine/lib/json2.js
104
+ - lib/jasmine.rb
105
+ - lib/jasmine/base.rb
106
+ - lib/jasmine/config.rb
107
+ - lib/jasmine/run.html.erb
108
+ - lib/jasmine/selenium_driver.rb
109
+ - lib/jasmine/server.rb
110
+ - lib/jasmine/spec_builder.rb
111
+ - README.markdown
112
+ has_rdoc: true
113
+ homepage: http://github.com/satisfaction/jasmine-ruby
114
+ licenses: []
115
+
116
+ post_install_message:
117
+ rdoc_options:
118
+ - --charset=UTF-8
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: "0"
126
+ version:
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: "0"
132
+ version:
133
+ requirements: []
134
+
135
+ rubyforge_project:
136
+ rubygems_version: 1.3.5
137
+ signing_key:
138
+ specification_version: 3
139
+ summary: Jasmine Ruby Runner
140
+ test_files:
141
+ - spec/config_spec.rb
142
+ - spec/jasmine_self_test_config.rb
143
+ - spec/jasmine_self_test_spec.rb
144
+ - spec/server_spec.rb
145
+ - spec/spec_helper.rb