konacha 1.5.1 → 2.0.0.beta1
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.
- data/History.md +7 -0
- data/README.md +71 -57
- data/app/assets/javascripts/konacha/iframe.js +40 -0
- data/app/assets/javascripts/konacha/parent.js +14 -0
- data/app/assets/javascripts/konacha/runner.js +45 -0
- data/app/assets/stylesheets/konacha.css +75 -0
- data/app/controllers/konacha/specs_controller.rb +6 -1
- data/app/models/konacha/spec.rb +1 -1
- data/app/views/konacha/specs/iframe.html.erb +18 -0
- data/app/views/konacha/specs/parent.html.erb +16 -0
- data/config/routes.rb +4 -2
- data/images/frame-select.png +0 -0
- data/konacha.gemspec +1 -1
- data/lib/konacha/engine.rb +1 -0
- data/lib/konacha/runner.rb +22 -57
- data/spec/controllers/specs_controller_spec.rb +4 -4
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/spec/isolated/errors/failing_iframe_spec.js.coffee +1 -0
- data/spec/dummy/spec/javascripts/{test_element_spec.js.coffee → body_spec.js.coffee} +4 -7
- data/spec/dummy/spec/javascripts/isolation/a_spec.js +6 -0
- data/spec/dummy/spec/javascripts/isolation/b_spec.js +6 -0
- data/spec/dummy/spec/javascripts/templating_spec.js +4 -4
- data/spec/dummy/spec/javascripts/ui_spec.js +7 -0
- data/spec/error_handling_spec.rb +33 -0
- data/spec/models/spec_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/views/specs/{specs.html.erb_spec.rb → iframe.html.erb_spec.rb} +12 -8
- data/vendor/assets/javascripts/mocha.js +297 -114
- metadata +195 -180
- data/app/views/konacha/specs/specs.html.erb +0 -16
- data/lib/assets/javascripts/konacha.js +0 -20
- data/lib/assets/javascripts/konacha/runner.js +0 -50
- data/lib/assets/javascripts/konacha/server.js +0 -6
- data/lib/assets/stylesheets/konacha.css +0 -5
- data/spec/dummy/spec/javascripts/konacha_config.js +0 -2
- data/spec/dummy/spec/javascripts/konacha_config_spec.js +0 -9
data/config/routes.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
Konacha::Engine.routes.draw do
|
2
|
-
match
|
3
|
-
match
|
2
|
+
match '/iframe' => 'specs#iframe', :as => 'iframe'
|
3
|
+
match '/iframe/*path' => 'specs#iframe'
|
4
|
+
match '/' => 'specs#parent', :as => 'parent'
|
5
|
+
match '*path' => 'specs#parent'
|
4
6
|
end
|
Binary file
|
data/konacha.gemspec
CHANGED
@@ -17,7 +17,7 @@ the asset pipeline and engines.}
|
|
17
17
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
18
|
gem.name = "konacha"
|
19
19
|
gem.require_paths = ["lib"]
|
20
|
-
gem.version = "
|
20
|
+
gem.version = "2.0.0.beta1"
|
21
21
|
|
22
22
|
gem.add_dependency "railties", "~> 3.1"
|
23
23
|
gem.add_dependency "actionpack", "~> 3.1"
|
data/lib/konacha/engine.rb
CHANGED
data/lib/konacha/runner.rb
CHANGED
@@ -7,7 +7,7 @@ module Konacha
|
|
7
7
|
new.run
|
8
8
|
end
|
9
9
|
|
10
|
-
attr_reader :io
|
10
|
+
attr_reader :io, :examples
|
11
11
|
|
12
12
|
def initialize(options = {})
|
13
13
|
@io = options[:output] || STDOUT
|
@@ -16,7 +16,27 @@ module Konacha
|
|
16
16
|
def run
|
17
17
|
before = Time.now
|
18
18
|
|
19
|
-
|
19
|
+
begin
|
20
|
+
session.visit("/")
|
21
|
+
|
22
|
+
dots_printed = 0
|
23
|
+
begin
|
24
|
+
sleep 0.1
|
25
|
+
done, dots = session.evaluate_script('[Konacha.done, Konacha.dots]')
|
26
|
+
if dots
|
27
|
+
io.write colorize_dots(dots[dots_printed..-1])
|
28
|
+
io.flush
|
29
|
+
dots_printed = dots.length
|
30
|
+
end
|
31
|
+
end until done
|
32
|
+
|
33
|
+
@examples = JSON.parse(session.evaluate_script('Konacha.getResults()')).map do |row|
|
34
|
+
Example.new(row)
|
35
|
+
end
|
36
|
+
rescue => e
|
37
|
+
raise e, "Error communicating with browser process: #{e}", e.backtrace
|
38
|
+
end
|
39
|
+
|
20
40
|
io.puts ""
|
21
41
|
io.puts ""
|
22
42
|
failure_messages.each { |msg| io.write("#{msg}\n\n") }
|
@@ -27,10 +47,6 @@ module Konacha
|
|
27
47
|
passed?
|
28
48
|
end
|
29
49
|
|
30
|
-
def examples
|
31
|
-
spec_runners.map { |spec_runner| spec_runner.examples }.flatten
|
32
|
-
end
|
33
|
-
|
34
50
|
def pending_examples
|
35
51
|
examples.select { |example| example.pending? }
|
36
52
|
end
|
@@ -51,27 +67,6 @@ module Konacha
|
|
51
67
|
@session ||= Capybara::Session.new(Konacha.driver, Konacha.application)
|
52
68
|
end
|
53
69
|
|
54
|
-
def spec_runners
|
55
|
-
@spec_runners ||= Konacha::Spec.all.map { |spec| SpecRunner.new(self, spec) }
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class SpecRunner
|
60
|
-
attr_reader :runner, :spec, :examples
|
61
|
-
|
62
|
-
def initialize(runner, spec)
|
63
|
-
@runner = runner
|
64
|
-
@spec = spec
|
65
|
-
end
|
66
|
-
|
67
|
-
def session
|
68
|
-
runner.session
|
69
|
-
end
|
70
|
-
|
71
|
-
def io
|
72
|
-
runner.io
|
73
|
-
end
|
74
|
-
|
75
70
|
def colorize_dots(dots)
|
76
71
|
dots = dots.chars.map do |d|
|
77
72
|
case d
|
@@ -83,27 +78,6 @@ module Konacha
|
|
83
78
|
end
|
84
79
|
dots.join ''
|
85
80
|
end
|
86
|
-
|
87
|
-
def run
|
88
|
-
session.visit(spec.url)
|
89
|
-
|
90
|
-
dots_printed = 0
|
91
|
-
begin
|
92
|
-
sleep 0.1
|
93
|
-
done, dots = session.evaluate_script('[Konacha.done, Konacha.dots]')
|
94
|
-
if dots
|
95
|
-
io.write colorize_dots(dots[dots_printed..-1])
|
96
|
-
io.flush
|
97
|
-
dots_printed = dots.length
|
98
|
-
end
|
99
|
-
end until done
|
100
|
-
|
101
|
-
@examples = JSON.parse(session.evaluate_script('Konacha.getResults()')).map do |row|
|
102
|
-
Example.new(row)
|
103
|
-
end
|
104
|
-
rescue => e
|
105
|
-
raise e, "Error communicating with browser process: #{e}", e.backtrace
|
106
|
-
end
|
107
81
|
end
|
108
82
|
|
109
83
|
class Example
|
@@ -135,13 +109,4 @@ module Konacha
|
|
135
109
|
end
|
136
110
|
end
|
137
111
|
end
|
138
|
-
|
139
|
-
class Error < StandardError
|
140
|
-
attr_accessor :original
|
141
|
-
|
142
|
-
def initialize(msg, original=nil);
|
143
|
-
super(msg);
|
144
|
-
@original = original;
|
145
|
-
end
|
146
|
-
end
|
147
112
|
end
|
@@ -5,18 +5,18 @@ describe Konacha::SpecsController do
|
|
5
5
|
@routes = Konacha::Engine.routes
|
6
6
|
end
|
7
7
|
|
8
|
-
describe "#
|
8
|
+
describe "#iframe" do
|
9
9
|
it "assigns the result of Spec.find to @specs" do
|
10
10
|
Konacha::Spec.should_receive(:find).with("spec_path") { :spec }
|
11
|
-
get :
|
11
|
+
get :iframe, :path => "spec_path"
|
12
12
|
assigns[:specs].should == :spec
|
13
13
|
end
|
14
14
|
|
15
15
|
it "404s if there is no match for the given path" do
|
16
16
|
Konacha::Spec.should_receive(:find).with("array_spec") { raise Konacha::Spec::NotFound }
|
17
|
-
get :
|
17
|
+
get :iframe, :path => "array_spec"
|
18
18
|
response.status.should == 404
|
19
|
-
response.should_not render_template("konacha/specs/
|
19
|
+
response.should_not render_template("konacha/specs/iframe")
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
syntax error!
|
@@ -1,6 +1,9 @@
|
|
1
1
|
#= require jquery
|
2
2
|
|
3
|
-
describe "the #konacha element", ->
|
3
|
+
describe "the body#konacha element", ->
|
4
|
+
it "is empty", ->
|
5
|
+
$('#konacha').html().should.equal ''
|
6
|
+
|
4
7
|
it "can have content added in one test...", ->
|
5
8
|
$('#konacha').append('<h1 id="added">New Stuff</h1>')
|
6
9
|
$('#konacha h1#added').length.should.equal(1)
|
@@ -14,11 +17,5 @@ describe "the #konacha element", ->
|
|
14
17
|
it "... that is removed before the next one starts", ->
|
15
18
|
$('#konacha').hasClass('test').should.be.false
|
16
19
|
|
17
|
-
it "can be removed in one test...", ->
|
18
|
-
$('#konacha').remove()
|
19
|
-
|
20
|
-
it "... and is re-added before the next one starts", ->
|
21
|
-
$('#konacha').length.should.equal(1)
|
22
|
-
|
23
20
|
it "is visible", ->
|
24
21
|
$('#konacha').is(':visible').should.be.true
|
@@ -1,9 +1,9 @@
|
|
1
1
|
//= require spec_helper
|
2
2
|
//= require jquery
|
3
3
|
|
4
|
-
describe("templating", function(){
|
5
|
-
it("is built in to Sprockets", function(){
|
6
|
-
$('
|
7
|
-
$('
|
4
|
+
describe("templating", function() {
|
5
|
+
it("is built in to Sprockets", function() {
|
6
|
+
$('body').html(JST['templates/hello']());
|
7
|
+
$('body h1').text().should.equal('Hello Konacha!');
|
8
8
|
});
|
9
9
|
});
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Konacha, :type => :request do
|
4
|
+
before do
|
5
|
+
Konacha.mode = :server
|
6
|
+
end
|
7
|
+
|
8
|
+
around do |example|
|
9
|
+
begin
|
10
|
+
spec_dir = Konacha.config.spec_dir
|
11
|
+
Konacha.config.spec_dir = "spec/isolated/errors"
|
12
|
+
example.run
|
13
|
+
ensure
|
14
|
+
Konacha.config.spec_dir = spec_dir
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "inserts a failing test when an iframe fails to load" do
|
19
|
+
silencing_stderr do
|
20
|
+
visit "/failing_iframe_spec"
|
21
|
+
page.should have_content("failing_iframe_spec.js.coffee")
|
22
|
+
page.should have_css(".test.fail")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def silencing_stderr
|
27
|
+
stderr = $stderr
|
28
|
+
$stderr = StringIO.new
|
29
|
+
yield
|
30
|
+
ensure
|
31
|
+
$stderr = stderr
|
32
|
+
end
|
33
|
+
end
|
data/spec/models/spec_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "konacha/specs/
|
4
|
-
|
5
|
-
assign(:
|
6
|
-
Konacha.should_receive(:mode).any_number_of_times { :runner }
|
7
|
-
|
8
|
-
render
|
9
|
-
|
10
|
-
rendered.should have_css("script[src='/assets/konacha/runner.js']")
|
3
|
+
describe "konacha/specs/iframe" do
|
4
|
+
before do
|
5
|
+
assign(:stylesheets, [])
|
11
6
|
end
|
12
7
|
|
13
8
|
def asset_double(asset_name, dependencies = [])
|
@@ -64,4 +59,13 @@ describe "konacha/specs/specs" do
|
|
64
59
|
rendered.should have_selector("script[src='/assets/dependency_a.js?body=1']", :count => 1)
|
65
60
|
rendered.should have_selector("script[src='/assets/dependency_b.js?body=1']", :count => 1)
|
66
61
|
end
|
62
|
+
|
63
|
+
it "render the stylesheets" do
|
64
|
+
assign(:stylesheets, %w(foo bar))
|
65
|
+
|
66
|
+
render
|
67
|
+
|
68
|
+
rendered.should have_selector("link[href='/assets/foo.css']")
|
69
|
+
rendered.should have_selector("link[href='/assets/bar.css']")
|
70
|
+
end
|
67
71
|
end
|
@@ -433,6 +433,19 @@ Context.prototype.timeout = function(ms){
|
|
433
433
|
return this;
|
434
434
|
};
|
435
435
|
|
436
|
+
/**
|
437
|
+
* Set test slowness threshold `ms`.
|
438
|
+
*
|
439
|
+
* @param {Number} ms
|
440
|
+
* @return {Context} self
|
441
|
+
* @api private
|
442
|
+
*/
|
443
|
+
|
444
|
+
Context.prototype.slow = function(ms){
|
445
|
+
this.runnable().slow(ms);
|
446
|
+
return this;
|
447
|
+
};
|
448
|
+
|
436
449
|
/**
|
437
450
|
* Inspect the context void of `._runnable`.
|
438
451
|
*
|
@@ -984,6 +997,7 @@ function image(name) {
|
|
984
997
|
* - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
|
985
998
|
* - `globals` array of accepted globals
|
986
999
|
* - `timeout` timeout in milliseconds
|
1000
|
+
* - `slow` milliseconds to wait before considering a test slow
|
987
1001
|
* - `ignoreLeaks` ignore global leaks
|
988
1002
|
* - `grep` string or regexp to filter tests with
|
989
1003
|
*
|
@@ -999,7 +1013,8 @@ function Mocha(options) {
|
|
999
1013
|
this.suite = new exports.Suite('', new exports.Context);
|
1000
1014
|
this.ui(options.ui);
|
1001
1015
|
this.reporter(options.reporter);
|
1002
|
-
if (options.timeout) this.
|
1016
|
+
if (options.timeout) this.timeout(options.timeout);
|
1017
|
+
if (options.slow) this.slow(options.slow);
|
1003
1018
|
}
|
1004
1019
|
|
1005
1020
|
/**
|
@@ -1015,16 +1030,24 @@ Mocha.prototype.addFile = function(file){
|
|
1015
1030
|
};
|
1016
1031
|
|
1017
1032
|
/**
|
1018
|
-
* Set reporter to `
|
1033
|
+
* Set reporter to `reporter`, defaults to "dot".
|
1019
1034
|
*
|
1020
|
-
* @param {String} name
|
1035
|
+
* @param {String|Function} reporter name of a reporter or a reporter constructor
|
1021
1036
|
* @api public
|
1022
1037
|
*/
|
1023
1038
|
|
1024
|
-
Mocha.prototype.reporter = function(
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1039
|
+
Mocha.prototype.reporter = function(reporter){
|
1040
|
+
if ('function' == typeof reporter) {
|
1041
|
+
this._reporter = reporter;
|
1042
|
+
} else {
|
1043
|
+
reporter = reporter || 'dot';
|
1044
|
+
try {
|
1045
|
+
this._reporter = require('./reporters/' + reporter);
|
1046
|
+
} catch (err) {
|
1047
|
+
this._reporter = require(reporter);
|
1048
|
+
}
|
1049
|
+
if (!this._reporter) throw new Error('invalid reporter "' + reporter + '"');
|
1050
|
+
}
|
1028
1051
|
return this;
|
1029
1052
|
};
|
1030
1053
|
|
@@ -1125,6 +1148,18 @@ Mocha.prototype.ignoreLeaks = function(){
|
|
1125
1148
|
return this;
|
1126
1149
|
};
|
1127
1150
|
|
1151
|
+
/**
|
1152
|
+
* Enable global leak checking.
|
1153
|
+
*
|
1154
|
+
* @return {Mocha}
|
1155
|
+
* @api public
|
1156
|
+
*/
|
1157
|
+
|
1158
|
+
Mocha.prototype.checkLeaks = function(){
|
1159
|
+
this.options.ignoreLeaks = false;
|
1160
|
+
return this;
|
1161
|
+
};
|
1162
|
+
|
1128
1163
|
/**
|
1129
1164
|
* Enable growl support.
|
1130
1165
|
*
|
@@ -1138,15 +1173,41 @@ Mocha.prototype.growl = function(){
|
|
1138
1173
|
};
|
1139
1174
|
|
1140
1175
|
/**
|
1141
|
-
* Ignore `globals
|
1176
|
+
* Ignore `globals` array or string.
|
1142
1177
|
*
|
1143
|
-
* @param {Array} globals
|
1178
|
+
* @param {Array|String} globals
|
1144
1179
|
* @return {Mocha}
|
1145
1180
|
* @api public
|
1146
1181
|
*/
|
1147
1182
|
|
1148
1183
|
Mocha.prototype.globals = function(globals){
|
1149
|
-
this.options.globals = globals;
|
1184
|
+
this.options.globals = (this.options.globals || []).concat(globals);
|
1185
|
+
return this;
|
1186
|
+
};
|
1187
|
+
|
1188
|
+
/**
|
1189
|
+
* Set the timeout in milliseconds.
|
1190
|
+
*
|
1191
|
+
* @param {Number} timeout
|
1192
|
+
* @return {Mocha}
|
1193
|
+
* @api public
|
1194
|
+
*/
|
1195
|
+
|
1196
|
+
Mocha.prototype.timeout = function(timeout){
|
1197
|
+
this.suite.timeout(timeout);
|
1198
|
+
return this;
|
1199
|
+
};
|
1200
|
+
|
1201
|
+
/**
|
1202
|
+
* Set slowness threshold in milliseconds.
|
1203
|
+
*
|
1204
|
+
* @param {Number} slow
|
1205
|
+
* @return {Mocha}
|
1206
|
+
* @api public
|
1207
|
+
*/
|
1208
|
+
|
1209
|
+
Mocha.prototype.slow = function(slow){
|
1210
|
+
this.suite.slow(slow);
|
1150
1211
|
return this;
|
1151
1212
|
};
|
1152
1213
|
|
@@ -1159,7 +1220,7 @@ Mocha.prototype.globals = function(globals){
|
|
1159
1220
|
*/
|
1160
1221
|
|
1161
1222
|
Mocha.prototype.run = function(fn){
|
1162
|
-
this.loadFiles();
|
1223
|
+
if (this.files.length) this.loadFiles();
|
1163
1224
|
var suite = this.suite;
|
1164
1225
|
var options = this.options;
|
1165
1226
|
var runner = new exports.Runner(suite);
|
@@ -1173,6 +1234,90 @@ Mocha.prototype.run = function(fn){
|
|
1173
1234
|
|
1174
1235
|
}); // module: mocha.js
|
1175
1236
|
|
1237
|
+
require.register("ms.js", function(module, exports, require){
|
1238
|
+
|
1239
|
+
/**
|
1240
|
+
* Helpers.
|
1241
|
+
*/
|
1242
|
+
|
1243
|
+
var s = 1000;
|
1244
|
+
var m = s * 60;
|
1245
|
+
var h = m * 60;
|
1246
|
+
var d = h * 24;
|
1247
|
+
|
1248
|
+
/**
|
1249
|
+
* Parse or format the given `val`.
|
1250
|
+
*
|
1251
|
+
* @param {String|Number} val
|
1252
|
+
* @return {String|Number}
|
1253
|
+
* @api public
|
1254
|
+
*/
|
1255
|
+
|
1256
|
+
module.exports = function(val){
|
1257
|
+
if ('string' == typeof val) return parse(val);
|
1258
|
+
return format(val);
|
1259
|
+
}
|
1260
|
+
|
1261
|
+
/**
|
1262
|
+
* Parse the given `str` and return milliseconds.
|
1263
|
+
*
|
1264
|
+
* @param {String} str
|
1265
|
+
* @return {Number}
|
1266
|
+
* @api private
|
1267
|
+
*/
|
1268
|
+
|
1269
|
+
function parse(str) {
|
1270
|
+
var m = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
|
1271
|
+
if (!m) return;
|
1272
|
+
var n = parseFloat(m[1]);
|
1273
|
+
var type = (m[2] || 'ms').toLowerCase();
|
1274
|
+
switch (type) {
|
1275
|
+
case 'years':
|
1276
|
+
case 'year':
|
1277
|
+
case 'y':
|
1278
|
+
return n * 31557600000;
|
1279
|
+
case 'days':
|
1280
|
+
case 'day':
|
1281
|
+
case 'd':
|
1282
|
+
return n * 86400000;
|
1283
|
+
case 'hours':
|
1284
|
+
case 'hour':
|
1285
|
+
case 'h':
|
1286
|
+
return n * 3600000;
|
1287
|
+
case 'minutes':
|
1288
|
+
case 'minute':
|
1289
|
+
case 'm':
|
1290
|
+
return n * 60000;
|
1291
|
+
case 'seconds':
|
1292
|
+
case 'second':
|
1293
|
+
case 's':
|
1294
|
+
return n * 1000;
|
1295
|
+
case 'ms':
|
1296
|
+
return n;
|
1297
|
+
}
|
1298
|
+
}
|
1299
|
+
|
1300
|
+
/**
|
1301
|
+
* Format the given `ms`.
|
1302
|
+
*
|
1303
|
+
* @param {Number} ms
|
1304
|
+
* @return {String}
|
1305
|
+
* @api public
|
1306
|
+
*/
|
1307
|
+
|
1308
|
+
function format(ms) {
|
1309
|
+
if (ms == d) return (ms / d) + ' day';
|
1310
|
+
if (ms > d) return (ms / d) + ' days';
|
1311
|
+
if (ms == h) return (ms / h) + ' hour';
|
1312
|
+
if (ms > h) return (ms / h) + ' hours';
|
1313
|
+
if (ms == m) return (ms / m) + ' minute';
|
1314
|
+
if (ms > m) return (ms / m) + ' minutes';
|
1315
|
+
if (ms == s) return (ms / s) + ' second';
|
1316
|
+
if (ms > s) return (ms / s) + ' seconds';
|
1317
|
+
return ms + ' ms';
|
1318
|
+
}
|
1319
|
+
}); // module: ms.js
|
1320
|
+
|
1176
1321
|
require.register("reporters/base.js", function(module, exports, require){
|
1177
1322
|
|
1178
1323
|
/**
|
@@ -1180,7 +1325,8 @@ require.register("reporters/base.js", function(module, exports, require){
|
|
1180
1325
|
*/
|
1181
1326
|
|
1182
1327
|
var tty = require('browser/tty')
|
1183
|
-
, diff = require('browser/diff')
|
1328
|
+
, diff = require('browser/diff')
|
1329
|
+
, ms = require('../ms');
|
1184
1330
|
|
1185
1331
|
/**
|
1186
1332
|
* Save timer references to avoid Sinon interfering (see GH-237).
|
@@ -1294,13 +1440,6 @@ exports.cursor = {
|
|
1294
1440
|
}
|
1295
1441
|
};
|
1296
1442
|
|
1297
|
-
/**
|
1298
|
-
* A test is considered slow if it
|
1299
|
-
* exceeds the following value in milliseconds.
|
1300
|
-
*/
|
1301
|
-
|
1302
|
-
exports.slow = 75;
|
1303
|
-
|
1304
1443
|
/**
|
1305
1444
|
* Outut the given `failures` as a list.
|
1306
1445
|
*
|
@@ -1402,8 +1541,8 @@ function Base(runner) {
|
|
1402
1541
|
runner.on('pass', function(test){
|
1403
1542
|
stats.passes = stats.passes || 0;
|
1404
1543
|
|
1405
|
-
var medium =
|
1406
|
-
test.speed = test.duration >
|
1544
|
+
var medium = test.slow() / 2;
|
1545
|
+
test.speed = test.duration > test.slow()
|
1407
1546
|
? 'slow'
|
1408
1547
|
: test.duration > medium
|
1409
1548
|
? 'medium'
|
@@ -1466,12 +1605,12 @@ Base.prototype.epilogue = function(){
|
|
1466
1605
|
// pass
|
1467
1606
|
fmt = color('bright pass', ' ✔')
|
1468
1607
|
+ color('green', ' %d %s complete')
|
1469
|
-
+ color('light', ' (%
|
1608
|
+
+ color('light', ' (%s)');
|
1470
1609
|
|
1471
1610
|
console.log(fmt,
|
1472
1611
|
stats.tests || 0,
|
1473
1612
|
pluralize(stats.tests),
|
1474
|
-
stats.duration);
|
1613
|
+
ms(stats.duration));
|
1475
1614
|
|
1476
1615
|
// pending
|
1477
1616
|
if (stats.pending) {
|
@@ -1508,7 +1647,10 @@ function pad(str, len) {
|
|
1508
1647
|
|
1509
1648
|
function errorDiff(err, type) {
|
1510
1649
|
return diff['diff' + type](err.actual, err.expected).map(function(str){
|
1511
|
-
|
1650
|
+
str.value = str.value
|
1651
|
+
.replace(/\t/g, '<tab>')
|
1652
|
+
.replace(/\r/g, '<CR>')
|
1653
|
+
.replace(/\n/g, '<LF>\n');
|
1512
1654
|
if (str.added) return colorLines('diff added', str.value);
|
1513
1655
|
if (str.removed) return colorLines('diff removed', str.value);
|
1514
1656
|
return str.value;
|
@@ -1759,13 +1901,12 @@ var statsTemplate = '<ul id="stats">'
|
|
1759
1901
|
* @api public
|
1760
1902
|
*/
|
1761
1903
|
|
1762
|
-
function HTML(runner) {
|
1904
|
+
function HTML(runner, root) {
|
1763
1905
|
Base.call(this, runner);
|
1764
1906
|
|
1765
1907
|
var self = this
|
1766
1908
|
, stats = this.stats
|
1767
1909
|
, total = runner.total
|
1768
|
-
, root = document.getElementById('mocha')
|
1769
1910
|
, stat = fragment(statsTemplate)
|
1770
1911
|
, items = stat.getElementsByTagName('li')
|
1771
1912
|
, passes = items[1].getElementsByTagName('em')[0]
|
@@ -1779,6 +1920,8 @@ function HTML(runner) {
|
|
1779
1920
|
, progress
|
1780
1921
|
, ctx
|
1781
1922
|
|
1923
|
+
root = root || document.getElementById('mocha');
|
1924
|
+
|
1782
1925
|
if (canvas.getContext) {
|
1783
1926
|
var ratio = window.devicePixelRatio || 1;
|
1784
1927
|
canvas.style.width = canvas.width;
|
@@ -1813,8 +1956,7 @@ function HTML(runner) {
|
|
1813
1956
|
if (suite.root) return;
|
1814
1957
|
|
1815
1958
|
// suite
|
1816
|
-
var
|
1817
|
-
var url = location.protocol + '//' + location.host + location.pathname + '?grep=' + grep;
|
1959
|
+
var url = '?grep=' + encodeURIComponent(suite.fullTitle());
|
1818
1960
|
var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
|
1819
1961
|
|
1820
1962
|
// container
|
@@ -3045,10 +3187,10 @@ function TAP(runner) {
|
|
3045
3187
|
|
3046
3188
|
var self = this
|
3047
3189
|
, stats = this.stats
|
3048
|
-
, total = runner.total
|
3049
3190
|
, n = 1;
|
3050
3191
|
|
3051
3192
|
runner.on('start', function(){
|
3193
|
+
var total = runner.grepTotal(runner.suite);
|
3052
3194
|
console.log('%d..%d', 1, total);
|
3053
3195
|
});
|
3054
3196
|
|
@@ -3313,6 +3455,7 @@ function Runnable(title, fn) {
|
|
3313
3455
|
this.async = fn && fn.length;
|
3314
3456
|
this.sync = ! this.async;
|
3315
3457
|
this._timeout = 2000;
|
3458
|
+
this._slow = 75;
|
3316
3459
|
this.timedOut = false;
|
3317
3460
|
}
|
3318
3461
|
|
@@ -3340,6 +3483,21 @@ Runnable.prototype.timeout = function(ms){
|
|
3340
3483
|
return this;
|
3341
3484
|
};
|
3342
3485
|
|
3486
|
+
/**
|
3487
|
+
* Set & get slow `ms`.
|
3488
|
+
*
|
3489
|
+
* @param {Number} ms
|
3490
|
+
* @return {Runnable|Number} ms or self
|
3491
|
+
* @api private
|
3492
|
+
*/
|
3493
|
+
|
3494
|
+
Runnable.prototype.slow = function(ms){
|
3495
|
+
if (0 === arguments.length) return this._slow;
|
3496
|
+
debug('timeout %d', ms);
|
3497
|
+
this._slow = ms;
|
3498
|
+
return this;
|
3499
|
+
};
|
3500
|
+
|
3343
3501
|
/**
|
3344
3502
|
* Return the full title generated by recursively
|
3345
3503
|
* concatenating the parent's full title.
|
@@ -3651,7 +3809,6 @@ Runner.prototype.failHook = function(hook, err){
|
|
3651
3809
|
Runner.prototype.hook = function(name, fn){
|
3652
3810
|
var suite = this.suite
|
3653
3811
|
, hooks = suite['_' + name]
|
3654
|
-
, ms = suite._timeout
|
3655
3812
|
, self = this
|
3656
3813
|
, timer;
|
3657
3814
|
|
@@ -3961,6 +4118,7 @@ function filterLeaks(ok) {
|
|
3961
4118
|
return matched.length == 0 && (!global.navigator || 'onerror' !== key);
|
3962
4119
|
});
|
3963
4120
|
}
|
4121
|
+
|
3964
4122
|
}); // module: runner.js
|
3965
4123
|
|
3966
4124
|
require.register("suite.js", function(module, exports, require){
|
@@ -3971,6 +4129,7 @@ require.register("suite.js", function(module, exports, require){
|
|
3971
4129
|
|
3972
4130
|
var EventEmitter = require('browser/events').EventEmitter
|
3973
4131
|
, debug = require('browser/debug')('mocha:suite')
|
4132
|
+
, milliseconds = require('./ms')
|
3974
4133
|
, utils = require('./utils')
|
3975
4134
|
, Hook = require('./hook');
|
3976
4135
|
|
@@ -4023,6 +4182,7 @@ function Suite(title, ctx) {
|
|
4023
4182
|
this._afterAll = [];
|
4024
4183
|
this.root = !title;
|
4025
4184
|
this._timeout = 2000;
|
4185
|
+
this._slow = 75;
|
4026
4186
|
this._bail = false;
|
4027
4187
|
}
|
4028
4188
|
|
@@ -4046,6 +4206,7 @@ Suite.prototype.clone = function(){
|
|
4046
4206
|
debug('clone');
|
4047
4207
|
suite.ctx = this.ctx;
|
4048
4208
|
suite.timeout(this.timeout());
|
4209
|
+
suite.slow(this.slow());
|
4049
4210
|
suite.bail(this.bail());
|
4050
4211
|
return suite;
|
4051
4212
|
};
|
@@ -4060,12 +4221,28 @@ Suite.prototype.clone = function(){
|
|
4060
4221
|
|
4061
4222
|
Suite.prototype.timeout = function(ms){
|
4062
4223
|
if (0 == arguments.length) return this._timeout;
|
4063
|
-
if (
|
4224
|
+
if ('string' == typeof ms) ms = milliseconds(ms);
|
4064
4225
|
debug('timeout %d', ms);
|
4065
4226
|
this._timeout = parseInt(ms, 10);
|
4066
4227
|
return this;
|
4067
4228
|
};
|
4068
4229
|
|
4230
|
+
/**
|
4231
|
+
* Set slow `ms` or short-hand such as "2s".
|
4232
|
+
*
|
4233
|
+
* @param {Number|String} ms
|
4234
|
+
* @return {Suite|Number} for chaining
|
4235
|
+
* @api private
|
4236
|
+
*/
|
4237
|
+
|
4238
|
+
Suite.prototype.slow = function(ms){
|
4239
|
+
if (0 === arguments.length) return this._slow;
|
4240
|
+
if ('string' == typeof ms) ms = milliseconds(ms);
|
4241
|
+
debug('slow %d', ms);
|
4242
|
+
this._slow = ms;
|
4243
|
+
return this;
|
4244
|
+
};
|
4245
|
+
|
4069
4246
|
/**
|
4070
4247
|
* Sets whether to bail after first error.
|
4071
4248
|
*
|
@@ -4094,6 +4271,7 @@ Suite.prototype.beforeAll = function(fn){
|
|
4094
4271
|
var hook = new Hook('"before all" hook', fn);
|
4095
4272
|
hook.parent = this;
|
4096
4273
|
hook.timeout(this.timeout());
|
4274
|
+
hook.slow(this.slow());
|
4097
4275
|
hook.ctx = this.ctx;
|
4098
4276
|
this._beforeAll.push(hook);
|
4099
4277
|
this.emit('beforeAll', hook);
|
@@ -4113,6 +4291,7 @@ Suite.prototype.afterAll = function(fn){
|
|
4113
4291
|
var hook = new Hook('"after all" hook', fn);
|
4114
4292
|
hook.parent = this;
|
4115
4293
|
hook.timeout(this.timeout());
|
4294
|
+
hook.slow(this.slow());
|
4116
4295
|
hook.ctx = this.ctx;
|
4117
4296
|
this._afterAll.push(hook);
|
4118
4297
|
this.emit('afterAll', hook);
|
@@ -4132,6 +4311,7 @@ Suite.prototype.beforeEach = function(fn){
|
|
4132
4311
|
var hook = new Hook('"before each" hook', fn);
|
4133
4312
|
hook.parent = this;
|
4134
4313
|
hook.timeout(this.timeout());
|
4314
|
+
hook.slow(this.slow());
|
4135
4315
|
hook.ctx = this.ctx;
|
4136
4316
|
this._beforeEach.push(hook);
|
4137
4317
|
this.emit('beforeEach', hook);
|
@@ -4151,6 +4331,7 @@ Suite.prototype.afterEach = function(fn){
|
|
4151
4331
|
var hook = new Hook('"after each" hook', fn);
|
4152
4332
|
hook.parent = this;
|
4153
4333
|
hook.timeout(this.timeout());
|
4334
|
+
hook.slow(this.slow());
|
4154
4335
|
hook.ctx = this.ctx;
|
4155
4336
|
this._afterEach.push(hook);
|
4156
4337
|
this.emit('afterEach', hook);
|
@@ -4168,6 +4349,7 @@ Suite.prototype.afterEach = function(fn){
|
|
4168
4349
|
Suite.prototype.addSuite = function(suite){
|
4169
4350
|
suite.parent = this;
|
4170
4351
|
suite.timeout(this.timeout());
|
4352
|
+
suite.slow(this.slow());
|
4171
4353
|
suite.bail(this.bail());
|
4172
4354
|
this.suites.push(suite);
|
4173
4355
|
this.emit('suite', suite);
|
@@ -4185,6 +4367,7 @@ Suite.prototype.addSuite = function(suite){
|
|
4185
4367
|
Suite.prototype.addTest = function(test){
|
4186
4368
|
test.parent = this;
|
4187
4369
|
test.timeout(this.timeout());
|
4370
|
+
test.slow(this.slow());
|
4188
4371
|
test.ctx = this.ctx;
|
4189
4372
|
this.tests.push(test);
|
4190
4373
|
this.emit('test', test);
|
@@ -4303,7 +4486,7 @@ var ignore = ['node_modules', '.git'];
|
|
4303
4486
|
* @api private
|
4304
4487
|
*/
|
4305
4488
|
|
4306
|
-
exports.escape = function(html)
|
4489
|
+
exports.escape = function(html){
|
4307
4490
|
return String(html)
|
4308
4491
|
.replace(/&/g, '&')
|
4309
4492
|
.replace(/"/g, '"')
|
@@ -4320,7 +4503,7 @@ exports.escape = function(html) {
|
|
4320
4503
|
* @api private
|
4321
4504
|
*/
|
4322
4505
|
|
4323
|
-
exports.forEach = function(arr, fn, scope)
|
4506
|
+
exports.forEach = function(arr, fn, scope){
|
4324
4507
|
for (var i = 0, l = arr.length; i < l; i++)
|
4325
4508
|
fn.call(scope, arr[i], i);
|
4326
4509
|
};
|
@@ -4334,7 +4517,7 @@ exports.forEach = function(arr, fn, scope) {
|
|
4334
4517
|
* @api private
|
4335
4518
|
*/
|
4336
4519
|
|
4337
|
-
exports.indexOf = function
|
4520
|
+
exports.indexOf = function(arr, obj, start){
|
4338
4521
|
for (var i = start || 0, l = arr.length; i < l; i++) {
|
4339
4522
|
if (arr[i] === obj)
|
4340
4523
|
return i;
|
@@ -4348,15 +4531,14 @@ exports.indexOf = function (arr, obj, start) {
|
|
4348
4531
|
* @param {Array} array
|
4349
4532
|
* @param {Function} fn
|
4350
4533
|
* @param {Object} initial value
|
4351
|
-
* @param {Object} scope
|
4352
4534
|
* @api private
|
4353
4535
|
*/
|
4354
4536
|
|
4355
|
-
exports.reduce = function(arr, fn, val
|
4537
|
+
exports.reduce = function(arr, fn, val){
|
4356
4538
|
var rval = val;
|
4357
4539
|
|
4358
4540
|
for (var i = 0, l = arr.length; i < l; i++) {
|
4359
|
-
rval = fn
|
4541
|
+
rval = fn(rval, arr[i], i, arr);
|
4360
4542
|
}
|
4361
4543
|
|
4362
4544
|
return rval;
|
@@ -4367,17 +4549,15 @@ exports.reduce = function(arr, fn, val, scope) {
|
|
4367
4549
|
*
|
4368
4550
|
* @param {Array} array
|
4369
4551
|
* @param {Function} fn
|
4370
|
-
* @param {Object} scope
|
4371
4552
|
* @api private
|
4372
4553
|
*/
|
4373
4554
|
|
4374
|
-
exports.filter = function(arr, fn
|
4555
|
+
exports.filter = function(arr, fn){
|
4375
4556
|
var ret = [];
|
4376
4557
|
|
4377
4558
|
for (var i = 0, l = arr.length; i < l; i++) {
|
4378
4559
|
var val = arr[i];
|
4379
|
-
if (fn
|
4380
|
-
ret.push(val);
|
4560
|
+
if (fn(val, i, arr)) ret.push(val);
|
4381
4561
|
}
|
4382
4562
|
|
4383
4563
|
return ret;
|
@@ -4511,6 +4691,60 @@ exports.escapeRegexp = function(str){
|
|
4511
4691
|
exports.trim = function(str){
|
4512
4692
|
return str.replace(/^\s+|\s+$/g, '');
|
4513
4693
|
};
|
4694
|
+
|
4695
|
+
/**
|
4696
|
+
* Parse the given `qs`.
|
4697
|
+
*
|
4698
|
+
* @param {String} qs
|
4699
|
+
* @return {Object}
|
4700
|
+
* @api private
|
4701
|
+
*/
|
4702
|
+
|
4703
|
+
exports.parseQuery = function(qs){
|
4704
|
+
return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
|
4705
|
+
var i = pair.indexOf('=')
|
4706
|
+
, key = pair.slice(0, i)
|
4707
|
+
, val = pair.slice(++i);
|
4708
|
+
|
4709
|
+
obj[key] = decodeURIComponent(val);
|
4710
|
+
return obj;
|
4711
|
+
}, {});
|
4712
|
+
};
|
4713
|
+
|
4714
|
+
/**
|
4715
|
+
* Highlight the given string of `js`.
|
4716
|
+
*
|
4717
|
+
* @param {String} js
|
4718
|
+
* @return {String}
|
4719
|
+
* @api private
|
4720
|
+
*/
|
4721
|
+
|
4722
|
+
function highlight(js) {
|
4723
|
+
return js
|
4724
|
+
.replace(/</g, '<')
|
4725
|
+
.replace(/>/g, '>')
|
4726
|
+
.replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
|
4727
|
+
.replace(/('.*?')/gm, '<span class="string">$1</span>')
|
4728
|
+
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
|
4729
|
+
.replace(/(\d+)/gm, '<span class="number">$1</span>')
|
4730
|
+
.replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
|
4731
|
+
.replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
|
4732
|
+
}
|
4733
|
+
|
4734
|
+
/**
|
4735
|
+
* Highlight the contents of tag `name`.
|
4736
|
+
*
|
4737
|
+
* @param {String} name
|
4738
|
+
* @api private
|
4739
|
+
*/
|
4740
|
+
|
4741
|
+
exports.highlightTags = function(name) {
|
4742
|
+
var code = document.getElementsByTagName(name);
|
4743
|
+
for (var i = 0, len = code.length; i < len; ++i) {
|
4744
|
+
code[i].innerHTML = highlight(code[i].innerHTML);
|
4745
|
+
}
|
4746
|
+
};
|
4747
|
+
|
4514
4748
|
}); // module: utils.js
|
4515
4749
|
/**
|
4516
4750
|
* Node shims.
|
@@ -4574,69 +4808,25 @@ process.on = function(e, fn){
|
|
4574
4808
|
}
|
4575
4809
|
};
|
4576
4810
|
|
4577
|
-
/**
|
4578
|
-
* Expose mocha.
|
4579
|
-
*/
|
4580
|
-
|
4581
|
-
window.mocha = require('mocha');
|
4582
|
-
|
4583
4811
|
// boot
|
4584
4812
|
;(function(){
|
4585
|
-
var utils = mocha.utils
|
4586
|
-
, options = {}
|
4587
|
-
|
4588
|
-
// TODO: use new Mocha here... not mocha.grep etc
|
4589
|
-
|
4590
|
-
mocha.suite = new mocha.Suite('', new mocha.Context());
|
4591
|
-
|
4592
|
-
/**
|
4593
|
-
* Highlight the given string of `js`.
|
4594
|
-
*/
|
4595
|
-
|
4596
|
-
function highlight(js) {
|
4597
|
-
return js
|
4598
|
-
.replace(/</g, '<')
|
4599
|
-
.replace(/>/g, '>')
|
4600
|
-
.replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
|
4601
|
-
.replace(/('.*?')/gm, '<span class="string">$1</span>')
|
4602
|
-
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
|
4603
|
-
.replace(/(\d+)/gm, '<span class="number">$1</span>')
|
4604
|
-
.replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
|
4605
|
-
.replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
|
4606
|
-
}
|
4607
4813
|
|
4608
4814
|
/**
|
4609
|
-
*
|
4815
|
+
* Expose mocha.
|
4610
4816
|
*/
|
4611
4817
|
|
4612
|
-
|
4613
|
-
|
4614
|
-
for (var i = 0, len = code.length; i < len; ++i) {
|
4615
|
-
code[i].innerHTML = highlight(code[i].innerHTML);
|
4616
|
-
}
|
4617
|
-
}
|
4818
|
+
var Mocha = window.Mocha = require('mocha'),
|
4819
|
+
mocha = window.mocha = new Mocha({ reporter: 'html' });
|
4618
4820
|
|
4619
4821
|
/**
|
4620
|
-
*
|
4822
|
+
* Override ui to ensure that the ui functions are initialized.
|
4823
|
+
* Normally this would happen in Mocha.prototype.loadFiles.
|
4621
4824
|
*/
|
4622
4825
|
|
4623
|
-
function
|
4624
|
-
|
4625
|
-
|
4626
|
-
|
4627
|
-
, val = pair.slice(++i);
|
4628
|
-
|
4629
|
-
obj[key] = decodeURIComponent(val);
|
4630
|
-
return obj;
|
4631
|
-
}, {});
|
4632
|
-
}
|
4633
|
-
|
4634
|
-
/**
|
4635
|
-
* Grep.
|
4636
|
-
*/
|
4637
|
-
|
4638
|
-
mocha.grep = function(str){
|
4639
|
-
options.grep = new RegExp(utils.escapeRegexp(str));
|
4826
|
+
mocha.ui = function(ui){
|
4827
|
+
Mocha.prototype.ui.call(this, ui);
|
4828
|
+
this.suite.emit('pre-require', window, null, this);
|
4829
|
+
return this;
|
4640
4830
|
};
|
4641
4831
|
|
4642
4832
|
/**
|
@@ -4644,14 +4834,9 @@ window.mocha = require('mocha');
|
|
4644
4834
|
*/
|
4645
4835
|
|
4646
4836
|
mocha.setup = function(opts){
|
4647
|
-
if ('string'
|
4648
|
-
|
4649
|
-
|
4650
|
-
ui = mocha.interfaces[options.ui];
|
4651
|
-
if (!ui) throw new Error('invalid mocha interface "' + ui + '"');
|
4652
|
-
if (options.timeout) mocha.suite.timeout(options.timeout);
|
4653
|
-
ui(mocha.suite);
|
4654
|
-
mocha.suite.emit('pre-require', window, null, mocha);
|
4837
|
+
if ('string' == typeof opts) opts = { ui: opts };
|
4838
|
+
for (var opt in opts) this[opt](opts[opt]);
|
4839
|
+
return this;
|
4655
4840
|
};
|
4656
4841
|
|
4657
4842
|
/**
|
@@ -4659,18 +4844,16 @@ window.mocha = require('mocha');
|
|
4659
4844
|
*/
|
4660
4845
|
|
4661
4846
|
mocha.run = function(fn){
|
4662
|
-
mocha.
|
4663
|
-
|
4664
|
-
|
4665
|
-
var
|
4666
|
-
|
4667
|
-
|
4668
|
-
|
4669
|
-
|
4670
|
-
|
4671
|
-
|
4672
|
-
runner.on('end', highlightCode);
|
4673
|
-
return runner.run(fn);
|
4847
|
+
var options = mocha.options;
|
4848
|
+
mocha.globals('location');
|
4849
|
+
|
4850
|
+
var query = Mocha.utils.parseQuery(window.location.search || '');
|
4851
|
+
if (query.grep) mocha.grep(query.grep);
|
4852
|
+
|
4853
|
+
return Mocha.prototype.run.call(mocha, function(){
|
4854
|
+
Mocha.utils.highlightTags('code');
|
4855
|
+
if (fn) fn();
|
4856
|
+
});
|
4674
4857
|
};
|
4675
4858
|
})();
|
4676
4859
|
})();
|