rails31-evergreen 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +193 -0
- data/bin/evergreen +18 -0
- data/config/routes.rb +3 -0
- data/lib/evergreen.rb +41 -0
- data/lib/evergreen/application.rb +43 -0
- data/lib/evergreen/cli.rb +23 -0
- data/lib/evergreen/rails.rb +12 -0
- data/lib/evergreen/reports.rb +79 -0
- data/lib/evergreen/resources/evergreen.css +64 -0
- data/lib/evergreen/resources/evergreen.js +80 -0
- data/lib/evergreen/resources/jasmine-html.js +190 -0
- data/lib/evergreen/resources/jasmine.css +166 -0
- data/lib/evergreen/resources/jasmine.js +2477 -0
- data/lib/evergreen/resources/json2.js +478 -0
- data/lib/evergreen/resources/version.rb +6 -0
- data/lib/evergreen/runner.rb +148 -0
- data/lib/evergreen/server.rb +22 -0
- data/lib/evergreen/spec.rb +52 -0
- data/lib/evergreen/suite.rb +44 -0
- data/lib/evergreen/tasks.rb +6 -0
- data/lib/evergreen/template.rb +32 -0
- data/lib/evergreen/version.rb +3 -0
- data/lib/evergreen/views/layout.erb +19 -0
- data/lib/evergreen/views/list.erb +9 -0
- data/lib/evergreen/views/spec.erb +40 -0
- data/lib/jasmine/Gemfile +6 -0
- data/lib/jasmine/MIT.LICENSE +20 -0
- data/lib/jasmine/README.markdown +28 -0
- data/lib/jasmine/Rakefile +182 -0
- data/lib/jasmine/cruise_config.rb +21 -0
- data/lib/jasmine/example/SpecRunner.html +27 -0
- data/lib/jasmine/example/spec/PlayerSpec.js +58 -0
- data/lib/jasmine/example/spec/SpecHelper.js +9 -0
- data/lib/jasmine/example/src/Player.js +22 -0
- data/lib/jasmine/example/src/Song.js +7 -0
- data/lib/jasmine/images/fail-16.png +0 -0
- data/lib/jasmine/images/fail.png +0 -0
- data/lib/jasmine/images/go-16.png +0 -0
- data/lib/jasmine/images/go.png +0 -0
- data/lib/jasmine/images/pending-16.png +0 -0
- data/lib/jasmine/images/pending.png +0 -0
- data/lib/jasmine/images/question-bk.png +0 -0
- data/lib/jasmine/images/questionbk-16.png +0 -0
- data/lib/jasmine/images/spinner.gif +0 -0
- data/lib/jasmine/jsdoc-template/allclasses.tmpl +17 -0
- data/lib/jasmine/jsdoc-template/allfiles.tmpl +56 -0
- data/lib/jasmine/jsdoc-template/class.tmpl +646 -0
- data/lib/jasmine/jsdoc-template/index.tmpl +39 -0
- data/lib/jasmine/jsdoc-template/publish.js +184 -0
- data/lib/jasmine/jsdoc-template/static/default.css +162 -0
- data/lib/jasmine/jsdoc-template/static/header.html +2 -0
- data/lib/jasmine/jsdoc-template/static/index.html +19 -0
- data/lib/jasmine/jsdoc-template/symbol.tmpl +35 -0
- data/lib/jasmine/lib/jasmine-html.js +188 -0
- data/lib/jasmine/lib/jasmine.css +166 -0
- data/lib/jasmine/lib/jasmine.js +2421 -0
- data/lib/jasmine/lib/json2.js +478 -0
- data/lib/jasmine/spec/runner.html +80 -0
- data/lib/jasmine/spec/suites/BaseSpec.js +27 -0
- data/lib/jasmine/spec/suites/CustomMatchersSpec.js +97 -0
- data/lib/jasmine/spec/suites/EnvSpec.js +158 -0
- data/lib/jasmine/spec/suites/ExceptionsSpec.js +107 -0
- data/lib/jasmine/spec/suites/JsApiReporterSpec.js +103 -0
- data/lib/jasmine/spec/suites/MatchersSpec.js +795 -0
- data/lib/jasmine/spec/suites/MockClockSpec.js +38 -0
- data/lib/jasmine/spec/suites/MultiReporterSpec.js +45 -0
- data/lib/jasmine/spec/suites/NestedResultsSpec.js +54 -0
- data/lib/jasmine/spec/suites/PrettyPrintSpec.js +93 -0
- data/lib/jasmine/spec/suites/QueueSpec.js +23 -0
- data/lib/jasmine/spec/suites/ReporterSpec.js +56 -0
- data/lib/jasmine/spec/suites/RunnerSpec.js +267 -0
- data/lib/jasmine/spec/suites/SpecRunningSpec.js +1253 -0
- data/lib/jasmine/spec/suites/SpecSpec.js +124 -0
- data/lib/jasmine/spec/suites/SpySpec.js +201 -0
- data/lib/jasmine/spec/suites/SuiteSpec.js +120 -0
- data/lib/jasmine/spec/suites/TrivialReporterSpec.js +238 -0
- data/lib/jasmine/spec/suites/UtilSpec.js +40 -0
- data/lib/jasmine/spec/suites/WaitsForBlockSpec.js +87 -0
- data/lib/jasmine/src/Block.js +22 -0
- data/lib/jasmine/src/Env.js +264 -0
- data/lib/jasmine/src/JsApiReporter.js +102 -0
- data/lib/jasmine/src/Matchers.js +354 -0
- data/lib/jasmine/src/MultiReporter.js +35 -0
- data/lib/jasmine/src/NestedResults.js +80 -0
- data/lib/jasmine/src/PrettyPrinter.js +122 -0
- data/lib/jasmine/src/Queue.js +99 -0
- data/lib/jasmine/src/Reporter.js +31 -0
- data/lib/jasmine/src/Runner.js +77 -0
- data/lib/jasmine/src/Spec.js +242 -0
- data/lib/jasmine/src/Suite.js +82 -0
- data/lib/jasmine/src/WaitsBlock.js +13 -0
- data/lib/jasmine/src/WaitsForBlock.js +52 -0
- data/lib/jasmine/src/base.js +589 -0
- data/lib/jasmine/src/html/TrivialReporter.js +188 -0
- data/lib/jasmine/src/html/jasmine.css +166 -0
- data/lib/jasmine/src/mock-timeout.js +183 -0
- data/lib/jasmine/src/util.js +67 -0
- data/lib/jasmine/src/version.json +5 -0
- data/lib/tasks/evergreen.rake +54 -0
- data/spec/evergreen_spec.rb +29 -0
- data/spec/meta_spec.rb +50 -0
- data/spec/runner_spec.rb +33 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/spec_spec.rb +28 -0
- data/spec/suite1/public/jquery.js +152 -0
- data/spec/suite1/public/styles.css +3 -0
- data/spec/suite1/spec/javascripts/bar_spec.js +0 -0
- data/spec/suite1/spec/javascripts/coffeescript_spec.coffee +7 -0
- data/spec/suite1/spec/javascripts/failing_spec.js +12 -0
- data/spec/suite1/spec/javascripts/foo_spec.js +0 -0
- data/spec/suite1/spec/javascripts/invalid_coffee_spec.coffee +1 -0
- data/spec/suite1/spec/javascripts/libs/lucid_spec.js +0 -0
- data/spec/suite1/spec/javascripts/models/game_spec.js +0 -0
- data/spec/suite1/spec/javascripts/slow_spec.coffee +8 -0
- data/spec/suite1/spec/javascripts/spec_helper.coffee +1 -0
- data/spec/suite1/spec/javascripts/spec_helper.js +1 -0
- data/spec/suite1/spec/javascripts/templates/another_template.html +1 -0
- data/spec/suite1/spec/javascripts/templates/escape.html +1 -0
- data/spec/suite1/spec/javascripts/templates/one_template.html +1 -0
- data/spec/suite1/spec/javascripts/templates/script_tags.html +3 -0
- data/spec/suite1/spec/javascripts/templates_spec.js +55 -0
- data/spec/suite1/spec/javascripts/testing_spec.js +11 -0
- data/spec/suite1/spec/javascripts/transactions_spec.js +14 -0
- data/spec/suite1/spec/javascripts/with_helper_spec.js +9 -0
- data/spec/suite2/config/evergreen.rb +5 -0
- data/spec/suite2/public_html/foo.js +1 -0
- data/spec/suite2/spec/awesome_spec.js +12 -0
- data/spec/suite2/spec/failing_spec.js +5 -0
- data/spec/suite2/templates/foo.html +1 -0
- data/spec/suite_spec.rb +26 -0
- data/spec/template_spec.rb +32 -0
- metadata +296 -0
data/README.rdoc
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
= Evergreen
|
2
|
+
|
3
|
+
"Because green is the new Blue(Ridge)"
|
4
|
+
|
5
|
+
Evergreen is a tool to run javascript unit tests for client side JavaScript. It
|
6
|
+
combines a server which allows you to serve up and run your specs in a browser,
|
7
|
+
as well as a runner which uses Capybara and any of its drivers to run your
|
8
|
+
specs. Evergreen uses the Jasmine unit testing framework for JavaScript.
|
9
|
+
|
10
|
+
http://github.com/jnicklas/evergreen
|
11
|
+
|
12
|
+
== Philosophy
|
13
|
+
|
14
|
+
Evergreen is a unit testing tool. Its purpose is to test JavaScript in
|
15
|
+
isolation from your application. If you need a tool that tests how your
|
16
|
+
JavaScript integrates with your application you should use an integration
|
17
|
+
testing framework, such as {Capybara}[http://github.com/jnicklas/capybara].
|
18
|
+
|
19
|
+
== Installation
|
20
|
+
|
21
|
+
Install as a Ruby gem:
|
22
|
+
|
23
|
+
gem install evergreen
|
24
|
+
|
25
|
+
== Usage
|
26
|
+
|
27
|
+
Evergreen assumes a file and directory structure, place all your javascript
|
28
|
+
code inside ./public and all spec files inside ./spec/javascripts. All spec
|
29
|
+
files should end in _spec.js. For example:
|
30
|
+
|
31
|
+
public/widget.js
|
32
|
+
spec/javascripts/widget_spec.js
|
33
|
+
|
34
|
+
You can require files from the public directory inside your spec file:
|
35
|
+
|
36
|
+
require('/widget.js')
|
37
|
+
|
38
|
+
describe('a widget', function() {
|
39
|
+
...
|
40
|
+
});
|
41
|
+
|
42
|
+
You can now look at your spec files inside a browser by starting up the
|
43
|
+
Evergreen server:
|
44
|
+
|
45
|
+
evergreen serve
|
46
|
+
|
47
|
+
Alternatively you can run the specs headlessly by running:
|
48
|
+
|
49
|
+
evergreen run
|
50
|
+
|
51
|
+
== Integrating with Rails 3
|
52
|
+
|
53
|
+
Add Evergreen to your Gemfile:
|
54
|
+
|
55
|
+
gem 'evergreen', :require => 'evergreen/rails'
|
56
|
+
|
57
|
+
Start your rails application and navigate to /evergreen. You should now see a
|
58
|
+
list of all spec files, click on one to run it.
|
59
|
+
|
60
|
+
There's a rake task provided for you that you can use to run your specs:
|
61
|
+
|
62
|
+
rake spec:javascripts
|
63
|
+
|
64
|
+
== Integrating with Rails 2
|
65
|
+
|
66
|
+
Add the following line to your Rakefile:
|
67
|
+
|
68
|
+
require 'evergreen/tasks'
|
69
|
+
|
70
|
+
This will give you the `spec:javascripts` rake task. Note that mounting is not
|
71
|
+
possible under Rails 2 and that `require 'evergreen/rails'` will fail.
|
72
|
+
|
73
|
+
== Configuration
|
74
|
+
|
75
|
+
By default, Evergreen uses Selenium to run your specs and assumes a certain
|
76
|
+
directory structure. If this standard is fine for you, then you don't need to
|
77
|
+
do anything else. If you need to configure Evergreen to suit your needs,
|
78
|
+
Evergreen will automatically look for and load the following files:
|
79
|
+
|
80
|
+
config/evergreen.rb
|
81
|
+
.evergreen
|
82
|
+
~/.evergreen
|
83
|
+
|
84
|
+
The content of these files could look like this:
|
85
|
+
|
86
|
+
require 'capybara/envjs'
|
87
|
+
|
88
|
+
Evergreen.configure do |config|
|
89
|
+
config.driver = :envjs
|
90
|
+
config.public_dir = 'public_html'
|
91
|
+
config.template_dir = 'templates'
|
92
|
+
config.spec_dir = 'spec'
|
93
|
+
end
|
94
|
+
|
95
|
+
== Transactions
|
96
|
+
|
97
|
+
One problem often faced when writing unit tests for client side code is that
|
98
|
+
changes to the page are not reverted for the next example, so that successive
|
99
|
+
examples become dependent on each other. Evergreen adds a special div to your
|
100
|
+
page with an id of test. This div is automatically emptied before each example.
|
101
|
+
You should avoid appending markup to the page body and instead append it to
|
102
|
+
this test div:
|
103
|
+
|
104
|
+
describe('transactions', function() {
|
105
|
+
it("should add stuff in one test...", function() {
|
106
|
+
$('#test').append('<h1 id="added">New Stuff</h1>');
|
107
|
+
expect($('#test h1#added').length).toEqual(1);
|
108
|
+
});
|
109
|
+
|
110
|
+
it("... should have been removed before the next starts", function() {
|
111
|
+
expect($('#test h1#added').length).toEqual(0);
|
112
|
+
});
|
113
|
+
});
|
114
|
+
|
115
|
+
== Templates
|
116
|
+
|
117
|
+
Even more powerful than that, Evergreen allows you to create HTML templates to
|
118
|
+
go along with your specs. Put the templates in their own folder like this:
|
119
|
+
|
120
|
+
spec/javascripts/templates/one_template.html
|
121
|
+
spec/javascripts/templates/another_template.html
|
122
|
+
|
123
|
+
You can then load the template into the test div, by calling the template
|
124
|
+
function in your specs:
|
125
|
+
|
126
|
+
describe('transactions', function() {
|
127
|
+
template('one_template.html')
|
128
|
+
|
129
|
+
it("should load the template in this test", function() {
|
130
|
+
...
|
131
|
+
});
|
132
|
+
});
|
133
|
+
|
134
|
+
== Spec Helper
|
135
|
+
|
136
|
+
If you add a spec_helper file like so:
|
137
|
+
|
138
|
+
spec/javascripts/spec_helper.js
|
139
|
+
|
140
|
+
It will automatically be loaded. This is a great place for adding custom
|
141
|
+
matchers and the like.
|
142
|
+
|
143
|
+
== CoffeeScript
|
144
|
+
|
145
|
+
Evergreen supports specs written in
|
146
|
+
{CoffeeScript}[http://github.com/jashkenas/coffee-script]. Just name your spec
|
147
|
+
file _spec.coffee and it will automatically be translated for you.
|
148
|
+
|
149
|
+
You can also add a CoffeeScript spec helper, but remember that CoffeeScript
|
150
|
+
encloses individual files in a closure, if you need something you define in the
|
151
|
+
spec helper to be available in your spec files, attach it to the window object:
|
152
|
+
|
153
|
+
# spec/javascripts/spec_helper.coffee
|
154
|
+
|
155
|
+
MyThing: "foo" # local to spec helper
|
156
|
+
window.MyThing: "foo" # global
|
157
|
+
|
158
|
+
== Development
|
159
|
+
|
160
|
+
If you plan to work on Evergreen, you need to checkout the Jasmine gem, which
|
161
|
+
is added as a git submodule. Run the following command:
|
162
|
+
|
163
|
+
git submodule update --init
|
164
|
+
|
165
|
+
If you're using a version of Evergreen from git with bundler, you need to tell
|
166
|
+
bundler to use submodules, this can be achieved with the following command:
|
167
|
+
|
168
|
+
gem 'evergreen', :submodules => true, :git => 'git://github.com/jnicklas/evergreen.git'
|
169
|
+
|
170
|
+
== License:
|
171
|
+
|
172
|
+
(The MIT License)
|
173
|
+
|
174
|
+
Copyright (c) 2009 Jonas Nicklas
|
175
|
+
|
176
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
177
|
+
a copy of this software and associated documentation files (the
|
178
|
+
'Software'), to deal in the Software without restriction, including
|
179
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
180
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
181
|
+
permit persons to whom the Software is furnished to do so, subject to
|
182
|
+
the following conditions:
|
183
|
+
|
184
|
+
The above copyright notice and this permission notice shall be
|
185
|
+
included in all copies or substantial portions of the Software.
|
186
|
+
|
187
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
188
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
189
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
190
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
191
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
192
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
193
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/evergreen
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
|
4
|
+
|
5
|
+
require 'evergreen'
|
6
|
+
|
7
|
+
begin
|
8
|
+
# The dup is to keep ARGV intact, so that tools like ruby-debug can respawn.
|
9
|
+
success = Evergreen::Cli.execute(ARGV.dup)
|
10
|
+
Kernel.exit(success ? 0 : 1)
|
11
|
+
rescue SystemExit => e
|
12
|
+
Kernel.exit(e.status)
|
13
|
+
rescue Exception => e
|
14
|
+
STDERR.puts("#{e.message} (#{e.class})")
|
15
|
+
STDERR.puts(e.backtrace.join("\n"))
|
16
|
+
Kernel.exit(1)
|
17
|
+
end
|
18
|
+
|
data/config/routes.rb
ADDED
data/lib/evergreen.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'capybara'
|
4
|
+
require 'launchy'
|
5
|
+
require 'evergreen/version'
|
6
|
+
require 'evergreen/application'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
module Evergreen
|
10
|
+
autoload :Cli, 'evergreen/cli'
|
11
|
+
autoload :Server, 'evergreen/server'
|
12
|
+
autoload :Runner, 'evergreen/runner'
|
13
|
+
autoload :Suite, 'evergreen/suite'
|
14
|
+
autoload :Spec, 'evergreen/spec'
|
15
|
+
autoload :Template, 'evergreen/template'
|
16
|
+
autoload :Reports, 'evergreen/reports'
|
17
|
+
|
18
|
+
class << self
|
19
|
+
attr_accessor :driver, :public_dir, :template_dir, :spec_dir
|
20
|
+
|
21
|
+
def configure
|
22
|
+
yield self
|
23
|
+
end
|
24
|
+
|
25
|
+
def extensions(&block)
|
26
|
+
@extensions = block if block
|
27
|
+
@extensions
|
28
|
+
end
|
29
|
+
|
30
|
+
def use_defaults!
|
31
|
+
configure do |config|
|
32
|
+
config.driver = :selenium
|
33
|
+
config.public_dir = 'public'
|
34
|
+
config.spec_dir = 'spec/javascripts'
|
35
|
+
config.template_dir = 'spec/javascripts/templates'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Evergreen.use_defaults!
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Evergreen
|
2
|
+
def self.application(suite)
|
3
|
+
Rack::Builder.new do
|
4
|
+
instance_eval(&Evergreen.extensions) if Evergreen.extensions
|
5
|
+
|
6
|
+
map "/resources" do
|
7
|
+
use Rack::Static, :urls => ["/"], :root => File.expand_path('resources', File.dirname(__FILE__))
|
8
|
+
run lambda { |env| [404, {}, "No such file"]}
|
9
|
+
end
|
10
|
+
|
11
|
+
map "/" do
|
12
|
+
app = Class.new(Sinatra::Base).tap do |app|
|
13
|
+
app.reset!
|
14
|
+
app.class_eval do
|
15
|
+
set :static, true
|
16
|
+
set :root, File.expand_path('.', File.dirname(__FILE__))
|
17
|
+
set :public, File.expand_path(File.join(suite.root, Evergreen.public_dir), File.dirname(__FILE__))
|
18
|
+
|
19
|
+
helpers do
|
20
|
+
def url(path)
|
21
|
+
request.env['SCRIPT_NAME'].to_s + path.to_s
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
get '/' do
|
26
|
+
@suite = suite
|
27
|
+
erb :list
|
28
|
+
end
|
29
|
+
|
30
|
+
get '/run/*' do |name|
|
31
|
+
@suite = suite
|
32
|
+
@spec = suite.get_spec(name)
|
33
|
+
@js_spec_helper = suite.get_spec('spec_helper.js')
|
34
|
+
@coffee_spec_helper = suite.get_spec('spec_helper.coffee')
|
35
|
+
erb :spec
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
run app
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Evergreen
|
2
|
+
class Cli
|
3
|
+
def self.execute(argv)
|
4
|
+
new.execute(argv)
|
5
|
+
end
|
6
|
+
|
7
|
+
def execute(argv)
|
8
|
+
command = argv.shift
|
9
|
+
root = File.expand_path(argv.shift || '.', Dir.pwd)
|
10
|
+
|
11
|
+
case command
|
12
|
+
when "serve"
|
13
|
+
Evergreen::Suite.new(root).serve
|
14
|
+
return true
|
15
|
+
when "run"
|
16
|
+
return Evergreen::Suite.new(root).run
|
17
|
+
else
|
18
|
+
puts "no such command '#{command}'"
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
3
|
+
# generates reports in junit xml for ci/jenkins
|
4
|
+
module Evergreen
|
5
|
+
module Reports
|
6
|
+
def self.filename(spec_result, index)
|
7
|
+
File.join(dir, "#{spec_result[:name]}.#{index}.xml")
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.dir
|
11
|
+
ENV['CI_REPORTS'] || File.expand_path("#{Dir.getwd}/reports")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.collect_data(suite)
|
15
|
+
# open new reporter
|
16
|
+
runners = suite.runner.instance_eval('spec_runners')
|
17
|
+
result_data = runners.map do |specrunner|
|
18
|
+
{
|
19
|
+
:name => specrunner.spec.name,
|
20
|
+
:passed => specrunner.spec.passed?,
|
21
|
+
:results => specrunner.examples.map { |r|
|
22
|
+
row = r.instance_variable_get("@row")
|
23
|
+
hash = {}
|
24
|
+
row.each {|k,v| hash[k] = v}
|
25
|
+
hash
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.find_filename(spec_result)
|
32
|
+
index = 0
|
33
|
+
while File.exists?(filename(spec_result, index))
|
34
|
+
index = index + 1
|
35
|
+
end
|
36
|
+
filename(spec_result, index)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.publish_spec(spec_result)
|
40
|
+
File.open(find_filename(spec_result), "w") do |f|
|
41
|
+
builder = Builder::XmlMarkup.new(:target => f, :indent => 2, :escape_attrs => true)
|
42
|
+
builder.instruct!
|
43
|
+
|
44
|
+
tests = 0
|
45
|
+
failures = 0
|
46
|
+
spec_result[:results].each do |result|
|
47
|
+
tests = tests + 1
|
48
|
+
failures = failures + 1 unless result['passed']
|
49
|
+
end
|
50
|
+
|
51
|
+
builder.testsuite({:name => spec_result[:name], :tests => tests, :failures => failures}) do
|
52
|
+
spec_result[:results].each do |result|
|
53
|
+
builder.testcase({'name' => "#{spec_result[:name]} - #{result['name']}"}) do
|
54
|
+
unless result['passed']
|
55
|
+
builder.failure(:message => result['message']) do
|
56
|
+
builder.text!('Failed: '+result['name']+' '+result['message'])
|
57
|
+
if result['trace']
|
58
|
+
builder.text!(" -> in #{result['trace']['fileName']}:#{result['trace']['lineNumber']}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.publish!(suite)
|
69
|
+
result_data = collect_data(suite)
|
70
|
+
|
71
|
+
FileUtils.rm_rf(dir)
|
72
|
+
FileUtils.mkdir_p(dir)
|
73
|
+
|
74
|
+
result_data.each do |spec_result|
|
75
|
+
publish_spec(spec_result)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
body {
|
2
|
+
font-family: 'Lucida grande', 'sans-serif';
|
3
|
+
background: #f0f0f0;
|
4
|
+
}
|
5
|
+
|
6
|
+
a {
|
7
|
+
color: #00A500;
|
8
|
+
}
|
9
|
+
|
10
|
+
#page, #test, .jasmine_reporter {
|
11
|
+
width: 800px;
|
12
|
+
background: white;
|
13
|
+
-moz-border-radius: 3px;
|
14
|
+
padding: 20px;
|
15
|
+
margin: 50px auto 30px;
|
16
|
+
border: 1px solid #ddd
|
17
|
+
}
|
18
|
+
|
19
|
+
#test {
|
20
|
+
min-height: 50px;
|
21
|
+
max-height: 300px;
|
22
|
+
overflow: auto;
|
23
|
+
margin: 30px auto 30px;
|
24
|
+
}
|
25
|
+
|
26
|
+
.jasmine_reporter {
|
27
|
+
margin: 30px auto 30px;
|
28
|
+
}
|
29
|
+
|
30
|
+
#page h1 {
|
31
|
+
font-size: 24px;
|
32
|
+
margin: 0 0 15px;
|
33
|
+
}
|
34
|
+
|
35
|
+
#page a.back {
|
36
|
+
font-size: 12px;
|
37
|
+
}
|
38
|
+
|
39
|
+
#page ul {
|
40
|
+
margin: 0;
|
41
|
+
padding: 0;
|
42
|
+
}
|
43
|
+
|
44
|
+
#page ul li {
|
45
|
+
list-style: none;
|
46
|
+
border: 1px solid #ddd;
|
47
|
+
-moz-border-radius: 3px;
|
48
|
+
margin: 10px 0;
|
49
|
+
background: #f5f5f5;
|
50
|
+
}
|
51
|
+
|
52
|
+
#page ul li a {
|
53
|
+
padding: 7px 10px;
|
54
|
+
display: block;
|
55
|
+
text-decoration: none;
|
56
|
+
}
|
57
|
+
|
58
|
+
#footer {
|
59
|
+
margin: 0 auto 30px;
|
60
|
+
width: 600px;
|
61
|
+
text-align: center;
|
62
|
+
font-size: 13px;
|
63
|
+
color: #aaa;
|
64
|
+
}
|