konacha 2.0.0 → 2.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.
- 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
|