gerbil-rails 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -1,78 +1,135 @@
|
|
1
1
|
//= require gerbil
|
2
2
|
//= require jquery-1.7.1
|
3
3
|
|
4
|
-
Gerbil.Rails = {
|
5
|
-
formatter: (function($) {
|
6
|
-
var currentScenario, ok, fail, pending;
|
7
|
-
|
8
|
-
function test(text, className) {
|
9
|
-
var li = $("<li/>").addClass(className).html(text);
|
10
|
-
currentScenario.find("ul").append(li);
|
11
|
-
|
12
|
-
currentScenario.
|
13
|
-
removeClass("fail").
|
14
|
-
removeClass("pending").
|
15
|
-
removeClass("ok");
|
16
|
-
|
17
|
-
if (fail > 0) {
|
18
|
-
currentScenario.addClass("fail");
|
19
|
-
} else if (pending > 0) {
|
20
|
-
currentScenario.addClass("pending");
|
21
|
-
} else if (ok > 0) {
|
22
|
-
currentScenario.addClass("ok");
|
23
|
-
}
|
24
|
-
}
|
4
|
+
Gerbil.Rails = {}
|
25
5
|
|
26
|
-
|
27
|
-
if (typeof plural == "undefined")
|
28
|
-
plural = singular + "s";
|
29
|
-
return n == 1 ? [n, singular].join(" ") : [n, plural].join(" ");
|
30
|
-
}
|
6
|
+
Gerbil.Rails.jQuery = jQuery.noConflict(true);
|
31
7
|
|
32
|
-
|
33
|
-
|
34
|
-
ok = fail = pending = 0;
|
8
|
+
Gerbil.Rails.formatter = (function($) {
|
9
|
+
var currentScenario, status;
|
35
10
|
|
36
|
-
|
37
|
-
|
38
|
-
|
11
|
+
function test(text, className) {
|
12
|
+
var li = $("<li/>").addClass(className).html(text);
|
13
|
+
currentScenario.find("ul").append(li);
|
39
14
|
|
40
|
-
|
41
|
-
|
15
|
+
currentScenario.
|
16
|
+
removeClass("fail").
|
17
|
+
removeClass("pending").
|
18
|
+
removeClass("ok");
|
42
19
|
|
43
|
-
|
44
|
-
|
45
|
-
|
20
|
+
if (status.fail > 0) {
|
21
|
+
currentScenario.addClass("fail");
|
22
|
+
} else if (status.pending > 0) {
|
23
|
+
currentScenario.addClass("pending");
|
24
|
+
} else if (status.ok > 0) {
|
25
|
+
currentScenario.addClass("ok");
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
function pluralize(n, singular, plural) {
|
30
|
+
if (typeof plural == "undefined")
|
31
|
+
plural = singular + "s";
|
32
|
+
return n == 1 ? [n, singular].join(" ") : [n, plural].join(" ");
|
33
|
+
}
|
34
|
+
|
35
|
+
return {
|
36
|
+
scenario: function(msg) {
|
37
|
+
status = { ok: 0, fail: 0, pending: 0 };
|
38
|
+
|
39
|
+
currentScenario = $("<section/>");
|
40
|
+
currentScenario.append("<h1>Running <strong>" + msg + "</strong></h1>");
|
41
|
+
currentScenario.append("<ul/>");
|
42
|
+
|
43
|
+
$("#results").append(currentScenario);
|
44
|
+
},
|
45
|
+
|
46
|
+
summary: function(summary) {
|
47
|
+
var msg, p = $("<p class='summary'/>"),
|
48
|
+
time = Math.round(100 * summary.time) / 100;
|
49
|
+
|
50
|
+
msg = [[summary.pass, "passed"].join(" "),
|
51
|
+
[summary.fail, "failed"].join(" "),
|
52
|
+
[summary.pending, "pending"].join(" ")].join(", ");
|
53
|
+
|
54
|
+
msg += " (" + summary.total + " total, " + pluralize(summary.assertions, "assertion") + ")";
|
55
|
+
msg += " in " + time + "s.";
|
56
|
+
|
57
|
+
p.text(msg);
|
58
|
+
currentScenario.append(p);
|
59
|
+
currentScenario.addClass("finished");
|
60
|
+
},
|
61
|
+
|
62
|
+
ok: function(msg) {
|
63
|
+
status.ok++
|
64
|
+
test(msg, "ok");
|
65
|
+
},
|
66
|
+
|
67
|
+
fail: function(msg) {
|
68
|
+
status.fail++
|
69
|
+
test(msg, "fail");
|
70
|
+
},
|
71
|
+
|
72
|
+
pending: function(msg) {
|
73
|
+
status.pending++
|
74
|
+
test(msg, "pending");
|
75
|
+
}
|
76
|
+
};
|
46
77
|
|
47
|
-
|
48
|
-
[summary.fail, "failed"].join(" "),
|
49
|
-
[summary.pending, "pending"].join(" ")].join(", ");
|
78
|
+
})(Gerbil.Rails.jQuery);
|
50
79
|
|
51
|
-
|
52
|
-
|
80
|
+
Gerbil.Rails.run = (function($) {
|
81
|
+
return function() {
|
82
|
+
function flashTitle(token, times) {
|
83
|
+
$("title").text(" spec runner");
|
53
84
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
},
|
85
|
+
setTimeout(function() {
|
86
|
+
$("title").text(token + " spec runner");
|
87
|
+
}, 200);
|
58
88
|
|
59
|
-
|
60
|
-
ok += 1;
|
61
|
-
test(msg, "ok");
|
62
|
-
},
|
89
|
+
if (times == 0) return;
|
63
90
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
91
|
+
setTimeout(function() {
|
92
|
+
flashTitle(token, times - 1);
|
93
|
+
}, 1000);
|
94
|
+
}
|
68
95
|
|
69
|
-
|
70
|
-
|
71
|
-
|
96
|
+
flashTitle("⌛", 0);
|
97
|
+
$.ajax({
|
98
|
+
url: "/assets/spec.js",
|
99
|
+
type: "GET",
|
100
|
+
dataType: "script",
|
101
|
+
success: function() {
|
102
|
+
$("#results").empty()
|
103
|
+
},
|
104
|
+
complete: function() {
|
105
|
+
setTimeout(function() {
|
106
|
+
var fail = $("section.fail").length,
|
107
|
+
pending = $("section.pending").length,
|
108
|
+
ok = $("section.ok").length;
|
109
|
+
|
110
|
+
if (fail > 0) {
|
111
|
+
flashTitle("✘", 2);
|
112
|
+
} else if (pending > 0) {
|
113
|
+
flashTitle("☯", 2);
|
114
|
+
} else if (ok > 0) {
|
115
|
+
flashTitle("✔", 2);
|
116
|
+
}
|
117
|
+
}, 0);
|
72
118
|
}
|
73
|
-
};
|
74
|
-
|
75
|
-
|
76
|
-
};
|
119
|
+
});
|
120
|
+
}
|
121
|
+
})(Gerbil.Rails.jQuery);
|
77
122
|
|
78
123
|
Gerbil.formatter = Gerbil.Rails.formatter;
|
124
|
+
|
125
|
+
Gerbil.Rails.jQuery(function($) {
|
126
|
+
var reload = $("#reload");
|
127
|
+
|
128
|
+
setInterval(function() {
|
129
|
+
if (!reload.is(":checked"))
|
130
|
+
return;
|
131
|
+
Gerbil.Rails.run();
|
132
|
+
}, 30000);
|
133
|
+
|
134
|
+
Gerbil.Rails.run();
|
135
|
+
});
|
@@ -2,12 +2,18 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<meta charset="utf8">
|
5
|
-
<title
|
5
|
+
<title>⌛ spec sunner</title>
|
6
6
|
<%= stylesheet_link_tag "gerbil/rails" %>
|
7
|
-
<%= javascript_include_tag "gerbil/rails" %>
|
8
|
-
<%= javascript_include_tag "spec" %>
|
9
7
|
<%= csrf_meta_tags %>
|
10
8
|
</head>
|
11
9
|
<body>
|
10
|
+
<div class="reload">
|
11
|
+
<label for="reload">
|
12
|
+
<%= check_box_tag "reload", true, checked: true %>
|
13
|
+
Reload this page every 30 seconds?
|
14
|
+
</label>
|
15
|
+
</div>
|
16
|
+
<div id="results"></div>
|
17
|
+
<%= javascript_include_tag "gerbil/rails" %>
|
12
18
|
</body>
|
13
19
|
</html>
|
data/gerbil-rails.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.homepage = "http://github.com/foca/gerbil-rails"
|
9
9
|
s.authors = ["Nicolas Sanguinetti"]
|
10
10
|
s.email = "hi@nicolassanguinetti.info"
|
11
|
-
s.version = "0.0
|
11
|
+
s.version = "0.1.0"
|
12
12
|
s.platform = Gem::Platform::RUBY
|
13
13
|
s.add_dependency("rails")
|
14
14
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
var Smoking = function(object, stubs) {
|
2
|
+
this.stubs = stubs;
|
3
|
+
this.extend = function(destination, source) {
|
4
|
+
for (var property in source) destination[property] = source[property];
|
5
|
+
return destination;
|
6
|
+
};
|
7
|
+
|
8
|
+
this.clone = function(object) { return this.extend({}, object); };
|
9
|
+
|
10
|
+
this.stub = function() {
|
11
|
+
var stubbedObject = new Object;
|
12
|
+
for(var arg in this.stubs) stubbedObject[arg] = this.stubs[arg];
|
13
|
+
this.extend(this.object, stubbedObject);
|
14
|
+
return this.object;
|
15
|
+
};
|
16
|
+
|
17
|
+
this.intercept = function(method, interceptFn) {
|
18
|
+
var originalFn = this.object[method];
|
19
|
+
if(typeof originalFn == 'function') {
|
20
|
+
this.object[method] = function() {
|
21
|
+
interceptFn();
|
22
|
+
var args = Array.prototype.slice.call(arguments);
|
23
|
+
originalFn.apply(this, args);
|
24
|
+
};
|
25
|
+
}
|
26
|
+
},
|
27
|
+
|
28
|
+
this.object = this.clone(object);
|
29
|
+
return typeof this.stubs != 'undefined' ? this.stub() : this;
|
30
|
+
};
|
31
|
+
|
32
|
+
Smoking.prototype = {
|
33
|
+
expects: function(callExpectations) {
|
34
|
+
if(typeof callExpectations == 'string') callExpectations = new Object()[callExpectations] = 1;
|
35
|
+
this.extend(this.object, { ___smoking_call_expectations: callExpectations });
|
36
|
+
for(var arg in callExpectations) {
|
37
|
+
if(!this.object[arg] || typeof this.object[arg] != 'function') return;
|
38
|
+
var self = this;
|
39
|
+
this.intercept(arg, function() { self.object.___smoking_call_expectations[arg]--; });
|
40
|
+
};
|
41
|
+
return this.object;
|
42
|
+
},
|
43
|
+
|
44
|
+
verify: function() {
|
45
|
+
if(!this.object.___smoking_call_expectations) throw new Error("No mocks defined");
|
46
|
+
var expectations = this.object.___smoking_call_expectations;
|
47
|
+
for(var arg in expectations)
|
48
|
+
if(expectations[arg] !== 0) throw new RangeError(arg + " needs to be called " + expectations[arg] + " times");
|
49
|
+
delete this.object.___smoking_call_expectations;
|
50
|
+
return true;
|
51
|
+
}
|
52
|
+
|
53
|
+
}
|
54
|
+
|
55
|
+
var smoking = function(obj, stubs) { return new Smoking(obj, stubs); };
|
56
|
+
|
57
|
+
if(typeof module != 'undefined') module.exports = smoking;
|
@@ -0,0 +1,116 @@
|
|
1
|
+
if(typeof module != 'undefined') {
|
2
|
+
var fs = require('fs');
|
3
|
+
var IS_NODE = true;
|
4
|
+
}
|
5
|
+
|
6
|
+
var VCRConstructor = function VCR() {
|
7
|
+
this.config = {
|
8
|
+
hookInto: null,
|
9
|
+
host: null,
|
10
|
+
cassetteLibraryDir: 'cassettes'
|
11
|
+
}
|
12
|
+
};
|
13
|
+
|
14
|
+
VCRConstructor.Store = {
|
15
|
+
set: function(dir, name, cassette) {
|
16
|
+
var data = JSON.stringify(cassette);
|
17
|
+
if(IS_NODE) {
|
18
|
+
fs.writeFile(dir + '/' + name + ".json", data);
|
19
|
+
} else {
|
20
|
+
localStorage.setItem(name, data);
|
21
|
+
}
|
22
|
+
},
|
23
|
+
|
24
|
+
get: function(dir, name) {
|
25
|
+
if(IS_NODE) {
|
26
|
+
try{
|
27
|
+
var data = fs.readFileSync(dir + '/' + name + ".json");
|
28
|
+
} catch(e) {
|
29
|
+
var data = false;
|
30
|
+
}
|
31
|
+
} else {
|
32
|
+
var data = localStorage.getItem(name);
|
33
|
+
}
|
34
|
+
return !data ? false : JSON.parse(data);
|
35
|
+
}
|
36
|
+
};
|
37
|
+
|
38
|
+
VCRConstructor.Context = function VCRContext(name, config) {
|
39
|
+
var self = this;
|
40
|
+
|
41
|
+
this.hookInto = config.hookInto;
|
42
|
+
this.cassetteLibraryDir = config.cassetteLibraryDir;
|
43
|
+
this.name = name;
|
44
|
+
this.type = null;
|
45
|
+
this.url = null;
|
46
|
+
|
47
|
+
this.XMLHttpRequest = function() {
|
48
|
+
var XHR = new self.hookInto;
|
49
|
+
|
50
|
+
return self.intercept(XHR, {
|
51
|
+
open: function(type, url) {
|
52
|
+
self.type = type.toUpperCase();
|
53
|
+
self.url = url;
|
54
|
+
},
|
55
|
+
send: function(data) {
|
56
|
+
var response = self.getCassetteFor(self.type, self.url);
|
57
|
+
var callback = this.onreadystatechange;
|
58
|
+
var fakeXHR = this;
|
59
|
+
|
60
|
+
if(!response) {
|
61
|
+
XHR.open(self.type, config.host + self.url);
|
62
|
+
XHR.send(data);
|
63
|
+
XHR.onreadystatechange = function() {
|
64
|
+
if(this.readyState === 4) {
|
65
|
+
self.setCassetteFor(self.type, self.url, this)
|
66
|
+
}
|
67
|
+
self.extend(fakeXHR, this);
|
68
|
+
}
|
69
|
+
} else {
|
70
|
+
self.extend(fakeXHR, response);
|
71
|
+
}
|
72
|
+
typeof callback == 'function' && callback();
|
73
|
+
}
|
74
|
+
});
|
75
|
+
};
|
76
|
+
|
77
|
+
this.extend = function(destination, source, object) {
|
78
|
+
for (var property in source) {
|
79
|
+
destination[property] = object ? (object[property] || source[property]) : source[property];
|
80
|
+
}
|
81
|
+
return destination;
|
82
|
+
};
|
83
|
+
|
84
|
+
this.intercept = function(source, object) {
|
85
|
+
return self.extend({}, source, object);
|
86
|
+
};
|
87
|
+
|
88
|
+
this.getCassetteFor = function(type, url) {
|
89
|
+
var cassette = VCRConstructor.Store.get(self.cassetteLibraryDir, self.name);
|
90
|
+
self.cassette = cassette ? cassette : {};
|
91
|
+
return self.cassette[type + "," + url];
|
92
|
+
};
|
93
|
+
|
94
|
+
this.setCassetteFor = function(type, url, response) {
|
95
|
+
self.cassette[type + "," + url] = response;
|
96
|
+
VCRConstructor.Store.set(self.cassetteLibraryDir, self.name, self.cassette);
|
97
|
+
}
|
98
|
+
};
|
99
|
+
|
100
|
+
VCRConstructor.prototype = {
|
101
|
+
constructor: VCRConstructor,
|
102
|
+
|
103
|
+
configure: function(fn) {
|
104
|
+
fn(this.config);
|
105
|
+
},
|
106
|
+
|
107
|
+
useCassette: function(name, fn) {
|
108
|
+
fn(new VCRConstructor.Context(name, this.config));
|
109
|
+
}
|
110
|
+
};
|
111
|
+
|
112
|
+
if(IS_NODE) {
|
113
|
+
module.exports = new VCRConstructor;
|
114
|
+
} else {
|
115
|
+
var VCR = new VCRConstructor;
|
116
|
+
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gerbil-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &70209328773680 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70209328773680
|
25
25
|
description: Full support for the Rails 3.1 asset pipeline when testing your coffeescript
|
26
26
|
or javascript files using Gerbil
|
27
27
|
email: hi@nicolassanguinetti.info
|
@@ -45,6 +45,8 @@ files:
|
|
45
45
|
- lib/gerbil/rails.rb
|
46
46
|
- vendor/assets/javascripts/gerbil.js
|
47
47
|
- vendor/assets/javascripts/jquery-1.7.1.js
|
48
|
+
- vendor/assets/javascripts/smoking.js
|
49
|
+
- vendor/assets/javascripts/vcr.js
|
48
50
|
homepage: http://github.com/foca/gerbil-rails
|
49
51
|
licenses: []
|
50
52
|
post_install_message:
|
@@ -65,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
67
|
version: '0'
|
66
68
|
requirements: []
|
67
69
|
rubyforge_project:
|
68
|
-
rubygems_version: 1.8.
|
70
|
+
rubygems_version: 1.8.11
|
69
71
|
signing_key:
|
70
72
|
specification_version: 3
|
71
73
|
summary: Testing for Rails' Asset Pipeline using Gerbil
|