konacha 2.0.0.beta2 → 2.0.0.beta3
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 +4 -2
- data/LICENSE +25 -0
- data/README.md +24 -2
- data/app/assets/javascripts/konacha/parent.js +2 -1
- data/app/assets/javascripts/konacha/runner.js +48 -23
- data/konacha.gemspec +1 -1
- data/lib/konacha.rb +2 -0
- data/lib/konacha/engine.rb +1 -0
- data/lib/konacha/formatter.rb +80 -0
- data/lib/konacha/reporter.rb +91 -0
- data/lib/konacha/reporter/example.rb +34 -0
- data/lib/konacha/reporter/example_group.rb +37 -0
- data/lib/konacha/reporter/metadata.rb +81 -0
- data/lib/konacha/runner.rb +24 -78
- data/spec/formatter_spec.rb +69 -0
- data/spec/reporter/example_group_spec.rb +64 -0
- data/spec/reporter/example_spec.rb +77 -0
- data/spec/reporter/metadata_spec.rb +68 -0
- data/spec/reporter_spec.rb +112 -0
- data/spec/runner_spec.rb +88 -19
- data/vendor/assets/javascripts/chai.js +121 -62
- data/vendor/assets/javascripts/mocha.js +64 -17
- data/vendor/assets/stylesheets/mocha.css +4 -0
- metadata +21 -3
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Konacha::Reporter do
|
4
|
+
let(:formatter) { double('formatter').as_null_object }
|
5
|
+
subject { described_class.new(formatter) }
|
6
|
+
|
7
|
+
describe "#start" do
|
8
|
+
it "sets the start time to the current time" do
|
9
|
+
subject.start
|
10
|
+
subject.start_time.should be_within(1.second).of(Time.now)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "processes the start event" do
|
14
|
+
subject.should_receive(:process_event).with(:start, nil)
|
15
|
+
subject.start
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#finish" do
|
20
|
+
it "calls #stop" do
|
21
|
+
subject.should_receive(:stop)
|
22
|
+
subject.finish
|
23
|
+
end
|
24
|
+
|
25
|
+
it "processes events" do
|
26
|
+
subject.stub(:stop)
|
27
|
+
subject.should_receive(:process_event).with(:start_dump).ordered
|
28
|
+
subject.should_receive(:process_event).with(:dump_pending).ordered
|
29
|
+
subject.should_receive(:process_event).with(:dump_failures).ordered
|
30
|
+
subject.should_receive(:process_event).with(:dump_summary, nil, 0, 0, 0).ordered
|
31
|
+
subject.should_receive(:process_event).with(:close).ordered
|
32
|
+
subject.finish
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#stop" do
|
37
|
+
it "calculates duration" do
|
38
|
+
subject.start
|
39
|
+
subject.stop
|
40
|
+
subject.duration.should_not be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it "processes the stop event" do
|
44
|
+
subject.should_receive(:process_event).with(:stop)
|
45
|
+
subject.stop
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#process_mocha_event" do
|
50
|
+
it "creates the object" do
|
51
|
+
subject.stub(:process_event)
|
52
|
+
subject.should_receive(:update_or_create_object).with('data', 'type')
|
53
|
+
subject.process_mocha_event({'data' => 'data', 'type' => 'type'})
|
54
|
+
end
|
55
|
+
|
56
|
+
it "calls #process_event with the converted event name" do
|
57
|
+
object = double('test')
|
58
|
+
subject.stub(:update_or_create_object) { object }
|
59
|
+
subject.should_receive(:process_event).with(:example_started, object)
|
60
|
+
subject.process_mocha_event({'event' => 'test', 'type' => 'test'})
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#process_event" do
|
65
|
+
describe "increments counts" do
|
66
|
+
it "increments example count" do
|
67
|
+
subject.process_event(:example_started)
|
68
|
+
subject.example_count.should == 1
|
69
|
+
end
|
70
|
+
|
71
|
+
it "increments pending count" do
|
72
|
+
subject.process_event(:example_pending)
|
73
|
+
subject.pending_count.should == 1
|
74
|
+
end
|
75
|
+
|
76
|
+
it "increments failed count" do
|
77
|
+
subject.process_event(:example_failed)
|
78
|
+
subject.failure_count.should == 1
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "forwards the call on to the formatters" do
|
83
|
+
formatter.should_receive(:example_started).with('arg!')
|
84
|
+
subject.process_event(:example_started, 'arg!')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#update_or_create_object" do
|
89
|
+
describe "creates the right type of object" do
|
90
|
+
it "creates example if test" do
|
91
|
+
subject.update_or_create_object({}, 'test').should be_a(Konacha::Reporter::Example)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "creates example_group if suite" do
|
95
|
+
subject.update_or_create_object({}, 'suite').should be_a(Konacha::Reporter::ExampleGroup)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it "updates if the object with same fullTitle exists" do
|
100
|
+
data = {'fullTitle' => 'title'}
|
101
|
+
object = subject.update_or_create_object(data, 'test')
|
102
|
+
object.should_receive(:update_metadata).with(data)
|
103
|
+
subject.update_or_create_object(data, 'test').should == object
|
104
|
+
end
|
105
|
+
|
106
|
+
it "links up the parent correctly" do
|
107
|
+
suite = subject.update_or_create_object({'fullTitle' => 'suite'}, 'suite')
|
108
|
+
object = subject.update_or_create_object({'fullTitle' => 'suite awesome', 'parentFullTitle' => 'suite'}, 'test')
|
109
|
+
object.parent.should == suite
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/spec/runner_spec.rb
CHANGED
@@ -3,29 +3,98 @@ require 'spec_helper'
|
|
3
3
|
describe Konacha::Runner do
|
4
4
|
before do
|
5
5
|
Konacha.mode = :runner
|
6
|
-
|
6
|
+
STDOUT.stub(:puts)
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
describe ".new" do
|
10
|
+
before do
|
11
|
+
class TestFormatter
|
12
|
+
def initialize(io)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
ENV['FORMAT'] = 'Konacha::Formatter,TestFormatter'
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
Object.send(:remove_const, :TestFormatter)
|
20
|
+
ENV.delete('FORMAT')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "initializes a reporter with formatters named by the FORMAT environment variable" do
|
24
|
+
Konacha::Reporter.should_receive(:new).with(instance_of(Konacha::Formatter), instance_of(TestFormatter))
|
25
|
+
described_class.new
|
26
|
+
end
|
27
|
+
end
|
11
28
|
|
12
29
|
describe "#run" do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
30
|
+
let(:suite) do
|
31
|
+
{'event' => 'suite',
|
32
|
+
'type' => 'suite',
|
33
|
+
'data' => {
|
34
|
+
'title' => 'failure',
|
35
|
+
'fullTitle' => 'failure'
|
36
|
+
}}
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:suite_end) do
|
40
|
+
{'event' => 'suite end',
|
41
|
+
'type' => 'suite',
|
42
|
+
'data' => {
|
43
|
+
'title' => 'failure',
|
44
|
+
'fullTitle' => 'failure'
|
45
|
+
}}
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:test) do
|
49
|
+
{'event' => 'test',
|
50
|
+
'type' => 'test',
|
51
|
+
'data' => {
|
52
|
+
'title' => 'fails',
|
53
|
+
'fullTitle' => 'failure fails',
|
54
|
+
'parentFullTitle' => 'failure'}}
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:failure) do
|
58
|
+
{'event' => 'fail',
|
59
|
+
'type' => 'test',
|
60
|
+
'data' => {
|
61
|
+
'title' => 'fails',
|
62
|
+
'fullTitle' => 'failure fails',
|
63
|
+
'parentFullTitle' => 'failure',
|
64
|
+
'status' => 'failed',
|
65
|
+
'error' => {'message' => 'expected 4 to equal 5', 'expected' => 5}}}
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:pass) do
|
69
|
+
{'event' => 'pass',
|
70
|
+
'type' => 'test',
|
71
|
+
'data' => {
|
72
|
+
'title' => 'is empty',
|
73
|
+
'fullTitle' => 'the body#konacha element is empty',
|
74
|
+
'parentFullTitle' => 'the body#konacha element',
|
75
|
+
'status' => 'passed',
|
76
|
+
'duration' => anything}}
|
77
|
+
end
|
78
|
+
|
79
|
+
let(:pending) do
|
80
|
+
{'event' => 'pending',
|
81
|
+
'type' => 'test',
|
82
|
+
'data' => {
|
83
|
+
'title' => 'is pending',
|
84
|
+
'fullTitle' => 'pending test is pending',
|
85
|
+
'parentFullTitle' => 'pending test',
|
86
|
+
'status' => 'pending'}}
|
87
|
+
end
|
88
|
+
|
89
|
+
it "passes along the right events" do
|
90
|
+
subject.reporter.should_receive(:process_mocha_event).with(suite)
|
91
|
+
subject.reporter.should_receive(:process_mocha_event).with(suite_end)
|
92
|
+
subject.reporter.should_receive(:process_mocha_event).with(test)
|
93
|
+
subject.reporter.should_receive(:process_mocha_event).with(failure)
|
94
|
+
subject.reporter.should_receive(:process_mocha_event).with(pass)
|
95
|
+
subject.reporter.should_receive(:process_mocha_event).with(pending)
|
96
|
+
subject.reporter.should_receive(:process_mocha_event).any_number_of_times
|
97
|
+
subject.run
|
29
98
|
end
|
30
99
|
end
|
31
100
|
end
|
@@ -74,7 +74,7 @@
|
|
74
74
|
* Chai version
|
75
75
|
*/
|
76
76
|
|
77
|
-
exports.version = '1.
|
77
|
+
exports.version = '1.3.0';
|
78
78
|
|
79
79
|
/*!
|
80
80
|
* Primary `Assertion` prototype
|
@@ -393,10 +393,12 @@
|
|
393
393
|
* @name a
|
394
394
|
* @alias an
|
395
395
|
* @param {String} type
|
396
|
+
* @param {String} message _optional_
|
396
397
|
* @api public
|
397
398
|
*/
|
398
399
|
|
399
|
-
function an(type) {
|
400
|
+
function an(type, msg) {
|
401
|
+
if (msg) flag(this, 'message', msg);
|
400
402
|
var obj = flag(this, 'object')
|
401
403
|
, klassStart = type.charAt(0).toUpperCase()
|
402
404
|
, klass = klassStart + type.slice(1)
|
@@ -427,6 +429,7 @@
|
|
427
429
|
* @name include
|
428
430
|
* @alias contain
|
429
431
|
* @param {Object|String|Number} obj
|
432
|
+
* @param {String} message _optional_
|
430
433
|
* @api public
|
431
434
|
*/
|
432
435
|
|
@@ -434,7 +437,8 @@
|
|
434
437
|
flag(this, 'contains', true);
|
435
438
|
}
|
436
439
|
|
437
|
-
function include (val) {
|
440
|
+
function include (val, msg) {
|
441
|
+
if (msg) flag(this, 'message', msg);
|
438
442
|
var obj = flag(this, 'object')
|
439
443
|
this.assert(
|
440
444
|
~obj.indexOf(val)
|
@@ -652,10 +656,12 @@
|
|
652
656
|
* @alias eq
|
653
657
|
* @alias deep.equal
|
654
658
|
* @param {Mixed} value
|
659
|
+
* @param {String} message _optional_
|
655
660
|
* @api public
|
656
661
|
*/
|
657
662
|
|
658
|
-
function assertEqual (val) {
|
663
|
+
function assertEqual (val, msg) {
|
664
|
+
if (msg) flag(this, 'message', msg);
|
659
665
|
var obj = flag(this, 'object');
|
660
666
|
if (flag(this, 'deep')) {
|
661
667
|
return this.eql(val);
|
@@ -683,10 +689,12 @@
|
|
683
689
|
*
|
684
690
|
* @name eql
|
685
691
|
* @param {Mixed} value
|
692
|
+
* @param {String} message _optional_
|
686
693
|
* @api public
|
687
694
|
*/
|
688
695
|
|
689
|
-
Assertion.addMethod('eql', function (obj) {
|
696
|
+
Assertion.addMethod('eql', function (obj, msg) {
|
697
|
+
if (msg) flag(this, 'message', msg);
|
690
698
|
this.assert(
|
691
699
|
_.eql(obj, flag(this, 'object'))
|
692
700
|
, 'expected #{this} to deeply equal #{exp}'
|
@@ -714,13 +722,15 @@
|
|
714
722
|
* @alias gt
|
715
723
|
* @alias greaterThan
|
716
724
|
* @param {Number} value
|
725
|
+
* @param {String} message _optional_
|
717
726
|
* @api public
|
718
727
|
*/
|
719
728
|
|
720
|
-
function assertAbove (n) {
|
729
|
+
function assertAbove (n, msg) {
|
730
|
+
if (msg) flag(this, 'message', msg);
|
721
731
|
var obj = flag(this, 'object');
|
722
732
|
if (flag(this, 'doLength')) {
|
723
|
-
new Assertion(obj).to.have.property('length');
|
733
|
+
new Assertion(obj, msg).to.have.property('length');
|
724
734
|
var len = obj.length;
|
725
735
|
this.assert(
|
726
736
|
len > n
|
@@ -761,13 +771,15 @@
|
|
761
771
|
* @alias lt
|
762
772
|
* @alias lessThan
|
763
773
|
* @param {Number} value
|
774
|
+
* @param {String} message _optional_
|
764
775
|
* @api public
|
765
776
|
*/
|
766
777
|
|
767
|
-
function assertBelow (n) {
|
778
|
+
function assertBelow (n, msg) {
|
779
|
+
if (msg) flag(this, 'message', msg);
|
768
780
|
var obj = flag(this, 'object');
|
769
781
|
if (flag(this, 'doLength')) {
|
770
|
-
new Assertion(obj).to.have.property('length');
|
782
|
+
new Assertion(obj, msg).to.have.property('length');
|
771
783
|
var len = obj.length;
|
772
784
|
this.assert(
|
773
785
|
len < n
|
@@ -807,14 +819,16 @@
|
|
807
819
|
* @name within
|
808
820
|
* @param {Number} start lowerbound inclusive
|
809
821
|
* @param {Number} finish upperbound inclusive
|
822
|
+
* @param {String} message _optional_
|
810
823
|
* @api public
|
811
824
|
*/
|
812
825
|
|
813
|
-
Assertion.addMethod('within', function (start, finish) {
|
826
|
+
Assertion.addMethod('within', function (start, finish, msg) {
|
827
|
+
if (msg) flag(this, 'message', msg);
|
814
828
|
var obj = flag(this, 'object')
|
815
829
|
, range = start + '..' + finish;
|
816
830
|
if (flag(this, 'doLength')) {
|
817
|
-
new Assertion(obj).to.have.property('length');
|
831
|
+
new Assertion(obj, msg).to.have.property('length');
|
818
832
|
var len = obj.length;
|
819
833
|
this.assert(
|
820
834
|
len >= start && len <= finish
|
@@ -843,11 +857,13 @@
|
|
843
857
|
*
|
844
858
|
* @name instanceof
|
845
859
|
* @param {Constructor} constructor
|
860
|
+
* @param {String} message _optional_
|
846
861
|
* @alias instanceOf
|
847
862
|
* @api public
|
848
863
|
*/
|
849
864
|
|
850
|
-
function assertInstanceOf (constructor) {
|
865
|
+
function assertInstanceOf (constructor, msg) {
|
866
|
+
if (msg) flag(this, 'message', msg);
|
851
867
|
var name = _.getName(constructor);
|
852
868
|
this.assert(
|
853
869
|
flag(this, 'object') instanceof constructor
|
@@ -913,11 +929,14 @@
|
|
913
929
|
* @alias deep.property
|
914
930
|
* @param {String} name
|
915
931
|
* @param {Mixed} value (optional)
|
932
|
+
* @param {String} message _optional_
|
916
933
|
* @returns value of property for chaining
|
917
934
|
* @api public
|
918
935
|
*/
|
919
936
|
|
920
|
-
Assertion.addMethod('property', function (name, val) {
|
937
|
+
Assertion.addMethod('property', function (name, val, msg) {
|
938
|
+
if (msg) flag(this, 'message', msg);
|
939
|
+
|
921
940
|
var descriptor = flag(this, 'deep') ? 'deep property ' : 'property '
|
922
941
|
, negate = flag(this, 'negate')
|
923
942
|
, obj = flag(this, 'object')
|
@@ -927,7 +946,8 @@
|
|
927
946
|
|
928
947
|
if (negate && undefined !== val) {
|
929
948
|
if (undefined === value) {
|
930
|
-
|
949
|
+
msg = (msg != null) ? msg + ': ' : '';
|
950
|
+
throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
|
931
951
|
}
|
932
952
|
} else {
|
933
953
|
this.assert(
|
@@ -960,10 +980,12 @@
|
|
960
980
|
* @name ownProperty
|
961
981
|
* @alias haveOwnProperty
|
962
982
|
* @param {String} name
|
983
|
+
* @param {String} message _optional_
|
963
984
|
* @api public
|
964
985
|
*/
|
965
986
|
|
966
|
-
function assertOwnProperty (name) {
|
987
|
+
function assertOwnProperty (name, msg) {
|
988
|
+
if (msg) flag(this, 'message', msg);
|
967
989
|
var obj = flag(this, 'object');
|
968
990
|
this.assert(
|
969
991
|
obj.hasOwnProperty(name)
|
@@ -997,6 +1019,7 @@
|
|
997
1019
|
* @name length
|
998
1020
|
* @alias lengthOf
|
999
1021
|
* @param {Number} length
|
1022
|
+
* @param {String} message _optional_
|
1000
1023
|
* @api public
|
1001
1024
|
*/
|
1002
1025
|
|
@@ -1004,9 +1027,10 @@
|
|
1004
1027
|
flag(this, 'doLength', true);
|
1005
1028
|
}
|
1006
1029
|
|
1007
|
-
function assertLength (n) {
|
1030
|
+
function assertLength (n, msg) {
|
1031
|
+
if (msg) flag(this, 'message', msg);
|
1008
1032
|
var obj = flag(this, 'object');
|
1009
|
-
new Assertion(obj).to.have.property('length');
|
1033
|
+
new Assertion(obj, msg).to.have.property('length');
|
1010
1034
|
var len = obj.length;
|
1011
1035
|
|
1012
1036
|
this.assert(
|
@@ -1030,10 +1054,12 @@
|
|
1030
1054
|
*
|
1031
1055
|
* @name match
|
1032
1056
|
* @param {RegExp} RegularExpression
|
1057
|
+
* @param {String} message _optional_
|
1033
1058
|
* @api public
|
1034
1059
|
*/
|
1035
1060
|
|
1036
|
-
Assertion.addMethod('match', function (re) {
|
1061
|
+
Assertion.addMethod('match', function (re, msg) {
|
1062
|
+
if (msg) flag(this, 'message', msg);
|
1037
1063
|
var obj = flag(this, 'object');
|
1038
1064
|
this.assert(
|
1039
1065
|
re.exec(obj)
|
@@ -1051,12 +1077,14 @@
|
|
1051
1077
|
*
|
1052
1078
|
* @name string
|
1053
1079
|
* @param {String} string
|
1080
|
+
* @param {String} message _optional_
|
1054
1081
|
* @api public
|
1055
1082
|
*/
|
1056
1083
|
|
1057
|
-
Assertion.addMethod('string', function (str) {
|
1084
|
+
Assertion.addMethod('string', function (str, msg) {
|
1085
|
+
if (msg) flag(this, 'message', msg);
|
1058
1086
|
var obj = flag(this, 'object');
|
1059
|
-
new Assertion(obj).is.a('string');
|
1087
|
+
new Assertion(obj, msg).is.a('string');
|
1060
1088
|
|
1061
1089
|
this.assert(
|
1062
1090
|
~obj.indexOf(str)
|
@@ -1163,28 +1191,32 @@
|
|
1163
1191
|
* @alias throws
|
1164
1192
|
* @alias Throw
|
1165
1193
|
* @param {ErrorConstructor} constructor
|
1194
|
+
* @param {String|RegExp} expected error message
|
1195
|
+
* @param {String} message _optional_
|
1166
1196
|
* @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
|
1167
1197
|
* @api public
|
1168
1198
|
*/
|
1169
1199
|
|
1170
|
-
function assertThrows (constructor, msg) {
|
1200
|
+
function assertThrows (constructor, errMsg, msg) {
|
1201
|
+
if (msg) flag(this, 'message', msg);
|
1171
1202
|
var obj = flag(this, 'object');
|
1172
|
-
new Assertion(obj).is.a('function');
|
1203
|
+
new Assertion(obj, msg).is.a('function');
|
1173
1204
|
|
1174
1205
|
var thrown = false
|
1175
1206
|
, desiredError = null
|
1176
|
-
, name = null
|
1207
|
+
, name = null
|
1208
|
+
, thrownError = null;
|
1177
1209
|
|
1178
1210
|
if (arguments.length === 0) {
|
1179
|
-
|
1211
|
+
errMsg = null;
|
1180
1212
|
constructor = null;
|
1181
1213
|
} else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
|
1182
|
-
|
1214
|
+
errMsg = constructor;
|
1183
1215
|
constructor = null;
|
1184
1216
|
} else if (constructor && constructor instanceof Error) {
|
1185
1217
|
desiredError = constructor;
|
1186
1218
|
constructor = null;
|
1187
|
-
|
1219
|
+
errMsg = null;
|
1188
1220
|
} else if (typeof constructor === 'function') {
|
1189
1221
|
name = (new constructor()).name;
|
1190
1222
|
} else {
|
@@ -1207,38 +1239,43 @@
|
|
1207
1239
|
if (constructor) {
|
1208
1240
|
this.assert(
|
1209
1241
|
err instanceof constructor
|
1210
|
-
, 'expected #{this} to throw ' + name + ' but
|
1211
|
-
, 'expected #{this} to not throw ' + name );
|
1212
|
-
if (!
|
1242
|
+
, 'expected #{this} to throw ' + name + ' but ' + _.inspect(err) + ' was thrown'
|
1243
|
+
, 'expected #{this} to not throw ' + name + ' but ' + _.inspect(err) + ' was thrown');
|
1244
|
+
if (!errMsg) return this;
|
1213
1245
|
}
|
1214
1246
|
// next, check message
|
1215
|
-
if (err.message &&
|
1247
|
+
if (err.message && errMsg && errMsg instanceof RegExp) {
|
1216
1248
|
this.assert(
|
1217
|
-
|
1218
|
-
, 'expected #{this} to throw error matching ' +
|
1219
|
-
, 'expected #{this} to throw error not matching ' +
|
1249
|
+
errMsg.exec(err.message)
|
1250
|
+
, 'expected #{this} to throw error matching ' + errMsg + ' but got ' + _.inspect(err.message)
|
1251
|
+
, 'expected #{this} to throw error not matching ' + errMsg
|
1220
1252
|
);
|
1221
1253
|
return this;
|
1222
|
-
} else if (err.message &&
|
1254
|
+
} else if (err.message && errMsg && 'string' === typeof errMsg) {
|
1223
1255
|
this.assert(
|
1224
|
-
~err.message.indexOf(
|
1256
|
+
~err.message.indexOf(errMsg)
|
1225
1257
|
, 'expected #{this} to throw error including #{exp} but got #{act}'
|
1226
1258
|
, 'expected #{this} to throw error not including #{act}'
|
1227
|
-
,
|
1259
|
+
, errMsg
|
1228
1260
|
, err.message
|
1229
1261
|
);
|
1230
1262
|
return this;
|
1231
1263
|
} else {
|
1232
1264
|
thrown = true;
|
1265
|
+
thrownError = err;
|
1233
1266
|
}
|
1234
1267
|
}
|
1235
1268
|
|
1236
1269
|
var expectedThrown = name ? name : desiredError ? _.inspect(desiredError) : 'an error';
|
1270
|
+
var actuallyGot = ''
|
1271
|
+
if (thrown) {
|
1272
|
+
actuallyGot = ' but ' + _.inspect(thrownError) + ' was thrown'
|
1273
|
+
}
|
1237
1274
|
|
1238
1275
|
this.assert(
|
1239
1276
|
thrown === true
|
1240
|
-
, 'expected #{this} to throw ' + expectedThrown
|
1241
|
-
, 'expected #{this} to not throw ' + expectedThrown
|
1277
|
+
, 'expected #{this} to throw ' + expectedThrown + actuallyGot
|
1278
|
+
, 'expected #{this} to not throw ' + expectedThrown + actuallyGot
|
1242
1279
|
);
|
1243
1280
|
};
|
1244
1281
|
|
@@ -1263,10 +1300,12 @@
|
|
1263
1300
|
*
|
1264
1301
|
* @name respondTo
|
1265
1302
|
* @param {String} method
|
1303
|
+
* @param {String} message _optional_
|
1266
1304
|
* @api public
|
1267
1305
|
*/
|
1268
1306
|
|
1269
|
-
Assertion.addMethod('respondTo', function (method) {
|
1307
|
+
Assertion.addMethod('respondTo', function (method, msg) {
|
1308
|
+
if (msg) flag(this, 'message', msg);
|
1270
1309
|
var obj = flag(this, 'object')
|
1271
1310
|
, itself = flag(this, 'itself')
|
1272
1311
|
, context = ('function' === typeof obj && !itself)
|
@@ -1309,10 +1348,12 @@
|
|
1309
1348
|
*
|
1310
1349
|
* @name satisfy
|
1311
1350
|
* @param {Function} matcher
|
1351
|
+
* @param {String} message _optional_
|
1312
1352
|
* @api public
|
1313
1353
|
*/
|
1314
1354
|
|
1315
|
-
Assertion.addMethod('satisfy', function (matcher) {
|
1355
|
+
Assertion.addMethod('satisfy', function (matcher, msg) {
|
1356
|
+
if (msg) flag(this, 'message', msg);
|
1316
1357
|
var obj = flag(this, 'object');
|
1317
1358
|
this.assert(
|
1318
1359
|
matcher(obj)
|
@@ -1333,10 +1374,12 @@
|
|
1333
1374
|
* @name closeTo
|
1334
1375
|
* @param {Number} expected
|
1335
1376
|
* @param {Number} delta
|
1377
|
+
* @param {String} message _optional_
|
1336
1378
|
* @api public
|
1337
1379
|
*/
|
1338
1380
|
|
1339
|
-
Assertion.addMethod('closeTo', function (expected, delta) {
|
1381
|
+
Assertion.addMethod('closeTo', function (expected, delta, msg) {
|
1382
|
+
if (msg) flag(this, 'message', msg);
|
1340
1383
|
var obj = flag(this, 'object');
|
1341
1384
|
this.assert(
|
1342
1385
|
Math.abs(obj - expected) <= delta
|
@@ -2364,7 +2407,21 @@
|
|
2364
2407
|
function loadShould () {
|
2365
2408
|
// modify Object.prototype to have `should`
|
2366
2409
|
Object.defineProperty(Object.prototype, 'should',
|
2367
|
-
{
|
2410
|
+
{
|
2411
|
+
set: function (value) {
|
2412
|
+
// See https://github.com/chaijs/chai/issues/86: this makes
|
2413
|
+
// `whatever.should = someValue` actually set `someValue`, which is
|
2414
|
+
// especially useful for `global.should = require('chai').should()`.
|
2415
|
+
//
|
2416
|
+
// Note that we have to use [[DefineProperty]] instead of [[Put]]
|
2417
|
+
// since otherwise we would trigger this very setter!
|
2418
|
+
Object.defineProperty(this, 'should', {
|
2419
|
+
value: value,
|
2420
|
+
enumerable: true,
|
2421
|
+
configurable: true,
|
2422
|
+
writable: true
|
2423
|
+
});
|
2424
|
+
}
|
2368
2425
|
, get: function(){
|
2369
2426
|
if (this instanceof String || this instanceof Number) {
|
2370
2427
|
return new Assertion(this.constructor(this));
|
@@ -2378,31 +2435,31 @@
|
|
2378
2435
|
|
2379
2436
|
var should = {};
|
2380
2437
|
|
2381
|
-
should.equal = function (val1, val2) {
|
2382
|
-
new Assertion(val1).to.equal(val2);
|
2438
|
+
should.equal = function (val1, val2, msg) {
|
2439
|
+
new Assertion(val1, msg).to.equal(val2);
|
2383
2440
|
};
|
2384
2441
|
|
2385
|
-
should.Throw = function (fn, errt, errs) {
|
2386
|
-
new Assertion(fn).to.Throw(errt, errs);
|
2442
|
+
should.Throw = function (fn, errt, errs, msg) {
|
2443
|
+
new Assertion(fn, msg).to.Throw(errt, errs);
|
2387
2444
|
};
|
2388
2445
|
|
2389
|
-
should.exist = function (val) {
|
2390
|
-
new Assertion(val).to.exist;
|
2446
|
+
should.exist = function (val, msg) {
|
2447
|
+
new Assertion(val, msg).to.exist;
|
2391
2448
|
}
|
2392
2449
|
|
2393
2450
|
// negation
|
2394
2451
|
should.not = {}
|
2395
2452
|
|
2396
|
-
should.not.equal = function (val1, val2) {
|
2397
|
-
new Assertion(val1).to.not.equal(val2);
|
2453
|
+
should.not.equal = function (val1, val2, msg) {
|
2454
|
+
new Assertion(val1, msg).to.not.equal(val2);
|
2398
2455
|
};
|
2399
2456
|
|
2400
|
-
should.not.Throw = function (fn, errt, errs) {
|
2401
|
-
new Assertion(fn).to.not.Throw(errt, errs);
|
2457
|
+
should.not.Throw = function (fn, errt, errs, msg) {
|
2458
|
+
new Assertion(fn, msg).to.not.Throw(errt, errs);
|
2402
2459
|
};
|
2403
2460
|
|
2404
|
-
should.not.exist = function (val) {
|
2405
|
-
new Assertion(val).to.not.exist;
|
2461
|
+
should.not.exist = function (val, msg) {
|
2462
|
+
new Assertion(val, msg).to.not.exist;
|
2406
2463
|
}
|
2407
2464
|
|
2408
2465
|
should['throw'] = should['Throw'];
|
@@ -2577,22 +2634,23 @@
|
|
2577
2634
|
}); // module: chai/utils/addProperty.js
|
2578
2635
|
|
2579
2636
|
require.register("chai/utils/eql.js", function(module, exports, require){
|
2580
|
-
// This is directly from Node.js assert
|
2637
|
+
// This is (almost) directly from Node.js assert
|
2581
2638
|
// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js
|
2582
2639
|
|
2583
|
-
|
2584
2640
|
module.exports = _deepEqual;
|
2585
2641
|
|
2586
|
-
//
|
2587
|
-
|
2588
|
-
|
2589
|
-
|
2590
|
-
|
2591
|
-
|
2642
|
+
// for the browser
|
2643
|
+
var Buffer;
|
2644
|
+
try {
|
2645
|
+
Buffer = require('buffer').Buffer;
|
2646
|
+
} catch (ex) {
|
2647
|
+
Buffer = {
|
2648
|
+
isBuffer: function () { return false; }
|
2592
2649
|
};
|
2593
2650
|
}
|
2594
2651
|
|
2595
2652
|
function _deepEqual(actual, expected) {
|
2653
|
+
|
2596
2654
|
// 7.1. All identical values are equivalent, as determined by ===.
|
2597
2655
|
if (actual === expected) {
|
2598
2656
|
return true;
|
@@ -2677,6 +2735,7 @@
|
|
2677
2735
|
}
|
2678
2736
|
return true;
|
2679
2737
|
}
|
2738
|
+
|
2680
2739
|
}); // module: chai/utils/eql.js
|
2681
2740
|
|
2682
2741
|
require.register("chai/utils/flag.js", function(module, exports, require){
|