konacha 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +10 -0
- data/README.md +2 -2
- data/app/assets/javascripts/konacha/runner.js +19 -4
- data/app/views/konacha/specs/iframe.html.erb +1 -2
- data/config/routes.rb +3 -3
- data/konacha.gemspec +1 -1
- data/lib/konacha/reporter/metadata.rb +2 -3
- data/lib/konacha/runner.rb +1 -1
- data/spec/dummy/spec/javascripts/failing_spec.js +6 -0
- data/spec/reporter/metadata_spec.rb +15 -10
- data/spec/runner_spec.rb +23 -4
- data/spec/views/specs/iframe.html.erb_spec.rb +3 -36
- data/vendor/assets/javascripts/mocha.js +134 -40
- data/vendor/assets/stylesheets/mocha.css +43 -19
- metadata +4 -5
- data/app/helpers/konacha/specs_helper.rb +0 -11
data/History.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# master
|
2
2
|
|
3
|
+
# 2.1.0
|
4
|
+
|
5
|
+
* Improve capybara-webkit compatibility (#79)
|
6
|
+
* Update mocha (1.7.0+)
|
7
|
+
* Fix mocha error detection in `done()` (#74)
|
8
|
+
* Make spec file path is available to reporters
|
9
|
+
* Improve error reporting for `konacha:run` output
|
10
|
+
|
11
|
+
# 2.0.0
|
12
|
+
|
3
13
|
* Run tests in an iframe, with `<body id="konacha">`. Each test file is run in
|
4
14
|
isolation.
|
5
15
|
* Removed support for konacha_config.js and Konacha.mochaOptions in favor of
|
data/README.md
CHANGED
@@ -192,8 +192,8 @@ The `defined?` check is necessary to avoid a dependency on Konacha in the produc
|
|
192
192
|
environment.
|
193
193
|
|
194
194
|
The `spec_dir` option tells Konacha where to find JavaScript specs. `driver`
|
195
|
-
names a Capybara driver used for the `run` task (try `:
|
196
|
-
installing [
|
195
|
+
names a Capybara driver used for the `run` task (try `:poltergeist`, after
|
196
|
+
installing [PhantomJS](https://github.com/jonleighton/poltergeist#installing-phantomjs)).
|
197
197
|
The `stylesheets` option sets the stylesheets to be linked from the `<head>`
|
198
198
|
of the test runner iframe. The values above are the defaults.
|
199
199
|
|
@@ -11,19 +11,34 @@ mocha.reporter(function(runner) {
|
|
11
11
|
fullTitle:test.fullTitle(),
|
12
12
|
duration:test.duration,
|
13
13
|
parentFullTitle:test.parent.fullTitle(),
|
14
|
-
status:status
|
14
|
+
status:status,
|
15
|
+
path:test.parent.path
|
15
16
|
};
|
16
17
|
|
17
|
-
if (status == "failed")
|
18
|
-
|
18
|
+
if (status == "failed") {
|
19
|
+
// Error objects don't serialize properly, so we copy attributes. Note
|
20
|
+
// that iterating over test.err skips name and message.
|
21
|
+
obj.error = {
|
22
|
+
name: test.err.name,
|
23
|
+
message: test.err.message,
|
24
|
+
// We could copy stack, fileName, and lineNumber here, but they're not
|
25
|
+
// available for AssertionErrors. If we had them reliably, we could
|
26
|
+
// easily display them as well.
|
27
|
+
};
|
28
|
+
}
|
19
29
|
|
20
30
|
return obj;
|
21
31
|
};
|
22
32
|
|
23
33
|
var createSuiteObject = function(suite) {
|
34
|
+
// We need to propagate the path down the suite tree
|
35
|
+
if (suite.parent)
|
36
|
+
suite.path = suite.parent.path;
|
37
|
+
|
24
38
|
var obj = {
|
25
39
|
title:suite.title,
|
26
|
-
fullTitle:suite.fullTitle()
|
40
|
+
fullTitle:suite.fullTitle(),
|
41
|
+
path:suite.path
|
27
42
|
};
|
28
43
|
|
29
44
|
if (suite.parent)
|
data/config/routes.rb
CHANGED
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 = "2.
|
20
|
+
gem.version = "2.1.0"
|
21
21
|
|
22
22
|
gem.add_dependency "railties", "~> 3.1"
|
23
23
|
gem.add_dependency "actionpack", "~> 3.1"
|
@@ -24,8 +24,7 @@ module Konacha
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def file_path
|
27
|
-
|
28
|
-
"" # RSpec's BaseFormatter expects the return value to be a string
|
27
|
+
data['path']
|
29
28
|
end
|
30
29
|
|
31
30
|
alias_method :location, :file_path
|
@@ -49,7 +48,7 @@ module Konacha
|
|
49
48
|
return unless data['status'] == "failed"
|
50
49
|
|
51
50
|
@exception ||= begin
|
52
|
-
e = Reporter::SpecException.new(data['error']['message'])
|
51
|
+
e = Reporter::SpecException.new("#{data['error']['name']}: #{data['error']['message']}")
|
53
52
|
e.set_backtrace([])
|
54
53
|
e
|
55
54
|
end
|
data/lib/konacha/runner.rb
CHANGED
@@ -19,7 +19,7 @@ module Konacha
|
|
19
19
|
done = false
|
20
20
|
begin
|
21
21
|
sleep 0.1
|
22
|
-
events = JSON.parse(session.evaluate_script('Konacha.getEvents()'))
|
22
|
+
events = JSON.parse(session.evaluate_script('window.top.Konacha.getEvents()'))
|
23
23
|
if events
|
24
24
|
events[events_consumed..-1].each do |event|
|
25
25
|
done = true if event['event'] == 'end'
|
@@ -2,4 +2,10 @@ describe("failure", function(){
|
|
2
2
|
it("fails", function(){
|
3
3
|
(2 + 2).should.equal(5);
|
4
4
|
});
|
5
|
+
|
6
|
+
it("errors", function() {
|
7
|
+
// Mocha catches and re-throws string exceptions, so we only need to test
|
8
|
+
// throwing real Error objects.
|
9
|
+
throw new Error("this one errors out");
|
10
|
+
});
|
5
11
|
});
|
@@ -28,9 +28,9 @@ describe Konacha::Reporter::Metadata do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "builds a SpecException object" do
|
31
|
-
subject.update('status' => 'failed', 'error' => {'message' => 'expected this to work'})
|
31
|
+
subject.update('status' => 'failed', 'error' => {'name' => 'Error', 'message' => 'expected this to work'})
|
32
32
|
subject.exception.should be_a(Konacha::Reporter::SpecException)
|
33
|
-
subject.exception.message.should == 'expected this to work'
|
33
|
+
subject.exception.message.should == 'Error: expected this to work'
|
34
34
|
subject.exception.backtrace.should == []
|
35
35
|
end
|
36
36
|
end
|
@@ -52,17 +52,22 @@ describe Konacha::Reporter::Metadata do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
|
-
it "
|
57
|
-
subject.update(
|
58
|
-
subject.
|
55
|
+
shared_examples_for "data delegation method" do |key, method|
|
56
|
+
it "returns data['#{key}']" do
|
57
|
+
subject.update(key => 'super test')
|
58
|
+
subject.send(method).should == 'super test'
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
describe "#file_path" do
|
63
|
+
it_behaves_like "data delegation method", "path", "file_path"
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#description" do
|
67
|
+
it_behaves_like "data delegation method", "title", "description"
|
68
|
+
end
|
69
|
+
|
62
70
|
describe "#full_description" do
|
63
|
-
|
64
|
-
subject.update('fullTitle' => 'super test')
|
65
|
-
subject.full_description.should == 'super test'
|
66
|
-
end
|
71
|
+
it_behaves_like "data delegation method", "fullTitle", "full_description"
|
67
72
|
end
|
68
73
|
end
|
data/spec/runner_spec.rb
CHANGED
@@ -32,7 +32,8 @@ describe Konacha::Runner do
|
|
32
32
|
'type' => 'suite',
|
33
33
|
'data' => {
|
34
34
|
'title' => 'failure',
|
35
|
-
'fullTitle' => 'failure'
|
35
|
+
'fullTitle' => 'failure',
|
36
|
+
'path' => 'failing_spec.js'
|
36
37
|
}}
|
37
38
|
end
|
38
39
|
|
@@ -41,7 +42,8 @@ describe Konacha::Runner do
|
|
41
42
|
'type' => 'suite',
|
42
43
|
'data' => {
|
43
44
|
'title' => 'failure',
|
44
|
-
'fullTitle' => 'failure'
|
45
|
+
'fullTitle' => 'failure',
|
46
|
+
'path' => 'failing_spec.js'
|
45
47
|
}}
|
46
48
|
end
|
47
49
|
|
@@ -51,7 +53,8 @@ describe Konacha::Runner do
|
|
51
53
|
'data' => {
|
52
54
|
'title' => 'fails',
|
53
55
|
'fullTitle' => 'failure fails',
|
54
|
-
'parentFullTitle' => 'failure'
|
56
|
+
'parentFullTitle' => 'failure',
|
57
|
+
'path' => 'failing_spec.js'}}
|
55
58
|
end
|
56
59
|
|
57
60
|
let(:failure) do
|
@@ -62,7 +65,20 @@ describe Konacha::Runner do
|
|
62
65
|
'fullTitle' => 'failure fails',
|
63
66
|
'parentFullTitle' => 'failure',
|
64
67
|
'status' => 'failed',
|
65
|
-
'
|
68
|
+
'path' => 'failing_spec.js',
|
69
|
+
'error' => {'message' => 'expected 4 to equal 5', 'name' => 'AssertionError'}}}
|
70
|
+
end
|
71
|
+
|
72
|
+
let(:error) do
|
73
|
+
{'event' => 'fail',
|
74
|
+
'type' => 'test',
|
75
|
+
'data' => {
|
76
|
+
'title' => 'errors',
|
77
|
+
'fullTitle' => 'failure errors',
|
78
|
+
'parentFullTitle' => 'failure',
|
79
|
+
'status' => 'failed',
|
80
|
+
'path' => 'failing_spec.js',
|
81
|
+
'error' => {'message' => 'this one errors out', 'name' => 'Error'}}}
|
66
82
|
end
|
67
83
|
|
68
84
|
let(:pass) do
|
@@ -73,6 +89,7 @@ describe Konacha::Runner do
|
|
73
89
|
'fullTitle' => 'the body#konacha element is empty',
|
74
90
|
'parentFullTitle' => 'the body#konacha element',
|
75
91
|
'status' => 'passed',
|
92
|
+
'path' => 'body_spec.js.coffee',
|
76
93
|
'duration' => anything}}
|
77
94
|
end
|
78
95
|
|
@@ -83,6 +100,7 @@ describe Konacha::Runner do
|
|
83
100
|
'title' => 'is pending',
|
84
101
|
'fullTitle' => 'pending test is pending',
|
85
102
|
'parentFullTitle' => 'pending test',
|
103
|
+
'path' => 'pending_spec.js',
|
86
104
|
'status' => 'pending'}}
|
87
105
|
end
|
88
106
|
|
@@ -95,6 +113,7 @@ describe Konacha::Runner do
|
|
95
113
|
subject.reporter.should_receive(:process_mocha_event).with(suite_end)
|
96
114
|
subject.reporter.should_receive(:process_mocha_event).with(test)
|
97
115
|
subject.reporter.should_receive(:process_mocha_event).with(failure)
|
116
|
+
subject.reporter.should_receive(:process_mocha_event).with(error)
|
98
117
|
subject.reporter.should_receive(:process_mocha_event).with(pass)
|
99
118
|
subject.reporter.should_receive(:process_mocha_event).with(pending)
|
100
119
|
subject.reporter.should_receive(:process_mocha_event).with(end_event)
|
@@ -5,54 +5,21 @@ describe "konacha/specs/iframe" do
|
|
5
5
|
assign(:stylesheets, [])
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
asset = double("asset called '#{asset_name}'")
|
10
|
-
asset.stub(:to_a).and_return([dependencies, asset].flatten)
|
11
|
-
asset.stub(:logical_path).and_return(asset_name)
|
12
|
-
view.asset_paths.stub(:asset_for).with(asset_name, "js").and_return(asset)
|
13
|
-
asset
|
14
|
-
end
|
15
|
-
|
16
|
-
def spec_double(asset_name, dependencies = [])
|
17
|
-
asset_double(asset_name, dependencies)
|
8
|
+
def spec_double(asset_name)
|
18
9
|
double("spec called '#{asset_name}'", :asset_name => asset_name, :path => "#{asset_name}.js")
|
19
10
|
end
|
20
11
|
|
21
|
-
let(:dependency) { asset_double("dependency") }
|
22
|
-
|
23
12
|
it "renders a script tag for @spec" do
|
24
13
|
assign(:spec, spec_double("a_spec"))
|
25
14
|
|
26
15
|
render
|
27
16
|
|
28
|
-
rendered.should have_selector("script[src='/assets/a_spec.js
|
29
|
-
end
|
30
|
-
|
31
|
-
it "renders a script tag for a spec's dependencies" do
|
32
|
-
assign(:spec, spec_double("spec", [dependency]))
|
33
|
-
|
34
|
-
render
|
35
|
-
|
36
|
-
rendered.should have_selector("script[src='/assets/dependency.js?body=1']")
|
37
|
-
rendered.should have_selector("script[src='/assets/spec.js?body=1']")
|
38
|
-
end
|
39
|
-
|
40
|
-
it "renders only one script tag for dependencies of dependencies" do
|
41
|
-
dependency_a = asset_double("dependency_a")
|
42
|
-
dependency_b = asset_double("dependency_b", [dependency_a])
|
43
|
-
|
44
|
-
assign(:spec, spec_double("a_spec", [dependency_a, dependency_b]))
|
45
|
-
|
46
|
-
render
|
47
|
-
|
48
|
-
rendered.should have_selector("script[src='/assets/dependency_a.js?body=1']", :count => 1)
|
49
|
-
rendered.should have_selector("script[src='/assets/dependency_b.js?body=1']", :count => 1)
|
17
|
+
rendered.should have_selector("script[src='/assets/a_spec.js']")
|
50
18
|
end
|
51
19
|
|
52
|
-
it "
|
20
|
+
it "renders the stylesheets" do
|
53
21
|
assign(:spec, spec_double("a_spec"))
|
54
22
|
assign(:stylesheets, %w(foo bar))
|
55
|
-
assign(:specs, [])
|
56
23
|
|
57
24
|
render
|
58
25
|
|
@@ -591,7 +591,7 @@ module.exports = function(suite){
|
|
591
591
|
context.describe = context.context = function(title, fn){
|
592
592
|
var suite = Suite.create(suites[0], title);
|
593
593
|
suites.unshift(suite);
|
594
|
-
fn();
|
594
|
+
fn.call(suite);
|
595
595
|
suites.shift();
|
596
596
|
return suite;
|
597
597
|
};
|
@@ -606,7 +606,7 @@ module.exports = function(suite){
|
|
606
606
|
var suite = Suite.create(suites[0], title);
|
607
607
|
suite.pending = true;
|
608
608
|
suites.unshift(suite);
|
609
|
-
fn();
|
609
|
+
fn.call(suite);
|
610
610
|
suites.shift();
|
611
611
|
};
|
612
612
|
|
@@ -903,7 +903,7 @@ module.exports = function(suite){
|
|
903
903
|
context.suite = function(title, fn){
|
904
904
|
var suite = Suite.create(suites[0], title);
|
905
905
|
suites.unshift(suite);
|
906
|
-
fn();
|
906
|
+
fn.call(suite);
|
907
907
|
suites.shift();
|
908
908
|
return suite;
|
909
909
|
};
|
@@ -937,6 +937,14 @@ module.exports = function(suite){
|
|
937
937
|
var test = context.test(title, fn);
|
938
938
|
mocha.grep(test.fullTitle());
|
939
939
|
};
|
940
|
+
|
941
|
+
/**
|
942
|
+
* Pending test case.
|
943
|
+
*/
|
944
|
+
|
945
|
+
context.test.skip = function(title){
|
946
|
+
context.test(title);
|
947
|
+
};
|
940
948
|
});
|
941
949
|
};
|
942
950
|
|
@@ -1211,6 +1219,18 @@ Mocha.prototype.slow = function(slow){
|
|
1211
1219
|
return this;
|
1212
1220
|
};
|
1213
1221
|
|
1222
|
+
/**
|
1223
|
+
* Makes all tests async (accepting a callback)
|
1224
|
+
*
|
1225
|
+
* @return {Mocha}
|
1226
|
+
* @api public
|
1227
|
+
*/
|
1228
|
+
|
1229
|
+
Mocha.prototype.asyncOnly = function(){
|
1230
|
+
this.options.asyncOnly = true;
|
1231
|
+
return this;
|
1232
|
+
};
|
1233
|
+
|
1214
1234
|
/**
|
1215
1235
|
* Run tests and invoke `fn()` when complete.
|
1216
1236
|
*
|
@@ -1226,6 +1246,7 @@ Mocha.prototype.run = function(fn){
|
|
1226
1246
|
var runner = new exports.Runner(suite);
|
1227
1247
|
var reporter = new this._reporter(runner);
|
1228
1248
|
runner.ignoreLeaks = options.ignoreLeaks;
|
1249
|
+
runner.asyncOnly = options.asyncOnly;
|
1229
1250
|
if (options.grep) runner.grep(options.grep, options.invert);
|
1230
1251
|
if (options.globals) runner.globals(options.globals);
|
1231
1252
|
if (options.growl) this._growl(runner, reporter);
|
@@ -1306,14 +1327,14 @@ function parse(str) {
|
|
1306
1327
|
*/
|
1307
1328
|
|
1308
1329
|
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';
|
1330
|
+
if (ms == d) return Math.round(ms / d) + ' day';
|
1331
|
+
if (ms > d) return Math.round(ms / d) + ' days';
|
1332
|
+
if (ms == h) return Math.round(ms / h) + ' hour';
|
1333
|
+
if (ms > h) return Math.round(ms / h) + ' hours';
|
1334
|
+
if (ms == m) return Math.round(ms / m) + ' minute';
|
1335
|
+
if (ms > m) return Math.round(ms / m) + ' minutes';
|
1336
|
+
if (ms == s) return Math.round(ms / s) + ' second';
|
1337
|
+
if (ms > s) return Math.round(ms / s) + ' seconds';
|
1317
1338
|
return ms + ' ms';
|
1318
1339
|
}
|
1319
1340
|
}); // module: ms.js
|
@@ -1382,6 +1403,23 @@ exports.colors = {
|
|
1382
1403
|
, 'diff removed': 41
|
1383
1404
|
};
|
1384
1405
|
|
1406
|
+
/**
|
1407
|
+
* Default symbol map.
|
1408
|
+
*/
|
1409
|
+
|
1410
|
+
exports.symbols = {
|
1411
|
+
ok: '✔',
|
1412
|
+
err: '✖',
|
1413
|
+
dot: '․'
|
1414
|
+
};
|
1415
|
+
|
1416
|
+
// With node.js on Windows: use symbols available in terminal default fonts
|
1417
|
+
if ('win32' == process.platform) {
|
1418
|
+
exports.symbols.ok = '\u221A';
|
1419
|
+
exports.symbols.err = '\u00D7';
|
1420
|
+
exports.symbols.dot = '.';
|
1421
|
+
}
|
1422
|
+
|
1385
1423
|
/**
|
1386
1424
|
* Color `str` with the given `type`,
|
1387
1425
|
* allowing colors to be disabled,
|
@@ -1532,6 +1570,8 @@ function Base(runner) {
|
|
1532
1570
|
if (!runner) return;
|
1533
1571
|
this.runner = runner;
|
1534
1572
|
|
1573
|
+
runner.stats = stats;
|
1574
|
+
|
1535
1575
|
runner.on('start', function(){
|
1536
1576
|
stats.start = new Date;
|
1537
1577
|
});
|
@@ -1596,7 +1636,7 @@ Base.prototype.epilogue = function(){
|
|
1596
1636
|
|
1597
1637
|
// failure
|
1598
1638
|
if (stats.failures) {
|
1599
|
-
fmt = color('bright fail', '
|
1639
|
+
fmt = color('bright fail', ' ' + exports.symbols.err)
|
1600
1640
|
+ color('fail', ' %d of %d %s failed')
|
1601
1641
|
+ color('light', ':')
|
1602
1642
|
|
@@ -1611,7 +1651,7 @@ Base.prototype.epilogue = function(){
|
|
1611
1651
|
}
|
1612
1652
|
|
1613
1653
|
// pass
|
1614
|
-
fmt = color('bright pass', '
|
1654
|
+
fmt = color('bright pass', ' ' + exports.symbols.ok)
|
1615
1655
|
+ color('green', ' %d %s complete')
|
1616
1656
|
+ color('light', ' (%s)');
|
1617
1657
|
|
@@ -1723,7 +1763,7 @@ function Doc(runner) {
|
|
1723
1763
|
++indents;
|
1724
1764
|
console.log('%s<section class="suite">', indent());
|
1725
1765
|
++indents;
|
1726
|
-
console.log('%s<h1>%s</h1>', indent(), suite.title);
|
1766
|
+
console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
|
1727
1767
|
console.log('%s<dl>', indent());
|
1728
1768
|
});
|
1729
1769
|
|
@@ -1736,7 +1776,7 @@ function Doc(runner) {
|
|
1736
1776
|
});
|
1737
1777
|
|
1738
1778
|
runner.on('pass', function(test){
|
1739
|
-
console.log('%s <dt>%s</dt>', indent(), test.title);
|
1779
|
+
console.log('%s <dt>%s</dt>', indent(), utils.escape(test.title));
|
1740
1780
|
var code = utils.escape(utils.clean(test.fn.toString()));
|
1741
1781
|
console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
|
1742
1782
|
});
|
@@ -1772,7 +1812,6 @@ function Dot(runner) {
|
|
1772
1812
|
var self = this
|
1773
1813
|
, stats = this.stats
|
1774
1814
|
, width = Base.window.width * .75 | 0
|
1775
|
-
, c = '․'
|
1776
1815
|
, n = 0;
|
1777
1816
|
|
1778
1817
|
runner.on('start', function(){
|
@@ -1780,21 +1819,21 @@ function Dot(runner) {
|
|
1780
1819
|
});
|
1781
1820
|
|
1782
1821
|
runner.on('pending', function(test){
|
1783
|
-
process.stdout.write(color('pending',
|
1822
|
+
process.stdout.write(color('pending', Base.symbols.dot));
|
1784
1823
|
});
|
1785
1824
|
|
1786
1825
|
runner.on('pass', function(test){
|
1787
1826
|
if (++n % width == 0) process.stdout.write('\n ');
|
1788
1827
|
if ('slow' == test.speed) {
|
1789
|
-
process.stdout.write(color('bright yellow',
|
1828
|
+
process.stdout.write(color('bright yellow', Base.symbols.dot));
|
1790
1829
|
} else {
|
1791
|
-
process.stdout.write(color(test.speed,
|
1830
|
+
process.stdout.write(color(test.speed, Base.symbols.dot));
|
1792
1831
|
}
|
1793
1832
|
});
|
1794
1833
|
|
1795
1834
|
runner.on('fail', function(test, err){
|
1796
1835
|
if (++n % width == 0) process.stdout.write('\n ');
|
1797
|
-
process.stdout.write(color('fail',
|
1836
|
+
process.stdout.write(color('fail', Base.symbols.dot));
|
1798
1837
|
});
|
1799
1838
|
|
1800
1839
|
runner.on('end', function(){
|
@@ -1897,7 +1936,7 @@ exports = module.exports = HTML;
|
|
1897
1936
|
* Stats template.
|
1898
1937
|
*/
|
1899
1938
|
|
1900
|
-
var statsTemplate = '<ul id="stats">'
|
1939
|
+
var statsTemplate = '<ul id="mocha-stats">'
|
1901
1940
|
+ '<li class="progress"><canvas width="40" height="40"></canvas></li>'
|
1902
1941
|
+ '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
|
1903
1942
|
+ '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
|
@@ -1925,7 +1964,7 @@ function HTML(runner, root) {
|
|
1925
1964
|
, failuresLink = items[2].getElementsByTagName('a')[0]
|
1926
1965
|
, duration = items[3].getElementsByTagName('em')[0]
|
1927
1966
|
, canvas = stat.getElementsByTagName('canvas')[0]
|
1928
|
-
, report = fragment('<ul id="report"></ul>')
|
1967
|
+
, report = fragment('<ul id="mocha-report"></ul>')
|
1929
1968
|
, stack = [report]
|
1930
1969
|
, progress
|
1931
1970
|
, ctx
|
@@ -1992,7 +2031,7 @@ function HTML(runner, root) {
|
|
1992
2031
|
window.scrollTo(0, document.body.scrollHeight);
|
1993
2032
|
|
1994
2033
|
// TODO: add to stats
|
1995
|
-
var percent = stats.tests / total * 100 | 0;
|
2034
|
+
var percent = stats.tests / this.total * 100 | 0;
|
1996
2035
|
if (progress) progress.update(percent).draw(ctx);
|
1997
2036
|
|
1998
2037
|
// update stats
|
@@ -2003,11 +2042,11 @@ function HTML(runner, root) {
|
|
2003
2042
|
|
2004
2043
|
// test
|
2005
2044
|
if ('passed' == test.state) {
|
2006
|
-
var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span></h2></li>', test.speed, test.title, test.duration);
|
2045
|
+
var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="?grep=%e" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, encodeURIComponent(test.fullTitle()));
|
2007
2046
|
} else if (test.pending) {
|
2008
2047
|
var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
|
2009
2048
|
} else {
|
2010
|
-
var el = fragment('<li class="test fail"><h2>%e
|
2049
|
+
var el = fragment('<li class="test fail"><h2>%e <a href="?grep=%e" class="replay">‣</a></h2></li>', test.title, encodeURIComponent(test.fullTitle()));
|
2011
2050
|
var str = test.err.stack || test.err.toString();
|
2012
2051
|
|
2013
2052
|
// FF / Opera do not add the message
|
@@ -2043,7 +2082,8 @@ function HTML(runner, root) {
|
|
2043
2082
|
pre.style.display = 'none';
|
2044
2083
|
}
|
2045
2084
|
|
2046
|
-
|
2085
|
+
// Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
|
2086
|
+
if (stack[0]) stack[0].appendChild(el);
|
2047
2087
|
});
|
2048
2088
|
}
|
2049
2089
|
|
@@ -2052,7 +2092,7 @@ function HTML(runner, root) {
|
|
2052
2092
|
*/
|
2053
2093
|
|
2054
2094
|
function error(msg) {
|
2055
|
-
document.body.appendChild(fragment('<div id="error">%s</div>', msg));
|
2095
|
+
document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
|
2056
2096
|
}
|
2057
2097
|
|
2058
2098
|
/**
|
@@ -2230,6 +2270,10 @@ function map(cov) {
|
|
2230
2270
|
ret.sloc += data.sloc;
|
2231
2271
|
}
|
2232
2272
|
|
2273
|
+
ret.files.sort(function(a, b) {
|
2274
|
+
return a.filename.localeCompare(b.filename);
|
2275
|
+
});
|
2276
|
+
|
2233
2277
|
if (ret.sloc > 0) {
|
2234
2278
|
ret.coverage = (ret.hits / ret.sloc) * 100;
|
2235
2279
|
}
|
@@ -2584,7 +2628,7 @@ function List(runner) {
|
|
2584
2628
|
});
|
2585
2629
|
|
2586
2630
|
runner.on('pass', function(test){
|
2587
|
-
var fmt = color('checkmark', '
|
2631
|
+
var fmt = color('checkmark', ' '+Base.symbols.dot)
|
2588
2632
|
+ color('pass', ' %s: ')
|
2589
2633
|
+ color(test.speed, '%dms');
|
2590
2634
|
cursor.CR();
|
@@ -2680,7 +2724,7 @@ function Markdown(runner) {
|
|
2680
2724
|
runner.on('suite', function(suite){
|
2681
2725
|
++level;
|
2682
2726
|
var slug = utils.slug(suite.fullTitle());
|
2683
|
-
buf += '<a name="' + slug + '"
|
2727
|
+
buf += '<a name="' + slug + '"></a>' + '\n';
|
2684
2728
|
buf += title(suite.title) + '\n';
|
2685
2729
|
});
|
2686
2730
|
|
@@ -3056,7 +3100,7 @@ function Progress(runner, options) {
|
|
3056
3100
|
// default chars
|
3057
3101
|
options.open = options.open || '[';
|
3058
3102
|
options.complete = options.complete || '▬';
|
3059
|
-
options.incomplete = options.incomplete ||
|
3103
|
+
options.incomplete = options.incomplete || Base.symbols.dot;
|
3060
3104
|
options.close = options.close || ']';
|
3061
3105
|
options.verbose = false;
|
3062
3106
|
|
@@ -3165,13 +3209,13 @@ function Spec(runner) {
|
|
3165
3209
|
runner.on('pass', function(test){
|
3166
3210
|
if ('fast' == test.speed) {
|
3167
3211
|
var fmt = indent()
|
3168
|
-
+ color('checkmark', '
|
3212
|
+
+ color('checkmark', ' ' + Base.symbols.ok)
|
3169
3213
|
+ color('pass', ' %s ');
|
3170
3214
|
cursor.CR();
|
3171
3215
|
console.log(fmt, test.title);
|
3172
3216
|
} else {
|
3173
3217
|
var fmt = indent()
|
3174
|
-
+ color('checkmark', '
|
3218
|
+
+ color('checkmark', ' ' + Base.symbols.ok)
|
3175
3219
|
+ color('pass', ' %s ')
|
3176
3220
|
+ color(test.speed, '(%dms)');
|
3177
3221
|
cursor.CR();
|
@@ -3461,7 +3505,8 @@ require.register("runnable.js", function(module, exports, require){
|
|
3461
3505
|
*/
|
3462
3506
|
|
3463
3507
|
var EventEmitter = require('browser/events').EventEmitter
|
3464
|
-
, debug = require('browser/debug')('mocha:runnable')
|
3508
|
+
, debug = require('browser/debug')('mocha:runnable')
|
3509
|
+
, milliseconds = require('./ms');
|
3465
3510
|
|
3466
3511
|
/**
|
3467
3512
|
* Save timer references to avoid Sinon interfering (see GH-237).
|
@@ -3473,6 +3518,12 @@ var Date = global.Date
|
|
3473
3518
|
, clearTimeout = global.clearTimeout
|
3474
3519
|
, clearInterval = global.clearInterval;
|
3475
3520
|
|
3521
|
+
/**
|
3522
|
+
* Object#toString().
|
3523
|
+
*/
|
3524
|
+
|
3525
|
+
var toString = Object.prototype.toString;
|
3526
|
+
|
3476
3527
|
/**
|
3477
3528
|
* Expose `Runnable`.
|
3478
3529
|
*/
|
@@ -3508,13 +3559,14 @@ Runnable.prototype.constructor = Runnable;
|
|
3508
3559
|
/**
|
3509
3560
|
* Set & get timeout `ms`.
|
3510
3561
|
*
|
3511
|
-
* @param {Number} ms
|
3562
|
+
* @param {Number|String} ms
|
3512
3563
|
* @return {Runnable|Number} ms or self
|
3513
3564
|
* @api private
|
3514
3565
|
*/
|
3515
3566
|
|
3516
3567
|
Runnable.prototype.timeout = function(ms){
|
3517
3568
|
if (0 == arguments.length) return this._timeout;
|
3569
|
+
if ('string' == typeof ms) ms = milliseconds(ms);
|
3518
3570
|
debug('timeout %d', ms);
|
3519
3571
|
this._timeout = ms;
|
3520
3572
|
if (this.timer) this.resetTimeout();
|
@@ -3524,13 +3576,14 @@ Runnable.prototype.timeout = function(ms){
|
|
3524
3576
|
/**
|
3525
3577
|
* Set & get slow `ms`.
|
3526
3578
|
*
|
3527
|
-
* @param {Number} ms
|
3579
|
+
* @param {Number|String} ms
|
3528
3580
|
* @return {Runnable|Number} ms or self
|
3529
3581
|
* @api private
|
3530
3582
|
*/
|
3531
3583
|
|
3532
3584
|
Runnable.prototype.slow = function(ms){
|
3533
3585
|
if (0 === arguments.length) return this._slow;
|
3586
|
+
if ('string' == typeof ms) ms = milliseconds(ms);
|
3534
3587
|
debug('timeout %d', ms);
|
3535
3588
|
this._slow = ms;
|
3536
3589
|
return this;
|
@@ -3644,7 +3697,7 @@ Runnable.prototype.run = function(fn){
|
|
3644
3697
|
if (this.async) {
|
3645
3698
|
try {
|
3646
3699
|
this.fn.call(ctx, function(err){
|
3647
|
-
if (err
|
3700
|
+
if (toString.call(err) === "[object Error]") return done(err);
|
3648
3701
|
if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
|
3649
3702
|
done();
|
3650
3703
|
});
|
@@ -3653,7 +3706,11 @@ Runnable.prototype.run = function(fn){
|
|
3653
3706
|
}
|
3654
3707
|
return;
|
3655
3708
|
}
|
3656
|
-
|
3709
|
+
|
3710
|
+
if (this.asyncOnly) {
|
3711
|
+
return done(new Error('--async-only option in use without declaring `done()`'));
|
3712
|
+
}
|
3713
|
+
|
3657
3714
|
// sync
|
3658
3715
|
try {
|
3659
3716
|
if (!this.pending) this.fn.call(ctx);
|
@@ -3680,6 +3737,19 @@ var EventEmitter = require('browser/events').EventEmitter
|
|
3680
3737
|
, keys = utils.keys
|
3681
3738
|
, noop = function(){};
|
3682
3739
|
|
3740
|
+
/**
|
3741
|
+
* Non-enumerable globals.
|
3742
|
+
*/
|
3743
|
+
|
3744
|
+
var globals = [
|
3745
|
+
'setTimeout',
|
3746
|
+
'clearTimeout',
|
3747
|
+
'setInterval',
|
3748
|
+
'clearInterval',
|
3749
|
+
'XMLHttpRequest',
|
3750
|
+
'Date'
|
3751
|
+
];
|
3752
|
+
|
3683
3753
|
/**
|
3684
3754
|
* Expose `Runner`.
|
3685
3755
|
*/
|
@@ -3714,7 +3784,7 @@ function Runner(suite) {
|
|
3714
3784
|
this.on('test end', function(test){ self.checkGlobals(test); });
|
3715
3785
|
this.on('hook end', function(hook){ self.checkGlobals(hook); });
|
3716
3786
|
this.grep(/.*/);
|
3717
|
-
this.globals(
|
3787
|
+
this.globals(this.globalProps().concat(['errno']));
|
3718
3788
|
}
|
3719
3789
|
|
3720
3790
|
/**
|
@@ -3765,6 +3835,25 @@ Runner.prototype.grepTotal = function(suite) {
|
|
3765
3835
|
return total;
|
3766
3836
|
};
|
3767
3837
|
|
3838
|
+
/**
|
3839
|
+
* Return a list of global properties.
|
3840
|
+
*
|
3841
|
+
* @return {Array}
|
3842
|
+
* @api private
|
3843
|
+
*/
|
3844
|
+
|
3845
|
+
Runner.prototype.globalProps = function() {
|
3846
|
+
var props = utils.keys(global);
|
3847
|
+
|
3848
|
+
// non-enumerables
|
3849
|
+
for (var i = 0; i < globals.length; ++i) {
|
3850
|
+
if (~props.indexOf(globals[i])) continue;
|
3851
|
+
props.push(globals[i]);
|
3852
|
+
}
|
3853
|
+
|
3854
|
+
return props;
|
3855
|
+
};
|
3856
|
+
|
3768
3857
|
/**
|
3769
3858
|
* Allow the given `arr` of globals.
|
3770
3859
|
*
|
@@ -3791,7 +3880,7 @@ Runner.prototype.globals = function(arr){
|
|
3791
3880
|
Runner.prototype.checkGlobals = function(test){
|
3792
3881
|
if (this.ignoreLeaks) return;
|
3793
3882
|
var ok = this._globals;
|
3794
|
-
var globals =
|
3883
|
+
var globals = this.globalProps();
|
3795
3884
|
var isNode = process.kill;
|
3796
3885
|
var leaks;
|
3797
3886
|
|
@@ -3971,6 +4060,8 @@ Runner.prototype.runTest = function(fn){
|
|
3971
4060
|
var test = this.test
|
3972
4061
|
, self = this;
|
3973
4062
|
|
4063
|
+
if (this.asyncOnly) test.asyncOnly = true;
|
4064
|
+
|
3974
4065
|
try {
|
3975
4066
|
test.on('error', function(err){
|
3976
4067
|
self.fail(test, err);
|
@@ -3992,7 +4083,7 @@ Runner.prototype.runTest = function(fn){
|
|
3992
4083
|
|
3993
4084
|
Runner.prototype.runTests = function(suite, fn){
|
3994
4085
|
var self = this
|
3995
|
-
, tests = suite.tests
|
4086
|
+
, tests = suite.tests.slice()
|
3996
4087
|
, test;
|
3997
4088
|
|
3998
4089
|
function next(err) {
|
@@ -4160,6 +4251,8 @@ function filterLeaks(ok, globals) {
|
|
4160
4251
|
return filter(globals, function(key){
|
4161
4252
|
var matched = filter(ok, function(ok){
|
4162
4253
|
if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
|
4254
|
+
// Opera and IE expose global variables for HTML element IDs (issue #243)
|
4255
|
+
if (/^mocha-/.test(key)) return true;
|
4163
4256
|
return key == ok;
|
4164
4257
|
});
|
4165
4258
|
return matched.length == 0 && (!global.navigator || 'onerror' !== key);
|
@@ -4896,6 +4989,7 @@ process.on = function(e, fn){
|
|
4896
4989
|
|
4897
4990
|
var query = Mocha.utils.parseQuery(window.location.search || '');
|
4898
4991
|
if (query.grep) mocha.grep(query.grep);
|
4992
|
+
if (query.invert) mocha.invert();
|
4899
4993
|
|
4900
4994
|
return Mocha.prototype.run.call(mocha, function(){
|
4901
4995
|
Mocha.utils.highlightTags('code');
|
@@ -55,16 +55,6 @@ body {
|
|
55
55
|
margin-left: 15px;
|
56
56
|
}
|
57
57
|
|
58
|
-
#mocha .test:hover h2::after {
|
59
|
-
position: relative;
|
60
|
-
top: 0;
|
61
|
-
right: -10px;
|
62
|
-
content: '(view source)';
|
63
|
-
font-size: 12px;
|
64
|
-
font-family: arial;
|
65
|
-
color: #888;
|
66
|
-
}
|
67
|
-
|
68
58
|
#mocha .test.pending:hover h2::after {
|
69
59
|
content: '(pending)';
|
70
60
|
font-family: arial;
|
@@ -134,6 +124,8 @@ body {
|
|
134
124
|
|
135
125
|
#mocha .test pre.error {
|
136
126
|
color: #c00;
|
127
|
+
max-height: 300px;
|
128
|
+
overflow: auto;
|
137
129
|
}
|
138
130
|
|
139
131
|
#mocha .test pre {
|
@@ -145,24 +137,56 @@ body {
|
|
145
137
|
border-bottom-color: #ddd;
|
146
138
|
-webkit-border-radius: 3px;
|
147
139
|
-webkit-box-shadow: 0 1px 3px #eee;
|
140
|
+
-moz-border-radius: 3px;
|
141
|
+
-moz-box-shadow: 0 1px 3px #eee;
|
142
|
+
}
|
143
|
+
|
144
|
+
#mocha .test h2 {
|
145
|
+
position: relative;
|
146
|
+
}
|
147
|
+
|
148
|
+
#mocha .test a.replay {
|
149
|
+
position: absolute;
|
150
|
+
top: 3px;
|
151
|
+
right: -20px;
|
152
|
+
text-decoration: none;
|
153
|
+
vertical-align: middle;
|
154
|
+
display: block;
|
155
|
+
width: 15px;
|
156
|
+
height: 15px;
|
157
|
+
line-height: 15px;
|
158
|
+
text-align: center;
|
159
|
+
background: #eee;
|
160
|
+
font-size: 15px;
|
161
|
+
-moz-border-radius: 15px;
|
162
|
+
border-radius: 15px;
|
163
|
+
-webkit-transition: opacity 200ms;
|
164
|
+
-moz-transition: opacity 200ms;
|
165
|
+
transition: opacity 200ms;
|
166
|
+
opacity: 0.2;
|
167
|
+
color: #888;
|
168
|
+
}
|
169
|
+
|
170
|
+
#mocha .test:hover a.replay {
|
171
|
+
opacity: 1;
|
148
172
|
}
|
149
173
|
|
150
|
-
#report.pass .test.fail {
|
174
|
+
#mocha-report.pass .test.fail {
|
151
175
|
display: none;
|
152
176
|
}
|
153
177
|
|
154
|
-
#report.fail .test.pass {
|
178
|
+
#mocha-report.fail .test.pass {
|
155
179
|
display: none;
|
156
180
|
}
|
157
181
|
|
158
|
-
#error {
|
182
|
+
#mocha-error {
|
159
183
|
color: #c00;
|
160
184
|
font-size: 1.5 em;
|
161
185
|
font-weight: 100;
|
162
186
|
letter-spacing: 1px;
|
163
187
|
}
|
164
188
|
|
165
|
-
#stats {
|
189
|
+
#mocha-stats {
|
166
190
|
position: fixed;
|
167
191
|
top: 15px;
|
168
192
|
right: 10px;
|
@@ -171,25 +195,25 @@ body {
|
|
171
195
|
color: #888;
|
172
196
|
}
|
173
197
|
|
174
|
-
#stats .progress {
|
198
|
+
#mocha-stats .progress {
|
175
199
|
float: right;
|
176
200
|
padding-top: 0;
|
177
201
|
}
|
178
202
|
|
179
|
-
#stats em {
|
203
|
+
#mocha-stats em {
|
180
204
|
color: black;
|
181
205
|
}
|
182
206
|
|
183
|
-
#stats a {
|
207
|
+
#mocha-stats a {
|
184
208
|
text-decoration: none;
|
185
209
|
color: inherit;
|
186
210
|
}
|
187
211
|
|
188
|
-
#stats a:hover {
|
212
|
+
#mocha-stats a:hover {
|
189
213
|
border-bottom: 1px solid #eee;
|
190
214
|
}
|
191
215
|
|
192
|
-
#stats li {
|
216
|
+
#mocha-stats li {
|
193
217
|
display: inline-block;
|
194
218
|
margin: 0 5px;
|
195
219
|
list-style: none;
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: konacha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
@@ -219,7 +219,6 @@ files:
|
|
219
219
|
- app/assets/javascripts/konacha/runner.js
|
220
220
|
- app/assets/stylesheets/konacha.css
|
221
221
|
- app/controllers/konacha/specs_controller.rb
|
222
|
-
- app/helpers/konacha/specs_helper.rb
|
223
222
|
- app/models/konacha/spec.rb
|
224
223
|
- app/views/konacha/specs/iframe.html.erb
|
225
224
|
- app/views/konacha/specs/parent.html.erb
|
@@ -293,7 +292,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
293
292
|
version: '0'
|
294
293
|
segments:
|
295
294
|
- 0
|
296
|
-
hash:
|
295
|
+
hash: 3925858609207323185
|
297
296
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
298
297
|
none: false
|
299
298
|
requirements:
|
@@ -302,7 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
302
301
|
version: '0'
|
303
302
|
segments:
|
304
303
|
- 0
|
305
|
-
hash:
|
304
|
+
hash: 3925858609207323185
|
306
305
|
requirements: []
|
307
306
|
rubyforge_project:
|
308
307
|
rubygems_version: 1.8.24
|
@@ -1,11 +0,0 @@
|
|
1
|
-
module Konacha
|
2
|
-
module SpecsHelper
|
3
|
-
def spec_include_tag(*specs)
|
4
|
-
assets = specs.map do |spec|
|
5
|
-
asset_paths.asset_for(spec.asset_name, "js").to_a
|
6
|
-
end.flatten.map(&:logical_path).uniq
|
7
|
-
|
8
|
-
javascript_include_tag *(assets << {:body => true, :debug => false})
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|