evergreen 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +21 -2
- data/lib/evergreen.rb +2 -0
- data/lib/evergreen/evergreen.js +39 -3
- data/lib/evergreen/runner.rb +5 -5
- data/lib/evergreen/spec.rb +10 -2
- data/lib/evergreen/version.rb +1 -1
- data/lib/evergreen/views/list.erb +65 -4
- data/lib/evergreen/views/spec.erb +50 -2
- data/spec/evergreen_spec.rb +8 -2
- data/spec/fixtures/spec/javascripts/coffeescript_spec.coffee +7 -0
- data/spec/fixtures/spec/javascripts/spec_helper.coffee +1 -0
- data/spec/fixtures/spec/javascripts/spec_helper.js +1 -0
- data/spec/fixtures/spec/javascripts/with_helper_spec.js +9 -0
- data/spec/meta_spec.rb +5 -0
- data/spec/spec_spec.rb +16 -1
- metadata +8 -4
data/README.rdoc
CHANGED
@@ -71,11 +71,30 @@ One problem often faced when writing unit tests for client side code is that cha
|
|
71
71
|
|
72
72
|
Even more powerful than that, Evergreen allows you to create HTML templates to go along with your specs. Simply name the template the same as the spec, only with an html extension. For example:
|
73
73
|
|
74
|
-
|
75
|
-
|
74
|
+
spec/javascripts/widget_spec.js
|
75
|
+
spec/javascripts/widget_spec.html
|
76
76
|
|
77
77
|
The template will be placed inside the test div, so that means it should not include html, head, body or similar tags. The template will be restored for each example, so that at the start of each example, the markup inside the test div is identical.
|
78
78
|
|
79
|
+
== Spec Helper
|
80
|
+
|
81
|
+
If you add a spec_helper file like so:
|
82
|
+
|
83
|
+
spec/javascripts/spec_helper.js
|
84
|
+
|
85
|
+
It will automatically be loaded. This is a great place for adding custom matchers and the like.
|
86
|
+
|
87
|
+
== CoffeeScript
|
88
|
+
|
89
|
+
Evergreen supports specs written in {CoffeeScript}[http://github.com/jashkenas/coffee-script]. Just name your spec file _spec.coffee and it will automatically be translated for you.
|
90
|
+
|
91
|
+
You can also add a CoffeeScript spec helper, but remember that CoffeeScript encloses individual files in a closure, if you need something you define in the spec helper to be available in your spec files, attach it to the window object:
|
92
|
+
|
93
|
+
# spec/javascripts/spec_helper.coffee
|
94
|
+
|
95
|
+
MyThing: "foo" # local to spec helper
|
96
|
+
window.MyThing: "foo" # global
|
97
|
+
|
79
98
|
== License:
|
80
99
|
|
81
100
|
(The MIT License)
|
data/lib/evergreen.rb
CHANGED
data/lib/evergreen/evergreen.js
CHANGED
@@ -1,20 +1,25 @@
|
|
1
|
+
if(!this.JSON){this.JSON={};}
|
2
|
+
|
1
3
|
var Evergreen = {};
|
2
4
|
|
3
5
|
Evergreen.ReflectiveReporter = function() {
|
4
6
|
this.reportRunnerStarting = function(runner) {
|
5
|
-
|
7
|
+
Evergreen.results = [];
|
6
8
|
};
|
7
9
|
this.reportSpecResults = function(spec) {
|
8
10
|
var results = spec.results();
|
9
11
|
var item = results.getItems()[0] || {};
|
10
|
-
|
12
|
+
Evergreen.results.push({
|
11
13
|
name: spec.getFullName(),
|
12
14
|
passed: results.failedCount === 0,
|
13
15
|
message: item.message,
|
14
16
|
trace: item.trace
|
15
17
|
});
|
16
18
|
};
|
17
|
-
}
|
19
|
+
};
|
20
|
+
Evergreen.getResults = function() {
|
21
|
+
return JSON.stringify(Evergreen.results);
|
22
|
+
};
|
18
23
|
|
19
24
|
beforeEach(function() {
|
20
25
|
var test = document.getElementById('test');
|
@@ -24,3 +29,34 @@ beforeEach(function() {
|
|
24
29
|
var require = function(file) {
|
25
30
|
document.write('<script type="text/javascript" src="' + file + '"></script>');
|
26
31
|
};
|
32
|
+
|
33
|
+
// === JSON ===
|
34
|
+
|
35
|
+
(function(){function f(n){return n<10?'0'+n:n;}
|
36
|
+
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
|
37
|
+
f(this.getUTCMonth()+1)+'-'+
|
38
|
+
f(this.getUTCDate())+'T'+
|
39
|
+
f(this.getUTCHours())+':'+
|
40
|
+
f(this.getUTCMinutes())+':'+
|
41
|
+
f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
|
42
|
+
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
|
43
|
+
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
|
44
|
+
if(typeof rep==='function'){value=rep.call(holder,key,value);}
|
45
|
+
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
|
46
|
+
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
|
47
|
+
v=partial.length===0?'[]':gap?'[\n'+gap+
|
48
|
+
partial.join(',\n'+gap)+'\n'+
|
49
|
+
mind+']':'['+partial.join(',')+']';gap=mind;return v;}
|
50
|
+
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
|
51
|
+
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
|
52
|
+
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
|
53
|
+
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
|
54
|
+
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
|
55
|
+
return str('',{'':value});};}
|
56
|
+
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
|
57
|
+
return reviver.call(holder,key,value);}
|
58
|
+
text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
|
59
|
+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
|
60
|
+
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
|
61
|
+
throw new SyntaxError('JSON.parse');};}}());
|
62
|
+
|
data/lib/evergreen/runner.rb
CHANGED
@@ -34,9 +34,9 @@ module Evergreen
|
|
34
34
|
def failure_message
|
35
35
|
failed_examples.map do |row|
|
36
36
|
msg = []
|
37
|
-
msg << " Failed: #{row
|
38
|
-
msg << " #{row
|
39
|
-
msg << " in #{row
|
37
|
+
msg << " Failed: #{row['name']}"
|
38
|
+
msg << " #{row['message']}"
|
39
|
+
msg << " in #{row['trace']['fileName']}:#{row['trace']['lineNumber']}" if row['trace']
|
40
40
|
msg.join("\n")
|
41
41
|
end.join("\n\n")
|
42
42
|
end
|
@@ -44,14 +44,14 @@ module Evergreen
|
|
44
44
|
protected
|
45
45
|
|
46
46
|
def failed_examples
|
47
|
-
results.select { |row| !row
|
47
|
+
results.select { |row| !row['passed'] }
|
48
48
|
end
|
49
49
|
|
50
50
|
def results
|
51
51
|
@results ||= begin
|
52
52
|
session = Capybara::Session.new(:envjs, Evergreen.application(spec.root))
|
53
53
|
session.visit(spec.url)
|
54
|
-
session.evaluate_script('
|
54
|
+
JSON.parse(session.evaluate_script('Evergreen.getResults()'))
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
data/lib/evergreen/spec.rb
CHANGED
@@ -2,7 +2,7 @@ module Evergreen
|
|
2
2
|
class Spec
|
3
3
|
|
4
4
|
def self.all(root)
|
5
|
-
Dir.glob(File.join(root, 'spec/javascripts', '*_spec.js')).map do |path|
|
5
|
+
Dir.glob(File.join(root, 'spec/javascripts', '*_spec.{js,coffee}')).map do |path|
|
6
6
|
new(root, File.basename(path))
|
7
7
|
end
|
8
8
|
end
|
@@ -27,7 +27,11 @@ module Evergreen
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def read
|
30
|
-
|
30
|
+
if full_path =~ /\.coffee$/
|
31
|
+
%x(coffee -p #{full_path})
|
32
|
+
else
|
33
|
+
File.read(full_path)
|
34
|
+
end
|
31
35
|
end
|
32
36
|
alias_method :contents, :read
|
33
37
|
|
@@ -35,5 +39,9 @@ module Evergreen
|
|
35
39
|
"/run/#{name}"
|
36
40
|
end
|
37
41
|
|
42
|
+
def exist?
|
43
|
+
File.exist?(full_path)
|
44
|
+
end
|
45
|
+
|
38
46
|
end
|
39
47
|
end
|
data/lib/evergreen/version.rb
CHANGED
@@ -1,6 +1,67 @@
|
|
1
|
-
|
1
|
+
<!doctype html>
|
2
2
|
|
3
|
-
|
4
|
-
<
|
5
|
-
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<title>Evergreen</title>
|
6
|
+
<style type="text/css">
|
7
|
+
* { margin: 0; padding: 0; }
|
8
|
+
body {
|
9
|
+
font-family: 'Lucida grande', 'sans-serif';
|
10
|
+
background: #f0f0f0;
|
11
|
+
}
|
12
|
+
a {
|
13
|
+
color: #00A500;
|
14
|
+
}
|
6
15
|
|
16
|
+
#page {
|
17
|
+
width: 800px;
|
18
|
+
background: white;
|
19
|
+
-moz-border-radius: 3px;
|
20
|
+
padding: 20px;
|
21
|
+
margin: 50px auto 30px;
|
22
|
+
border: 1px solid #ddd
|
23
|
+
}
|
24
|
+
|
25
|
+
#page h1 {
|
26
|
+
margin: 0 0 30px;
|
27
|
+
}
|
28
|
+
|
29
|
+
#page ul li {
|
30
|
+
list-style: none;
|
31
|
+
border: 1px solid #ddd;
|
32
|
+
-moz-border-radius: 3px;
|
33
|
+
margin: 10px 0;
|
34
|
+
background: #f5f5f5;
|
35
|
+
}
|
36
|
+
|
37
|
+
#page ul li a {
|
38
|
+
padding: 7px 10px;
|
39
|
+
display: block;
|
40
|
+
text-decoration: none;
|
41
|
+
}
|
42
|
+
|
43
|
+
#footer {
|
44
|
+
margin: 0 auto 30px;
|
45
|
+
width: 600px;
|
46
|
+
text-align: center;
|
47
|
+
font-size: 13px;
|
48
|
+
color: #aaa;
|
49
|
+
}
|
50
|
+
</style>
|
51
|
+
</head>
|
52
|
+
<body>
|
53
|
+
<div id="page">
|
54
|
+
<h1>Evergreen</h1>
|
55
|
+
|
56
|
+
<ul id="specs">
|
57
|
+
<% @specs.each do |spec| %>
|
58
|
+
<li><a href="<%= url(spec.url) %>"><%= spec.name %></a></li>
|
59
|
+
<% end %>
|
60
|
+
</ul>
|
61
|
+
</div>
|
62
|
+
<div id="footer">
|
63
|
+
Powered by <a href="http://github.com/jnicklas/evergreen">Evergreen</a>.
|
64
|
+
Evergreen is sponsored by <a href="http://elabs.se">Elabs</a>.
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -7,10 +7,54 @@
|
|
7
7
|
<script type="text/javascript" src="<%= url("/lib/jasmine-html.js") %>"></script>
|
8
8
|
<script type="text/javascript" src="<%= url("/evergreen/evergreen.js") %>"></script>
|
9
9
|
<script type="text/javascript" src="<%= url("/spec/#{@spec.name}") %>"></script>
|
10
|
+
<% if @js_spec_helper.exist? %>
|
11
|
+
<script type="text/javascript" src="<%= url("/spec/#{@js_spec_helper.name}") %>"></script>
|
12
|
+
<% end %>
|
13
|
+
<% if @coffee_spec_helper.exist? %>
|
14
|
+
<script type="text/javascript" src="<%= url("/spec/#{@coffee_spec_helper.name}") %>"></script>
|
15
|
+
<% end %>
|
16
|
+
<style>
|
17
|
+
body {
|
18
|
+
font-family: 'Lucida grande', 'sans-serif';
|
19
|
+
background: #f0f0f0;
|
20
|
+
margin: 0;
|
21
|
+
padding: 0;
|
22
|
+
}
|
23
|
+
a {
|
24
|
+
color: #00A500;
|
25
|
+
}
|
26
|
+
|
27
|
+
.jasmine_reporter {
|
28
|
+
width: 800px;
|
29
|
+
background: white;
|
30
|
+
padding: 20px;
|
31
|
+
min-height: 50px;
|
32
|
+
margin: 30px auto 30px;
|
33
|
+
border: 1px solid #ddd;
|
34
|
+
-moz-border-radius: 3px;
|
35
|
+
width: 800px;
|
36
|
+
}
|
37
|
+
#test {
|
38
|
+
width: 800px;
|
39
|
+
background: white;
|
40
|
+
-moz-border-radius: 3px;
|
41
|
+
padding: 20px;
|
42
|
+
min-height: 50px;
|
43
|
+
margin: 50px auto 30px;
|
44
|
+
border: 1px solid #ddd
|
45
|
+
}
|
46
|
+
#footer {
|
47
|
+
margin: 0 auto 30px;
|
48
|
+
width: 600px;
|
49
|
+
text-align: center;
|
50
|
+
font-size: 13px;
|
51
|
+
color: #aaa;
|
52
|
+
}
|
53
|
+
</style>
|
10
54
|
</head>
|
11
55
|
<body>
|
12
|
-
|
13
|
-
|
56
|
+
<div id="test">
|
57
|
+
</div>
|
14
58
|
<script type="text/javascript">
|
15
59
|
(function() {
|
16
60
|
Evergreen.template = <%= @spec.template.to_json %>;
|
@@ -20,5 +64,9 @@
|
|
20
64
|
jasmineEnv.execute();
|
21
65
|
})();
|
22
66
|
</script>
|
67
|
+
<div id="footer">
|
68
|
+
Powered by <a href="http://github.com/jnicklas/evergreen">Evergreen</a>.
|
69
|
+
Evergreen is sponsored by <a href="http://elabs.se">Elabs</a>.
|
70
|
+
</div>
|
23
71
|
</body>
|
24
72
|
</html>
|
data/spec/evergreen_spec.rb
CHANGED
@@ -5,13 +5,19 @@ describe Evergreen, ".application" do
|
|
5
5
|
|
6
6
|
it "should show a successful test run" do
|
7
7
|
visit("/")
|
8
|
-
click_link("
|
8
|
+
click_link("testing_spec.js")
|
9
|
+
page.should have_content("2 specs, 0 failures")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should show a successful test run for a coffeescript spec" do
|
13
|
+
visit("/")
|
14
|
+
click_link("coffeescript_spec.coffee")
|
9
15
|
page.should have_content("2 specs, 0 failures")
|
10
16
|
end
|
11
17
|
|
12
18
|
it "should show errors for a failing spec" do
|
13
19
|
visit("/")
|
14
|
-
click_link("
|
20
|
+
click_link("failing_spec.js")
|
15
21
|
page.should have_content("2 specs, 1 failure")
|
16
22
|
page.should have_content("Expected 'bar' to equal 'noooooo'.")
|
17
23
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
window.CoffeeSpecHelper: { coffee: 'script' }
|
@@ -0,0 +1 @@
|
|
1
|
+
var SpecHelper = { spec: 'helper' };
|
data/spec/meta_spec.rb
CHANGED
@@ -9,6 +9,11 @@ describe Evergreen::Runner do
|
|
9
9
|
it { should pass }
|
10
10
|
end
|
11
11
|
|
12
|
+
context "with spec helper" do
|
13
|
+
let(:spec) { Evergreen::Spec.new(root, 'with_helper_spec.js') }
|
14
|
+
it { should pass }
|
15
|
+
end
|
16
|
+
|
12
17
|
context "with template spec" do
|
13
18
|
let(:spec) { Evergreen::Spec.new(root, 'templates_spec.js') }
|
14
19
|
it { should pass }
|
data/spec/spec_spec.rb
CHANGED
@@ -15,7 +15,7 @@ describe Evergreen::Spec do
|
|
15
15
|
subject { Evergreen::Spec.all(root) }
|
16
16
|
|
17
17
|
it "should find all specs in the given root directory" do
|
18
|
-
subject.map(&:name).should include('testing_spec.js', 'foo_spec.js', 'bar_spec.js')
|
18
|
+
subject.map(&:name).should include('testing_spec.js', 'foo_spec.js', 'bar_spec.js', 'coffeescript_spec.coffee')
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -24,7 +24,22 @@ describe Evergreen::Spec do
|
|
24
24
|
its(:template) { should == %(<h1 id="from-template">This is from the template</h1>\n) }
|
25
25
|
end
|
26
26
|
|
27
|
+
context "with coffeescript" do
|
28
|
+
subject { Evergreen::Spec.new(root, 'coffeescript_spec.coffee') }
|
29
|
+
its(:contents) { should =~ /describe\('coffeescript', function/ }
|
30
|
+
end
|
31
|
+
|
27
32
|
context "without a template" do
|
28
33
|
its(:template) { should == '' }
|
29
34
|
end
|
35
|
+
|
36
|
+
context "with existing spec file" do
|
37
|
+
it { should exist }
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with missing spec file" do
|
41
|
+
subject { Evergreen::Spec.new(root, 'does_not_exist.js') }
|
42
|
+
it { should_not exist }
|
43
|
+
end
|
44
|
+
|
30
45
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: evergreen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 2
|
10
|
+
version: 0.2.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jonas Nicklas
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-07-
|
18
|
+
date: 2010-07-11 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -203,12 +203,16 @@ files:
|
|
203
203
|
- spec/evergreen_spec.rb
|
204
204
|
- spec/fixtures/public/jquery.js
|
205
205
|
- spec/fixtures/spec/javascripts/bar_spec.js
|
206
|
+
- spec/fixtures/spec/javascripts/coffeescript_spec.coffee
|
206
207
|
- spec/fixtures/spec/javascripts/failing_spec.js
|
207
208
|
- spec/fixtures/spec/javascripts/foo_spec.js
|
209
|
+
- spec/fixtures/spec/javascripts/spec_helper.coffee
|
210
|
+
- spec/fixtures/spec/javascripts/spec_helper.js
|
208
211
|
- spec/fixtures/spec/javascripts/templates_spec.html
|
209
212
|
- spec/fixtures/spec/javascripts/templates_spec.js
|
210
213
|
- spec/fixtures/spec/javascripts/testing_spec.js
|
211
214
|
- spec/fixtures/spec/javascripts/transactions_spec.js
|
215
|
+
- spec/fixtures/spec/javascripts/with_helper_spec.js
|
212
216
|
- spec/meta_spec.rb
|
213
217
|
- spec/runner_spec.rb
|
214
218
|
- spec/spec_helper.rb
|