edgecase-jasmine 1.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/README.markdown +45 -0
  2. data/bin/jasmine +6 -0
  3. data/generators/jasmine/jasmine_generator.rb +30 -0
  4. data/generators/jasmine/templates/INSTALL +9 -0
  5. data/generators/jasmine/templates/jasmine-example/SpecRunner.html +27 -0
  6. data/generators/jasmine/templates/jasmine-example/spec/PlayerSpec.js +58 -0
  7. data/generators/jasmine/templates/jasmine-example/spec/SpecHelper.js +9 -0
  8. data/generators/jasmine/templates/jasmine-example/src/Player.js +22 -0
  9. data/generators/jasmine/templates/jasmine-example/src/Song.js +7 -0
  10. data/generators/jasmine/templates/lib/tasks/jasmine.rake +2 -0
  11. data/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml +81 -0
  12. data/generators/jasmine/templates/spec/javascripts/support/jasmine.yml +73 -0
  13. data/generators/jasmine/templates/spec/javascripts/support/jasmine_runner.rb +21 -0
  14. data/jasmine/example/SpecRunner.html +27 -0
  15. data/jasmine/lib/jasmine-html.js +188 -0
  16. data/jasmine/lib/jasmine.css +166 -0
  17. data/jasmine/lib/jasmine.js +2421 -0
  18. data/jasmine/lib/json2.js +478 -0
  19. data/lib/jasmine.rb +8 -0
  20. data/lib/jasmine/base.rb +59 -0
  21. data/lib/jasmine/command_line_tool.rb +68 -0
  22. data/lib/jasmine/config.rb +186 -0
  23. data/lib/jasmine/run.html.erb +43 -0
  24. data/lib/jasmine/selenium_driver.rb +44 -0
  25. data/lib/jasmine/server.rb +120 -0
  26. data/lib/jasmine/spec_builder.rb +152 -0
  27. data/lib/jasmine/tasks/jasmine.rake +31 -0
  28. data/spec/config_spec.rb +259 -0
  29. data/spec/jasmine_command_line_tool_spec.rb +26 -0
  30. data/spec/jasmine_self_test_config.rb +15 -0
  31. data/spec/jasmine_self_test_spec.rb +18 -0
  32. data/spec/rails_generator_spec.rb +27 -0
  33. data/spec/server_spec.rb +82 -0
  34. data/spec/spec_helper.rb +40 -0
  35. metadata +204 -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(#{MultiJson.encode(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"] == "log"
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,31 @@
1
+ namespace :jasmine do
2
+ task :require do
3
+ require 'jasmine'
4
+ end
5
+
6
+ desc "Run continuous integration tests"
7
+ task :ci => "jasmine:require" do
8
+ require "spec"
9
+ require 'spec/rake/spectask'
10
+
11
+ Spec::Rake::SpecTask.new(:jasmine_continuous_integration_runner) do |t|
12
+ t.spec_opts = ["--color", "--format", "specdoc"]
13
+ t.verbose = true
14
+ t.spec_files = ['spec/javascripts/support/jasmine_runner.rb']
15
+ end
16
+ Rake::Task["jasmine_continuous_integration_runner"].invoke
17
+ end
18
+
19
+ task :server => "jasmine:require" do
20
+ jasmine_config_overrides = 'spec/javascripts/support/jasmine_config.rb'
21
+ require jasmine_config_overrides if File.exists?(jasmine_config_overrides)
22
+
23
+ puts "your tests are here:"
24
+ puts " http://localhost:8888/"
25
+
26
+ Jasmine::Config.new.start_server
27
+ end
28
+ end
29
+
30
+ desc "Run specs via server"
31
+ task :jasmine => ['jasmine:server']
@@ -0,0 +1,259 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ describe Jasmine::Config do
4
+
5
+ describe "configuration" do
6
+
7
+ before(:all) do
8
+ temp_dir_before
9
+
10
+ Dir::chdir @tmp
11
+ `rails rails-project`
12
+ Dir::chdir 'rails-project'
13
+
14
+ FileUtils.cp_r(File.join(@root, 'generators'), 'vendor')
15
+
16
+ `./script/generate jasmine`
17
+
18
+ Dir::chdir @old_dir
19
+
20
+ @rails_dir = "#{@tmp}/rails-project"
21
+ end
22
+
23
+ after(:all) do
24
+ temp_dir_after
25
+ end
26
+
27
+ before(:each) do
28
+ @template_dir = File.expand_path(File.join(File.dirname(__FILE__), "../generators/jasmine/templates"))
29
+ @config = Jasmine::Config.new
30
+ end
31
+
32
+ describe "defaults" do
33
+
34
+ it "src_dir uses root when src dir is blank" do
35
+ @config.stub!(:project_root).and_return('some_project_root')
36
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
37
+ YAML.stub!(:load).and_return({'src_dir' => nil})
38
+ @config.src_dir.should == 'some_project_root'
39
+ end
40
+
41
+ it "should use correct default yaml config" do
42
+ @config.stub!(:project_root).and_return('some_project_root')
43
+ @config.simple_config_file.should == (File.join('some_project_root', 'spec/javascripts/support/jasmine.yml'))
44
+ end
45
+
46
+ end
47
+
48
+
49
+ describe "simple_config" do
50
+ before(:each) do
51
+ @config.stub!(:src_dir).and_return(File.join(@rails_dir, "."))
52
+ @config.stub!(:spec_dir).and_return(File.join(@rails_dir, "spec/javascripts"))
53
+ end
54
+
55
+ shared_examples_for "simple_config defaults" do
56
+ it "should return the correct files and mappings" do
57
+ @config.src_files.should == []
58
+ @config.stylesheets.should == []
59
+ @config.spec_files.should == ['PlayerSpec.js']
60
+ @config.helpers.should == ['helpers/SpecHelper.js']
61
+ @config.js_files.should == [
62
+ '/__spec__/helpers/SpecHelper.js',
63
+ '/__spec__/PlayerSpec.js',
64
+ ]
65
+ @config.js_files("PlayerSpec.js").should ==
66
+ ['/__spec__/helpers/SpecHelper.js',
67
+ '/__spec__/PlayerSpec.js']
68
+ @config.spec_files_full_paths.should == [
69
+ File.join(@rails_dir, 'spec/javascripts/PlayerSpec.js'),
70
+ ]
71
+ end
72
+ end
73
+
74
+ it "should parse ERB" do
75
+ @config.stub!(:simple_config_file).and_return(File.expand_path(File.join(File.dirname(__FILE__), 'fixture/jasmine.erb.yml')))
76
+ Dir.stub!(:glob).and_return do |glob_string|
77
+ glob_string
78
+ end
79
+ @config.src_files.should == [
80
+ 'file0.js',
81
+ 'file1.js',
82
+ 'file2.js',
83
+ ]
84
+ end
85
+
86
+
87
+ describe "if sources.yaml not found" do
88
+ before(:each) do
89
+ File.stub!(:exist?).and_return(false)
90
+ end
91
+ it_should_behave_like "simple_config defaults"
92
+ end
93
+
94
+ describe "if jasmine.yml is empty" do
95
+ before(:each) do
96
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
97
+ YAML.stub!(:load).and_return(false)
98
+ end
99
+ it_should_behave_like "simple_config defaults"
100
+
101
+ end
102
+
103
+ # describe "using default jasmine.yml" do
104
+ # before(:each) do
105
+ # @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
106
+ # end
107
+ # it_should_behave_like "simple_config defaults"
108
+ #
109
+ # end
110
+
111
+ describe "should use the first appearance of duplicate filenames" do
112
+ before(:each) do
113
+ Dir.stub!(:glob).and_return do |glob_string|
114
+ glob_string
115
+ end
116
+ fake_config = Hash.new.stub!(:[]).and_return(["file1.ext", "file2.ext", "file1.ext"])
117
+ @config.stub!(:simple_config).and_return(fake_config)
118
+ end
119
+
120
+ it "src_files" do
121
+ @config.src_files.should == ['file1.ext', 'file2.ext']
122
+ end
123
+
124
+ it "stylesheets" do
125
+ @config.stylesheets.should == ['file1.ext', 'file2.ext']
126
+ end
127
+
128
+ it "spec_files" do
129
+ @config.spec_files.should == ['file1.ext', 'file2.ext']
130
+ end
131
+
132
+ it "helpers" do
133
+ @config.spec_files.should == ['file1.ext', 'file2.ext']
134
+ end
135
+
136
+ it "js_files" do
137
+ @config.js_files.should == ["/file1.ext",
138
+ "/file2.ext",
139
+ "/__spec__/file1.ext",
140
+ "/__spec__/file2.ext",
141
+ "/__spec__/file1.ext",
142
+ "/__spec__/file2.ext"]
143
+ end
144
+
145
+ it "spec_files_full_paths" do
146
+ @config.spec_files_full_paths.should == [
147
+ File.expand_path("spec/javascripts/file1.ext", @rails_dir),
148
+ File.expand_path("spec/javascripts/file2.ext", @rails_dir)
149
+ ]
150
+ end
151
+
152
+ end
153
+
154
+ it "simple_config stylesheets" do
155
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
156
+ YAML.stub!(:load).and_return({'stylesheets' => ['foo.css', 'bar.css']})
157
+ Dir.stub!(:glob).and_return do |glob_string|
158
+ glob_string
159
+ end
160
+ @config.stylesheets.should == ['foo.css', 'bar.css']
161
+ end
162
+
163
+
164
+ it "using rails jasmine.yml" do
165
+ @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine-rails.yml'))
166
+ @config.spec_files.should == ['PlayerSpec.js']
167
+ @config.helpers.should == ['helpers/SpecHelper.js']
168
+ @config.src_files.should == ['public/javascripts/prototype.js',
169
+ 'public/javascripts/effects.js',
170
+ 'public/javascripts/controls.js',
171
+ 'public/javascripts/dragdrop.js',
172
+ 'public/javascripts/application.js',
173
+ 'public/javascripts/Player.js',
174
+ 'public/javascripts/Song.js']
175
+ @config.js_files.should == [
176
+ '/public/javascripts/prototype.js',
177
+ '/public/javascripts/effects.js',
178
+ '/public/javascripts/controls.js',
179
+ '/public/javascripts/dragdrop.js',
180
+ '/public/javascripts/application.js',
181
+ '/public/javascripts/Player.js',
182
+ '/public/javascripts/Song.js',
183
+ '/__spec__/helpers/SpecHelper.js',
184
+ '/__spec__/PlayerSpec.js',
185
+ ]
186
+ @config.js_files("PlayerSpec.js").should == [
187
+ '/public/javascripts/prototype.js',
188
+ '/public/javascripts/effects.js',
189
+ '/public/javascripts/controls.js',
190
+ '/public/javascripts/dragdrop.js',
191
+ '/public/javascripts/application.js',
192
+ '/public/javascripts/Player.js',
193
+ '/public/javascripts/Song.js',
194
+ '/__spec__/helpers/SpecHelper.js',
195
+ '/__spec__/PlayerSpec.js'
196
+ ]
197
+
198
+ end
199
+
200
+ end
201
+
202
+ end
203
+
204
+ describe "browser configuration" do
205
+ it "should use firefox by default" do
206
+ ENV.stub!(:[], "JASMINE_BROWSER").and_return(nil)
207
+ config = Jasmine::Config.new
208
+ config.stub!(:start_servers)
209
+ Jasmine::SeleniumDriver.should_receive(:new).
210
+ with(anything(), anything(), "*firefox", anything()).
211
+ and_return(mock(Jasmine::SeleniumDriver, :connect => true))
212
+ config.start
213
+ end
214
+
215
+ it "should use ENV['JASMINE_BROWSER'] if set" do
216
+ ENV.stub!(:[], "JASMINE_BROWSER").and_return("mosaic")
217
+ config = Jasmine::Config.new
218
+ config.stub!(:start_servers)
219
+ Jasmine::SeleniumDriver.should_receive(:new).
220
+ with(anything(), anything(), "*mosaic", anything()).
221
+ and_return(mock(Jasmine::SeleniumDriver, :connect => true))
222
+ config.start
223
+ end
224
+ end
225
+
226
+ describe "jasmine host" do
227
+ it "should use http://localhost by default" do
228
+ config = Jasmine::Config.new
229
+ config.instance_variable_set(:@jasmine_server_port, '1234')
230
+ config.stub!(:start_servers)
231
+
232
+ Jasmine::SeleniumDriver.should_receive(:new).
233
+ with(anything(), anything(), anything(), "http://localhost:1234/").
234
+ and_return(mock(Jasmine::SeleniumDriver, :connect => true))
235
+ config.start
236
+ end
237
+
238
+ it "should use ENV['JASMINE_HOST'] if set" do
239
+ ENV.stub!(:[], "JASMINE_HOST").and_return("http://some_host")
240
+ config = Jasmine::Config.new
241
+ config.instance_variable_set(:@jasmine_server_port, '1234')
242
+ config.stub!(:start_servers)
243
+
244
+ Jasmine::SeleniumDriver.should_receive(:new).
245
+ with(anything(), anything(), anything(), "http://some_host:1234/").
246
+ and_return(mock(Jasmine::SeleniumDriver, :connect => true))
247
+ config.start
248
+ end
249
+ end
250
+
251
+ describe "#start_selenium_server" do
252
+ it "should use an existing selenium server if SELENIUM_SERVER_PORT is set" do
253
+ config = Jasmine::Config.new
254
+ ENV.stub!(:[], "SELENIUM_SERVER_PORT").and_return(1234)
255
+ Jasmine.should_receive(:wait_for_listener).with(1234, "selenium server")
256
+ config.start_selenium_server
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ describe "Jasmine command line tool" do
4
+ before :each do
5
+ temp_dir_before
6
+ Dir::chdir @tmp
7
+ end
8
+
9
+ after :each do
10
+ temp_dir_after
11
+ end
12
+
13
+ it "should create files on init" do
14
+ output = capture_stdout do
15
+ Jasmine::CommandLineTool.new.process ["init"]
16
+ end
17
+ output.should =~ /Jasmine has been installed with example specs./
18
+
19
+ my_jasmine_lib = File.expand_path(File.join(@root, "lib"))
20
+ bootstrap = "$:.unshift('#{my_jasmine_lib}')"
21
+
22
+ ENV['JASMINE_GEM_PATH'] = "#{@root}/lib"
23
+ ci_output = `rake -E "#{bootstrap}" --trace jasmine:ci`
24
+ ci_output.should =~ (/[1-9][0-9]* examples, 0 failures/)
25
+ end
26
+ end