gerbil-rails 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
|