evergreen 0.4.1 → 1.0.0.rc
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -2
- data/config/routes.rb +1 -1
- data/lib/evergreen.rb +2 -1
- data/lib/evergreen/application.rb +57 -34
- data/lib/evergreen/cli.rb +9 -3
- data/lib/evergreen/rails.rb +8 -6
- data/lib/evergreen/resources/elabs.png +0 -0
- data/lib/evergreen/resources/evergreen.css +116 -8
- data/lib/evergreen/resources/jquery.js +152 -0
- data/lib/evergreen/resources/{evergreen.js → json2.js} +6 -61
- data/lib/evergreen/resources/list.js +51 -0
- data/lib/evergreen/resources/run.js +50 -0
- data/lib/evergreen/server.rb +1 -1
- data/lib/evergreen/spec.rb +1 -1
- data/lib/evergreen/suite.rb +11 -5
- data/lib/evergreen/tasks.rb +7 -3
- data/lib/evergreen/version.rb +1 -1
- data/lib/evergreen/views/_spec_error.erb +5 -0
- data/lib/evergreen/views/layout.erb +1 -1
- data/lib/evergreen/views/list.erb +11 -1
- data/lib/evergreen/views/{spec.erb → run.erb} +13 -12
- data/lib/tasks/evergreen.rake +3 -2
- data/spec/evergreen_spec.rb +23 -0
- data/spec/meta_spec.rb +3 -3
- data/spec/runner_spec.rb +1 -2
- data/spec/spec_helper.rb +5 -2
- data/spec/spec_spec.rb +3 -4
- data/spec/suite1/spec/javascripts/templates_spec.js +1 -4
- data/spec/suite2/public_html/foo.js +1 -1
- data/spec/suite2/spec/awesome_spec.js +1 -1
- data/spec/suite_spec.rb +5 -6
- data/spec/template_spec.rb +4 -6
- metadata +90 -134
@@ -1,56 +1,5 @@
|
|
1
|
-
if(!
|
2
|
-
|
3
|
-
var Evergreen = {};
|
4
|
-
|
5
|
-
Evergreen.dots = ""
|
6
|
-
|
7
|
-
Evergreen.ReflectiveReporter = function() {
|
8
|
-
this.reportRunnerStarting = function(runner) {
|
9
|
-
Evergreen.results = [];
|
10
|
-
};
|
11
|
-
this.reportSpecResults = function(spec) {
|
12
|
-
var results = spec.results();
|
13
|
-
var item = results.getItems()[0] || {};
|
14
|
-
Evergreen.results.push({
|
15
|
-
name: spec.getFullName(),
|
16
|
-
passed: results.failedCount === 0,
|
17
|
-
message: item.message,
|
18
|
-
trace: item.trace
|
19
|
-
});
|
20
|
-
Evergreen.dots += (results.failedCount === 0) ? "." : "F";
|
21
|
-
};
|
22
|
-
this.reportRunnerResults = function(runner) {
|
23
|
-
Evergreen.done = true;
|
24
|
-
};
|
25
|
-
};
|
26
|
-
|
27
|
-
Evergreen.templates = {};
|
28
|
-
|
29
|
-
Evergreen.getResults = function() {
|
30
|
-
return JSON.stringify(Evergreen.results);
|
31
|
-
};
|
32
|
-
|
33
|
-
beforeEach(function() {
|
34
|
-
document.getElementById('test').innerHTML = "";
|
35
|
-
});
|
36
|
-
|
37
|
-
var template = function(name) {
|
38
|
-
beforeEach(function() {
|
39
|
-
document.getElementById('test').innerHTML = Evergreen.templates[name]
|
40
|
-
});
|
41
|
-
};
|
42
|
-
|
43
|
-
var require = function(file) {
|
44
|
-
document.write('<script type="text/javascript" src="' + file + '"></script>');
|
45
|
-
};
|
46
|
-
|
47
|
-
var stylesheet = function(file) {
|
48
|
-
document.write('<link rel="stylesheet" type="text/css" href="' + file + '"/>');
|
49
|
-
};
|
50
|
-
|
51
|
-
// === JSON ===
|
52
|
-
|
53
|
-
(function(){function f(n){return n<10?'0'+n:n;}
|
1
|
+
var JSON;if(!JSON){JSON={};}
|
2
|
+
(function(){"use strict";function f(n){return n<10?'0'+n:n;}
|
54
3
|
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
|
55
4
|
f(this.getUTCMonth()+1)+'-'+
|
56
5
|
f(this.getUTCDate())+'T'+
|
@@ -62,19 +11,15 @@ function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(
|
|
62
11
|
if(typeof rep==='function'){value=rep.call(holder,key,value);}
|
63
12
|
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';}
|
64
13
|
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';}
|
65
|
-
v=partial.length===0?'[]':gap?'[\n'+gap+
|
66
|
-
|
67
|
-
mind+'
|
68
|
-
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);}}}}
|
69
|
-
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
|
70
|
-
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
|
14
|
+
v=partial.length===0?'[]':gap?'[\n'+gap+partial.join(',\n'+gap)+'\n'+mind+']':'['+partial.join(',')+']';gap=mind;return v;}
|
15
|
+
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){if(typeof rep[i]==='string'){k=rep[i];v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
|
16
|
+
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
|
71
17
|
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;}
|
72
18
|
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
|
73
19
|
return str('',{'':value});};}
|
74
|
-
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];}}}}
|
20
|
+
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.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
|
75
21
|
return reviver.call(holder,key,value);}
|
76
22
|
text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
|
77
23
|
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
|
78
24
|
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;}
|
79
25
|
throw new SyntaxError('JSON.parse');};}}());
|
80
|
-
|
@@ -0,0 +1,51 @@
|
|
1
|
+
var Evergreen = {};
|
2
|
+
|
3
|
+
Evergreen.Spec = function(element) {
|
4
|
+
var self = this;
|
5
|
+
this.element = $(element);
|
6
|
+
this.runLink = this.element.find('.run');
|
7
|
+
this.runLink.click(function() {
|
8
|
+
self.run()
|
9
|
+
return false;
|
10
|
+
});
|
11
|
+
}
|
12
|
+
|
13
|
+
Evergreen.Spec.prototype.run = function() {
|
14
|
+
var self = this
|
15
|
+
this.iframe = $('<iframe></iframe>').attr('src', this.runLink.attr('href')).appendTo(this.element)
|
16
|
+
this.iframe.css({ position: 'absolute', left: '-20000px' });
|
17
|
+
this.runLink.addClass('running').text('Running…');
|
18
|
+
$(this.iframe).load(function() {
|
19
|
+
var context = self.iframe.get(0).contentWindow;
|
20
|
+
var evergreen = context.Evergreen;
|
21
|
+
if(evergreen.done) {
|
22
|
+
self.done(evergreen.results);
|
23
|
+
} else {
|
24
|
+
evergreen.onDone = function() {
|
25
|
+
self.done(evergreen.results);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
});
|
29
|
+
}
|
30
|
+
|
31
|
+
Evergreen.Spec.prototype.done = function(results) {
|
32
|
+
var failed = []
|
33
|
+
$.each(results, function() {
|
34
|
+
if(!this.passed) { failed.push(this); }
|
35
|
+
});
|
36
|
+
|
37
|
+
this.runLink.removeClass('running');
|
38
|
+
|
39
|
+
if(failed.length) {
|
40
|
+
this.runLink.addClass('fail').removeClass('pass').text('Fail')
|
41
|
+
} else {
|
42
|
+
this.runLink.addClass('pass').removeClass('fail').text('Pass')
|
43
|
+
}
|
44
|
+
this.iframe.remove();
|
45
|
+
}
|
46
|
+
|
47
|
+
$(function() {
|
48
|
+
$('#specs li, #all').each(function() {
|
49
|
+
new Evergreen.Spec(this)
|
50
|
+
});
|
51
|
+
});
|
@@ -0,0 +1,50 @@
|
|
1
|
+
if(!this.JSON){this.JSON={};}
|
2
|
+
|
3
|
+
var Evergreen = {};
|
4
|
+
|
5
|
+
Evergreen.dots = ""
|
6
|
+
|
7
|
+
Evergreen.ReflectiveReporter = function() {
|
8
|
+
this.reportRunnerStarting = function(runner) {
|
9
|
+
Evergreen.results = [];
|
10
|
+
};
|
11
|
+
this.reportSpecResults = function(spec) {
|
12
|
+
var results = spec.results();
|
13
|
+
var item = results.getItems()[0] || {};
|
14
|
+
Evergreen.results.push({
|
15
|
+
name: spec.getFullName(),
|
16
|
+
passed: results.failedCount === 0,
|
17
|
+
message: item.message,
|
18
|
+
trace: item.trace
|
19
|
+
});
|
20
|
+
Evergreen.dots += (results.failedCount === 0) ? "." : "F";
|
21
|
+
};
|
22
|
+
this.reportRunnerResults = function(runner) {
|
23
|
+
Evergreen.done = true;
|
24
|
+
if(Evergreen.onDone) { Evergreen.onDone() }
|
25
|
+
};
|
26
|
+
};
|
27
|
+
|
28
|
+
Evergreen.templates = {};
|
29
|
+
|
30
|
+
Evergreen.getResults = function() {
|
31
|
+
return JSON.stringify(Evergreen.results);
|
32
|
+
};
|
33
|
+
|
34
|
+
beforeEach(function() {
|
35
|
+
document.getElementById('test').innerHTML = "";
|
36
|
+
});
|
37
|
+
|
38
|
+
var template = function(name) {
|
39
|
+
beforeEach(function() {
|
40
|
+
document.getElementById('test').innerHTML = Evergreen.templates[name]
|
41
|
+
});
|
42
|
+
};
|
43
|
+
|
44
|
+
var require = function(file) {
|
45
|
+
document.write('<script type="text/javascript" src="' + file + '"></script>');
|
46
|
+
};
|
47
|
+
|
48
|
+
var stylesheet = function(file) {
|
49
|
+
document.write('<link rel="stylesheet" type="text/css" href="' + file + '"/>');
|
50
|
+
};
|
data/lib/evergreen/server.rb
CHANGED
data/lib/evergreen/spec.rb
CHANGED
data/lib/evergreen/suite.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Evergreen
|
2
2
|
class Suite
|
3
|
-
attr_reader :
|
4
|
-
|
5
|
-
def initialize(root)
|
6
|
-
@root = root
|
3
|
+
attr_reader :runner, :server, :driver, :application
|
7
4
|
|
5
|
+
def initialize
|
8
6
|
paths = [
|
9
7
|
File.expand_path("config/evergreen.rb", root),
|
10
8
|
File.expand_path(".evergreen", root),
|
@@ -14,7 +12,15 @@ module Evergreen
|
|
14
12
|
|
15
13
|
@runner = Runner.new(self)
|
16
14
|
@server = Server.new(self)
|
17
|
-
@application = Evergreen.application
|
15
|
+
@application = Evergreen.application
|
16
|
+
end
|
17
|
+
|
18
|
+
def root
|
19
|
+
Evergreen.root
|
20
|
+
end
|
21
|
+
|
22
|
+
def mounted_at
|
23
|
+
Evergreen.mounted_at
|
18
24
|
end
|
19
25
|
|
20
26
|
def run
|
data/lib/evergreen/tasks.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'evergreen'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
# Rails 2.3 Rake tasks
|
4
|
+
namespace :spec do
|
5
|
+
desc "Run JavaScript specs via Evergreen"
|
6
|
+
task :javascripts => :environment do
|
7
|
+
result = Evergreen::Suite.new.run
|
8
|
+
Kernel.exit(1) unless result
|
9
|
+
end
|
5
10
|
end
|
6
|
-
|
data/lib/evergreen/version.rb
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
<div id="footer">
|
14
14
|
Powered by <a href="http://github.com/jnicklas/evergreen">Evergreen</a>.
|
15
|
-
Evergreen is sponsored by <a href="http://elabs.se">Elabs</a>.
|
15
|
+
Evergreen is sponsored by <a class="elabs" href="http://elabs.se"><img alt="Elabs" src="<%= url('/resources/elabs.png') %>"> Elabs</a>.
|
16
16
|
</div>
|
17
17
|
</body>
|
18
18
|
</html>
|
@@ -1,9 +1,19 @@
|
|
1
|
+
<script type="text/javascript" src="<%= url("/resources/jquery.js") %>"></script>
|
2
|
+
<script type="text/javascript" src="<%= url("/resources/list.js") %>"></script>
|
1
3
|
<div id="page">
|
2
4
|
<h1>Evergreen</h1>
|
3
5
|
|
6
|
+
<div id="all">
|
7
|
+
<a class="all" href="<%= url('/run/all') %>">All</a>
|
8
|
+
<a class="run" href="<%= url('/run/all') %>">Run</a>
|
9
|
+
</div>
|
10
|
+
|
4
11
|
<ul id="specs">
|
5
12
|
<% @suite.specs.each do |spec| %>
|
6
|
-
<li
|
13
|
+
<li>
|
14
|
+
<a href="<%= spec.url %>"><%= spec.name %></a>
|
15
|
+
<a class="run" href="<%= spec.url %>">Run</a>
|
16
|
+
</li>
|
7
17
|
<% end %>
|
8
18
|
</ul>
|
9
19
|
</div>
|
@@ -1,19 +1,20 @@
|
|
1
1
|
<script type="text/javascript" src="<%= url("/jasmine/jasmine.js") %>"></script>
|
2
2
|
<script type="text/javascript" src="<%= url("/jasmine/jasmine-html.js") %>"></script>
|
3
|
-
<script type="text/javascript" src="<%= url("/resources/
|
3
|
+
<script type="text/javascript" src="<%= url("/resources/json2.js") %>"></script>
|
4
|
+
<script type="text/javascript" src="<%= url("/resources/run.js") %>"></script>
|
4
5
|
<script type="text/javascript">
|
5
6
|
// <![CDATA[
|
6
|
-
|
7
|
-
<%= @js_spec_helper
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
7
|
+
<%= render_spec(@coffee_spec_helper) if @coffee_spec_helper.exist? %>;
|
8
|
+
<%= render_spec(@js_spec_helper) if @js_spec_helper.exist? %>;
|
9
|
+
<% if @spec %>
|
10
|
+
<%= render_spec(@spec) %>
|
11
|
+
<% else %>
|
12
|
+
<% @suite.specs.each do |spec| %>
|
13
|
+
describe("<%= spec.name %>", function() {
|
14
|
+
<%= render_spec(spec) %>;
|
15
|
+
});
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
17
18
|
// ]]>
|
18
19
|
</script>
|
19
20
|
|
data/lib/tasks/evergreen.rake
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
# Rails 3.0/3.1 Rake tasks
|
1
2
|
namespace :spec do
|
2
3
|
desc "Run JavaScript specs via Evergreen"
|
3
|
-
task :javascripts do
|
4
|
-
result = Evergreen::Suite.new
|
4
|
+
task :javascripts => :environment do
|
5
|
+
result = Evergreen::Suite.new.run
|
5
6
|
Kernel.exit(1) unless result
|
6
7
|
end
|
7
8
|
end
|
data/spec/evergreen_spec.rb
CHANGED
@@ -22,6 +22,29 @@ describe Evergreen, ".application" do
|
|
22
22
|
page.should have_content("Expected 'bar' to equal 'noooooo'.")
|
23
23
|
end
|
24
24
|
|
25
|
+
it "should run all specs" do
|
26
|
+
visit("/")
|
27
|
+
click_link("All")
|
28
|
+
page.should have_content("18 specs, 3 failures")
|
29
|
+
page.should have_content("Expected 'bar' to equal 'noooooo'.")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should run a spec inline" do
|
33
|
+
visit("/")
|
34
|
+
within('li', :text => 'testing_spec.js') do
|
35
|
+
click_link("Run")
|
36
|
+
page.should have_content('Pass')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should run a failing spec inline" do
|
41
|
+
visit("/")
|
42
|
+
within('li', :text => 'failing_spec.js') do
|
43
|
+
click_link("Run")
|
44
|
+
page.should have_content('Fail')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
25
48
|
it "should add extensions to Evergreen" do
|
26
49
|
visit('/awesome')
|
27
50
|
page.should have_content('Totally awesome')
|
data/spec/meta_spec.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Evergreen::Runner do
|
4
|
-
let(:suite) { Evergreen::Suite.new
|
4
|
+
let(:suite) { Evergreen::Suite.new }
|
5
5
|
subject { Evergreen::Spec.new(suite, template) }
|
6
6
|
|
7
7
|
context "with standard setup" do
|
8
|
-
|
8
|
+
before { Evergreen.root = File.expand_path('suite1', File.dirname(__FILE__)) }
|
9
9
|
|
10
10
|
context "with transactions spec" do
|
11
11
|
let(:template) { 'transactions_spec.js' }
|
@@ -34,7 +34,7 @@ describe Evergreen::Runner do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
context "with modified setup" do
|
37
|
-
|
37
|
+
before { Evergreen.root = File.expand_path('suite2', File.dirname(__FILE__)) }
|
38
38
|
|
39
39
|
context "with awesome spec" do
|
40
40
|
let(:template) { 'awesome_spec.js' }
|
data/spec/runner_spec.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Evergreen::Runner do
|
4
|
-
let(:
|
5
|
-
let(:suite) { Evergreen::Suite.new(root) }
|
4
|
+
let(:suite) { Evergreen::Suite.new }
|
6
5
|
let(:runner) { Evergreen::Runner.new(suite, buffer) }
|
7
6
|
let(:buffer) { StringIO.new }
|
8
7
|
|
data/spec/spec_helper.rb
CHANGED
@@ -9,13 +9,14 @@ require 'capybara-webkit'
|
|
9
9
|
|
10
10
|
TEST_DRIVER = :webkit
|
11
11
|
|
12
|
+
Evergreen.root = File.expand_path('suite1', File.dirname(__FILE__))
|
12
13
|
Evergreen.extensions do
|
13
14
|
map "/awesome" do
|
14
|
-
run lambda { |env| [200, {'Content-Type' => 'text/html'}, "<html><body>Totally awesome</body></html>"]}
|
15
|
+
run lambda { |env| [200, {'Content-Type' => 'text/html'}, ["<html><body>Totally awesome</body></html>"]]}
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
|
-
Capybara.app = Evergreen
|
19
|
+
Capybara.app = Evergreen.application
|
19
20
|
Capybara.default_driver = TEST_DRIVER
|
20
21
|
|
21
22
|
module EvergreenMatchers
|
@@ -44,6 +45,8 @@ RSpec.configure do |config|
|
|
44
45
|
config.include EvergreenMatchers
|
45
46
|
config.before do
|
46
47
|
Evergreen.use_defaults!
|
48
|
+
Evergreen.root = File.expand_path('suite1', File.dirname(__FILE__))
|
47
49
|
Evergreen.driver = TEST_DRIVER
|
50
|
+
Evergreen.application = Evergreen.build_application
|
48
51
|
end
|
49
52
|
end
|
data/spec/spec_spec.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Evergreen::Spec do
|
4
|
-
let(:
|
5
|
-
let(:suite) { Evergreen::Suite.new(root) }
|
4
|
+
let(:suite) { Evergreen::Suite.new }
|
6
5
|
subject { Evergreen::Spec.new(suite, 'testing_spec.js') }
|
7
6
|
|
8
7
|
its(:name) { should == 'testing_spec.js' }
|
9
|
-
its(:root) { should ==
|
10
|
-
its(:full_path) { should == "
|
8
|
+
its(:root) { should == File.expand_path('suite1', File.dirname(__FILE__)) }
|
9
|
+
its(:full_path) { should == File.expand_path("spec/javascripts/testing_spec.js", Evergreen.root) }
|
11
10
|
its(:url) { should == "/run/testing_spec.js" }
|
12
11
|
its(:contents) { should =~ /describe\('testing'/ }
|
13
12
|
|