1
- var sys = require ( 'sys' ) ;
2
- var util = require ( 'util' ) ;
1
+ // http://wiki.commonjs.org/wiki/Unit_Testing/1.0
2
+ //
3
+ // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
4
+ //
5
+ // Originally from narwhal.js (http://narwhaljs.org)
6
+ // Copyright (c) 2009 Thomas Robinson <280north.com>
7
+ //
8
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ // of this software and associated documentation files (the “Software”), to
10
+ // deal in the Software without restriction, including without limitation the
11
+ // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
+ // sell copies of the Software, and to permit persons to whom the Software is
13
+ // furnished to do so, subject to the following conditions:
14
+ //
15
+ // The above copyright notice and this permission notice shall be included in
16
+ // all copies or substantial portions of the Software.
17
+ //
18
+ // THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+ // UTILITY
26
+
27
+ var pSlice = Array . prototype . slice ;
28
+
29
+ // 1. The assert module provides functions that throw
30
+ // AssertionError's when particular conditions are not met. The
31
+ // assert module must conform to the following interface.
32
+
3
33
var assert = exports ;
4
34
5
- assert . AssertionError = function ( options ) {
35
+ // 2. The AssertionError is defined in assert.
36
+ // new assert.AssertionError({message: message, actual: actual, expected: expected})
37
+
38
+ assert . AssertionError = function AssertionError ( options ) {
6
39
this . name = "AssertionError" ;
7
40
this . message = options . message ;
8
41
this . actual = options . actual ;
9
42
this . expected = options . expected ;
10
43
this . operator = options . operator ;
11
-
12
- Error . captureStackTrace ( this , fail ) ;
44
+ //v8 specific
45
+ if ( Error . captureStackTrace ) {
46
+ Error . captureStackTrace ( this , fail ) ;
47
+ //node specific, removes the node machinery stack frames
48
+ if ( typeof ( __filename ) !== undefined ) {
49
+ var stack = this . stack . split ( '\n' ) ;
50
+ for ( var i = stack . length - 1 ; i >= 0 ; i -- ) {
51
+ if ( stack [ i ] . indexOf ( __filename ) != - 1 ) {
52
+ this . stack = stack . slice ( 0 , i + 2 ) . join ( '\n' ) ;
53
+ break ;
54
+ }
55
+ }
56
+ }
57
+ }
13
58
} ;
14
- sys . inherits ( assert . AssertionError , Error ) ;
59
+
60
+ assert . AssertionError . prototype . toString = function ( ) {
61
+ if ( this . message )
62
+ return [ this . name + ":" , this . message ] . join ( ' ' ) ;
63
+ else
64
+ return [ this . name + ":" , JSON . stringify ( this . expected ) , this . operator , JSON . stringify ( this . actual ) ] . join ( " " ) ;
65
+ }
15
66
16
67
// assert.AssertionError instanceof Error
17
68
18
- // assert.AssertionError.prototype = Object.create( Error.prototype) ;
69
+ assert . AssertionError . __proto__ = Error . prototype ;
19
70
20
71
// At present only the three keys mentioned above are used and
21
72
// understood by the spec. Implementations or sub modules can pass
@@ -37,14 +88,17 @@ function fail(actual, expected, message, operator) {
37
88
} ) ;
38
89
}
39
90
91
+ // EXTENSION! allows for well behaved errors defined elsewhere.
92
+ assert . fail = fail ;
93
+
40
94
// 4. Pure assertion tests whether a value is truthy, as determined
41
95
// by !!guard.
42
96
// assert.ok(guard, message_opt);
43
97
// This statement is equivalent to assert.equal(true, guard,
44
98
// message_opt);. To test strictly for the value true, use
45
99
// assert.strictEqual(true, guard, message_opt);.
46
100
47
- assert . ok = function ( value , message ) {
101
+ assert . ok = function ok ( value , message ) {
48
102
if ( ! ! ! value )
49
103
fail ( value , true , message , "==" ) ;
50
104
} ;
@@ -53,7 +107,7 @@ assert.ok = function (value, message) {
53
107
// ==.
54
108
// assert.equal(actual, expected, message_opt);
55
109
56
- assert . equal = function ( actual , expected , message ) {
110
+ assert . equal = function equal ( actual , expected , message ) {
57
111
if ( actual != expected )
58
112
fail ( actual , expected , message , "==" ) ;
59
113
} ;
@@ -62,21 +116,20 @@ assert.equal = function (actual, expected, message) {
62
116
// 6. The non-equality assertion tests for whether two objects are not equal
63
117
// with != assert.notEqual(actual, expected, message_opt);
64
118
65
- assert . notEqual = function ( actual , expected , message ) {
119
+ assert . notEqual = function notEqual ( actual , expected , message ) {
66
120
if ( actual == expected )
67
121
fail ( actual , expected , message , "!=" ) ;
68
122
} ;
69
123
70
124
// 7. The equivalence assertion tests a deep equality relation.
71
125
// assert.deepEqual(actual, expected, message_opt);
72
126
73
- exports . deepEqual = function ( actual , expected , message ) {
74
- if ( ! deepEqual ( actual , expected ) )
127
+ exports . deepEqual = function deepEqual ( actual , expected , message ) {
128
+ if ( ! _deepEqual ( actual , expected ) )
75
129
fail ( actual , expected , message , "deepEqual" ) ;
76
130
} ;
77
131
78
- function deepEqual ( actual , expected ) {
79
-
132
+ function _deepEqual ( actual , expected ) {
80
133
// 7.1. All identical values are equivalent, as determined by ===.
81
134
if ( actual === expected ) {
82
135
return true ;
@@ -85,7 +138,7 @@ function deepEqual(actual, expected) {
85
138
// equivalent if it is also a Date object that refers to the same time.
86
139
} else if ( actual instanceof Date
87
140
&& expected instanceof Date ) {
88
- return actual . toValue ( ) === expected . toValue ( ) ;
141
+ return actual . getTime ( ) === expected . getTime ( ) ;
89
142
90
143
// 7.3. Other pairs that do not both pass typeof value == "object",
91
144
// equivalence is determined by ==.
@@ -100,68 +153,113 @@ function deepEqual(actual, expected) {
100
153
// corresponding key, and an identical "prototype" property. Note: this
101
154
// accounts for both named and indexed properties on Arrays.
102
155
} else {
103
- return actual . prototype === expected . prototype && objEquiv ( actual , expected ) ;
156
+ return objEquiv ( actual , expected ) ;
104
157
}
105
158
}
106
159
107
- function objEquiv ( a , b , stack ) {
108
- return (
109
- ! util . no ( a ) && ! util . no ( b ) &&
110
- arrayEquiv (
111
- util . sort ( util . object . keys ( a ) ) ,
112
- util . sort ( util . object . keys ( b ) )
113
- ) &&
114
- util . object . keys ( a ) . every ( function ( key ) {
115
- return deepEqual ( a [ key ] , b [ key ] , stack ) ;
116
- } )
117
- ) ;
160
+ function isUndefinedOrNull ( value ) {
161
+ return value === null || value === undefined ;
118
162
}
119
163
120
- function arrayEquiv ( a , b , stack ) {
121
- return util . isArrayLike ( b ) &&
122
- a . length == b . length &&
123
- util . zip ( a , b ) . every ( util . apply ( function ( a , b ) {
124
- return deepEqual ( a , b , stack ) ;
125
- } ) ) ;
164
+ function isArguments ( object ) {
165
+ return Object . prototype . toString . call ( object ) == '[object Arguments]' ;
166
+ }
167
+
168
+ function objEquiv ( a , b ) {
169
+ if ( isUndefinedOrNull ( a ) || isUndefinedOrNull ( b ) )
170
+ return false ;
171
+ // an identical "prototype" property.
172
+ if ( a . prototype !== b . prototype ) return false ;
173
+ //~~~I've managed to break Object.keys through screwy arguments passing.
174
+ // Converting to array solves the problem.
175
+ if ( isArguments ( a ) ) {
176
+ if ( ! isArguments ( b ) ) {
177
+ return false ;
178
+ }
179
+ a = pSlice . call ( a ) ;
180
+ b = pSlice . call ( b ) ;
181
+ return _deepEqual ( a , b ) ;
182
+ }
183
+ try {
184
+ var ka = Object . keys ( a ) ,
185
+ kb = Object . keys ( b ) ,
186
+ key , i ;
187
+ } catch ( e ) { //happens when one is a string literal and the other isn't
188
+ return false ;
189
+ }
190
+ // having the same number of owned properties (keys incorporates hasOwnProperty)
191
+ if ( ka . length != kb . length )
192
+ return false ;
193
+ //the same set of keys (although not necessarily the same order),
194
+ ka . sort ( ) ;
195
+ kb . sort ( ) ;
196
+ //~~~cheap key test
197
+ for ( i = ka . length - 1 ; i >= 0 ; i -- ) {
198
+ if ( ka [ i ] != kb [ i ] )
199
+ return false ;
200
+ }
201
+ //equivalent values for every corresponding key, and
202
+ //~~~possibly expensive deep test
203
+ for ( i = ka . length - 1 ; i >= 0 ; i -- ) {
204
+ key = ka [ i ] ;
205
+ if ( ! _deepEqual ( a [ key ] , b [ key ] ) )
206
+ return false ;
207
+ }
208
+ return true ;
126
209
}
127
210
128
211
// 8. The non-equivalence assertion tests for any deep inequality.
129
212
// assert.notDeepEqual(actual, expected, message_opt);
130
213
131
- exports . notDeepEqual = function ( actual , expected , message ) {
132
- if ( deepEqual ( actual , expected ) )
214
+ exports . notDeepEqual = function notDeepEqual ( actual , expected , message ) {
215
+ if ( _deepEqual ( actual , expected ) )
133
216
fail ( actual , expected , message , "notDeepEqual" ) ;
134
217
} ;
135
218
136
219
// 9. The strict equality assertion tests strict equality, as determined by ===.
137
220
// assert.strictEqual(actual, expected, message_opt);
138
221
139
- assert . strictEqual = function ( actual , expected , message ) {
222
+ assert . strictEqual = function strictEqual ( actual , expected , message ) {
140
223
if ( actual !== expected )
141
224
fail ( actual , expected , message , "===" ) ;
142
225
} ;
143
226
144
227
// 10. The strict non-equality assertion tests for strict inequality, as determined by !==.
145
228
// assert.notStrictEqual(actual, expected, message_opt);
146
229
147
- assert . notStrictEqual = function ( actual , expected , message ) {
230
+ assert . notStrictEqual = function notStrictEqual ( actual , expected , message ) {
148
231
if ( actual === expected )
149
232
fail ( actual , expected , message , "!==" ) ;
150
233
} ;
151
234
152
235
// 11. Expected to throw an error:
153
236
// assert.throws(block, Error_opt, message_opt);
154
237
155
- assert [ "throws" ] = function ( block , Error , message ) {
156
- var threw = false ,
157
- exception = null ;
158
-
159
- if ( typeof Error == "string" ) {
160
- message = Error ;
161
- Error = undefined ;
162
- } else {
163
- Error = message ;
164
- message = "" ;
238
+ assert . throws = function ( block , /*optional*/ error , /*optional*/ message ) {
239
+ var args = [ true ]
240
+ _throws . apply ( this , args . concat ( pSlice . call ( arguments ) ) ) ;
241
+ }
242
+
243
+ // EXTENSION! This is annoying to write outside this module.
244
+ assert . doesNotThrow = function ( block , /*optional*/ error , /*optional*/ message ) {
245
+ var args = [ false ]
246
+ _throws . apply ( this , args . concat ( pSlice . call ( arguments ) ) ) ;
247
+ }
248
+
249
+ var _throws = function ( shouldThrow , block , err , message ) {
250
+ var exception = null
251
+ threw = false
252
+ typematters = true ;
253
+ message = message || "" ;
254
+
255
+ //handle optional arguments
256
+ if ( arguments . length == 3 ) {
257
+ if ( typeof ( err ) == "string" ) {
258
+ message = err ;
259
+ typematters = false ;
260
+ }
261
+ } else if ( arguments . length == 2 ) {
262
+ typematters = false ;
165
263
}
166
264
167
265
try {
@@ -170,7 +268,19 @@ assert["throws"] = function (block, Error, message) {
170
268
threw = true ;
171
269
exception = e ;
172
270
}
173
-
174
- if ( ! threw )
175
- fail ( "Expected exception" + ( message ? ": " + message : "" ) ) ;
271
+
272
+ if ( shouldThrow && ! threw ) {
273
+ fail ( "Missing expected exception" +
274
+ ( err && err . name ? " (" + err . name + ")." : '.' ) +
275
+ ( message ? " " + message : "" ) ) ;
276
+ }
277
+ if ( ! shouldThrow && threw && typematters && exception instanceof err ) {
278
+ fail ( "Got unwanted exception" +
279
+ ( err && err . name ? " (" + err . name + ")." : '.' ) +
280
+ ( message ? " " + message : "" ) ) ;
281
+ }
282
+ if ( ( shouldThrow && threw && typematters && ! ( exception instanceof err ) ) ||
283
+ ( ! shouldThrow && threw ) ) {
284
+ throw exception ;
285
+ }
176
286
} ;
0 commit comments