jspec 2.11.13 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +714 -0
- data/Manifest +51 -36
- data/README.md +968 -0
- data/Rakefile +4 -53
- data/bin/jspec +93 -224
- data/jspec.gemspec +5 -5
- data/lib/images/sprites.png +0 -0
- data/lib/jspec.css +2 -2
- data/lib/jspec.growl.js +115 -0
- data/lib/jspec.jquery.js +1 -1
- data/lib/jspec.js +98 -101
- data/lib/jspec.shell.js +5 -2
- data/lib/jspec.timers.js +1 -1
- data/lib/jspec.xhr.js +12 -2
- data/spec/commands/example_command.rb +19 -0
- data/spec/dom.html +33 -0
- data/spec/node.js +32 -0
- data/spec/rhino.js +24 -0
- data/spec/ruby/bin/init_spec.rb +101 -0
- data/spec/ruby/bin/install_spec.rb +141 -0
- data/spec/ruby/bin/run_spec.rb +0 -0
- data/spec/ruby/bin/shell_spec.rb +13 -0
- data/spec/ruby/bin/spec_helper.rb +25 -0
- data/spec/ruby/bin/update_spec.rb +72 -0
- data/spec/server.html +29 -0
- data/spec/server.rb +1 -1
- data/spec/{env.js → support/env.js} +554 -664
- data/spec/support/jquery.js +4376 -0
- data/spec/{helpers.js → unit/helpers.js} +2 -0
- data/spec/{spec.fixtures.js → unit/spec.fixtures.js} +0 -1
- data/spec/{spec.grammar-less.js → unit/spec.grammar-less.js} +0 -0
- data/spec/{spec.grammar.js → unit/spec.grammar.js} +1 -11
- data/spec/{spec.jquery.js → unit/spec.jquery.js} +0 -17
- data/spec/{spec.jquery.xhr.js → unit/spec.jquery.xhr.js} +13 -2
- data/spec/unit/spec.js +187 -0
- data/spec/{spec.matchers.js → unit/spec.matchers.js} +141 -66
- data/spec/{spec.modules.js → unit/spec.modules.js} +0 -0
- data/spec/{spec.shared-behaviors.js → unit/spec.shared-behaviors.js} +0 -0
- data/spec/{spec.utils.js → unit/spec.utils.js} +123 -22
- data/spec/{spec.xhr.js → unit/spec.xhr.js} +11 -10
- data/{server → src}/browsers.rb +23 -0
- data/{server → src}/helpers.rb +2 -17
- data/src/installables.rb +229 -0
- data/src/project.rb +340 -0
- data/{server → src}/routes.rb +1 -1
- data/{server → src}/server.rb +0 -0
- data/support/js.jar +0 -0
- data/templates/default/History.md +5 -0
- data/templates/default/{README.rdoc → Readme.md} +3 -3
- data/templates/default/lib/{yourlib.core.js → yourlib.js} +0 -0
- data/templates/default/spec/commands/example_command.rb +19 -0
- data/templates/default/spec/{spec.dom.html → dom.html} +5 -3
- data/templates/default/spec/rhino.js +10 -0
- data/templates/default/spec/server.html +18 -0
- data/templates/default/spec/unit/spec.helper.js +0 -0
- data/templates/default/spec/{spec.core.js → unit/spec.js} +0 -0
- data/templates/rails/commands/example_commands.rb +19 -0
- data/templates/rails/{spec.dom.html → dom.html} +4 -2
- data/templates/rails/rhino.js +10 -0
- data/templates/rails/server.html +18 -0
- data/templates/rails/unit/spec.helper.js +0 -0
- data/templates/rails/{spec.application.js → unit/spec.js} +0 -0
- metadata +56 -41
- data/History.rdoc +0 -590
- data/README.rdoc +0 -842
- data/spec/async +0 -1
- data/spec/jquery.js +0 -19
- data/spec/spec.dom.html +0 -34
- data/spec/spec.js +0 -166
- data/spec/spec.node.js +0 -46
- data/spec/spec.rhino.js +0 -23
- data/spec/spec.server.html +0 -29
- data/templates/default/History.rdoc +0 -4
- data/templates/default/spec/spec.rhino.js +0 -8
- data/templates/default/spec/spec.server.html +0 -16
- data/templates/rails/spec.rhino.js +0 -8
- data/templates/rails/spec.server.html +0 -16
data/jspec.gemspec
CHANGED
@@ -2,19 +2,19 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{jspec}
|
5
|
-
s.version = "
|
5
|
+
s.version = "3.0.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["TJ Holowaychuk"]
|
9
|
-
s.date = %q{
|
9
|
+
s.date = %q{2010-01-04}
|
10
10
|
s.default_executable = %q{jspec}
|
11
11
|
s.description = %q{JavaScript BDD Testing Framework}
|
12
12
|
s.email = %q{tj@vision-media.ca}
|
13
13
|
s.executables = ["jspec"]
|
14
|
-
s.extra_rdoc_files = ["README.
|
15
|
-
s.files = ["History.
|
14
|
+
s.extra_rdoc_files = ["README.md", "bin/jspec", "lib/images/bg.png", "lib/images/hr.png", "lib/images/loading.gif", "lib/images/sprites.bg.png", "lib/images/sprites.png", "lib/images/vr.png", "lib/jspec.css", "lib/jspec.growl.js", "lib/jspec.jquery.js", "lib/jspec.js", "lib/jspec.shell.js", "lib/jspec.timers.js", "lib/jspec.xhr.js"]
|
15
|
+
s.files = ["History.md", "Manifest", "README.md", "Rakefile", "bin/jspec", "lib/images/bg.png", "lib/images/hr.png", "lib/images/loading.gif", "lib/images/sprites.bg.png", "lib/images/sprites.png", "lib/images/vr.png", "lib/jspec.css", "lib/jspec.growl.js", "lib/jspec.jquery.js", "lib/jspec.js", "lib/jspec.shell.js", "lib/jspec.timers.js", "lib/jspec.xhr.js", "spec/commands/example_command.rb", "spec/dom.html", "spec/fixtures/test.html", "spec/fixtures/test.json", "spec/fixtures/test.xml", "spec/node.js", "spec/rhino.js", "spec/ruby/bin/init_spec.rb", "spec/ruby/bin/install_spec.rb", "spec/ruby/bin/run_spec.rb", "spec/ruby/bin/shell_spec.rb", "spec/ruby/bin/spec_helper.rb", "spec/ruby/bin/update_spec.rb", "spec/server.html", "spec/server.rb", "spec/support/env.js", "spec/support/jquery.js", "spec/unit/helpers.js", "spec/unit/spec.fixtures.js", "spec/unit/spec.grammar-less.js", "spec/unit/spec.grammar.js", "spec/unit/spec.jquery.js", "spec/unit/spec.jquery.xhr.js", "spec/unit/spec.js", "spec/unit/spec.matchers.js", "spec/unit/spec.modules.js", "spec/unit/spec.shared-behaviors.js", "spec/unit/spec.utils.js", "spec/unit/spec.xhr.js", "src/browsers.rb", "src/helpers.rb", "src/installables.rb", "src/project.rb", "src/routes.rb", "src/server.rb", "support/js.jar", "templates/default/History.md", "templates/default/Readme.md", "templates/default/lib/yourlib.js", "templates/default/spec/commands/example_command.rb", "templates/default/spec/dom.html", "templates/default/spec/rhino.js", "templates/default/spec/server.html", "templates/default/spec/server.rb", "templates/default/spec/unit/spec.helper.js", "templates/default/spec/unit/spec.js", "templates/rails/commands/example_commands.rb", "templates/rails/dom.html", "templates/rails/rhino.js", "templates/rails/server.html", "templates/rails/server.rb", "templates/rails/unit/spec.helper.js", "templates/rails/unit/spec.js", "jspec.gemspec"]
|
16
16
|
s.homepage = %q{http://visionmedia.github.com/jspec}
|
17
|
-
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Jspec", "--main", "README.
|
17
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Jspec", "--main", "README.md"]
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
s.rubyforge_project = %q{jspec}
|
20
20
|
s.rubygems_version = %q{1.3.5}
|
data/lib/images/sprites.png
CHANGED
Binary file
|
data/lib/jspec.css
CHANGED
@@ -114,12 +114,12 @@ body.jspec {
|
|
114
114
|
background: url(images/sprites.png) 3px -7px no-repeat;
|
115
115
|
}
|
116
116
|
#jspec-report td.fail {
|
117
|
-
background: url(images/sprites.png) 3px -
|
117
|
+
background: url(images/sprites.png) 3px -158px no-repeat;
|
118
118
|
font-weight: bold;
|
119
119
|
color: #FC0D0D;
|
120
120
|
}
|
121
121
|
#jspec-report td.requires-implementation {
|
122
|
-
background: url(images/sprites.png) 3px -
|
122
|
+
background: url(images/sprites.png) 3px -333px no-repeat;
|
123
123
|
}
|
124
124
|
#jspec-report tr.description td {
|
125
125
|
margin-top: 25px;
|
data/lib/jspec.growl.js
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
|
2
|
+
// JSpec - Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
|
3
|
+
|
4
|
+
;(function(){
|
5
|
+
|
6
|
+
Growl = {
|
7
|
+
|
8
|
+
// --- Version
|
9
|
+
|
10
|
+
version: '1.0.0',
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Execute the given _cmd_, returning an array of lines from stdout.
|
14
|
+
*
|
15
|
+
* Examples:
|
16
|
+
*
|
17
|
+
* Growl.exec('growlnotify', '-m', msg)
|
18
|
+
*
|
19
|
+
* @param {string ...} cmd
|
20
|
+
* @return {array}
|
21
|
+
* @api public
|
22
|
+
*/
|
23
|
+
|
24
|
+
exec: function(cmd) {
|
25
|
+
var lines = [], line
|
26
|
+
with (JavaImporter(java.lang, java.io)) {
|
27
|
+
var proccess = Runtime.getRuntime().exec(Array.prototype.slice.call(arguments))
|
28
|
+
var stream = new DataInputStream(proccess.getInputStream())
|
29
|
+
while (line = stream.readLine())
|
30
|
+
lines.push(line + '')
|
31
|
+
stream.close()
|
32
|
+
}
|
33
|
+
return lines
|
34
|
+
},
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Return the extension of the given _path_ or null.
|
38
|
+
*
|
39
|
+
* @param {string} path
|
40
|
+
* @return {string}
|
41
|
+
* @api private
|
42
|
+
*/
|
43
|
+
|
44
|
+
extname: function(path) {
|
45
|
+
return path.lastIndexOf('.') != -1 ?
|
46
|
+
path.slice(path.lastIndexOf('.') + 1, path.length) :
|
47
|
+
null
|
48
|
+
},
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Version of the 'growlnotify' binary.
|
52
|
+
*
|
53
|
+
* @return {string}
|
54
|
+
* @api private
|
55
|
+
*/
|
56
|
+
|
57
|
+
binVersion: function() {
|
58
|
+
try { return this.exec('growlnotify', '-v')[0].split(' ')[1] } catch (e) {}
|
59
|
+
},
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Send growl notification _msg_ with _options_.
|
63
|
+
*
|
64
|
+
* Options:
|
65
|
+
*
|
66
|
+
* - title Notification title
|
67
|
+
* - sticky Make the notification stick (defaults to false)
|
68
|
+
* - name Application name (defaults to growlnotify)
|
69
|
+
* - image
|
70
|
+
* - path to an icon sets --iconpath
|
71
|
+
* - path to an image sets --image
|
72
|
+
* - capitalized word sets --appIcon
|
73
|
+
* - filename uses extname as --icon
|
74
|
+
* - otherwise treated as --icon
|
75
|
+
*
|
76
|
+
* Examples:
|
77
|
+
*
|
78
|
+
* Growl.notify('New email')
|
79
|
+
* Growl.notify('5 new emails', { title: 'Thunderbird' })
|
80
|
+
*
|
81
|
+
* @param {string} msg
|
82
|
+
* @param {options} hash
|
83
|
+
* @api public
|
84
|
+
*/
|
85
|
+
|
86
|
+
notify: function(msg, options) {
|
87
|
+
options = options || {}
|
88
|
+
var args = ['growlnotify', '-m', msg]
|
89
|
+
if (!this.binVersion()) throw new Error('growlnotify executable is required')
|
90
|
+
if (image = options.image) {
|
91
|
+
var flag, ext = this.extname(image)
|
92
|
+
flag = flag || ext == 'icns' && 'iconpath'
|
93
|
+
flag = flag || /^[A-Z]/.test(image) && 'appIcon'
|
94
|
+
flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'
|
95
|
+
flag = flag || ext && (image = ext) && 'icon'
|
96
|
+
flag = flag || 'icon'
|
97
|
+
args.push('--' + flag, image)
|
98
|
+
}
|
99
|
+
if (options.sticky) args.push('--sticky')
|
100
|
+
if (options.name) args.push('--name', options.name)
|
101
|
+
if (options.title) args.push(options.title)
|
102
|
+
this.exec.apply(this, args)
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
JSpec.include({
|
107
|
+
name: 'Growl',
|
108
|
+
reporting: function(options){
|
109
|
+
var stats = JSpec.stats
|
110
|
+
if (stats.failures) Growl.notify('failed ' + stats.failures + ' assertions', { title: 'JSpec'})
|
111
|
+
else Growl.notify('passed ' + stats.passes + ' assertions', { title: 'JSpec' })
|
112
|
+
}
|
113
|
+
})
|
114
|
+
|
115
|
+
})()
|
data/lib/jspec.jquery.js
CHANGED
data/lib/jspec.js
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
|
2
2
|
// JSpec - Core - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
|
3
3
|
|
4
|
-
(function(){
|
4
|
+
;(function(){
|
5
5
|
|
6
6
|
JSpec = {
|
7
|
-
|
8
|
-
|
7
|
+
version : '3.1.0',
|
8
|
+
assert : true,
|
9
9
|
cache : {},
|
10
10
|
suites : [],
|
11
11
|
modules : [],
|
12
12
|
allSuites : [],
|
13
13
|
matchers : {},
|
14
14
|
stubbed : [],
|
15
|
+
options : {},
|
15
16
|
request : 'XMLHttpRequest' in this ? XMLHttpRequest : null,
|
16
17
|
stats : { specs: 0, assertions: 0, failures: 0, passes: 0, specsFinished: 0, suitesFinished: 0 },
|
17
|
-
options : { profile: false },
|
18
18
|
|
19
19
|
/**
|
20
20
|
* Default context in which bodies are evaluated.
|
@@ -51,15 +51,12 @@
|
|
51
51
|
},
|
52
52
|
|
53
53
|
/**
|
54
|
-
* Load fixture at _path_.
|
55
|
-
* supplies the means to resolve, and cache fixture contents
|
56
|
-
* via the DOM or Rhino.
|
54
|
+
* Load fixture at _path_.
|
57
55
|
*
|
58
56
|
* Fixtures are resolved as:
|
59
57
|
*
|
60
58
|
* - <path>
|
61
|
-
* -
|
62
|
-
* - fixtures/<path>.html
|
59
|
+
* - <path>.html
|
63
60
|
*
|
64
61
|
* @param {string} path
|
65
62
|
* @return {string}
|
@@ -69,18 +66,14 @@
|
|
69
66
|
fixture : function(path) {
|
70
67
|
if (JSpec.cache[path]) return JSpec.cache[path]
|
71
68
|
return JSpec.cache[path] =
|
72
|
-
JSpec.tryLoading(path) ||
|
73
|
-
JSpec.tryLoading('
|
74
|
-
JSpec.tryLoading('fixtures/' + path + '.html') ||
|
75
|
-
JSpec.tryLoading('spec/' + path) ||
|
76
|
-
JSpec.tryLoading('spec/fixtures/' + path) ||
|
77
|
-
JSpec.tryLoading('spec/fixtures/' + path + '.html')
|
69
|
+
JSpec.tryLoading(JSpec.options.fixturePath + '/' + path) ||
|
70
|
+
JSpec.tryLoading(JSpec.options.fixturePath + '/' + path + '.html')
|
78
71
|
}
|
79
72
|
},
|
80
73
|
|
81
74
|
// --- Objects
|
82
75
|
|
83
|
-
|
76
|
+
reporters : {
|
84
77
|
|
85
78
|
/**
|
86
79
|
* Report to server.
|
@@ -123,7 +116,7 @@
|
|
123
116
|
},
|
124
117
|
|
125
118
|
/**
|
126
|
-
* Default
|
119
|
+
* Default reporter, outputting to the DOM.
|
127
120
|
*
|
128
121
|
* Options:
|
129
122
|
* - reportToId id of element to output reports to, defaults to 'jspec'
|
@@ -149,6 +142,7 @@
|
|
149
142
|
report.innerHTML = '<div id="jspec-report" class="' + classes + '"><div class="heading"> \
|
150
143
|
<span class="passes">Passes: <em>' + results.stats.passes + '</em></span> \
|
151
144
|
<span class="failures">Failures: <em>' + results.stats.failures + '</em></span> \
|
145
|
+
<span class="passes">Duration: <em>' + results.duration + '</em> ms</span> \
|
152
146
|
</div><table class="suites">' + map(results.allSuites, function(suite) {
|
153
147
|
var displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran
|
154
148
|
if (displaySuite && suite.hasSpecs())
|
@@ -170,7 +164,7 @@
|
|
170
164
|
},
|
171
165
|
|
172
166
|
/**
|
173
|
-
* Terminal
|
167
|
+
* Terminal reporter.
|
174
168
|
*
|
175
169
|
* @api public
|
176
170
|
*/
|
@@ -178,7 +172,8 @@
|
|
178
172
|
Terminal : function(results, options) {
|
179
173
|
failuresOnly = option('failuresOnly')
|
180
174
|
print(color("\n Passes: ", 'bold') + color(results.stats.passes, 'green') +
|
181
|
-
|
175
|
+
color(" Failures: ", 'bold') + color(results.stats.failures, 'red') +
|
176
|
+
color(" Duration: ", 'bold') + color(results.duration, 'green') + " ms \n")
|
182
177
|
|
183
178
|
function indent(string) {
|
184
179
|
return string.replace(/^(.)/gm, ' $1')
|
@@ -208,7 +203,7 @@
|
|
208
203
|
},
|
209
204
|
|
210
205
|
/**
|
211
|
-
* Console
|
206
|
+
* Console reporter.
|
212
207
|
*
|
213
208
|
* @api public
|
214
209
|
*/
|
@@ -246,7 +241,8 @@
|
|
246
241
|
// Report assertion results
|
247
242
|
|
248
243
|
report : function() {
|
249
|
-
|
244
|
+
if (JSpec.assert)
|
245
|
+
this.passed ? JSpec.stats.passes++ : JSpec.stats.failures++
|
250
246
|
return this
|
251
247
|
},
|
252
248
|
|
@@ -270,7 +266,7 @@
|
|
270
266
|
// Proxy
|
271
267
|
|
272
268
|
object[method] = function(){
|
273
|
-
args =
|
269
|
+
args = toArray(arguments)
|
274
270
|
result = old.apply(object, args)
|
275
271
|
self.calls.push({ args : args, result : result })
|
276
272
|
return result
|
@@ -302,7 +298,7 @@
|
|
302
298
|
// Proxy arguments passed
|
303
299
|
|
304
300
|
with_args : function() {
|
305
|
-
this.expectedArgs =
|
301
|
+
this.expectedArgs = toArray(arguments)
|
306
302
|
return this
|
307
303
|
},
|
308
304
|
|
@@ -312,7 +308,7 @@
|
|
312
308
|
return any(this.calls, function(call){
|
313
309
|
return self.expectedResult.an_instance_of ?
|
314
310
|
call.result.constructor != self.expectedResult.an_instance_of:
|
315
|
-
|
311
|
+
!equal(self.expectedResult, call.result)
|
316
312
|
})
|
317
313
|
},
|
318
314
|
|
@@ -322,7 +318,7 @@
|
|
322
318
|
return any(this.calls, function(call){
|
323
319
|
return self.expectedResult.an_instance_of ?
|
324
320
|
call.result.constructor == self.expectedResult.an_instance_of:
|
325
|
-
|
321
|
+
equal(self.expectedResult, call.result)
|
326
322
|
})
|
327
323
|
},
|
328
324
|
|
@@ -346,7 +342,7 @@
|
|
346
342
|
if (arg == null) return call.args[i] == null
|
347
343
|
return arg.an_instance_of ?
|
348
344
|
call.args[i].constructor != arg.an_instance_of:
|
349
|
-
|
345
|
+
!equal(arg, call.args[i])
|
350
346
|
|
351
347
|
})
|
352
348
|
})
|
@@ -359,7 +355,7 @@
|
|
359
355
|
return any(self.expectedArgs, function(i, arg){
|
360
356
|
return arg.an_instance_of ?
|
361
357
|
call.args[i].constructor == arg.an_instance_of:
|
362
|
-
|
358
|
+
equal(arg, call.args[i])
|
363
359
|
|
364
360
|
})
|
365
361
|
})
|
@@ -380,7 +376,8 @@
|
|
380
376
|
// Report assertion results
|
381
377
|
|
382
378
|
report : function() {
|
383
|
-
|
379
|
+
if (JSpec.assert)
|
380
|
+
this.passed ? ++JSpec.stats.passes : ++JSpec.stats.failures
|
384
381
|
return this
|
385
382
|
},
|
386
383
|
|
@@ -506,14 +503,14 @@
|
|
506
503
|
|
507
504
|
pass : function(message) {
|
508
505
|
this.assertions.push({ passed: true, message: message })
|
509
|
-
++JSpec.stats.passes
|
506
|
+
if (JSpec.assert) ++JSpec.stats.passes
|
510
507
|
},
|
511
508
|
|
512
509
|
// Add failing assertion
|
513
510
|
|
514
511
|
fail : function(message) {
|
515
512
|
this.assertions.push({ passed: false, message: message })
|
516
|
-
++JSpec.stats.failures
|
513
|
+
if (JSpec.assert) ++JSpec.stats.failures
|
517
514
|
},
|
518
515
|
|
519
516
|
// Run deferred assertions
|
@@ -679,7 +676,7 @@
|
|
679
676
|
/**
|
680
677
|
* Include _object_ which may be a hash or Module instance.
|
681
678
|
*
|
682
|
-
* @param {
|
679
|
+
* @param {hash, Module} object
|
683
680
|
* @return {JSpec}
|
684
681
|
* @api public
|
685
682
|
*/
|
@@ -690,7 +687,7 @@
|
|
690
687
|
if ('init' in module) module.init()
|
691
688
|
if ('utilities' in module) extend(this.defaultContext, module.utilities)
|
692
689
|
if ('matchers' in module) this.addMatchers(module.matchers)
|
693
|
-
if ('
|
690
|
+
if ('reporters' in module) extend(this.reporters, module.reporters)
|
694
691
|
if ('DSLs' in module)
|
695
692
|
each(module.DSLs, function(name, methods){
|
696
693
|
JSpec.DSLs[name] = JSpec.DSLs[name] || {}
|
@@ -711,7 +708,7 @@
|
|
711
708
|
*/
|
712
709
|
|
713
710
|
hook : function(name, args) {
|
714
|
-
args =
|
711
|
+
args = toArray(arguments, 1)
|
715
712
|
return inject(JSpec.modules, [], function(results, module){
|
716
713
|
if (typeof module[name] == 'function')
|
717
714
|
results.push(JSpec.evalHook(module, name, args))
|
@@ -805,7 +802,7 @@
|
|
805
802
|
* @api public
|
806
803
|
*/
|
807
804
|
|
808
|
-
|
805
|
+
toArray : function(arguments, offset) {
|
809
806
|
return Array.prototype.slice.call(arguments, offset || 0)
|
810
807
|
},
|
811
808
|
|
@@ -842,7 +839,9 @@
|
|
842
839
|
return 'expected ' + puts(actual) + ' to ' +
|
843
840
|
(negate ? 'not ' : '') +
|
844
841
|
name.replace(/_/g, ' ') +
|
845
|
-
' ' +
|
842
|
+
' ' + (expected.length > 1 ?
|
843
|
+
puts.apply(this, expected.slice(1)) :
|
844
|
+
'')
|
846
845
|
},
|
847
846
|
|
848
847
|
/**
|
@@ -907,34 +906,35 @@
|
|
907
906
|
return (value = query(key)) !== null ? value :
|
908
907
|
JSpec.options[key] || null
|
909
908
|
},
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
909
|
+
|
910
|
+
/**
|
911
|
+
* Check if object _a_, is equal to object _b_.
|
912
|
+
*
|
913
|
+
* @param {object} a
|
914
|
+
* @param {object} b
|
915
|
+
* @return {bool}
|
916
|
+
* @api private
|
917
|
+
*/
|
918
|
+
|
919
|
+
equal: function(a, b) {
|
920
|
+
if (typeof a != typeof b) return
|
921
|
+
if (a === b) return true
|
922
|
+
if (a instanceof RegExp)
|
923
|
+
return a.toString() === b.toString()
|
924
|
+
if (a instanceof Date)
|
925
|
+
return Number(a) === Number(b)
|
926
|
+
if (typeof a != 'object') return
|
927
|
+
if (a.length !== undefined)
|
928
|
+
if (a.length !== b.length) return
|
929
|
+
else
|
930
|
+
for (var i = 0, len = a.length; i < len; ++i)
|
931
|
+
if (!equal(a[i], b[i]))
|
932
|
+
return
|
933
|
+
for (var key in a)
|
934
|
+
if (!equal(a[key], b[key]))
|
935
|
+
return
|
936
|
+
return true
|
937
|
+
},
|
938
938
|
|
939
939
|
/**
|
940
940
|
* Return last element of an array.
|
@@ -957,30 +957,35 @@
|
|
957
957
|
*/
|
958
958
|
|
959
959
|
puts : function(object) {
|
960
|
-
if (arguments.length > 1)
|
961
|
-
return map(
|
960
|
+
if (arguments.length > 1)
|
961
|
+
return map(toArray(arguments), function(arg){
|
962
962
|
return puts(arg)
|
963
963
|
}).join(', ')
|
964
|
-
|
965
|
-
if (object === undefined) return ''
|
964
|
+
if (object === undefined) return 'undefined'
|
966
965
|
if (object === null) return 'null'
|
967
966
|
if (object === true) return 'true'
|
968
967
|
if (object === false) return 'false'
|
969
968
|
if (object.an_instance_of) return 'an instance of ' + object.an_instance_of.name
|
970
|
-
if (object.jquery && object.selector.length > 0) return 'selector ' + puts(object.selector)
|
969
|
+
if (object.jquery && object.selector.length > 0) return 'selector ' + puts(object.selector)
|
971
970
|
if (object.jquery) return object.get(0).outerHTML
|
972
971
|
if (object.nodeName) return object.outerHTML
|
973
972
|
switch (object.constructor) {
|
974
|
-
case String: return "'" + object + "'"
|
975
|
-
case Number: return object
|
976
973
|
case Function: return object.name || object
|
974
|
+
case String:
|
975
|
+
return '"' + object
|
976
|
+
.replace(/"/g, '\\"')
|
977
|
+
.replace(/\n/g, '\\n')
|
978
|
+
.replace(/\t/g, '\\t')
|
979
|
+
+ '"'
|
977
980
|
case Array:
|
978
981
|
return inject(object, '[', function(b, v){
|
979
982
|
return b + ', ' + puts(v)
|
980
983
|
}).replace('[,', '[') + ' ]'
|
981
984
|
case Object:
|
985
|
+
object.__hit__ = true
|
982
986
|
return inject(object, '{', function(b, k, v) {
|
983
|
-
|
987
|
+
if (k == '__hit__') return b
|
988
|
+
return b + ', ' + k + ': ' + (v && v.__hit__ ? '<circular reference>' : puts(v))
|
984
989
|
}).replace('{,', '{') + ' }'
|
985
990
|
default:
|
986
991
|
return object.toString()
|
@@ -1024,7 +1029,7 @@
|
|
1024
1029
|
*/
|
1025
1030
|
|
1026
1031
|
does : function(actual, matcher, expected) {
|
1027
|
-
var assertion = new JSpec.Assertion(JSpec.matchers[matcher], actual,
|
1032
|
+
var assertion = new JSpec.Assertion(JSpec.matchers[matcher], actual, toArray(arguments, 2))
|
1028
1033
|
return assertion.run().result
|
1029
1034
|
},
|
1030
1035
|
|
@@ -1042,7 +1047,7 @@
|
|
1042
1047
|
|
1043
1048
|
expect : function(actual) {
|
1044
1049
|
assert = function(matcher, args, negate) {
|
1045
|
-
var expected =
|
1050
|
+
var expected = toArray(args, 1)
|
1046
1051
|
matcher.negate = negate
|
1047
1052
|
assertion = new JSpec.Assertion(matcher, actual, expected, negate)
|
1048
1053
|
hook('beforeAssertion', assertion)
|
@@ -1114,17 +1119,20 @@
|
|
1114
1119
|
/**
|
1115
1120
|
* Iterate an object, invoking the given callback.
|
1116
1121
|
*
|
1117
|
-
* @param {hash, array
|
1122
|
+
* @param {hash, array} object
|
1118
1123
|
* @param {function} callback
|
1119
1124
|
* @return {JSpec}
|
1120
1125
|
* @api public
|
1121
1126
|
*/
|
1122
1127
|
|
1123
1128
|
each : function(object, callback) {
|
1124
|
-
if (
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1129
|
+
if (object.constructor == Array)
|
1130
|
+
for (var i = 0, len = object.length; i < len; ++i)
|
1131
|
+
callIterator(callback, i, object[i])
|
1132
|
+
else
|
1133
|
+
for (var key in object)
|
1134
|
+
if (object.hasOwnProperty(key))
|
1135
|
+
callIterator(callback, key, object[key])
|
1128
1136
|
},
|
1129
1137
|
|
1130
1138
|
/**
|
@@ -1326,7 +1334,7 @@
|
|
1326
1334
|
var context = this.context || this.defaultContext
|
1327
1335
|
var contents = this.contentsOf(body)
|
1328
1336
|
hook('evaluatingBody', dsl, matchers, context, contents)
|
1329
|
-
try {
|
1337
|
+
try { with (dsl){ with (context) { with (matchers) { eval(contents) }}} }
|
1330
1338
|
catch(e) { error(errorMessage, e) }
|
1331
1339
|
},
|
1332
1340
|
|
@@ -1344,7 +1352,7 @@
|
|
1344
1352
|
return input.
|
1345
1353
|
replace(/\t/g, ' ').
|
1346
1354
|
replace(/\r\n|\n|\r/g, '\n').
|
1347
|
-
|
1355
|
+
split('__END__')[0].
|
1348
1356
|
replace(/([\w\.]+)\.(stub|destub)\((.*?)\)$/gm, '$2($1, $3)').
|
1349
1357
|
replace(/describe\s+(.*?)$/gm, 'describe($1, function(){').
|
1350
1358
|
replace(/^\s+it\s+(.*?)$/gm, ' it($1, function(){').
|
@@ -1381,8 +1389,9 @@
|
|
1381
1389
|
*/
|
1382
1390
|
|
1383
1391
|
report : function() {
|
1392
|
+
this.duration = Number(new Date) - this.start
|
1384
1393
|
hook('reporting', JSpec.options)
|
1385
|
-
new (JSpec.options.
|
1394
|
+
new (JSpec.options.reporter || JSpec.reporters.DOM)(JSpec, JSpec.options)
|
1386
1395
|
},
|
1387
1396
|
|
1388
1397
|
/**
|
@@ -1397,9 +1406,8 @@
|
|
1397
1406
|
run : function(options) {
|
1398
1407
|
if (any(hook('running'), haveStopped)) return this
|
1399
1408
|
if (options) extend(this.options, options)
|
1400
|
-
|
1409
|
+
this.start = Number(new Date)
|
1401
1410
|
each(this.suites, function(suite) { JSpec.runSuite(suite) })
|
1402
|
-
if (option('profile')) console.groupEnd()
|
1403
1411
|
return this
|
1404
1412
|
},
|
1405
1413
|
|
@@ -1462,10 +1470,8 @@
|
|
1462
1470
|
|
1463
1471
|
runSpec : function(spec) {
|
1464
1472
|
this.currentSpec = spec
|
1465
|
-
if (option('profile')) console.time(spec.description)
|
1466
1473
|
try { this.evalBody(spec.body) }
|
1467
1474
|
catch (e) { fail(e) }
|
1468
|
-
if (option('profile')) console.timeEnd(spec.description)
|
1469
1475
|
spec.runDeferredAssertions()
|
1470
1476
|
destub()
|
1471
1477
|
this.stats.specsFinished++
|
@@ -1588,8 +1594,7 @@
|
|
1588
1594
|
*/
|
1589
1595
|
|
1590
1596
|
tryLoading : function(file) {
|
1591
|
-
try { return JSpec.load(file) }
|
1592
|
-
catch (e) {}
|
1597
|
+
try { return JSpec.load(file) } catch (e) {}
|
1593
1598
|
},
|
1594
1599
|
|
1595
1600
|
/**
|
@@ -1638,14 +1643,15 @@
|
|
1638
1643
|
var main = this
|
1639
1644
|
var find = JSpec.any
|
1640
1645
|
var utils = 'haveStopped stub hookImmutable hook destub map any last pass fail range each option inject select \
|
1641
|
-
error escape extend puts
|
1642
|
-
while (utils.length)
|
1646
|
+
error escape extend puts query strip color does addMatchers callIterator toArray equal'.split(/\s+/)
|
1647
|
+
while (utils.length) eval('var ' + utils[0] + ' = JSpec.' + utils.shift())
|
1643
1648
|
if (!main.setTimeout) main.setTimeout = function(callback){ callback() }
|
1644
1649
|
|
1645
1650
|
// --- Matchers
|
1646
1651
|
|
1647
1652
|
addMatchers({
|
1648
1653
|
equal : "===",
|
1654
|
+
eql : "equal(actual, expected)",
|
1649
1655
|
be : "alias equal",
|
1650
1656
|
be_greater_than : ">",
|
1651
1657
|
be_less_than : "<",
|
@@ -1664,13 +1670,6 @@
|
|
1664
1670
|
have_length : "actual.length == expected",
|
1665
1671
|
be_within : "actual >= expected[0] && actual <= last(expected)",
|
1666
1672
|
have_length_within : "actual.length >= expected[0] && actual.length <= last(expected)",
|
1667
|
-
|
1668
|
-
eql : function(actual, expected) {
|
1669
|
-
return actual.constructor == Array ||
|
1670
|
-
actual instanceof Object ?
|
1671
|
-
hash(actual) == hash(expected):
|
1672
|
-
actual == expected
|
1673
|
-
},
|
1674
1673
|
|
1675
1674
|
receive : { defer : true, match : function(actual, method, times) {
|
1676
1675
|
proxy = new JSpec.ProxyAssertion(actual, method, times, this.negate)
|
@@ -1701,7 +1700,7 @@
|
|
1701
1700
|
break
|
1702
1701
|
|
1703
1702
|
case Array:
|
1704
|
-
state = any(actual, function(value){ return
|
1703
|
+
state = any(actual, function(value){ return equal(value, arg) })
|
1705
1704
|
break
|
1706
1705
|
}
|
1707
1706
|
if (!state) return false
|
@@ -1715,9 +1714,9 @@
|
|
1715
1714
|
this.e = e
|
1716
1715
|
var assert = function(arg) {
|
1717
1716
|
switch (arg.constructor) {
|
1718
|
-
case RegExp : return arg.test(e)
|
1717
|
+
case RegExp : return arg.test(e.message || e.toString())
|
1719
1718
|
case String : return arg == (e.message || e.toString())
|
1720
|
-
case Function : return
|
1719
|
+
case Function : return e instanceof arg || e.name == arg.name
|
1721
1720
|
}
|
1722
1721
|
}
|
1723
1722
|
return message ? assert(expected) && assert(message) :
|
@@ -1771,6 +1770,4 @@
|
|
1771
1770
|
}
|
1772
1771
|
})
|
1773
1772
|
|
1774
|
-
if ('exports' in main) exports.JSpec = JSpec
|
1775
|
-
|
1776
1773
|
})()
|