visionmedia-jspec 2.3.1 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +12 -0
- data/README.rdoc +81 -0
- data/Rakefile +1 -0
- data/bin/jspec +34 -34
- data/jspec.gemspec +5 -2
- data/lib/jspec.jquery.js +34 -37
- data/lib/jspec.js +120 -46
- data/spec/spec.jquery.js +8 -1
- data/spec/spec.utils.js +16 -0
- metadata +12 -2
data/History.rdoc
CHANGED
@@ -1,4 +1,16 @@
|
|
1
1
|
|
2
|
+
=== 2.4.0 / 2009-06-30
|
3
|
+
|
4
|
+
* Added hook() and hookImmutable()
|
5
|
+
* Added support for matcher lists ('be enabled disabled selected') == be_enabled, be_disabled etc
|
6
|
+
* Added JSpec.include()
|
7
|
+
* Added several hooks
|
8
|
+
* Added Module support
|
9
|
+
* Added grammar conversion of Foo.stub('method') to stub(Foo, 'method')
|
10
|
+
* Added grammar conversion of Foo.destub() to destub(Foo)
|
11
|
+
* Require bind gem
|
12
|
+
* Fixed `jspec` bin docs
|
13
|
+
|
2
14
|
=== 2.3.1 / 2009-06-25
|
3
15
|
|
4
16
|
* Fixed; all stubs generated with stub() are restored
|
data/README.rdoc
CHANGED
@@ -10,6 +10,7 @@ and much more.
|
|
10
10
|
|
11
11
|
* Highly readable
|
12
12
|
* Framework / DOM independent
|
13
|
+
* Modular via JSpec Module's and hooks
|
13
14
|
* Rhino support
|
14
15
|
* Async support
|
15
16
|
* Ruby JavaScript testing server
|
@@ -226,6 +227,12 @@ If you would like to whipe an object clear of stubs simply pass it
|
|
226
227
|
to destub() without an additional method argument:
|
227
228
|
|
228
229
|
destub(person)
|
230
|
+
|
231
|
+
Alternatively both these utility functions may be called as methods
|
232
|
+
on any object when using the JSpec grammar:
|
233
|
+
|
234
|
+
someObject.stub('method').and_return('whatever')
|
235
|
+
// Converted to stub(someObject, 'method').and_return('whatever')
|
229
236
|
|
230
237
|
== Helpers
|
231
238
|
|
@@ -417,7 +424,81 @@ for you, how ever this can be explicitly defined:
|
|
417
424
|
}
|
418
425
|
}
|
419
426
|
})
|
427
|
+
|
428
|
+
When defining matchers that are extremely similar in functionality, however
|
429
|
+
require different names, you may use a prefixed list of words like below which
|
430
|
+
defines be_disabled, be_selected, be_checked, and have_type, have_id, etc. Each
|
431
|
+
function must return the matcher body which will be used.
|
432
|
+
|
433
|
+
JSpec.addMatchers({
|
434
|
+
'be disabled selected checked' : function(attr) {
|
435
|
+
return 'jQuery(actual).attr("' + attr + '")'
|
436
|
+
},
|
437
|
+
|
438
|
+
'have type id title alt href src sel rev name target' : function(attr) {
|
439
|
+
return function(actual, value) {
|
440
|
+
return value ? jQuery(actual).attr(attr) == value:
|
441
|
+
jQuery(actual).attr(attr)
|
442
|
+
}
|
443
|
+
}
|
444
|
+
})
|
420
445
|
|
446
|
+
== Extending Or Hooking Into JSpec
|
447
|
+
|
448
|
+
JSpec provides a hook architecture for extending or analyzing various
|
449
|
+
points in its execution, through the use of 'Modules'. For a Module
|
450
|
+
example view lib/jspec.jquery.js.
|
451
|
+
|
452
|
+
The following methods or properties are utilized by JSpec:
|
453
|
+
|
454
|
+
- init : called to initialize a module
|
455
|
+
- utilities : hash of utility functions merged with JSpec.defaultContext
|
456
|
+
- matchers : hash of matchers merged with JSpec's core matchers via JSpec.addMatchers()
|
457
|
+
|
458
|
+
Below is a list of hooks, descriptions, and valid return values which
|
459
|
+
may simply be implemented as module methods.
|
460
|
+
|
461
|
+
- running(options) : started running JSpec with the options passed : returning 'stop' will halt running
|
462
|
+
- loading(file) : loading a file : returning 'stop' will prevent loading
|
463
|
+
- executing(file) : executing a file : returning 'stop' will prevent execution
|
464
|
+
- posting(data, url) : posting data to a url : returning 'stop' will prevent request
|
465
|
+
- reportingToServer(url) : reporting to server url : returning 'stop' will prevent reporting to server
|
466
|
+
- preprocessing(input) : before input string is preprocessed : return input string for next hook to preprocess
|
467
|
+
- stubbing(object, method, result) : called when stubbing an object's method, and return value (result). : (no return value)
|
468
|
+
- requiring(dependency, message) : requiring a dependency : (no return value)
|
469
|
+
- beforeAssertion(assertion) : before an assertion has been made : (no return value)
|
470
|
+
- afterAssertion(assertion) : after an assertion has been made : (no return value)
|
471
|
+
- addingMatcher(name, body) : unprocessed matcher name and body : (no return value)
|
472
|
+
- addingSuite(suite) : adding Suite instance to JSpec : (no return value)
|
473
|
+
- beforeSuite(suite) : before running of suite : (no return value)
|
474
|
+
- afterSuite(suite) : after running of suite : (no return value)
|
475
|
+
- beforeSpec(spec) : before running of spec : (no return value)
|
476
|
+
- afterSpec(spec) : after running of spec : (no return value)
|
477
|
+
- reporting(options) : called before reporting : (no return value)
|
478
|
+
- evaluatingBody(dsl, matchers, context, contents) : evaluating body contents, with the given context, matchers and dsl. : (no return value)
|
479
|
+
|
480
|
+
For example you may wish to proxy files which are being executed, simply implement the
|
481
|
+
executing method like below. This example will stop execution of any file matching /matchers/.
|
482
|
+
|
483
|
+
MyModule = {
|
484
|
+
executing : function(file) {
|
485
|
+
if (file.match(/matchers/))
|
486
|
+
return 'stop'
|
487
|
+
}
|
488
|
+
}
|
489
|
+
JSpec.include(MyModule)
|
490
|
+
|
491
|
+
Immutable values may also be passed to hooks using hookImmutable() internally. This allows
|
492
|
+
for simple numbers, strings, etc to be utilized or altered within a hook implementation. Below
|
493
|
+
is an example module which adds functionality to the JSpec grammar by converting SomeObject.stub('method')
|
494
|
+
to stub(SomeObject, 'method'):
|
495
|
+
|
496
|
+
JSpec.include({
|
497
|
+
preprocessing : function(input) {
|
498
|
+
return input.replace(/(\w+)\.(stub|destub)\((.*?)\)$/gm, '$2($1, $3)')
|
499
|
+
}
|
500
|
+
})
|
501
|
+
|
421
502
|
== JSpec Command-line Utility
|
422
503
|
|
423
504
|
When installed as a Ruby Gem, the `jspec` executable will become available,
|
data/Rakefile
CHANGED
@@ -13,6 +13,7 @@ Echoe.new "jspec", version do |p|
|
|
13
13
|
p.summary = "JavaScript BDD Testing Framework"
|
14
14
|
p.url = "http://visionmedia.github.com/jspec"
|
15
15
|
p.runtime_dependencies << "visionmedia-commander >=3.2.9"
|
16
|
+
p.runtime_dependencies << "visionmedia-bind >=0.2.6"
|
16
17
|
end
|
17
18
|
|
18
19
|
namespace :pkg do
|
data/bin/jspec
CHANGED
@@ -5,12 +5,13 @@ $:.unshift JSPEC_ROOT
|
|
5
5
|
|
6
6
|
require 'rubygems'
|
7
7
|
require 'commander'
|
8
|
+
require 'bind'
|
8
9
|
require 'fileutils'
|
9
10
|
|
10
11
|
RHINO = 'java org.mozilla.javascript.tools.shell.Main'
|
11
12
|
|
12
13
|
program :name, 'JSpec'
|
13
|
-
program :version, '2.
|
14
|
+
program :version, '2.4.0'
|
14
15
|
program :description, 'JavaScript BDD Testing Framework'
|
15
16
|
default_command :bind
|
16
17
|
|
@@ -58,20 +59,25 @@ end
|
|
58
59
|
command :run do |c|
|
59
60
|
c.syntax = 'jspec run [path] [options]'
|
60
61
|
c.summary = 'Run specifications'
|
61
|
-
c.description = 'Run specifications, defaulting [path] to spec/spec.html.
|
62
|
-
supply [path] if your specs do not reside
|
63
|
-
the default sub-command of
|
64
|
-
|
62
|
+
c.description = 'Run specifications, defaulting [path] to spec/spec.dom.html.
|
63
|
+
You will need to supply [path] if your specs do not reside
|
64
|
+
in this location. `run --bind` is the default sub-command of
|
65
|
+
jspec so you may simply execute `jspec` in order to bind execution
|
66
|
+
of your specs when a file is altered.
|
65
67
|
|
66
|
-
JSpec supports Rhino execution when installed. The [path] is assumed
|
67
|
-
spec/spec.js unless specified. See examples below for
|
68
|
+
JSpec supports Rhino execution when installed. The [path] is assumed
|
69
|
+
to be spec/spec.rhino.js unless specified. See examples below for
|
70
|
+
using the --rhino switch.
|
71
|
+
|
72
|
+
JSpec\'s server is also available via --server, which defaults
|
73
|
+
the [path] to spec/server.html'
|
68
74
|
c.example 'Run once in Safari', 'jspec run'
|
69
75
|
c.example 'Run once in Safari and Firefox', 'jspec run --browsers Safari,Firefox'
|
70
76
|
c.example 'Run custom spec file', 'jspec run foo.html'
|
71
77
|
c.example 'Auto-run browsers when a file is altered', 'jspec run --bind --browsers Safari,Firefox'
|
72
78
|
c.example 'Shortcut for the previous example', 'jspec --browsers Safari,Firefox'
|
73
79
|
c.example 'Auto-run rhino when a file is altered', 'jspec --rhino'
|
74
|
-
c.example 'Run Rhino specs once', 'jspec run --rhino'
|
80
|
+
c.example 'Run Rhino specs once', 'jspec run specs/something.js --rhino'
|
75
81
|
c.option '-b', '--browsers BROWSERS', Array, 'Specify browsers to test, defaults to Safari'
|
76
82
|
c.option '-p', '--paths PATHS', Array, 'Specify paths when binding, defaults to javascript within ./lib and ./spec'
|
77
83
|
c.option '-B', '--bind', 'Auto-run specs when source files or specs are altered'
|
@@ -79,32 +85,26 @@ command :run do |c|
|
|
79
85
|
c.option '-S', '--server', 'Run specs using the JSpec server'
|
80
86
|
c.option '-s', '--server-only', 'Start JSpec server without running browsers'
|
81
87
|
c.when_called do |args, options|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
else
|
103
|
-
action.call File.new(spec)
|
104
|
-
end
|
105
|
-
|
106
|
-
rescue LoadError
|
107
|
-
abort "jspec run requires the visionmedia-bind gem; http://visionmedia.github.com/bind/"
|
88
|
+
options.default :browsers => %w( Safari ), :paths => ['lib/**/*.js', 'spec/**/*.js']
|
89
|
+
|
90
|
+
# Actions
|
91
|
+
if options.rhino
|
92
|
+
spec = args.shift || 'spec/spec.rhino.js'
|
93
|
+
action = lambda { rhino spec }
|
94
|
+
elsif options.server
|
95
|
+
spec = args.shift || 'spec/spec.server.html'
|
96
|
+
action = lambda { start_server options, spec }
|
97
|
+
else
|
98
|
+
spec = args.shift || 'spec/spec.dom.html'
|
99
|
+
action = Bind::Actions::RefreshBrowsers.new spec, *options.browsers
|
100
|
+
end
|
101
|
+
|
102
|
+
# Binding
|
103
|
+
if options.bind
|
104
|
+
listener = Bind::Listener.new :paths => options.paths, :interval => 1, :actions => [action], :debug => $stdout
|
105
|
+
listener.run!
|
106
|
+
else
|
107
|
+
action.call File.new(spec)
|
108
108
|
end
|
109
109
|
end
|
110
110
|
end
|
data/jspec.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{jspec}
|
5
|
-
s.version = "2.
|
5
|
+
s.version = "2.4.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{2009-06-
|
9
|
+
s.date = %q{2009-06-30}
|
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}
|
@@ -26,10 +26,13 @@ Gem::Specification.new do |s|
|
|
26
26
|
|
27
27
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
28
|
s.add_runtime_dependency(%q<visionmedia-commander>, [">= 3.2.9"])
|
29
|
+
s.add_runtime_dependency(%q<visionmedia-bind>, [">= 0.2.6"])
|
29
30
|
else
|
30
31
|
s.add_dependency(%q<visionmedia-commander>, [">= 3.2.9"])
|
32
|
+
s.add_dependency(%q<visionmedia-bind>, [">= 0.2.6"])
|
31
33
|
end
|
32
34
|
else
|
33
35
|
s.add_dependency(%q<visionmedia-commander>, [">= 3.2.9"])
|
36
|
+
s.add_dependency(%q<visionmedia-bind>, [">= 0.2.6"])
|
34
37
|
end
|
35
38
|
end
|
data/lib/jspec.jquery.js
CHANGED
@@ -1,25 +1,28 @@
|
|
1
1
|
|
2
2
|
// JSpec - jQuery - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
|
3
3
|
|
4
|
-
(
|
5
|
-
|
6
|
-
// ---
|
7
|
-
|
8
|
-
|
4
|
+
JSpec.include({
|
5
|
+
|
6
|
+
// --- Initialize
|
7
|
+
|
8
|
+
init : function() {
|
9
|
+
this.requires('jQuery', 'when using jspec.jquery.js')
|
10
|
+
jQuery.ajaxSetup({ async : false })
|
11
|
+
},
|
12
|
+
|
13
|
+
// --- Utilities
|
14
|
+
|
15
|
+
utilities : {
|
16
|
+
element : jQuery,
|
17
|
+
elements : jQuery,
|
18
|
+
sandbox : function() {
|
19
|
+
return jQuery('<div class="sandbox"></div>')
|
20
|
+
}
|
21
|
+
},
|
9
22
|
|
10
|
-
// --- Async Support
|
11
|
-
|
12
|
-
jQuery.ajaxSetup({ async : false })
|
13
|
-
|
14
|
-
// --- Helpers
|
15
|
-
|
16
|
-
JSpec.defaultContext.element = jQuery
|
17
|
-
JSpec.defaultContext.elements = jQuery
|
18
|
-
JSpec.defaultContext.sandbox = function() { return jQuery('<div class="sandbox"></div>') }
|
19
|
-
|
20
23
|
// --- Matchers
|
21
|
-
|
22
|
-
|
24
|
+
|
25
|
+
matchers : {
|
23
26
|
have_tag : "jQuery(expected, actual).length == 1",
|
24
27
|
have_one : "alias have_tag",
|
25
28
|
have_tags : "jQuery(expected, actual).length > 1",
|
@@ -32,33 +35,27 @@
|
|
32
35
|
be_hidden : "jQuery(actual).is(':hidden')",
|
33
36
|
be_enabled : "!jQuery(actual).attr('disabled')",
|
34
37
|
have_class : "jQuery(actual).hasClass(expected)",
|
35
|
-
|
38
|
+
|
36
39
|
have_classes : function(actual) {
|
37
40
|
return !JSpec.any(JSpec.argumentsToArray(arguments, 1), function(arg){
|
38
41
|
return !JSpec.does(actual, 'have_class', arg)
|
39
42
|
})
|
40
43
|
},
|
41
|
-
|
44
|
+
|
42
45
|
have_attr : function(actual, attr, value) {
|
43
46
|
return value ? jQuery(actual).attr(attr) == value:
|
44
47
|
jQuery(actual).attr(attr)
|
48
|
+
},
|
49
|
+
|
50
|
+
'be disabled selected checked' : function(attr) {
|
51
|
+
return 'jQuery(actual).attr("' + attr + '")'
|
52
|
+
},
|
53
|
+
|
54
|
+
'have type id title alt href src sel rev name target' : function(attr) {
|
55
|
+
return function(actual, value) {
|
56
|
+
return JSpec.does(actual, 'have_attr', attr, value)
|
57
|
+
}
|
45
58
|
}
|
46
|
-
}
|
47
|
-
|
48
|
-
// --- be_BOOLATTR
|
49
|
-
|
50
|
-
JSpec.each('disabled selected checked', function(attr){
|
51
|
-
JSpec.addMatcher('be_' + attr, "jQuery(actual).attr('" + attr + "')")
|
52
|
-
})
|
53
|
-
|
54
|
-
// --- have_ATTR
|
55
|
-
|
56
|
-
JSpec.each('type id title alt href src rel rev name target', function(attr){
|
57
|
-
JSpec.addMatcher('have_' + attr, function(actual, value) {
|
58
|
-
return JSpec.matchers.have_attr.match(actual, attr, value)
|
59
|
-
})
|
60
|
-
})
|
61
|
-
|
62
|
-
})()
|
63
|
-
|
59
|
+
}
|
60
|
+
})
|
64
61
|
|
data/lib/jspec.js
CHANGED
@@ -5,8 +5,9 @@
|
|
5
5
|
|
6
6
|
JSpec = {
|
7
7
|
|
8
|
-
version : '2.
|
8
|
+
version : '2.4.0',
|
9
9
|
suites : [],
|
10
|
+
modules : [],
|
10
11
|
allSuites : [],
|
11
12
|
matchers : {},
|
12
13
|
stubbed : [],
|
@@ -431,7 +432,7 @@
|
|
431
432
|
|
432
433
|
runDeferredAssertions : function() {
|
433
434
|
each(this.assertions, function(assertion){
|
434
|
-
if (assertion.defer) assertion.run().report()
|
435
|
+
if (assertion.defer) assertion.run().report(), hook('afterAssertion', assertion)
|
435
436
|
})
|
436
437
|
},
|
437
438
|
|
@@ -473,6 +474,13 @@
|
|
473
474
|
})
|
474
475
|
},
|
475
476
|
|
477
|
+
Module : function(methods) {
|
478
|
+
extend(this, methods)
|
479
|
+
extend(this, {
|
480
|
+
requires : JSpec.requires
|
481
|
+
})
|
482
|
+
},
|
483
|
+
|
476
484
|
// --- DSLs
|
477
485
|
|
478
486
|
DSLs : {
|
@@ -513,6 +521,72 @@
|
|
513
521
|
|
514
522
|
// --- Methods
|
515
523
|
|
524
|
+
/**
|
525
|
+
* Check if _value_ is 'stop'. For use as a
|
526
|
+
* utility callback function.
|
527
|
+
*
|
528
|
+
* @param {mixed} value
|
529
|
+
* @return {bool}
|
530
|
+
* @api public
|
531
|
+
*/
|
532
|
+
|
533
|
+
haveStopped : function(value) {
|
534
|
+
return value === 'stop'
|
535
|
+
},
|
536
|
+
|
537
|
+
/**
|
538
|
+
* Include _object_ which may be a hash or Module instance.
|
539
|
+
*
|
540
|
+
* @param {has, Module} object
|
541
|
+
* @api public
|
542
|
+
*/
|
543
|
+
|
544
|
+
include : function(object) {
|
545
|
+
var module = object.constructor == JSpec.Module ? object : new JSpec.Module(object)
|
546
|
+
this.modules.push(module)
|
547
|
+
if ('init' in module) module.init()
|
548
|
+
if ('utilities' in module) extend(this.defaultContext, module.utilities)
|
549
|
+
if ('matchers' in module) this.addMatchers(module.matchers)
|
550
|
+
},
|
551
|
+
|
552
|
+
/**
|
553
|
+
* Add a module hook _name_, which is immediately
|
554
|
+
* called per module with the _args_ given. An array of
|
555
|
+
* hook return values is returned.
|
556
|
+
*
|
557
|
+
* @param {name} string
|
558
|
+
* @param {mixed} args ...
|
559
|
+
* @return {array}
|
560
|
+
* @api private
|
561
|
+
*/
|
562
|
+
|
563
|
+
hook : function(name, args) {
|
564
|
+
args = argumentsToArray(arguments, 1)
|
565
|
+
return inject(JSpec.modules, [], function(results, module){
|
566
|
+
if (typeof module[name] == 'function')
|
567
|
+
results.push(module[name].apply(module, args))
|
568
|
+
})
|
569
|
+
},
|
570
|
+
|
571
|
+
/**
|
572
|
+
* Same as hook() however accepts only one _arg_ which is
|
573
|
+
* considered immutable. This function passes the arg
|
574
|
+
* to the first module, then passes the return value of the last
|
575
|
+
* module called, to the following module.
|
576
|
+
*
|
577
|
+
* @param {string} name
|
578
|
+
* @param {mixed} arg
|
579
|
+
* @return {mixed}
|
580
|
+
* @api private
|
581
|
+
*/
|
582
|
+
|
583
|
+
hookImmutable : function(name, arg) {
|
584
|
+
return inject(JSpec.modules, arg, function(result, module){
|
585
|
+
if (typeof module[name] == 'function')
|
586
|
+
return module[name].call(module, result)
|
587
|
+
})
|
588
|
+
},
|
589
|
+
|
516
590
|
/**
|
517
591
|
* Find a suite by its description or name.
|
518
592
|
*
|
@@ -768,6 +842,9 @@
|
|
768
842
|
* does('foo', 'eql', 'foo')
|
769
843
|
* does([1,2], 'include', 1, 2)
|
770
844
|
*
|
845
|
+
* External hooks are not run for internal assertions
|
846
|
+
* performed by does().
|
847
|
+
*
|
771
848
|
* @param {mixed} actual
|
772
849
|
* @param {string} matcher
|
773
850
|
* @param {...} expected
|
@@ -794,11 +871,11 @@
|
|
794
871
|
|
795
872
|
expect : function(actual) {
|
796
873
|
assert = function(matcher, args, negate) {
|
797
|
-
var expected =
|
798
|
-
for (i = 1; i < args.length; i++) expected.push(args[i])
|
874
|
+
var expected = argumentsToArray(args, 1)
|
799
875
|
assertion = new JSpec.Assertion(matcher, actual, expected, negate)
|
876
|
+
hook('beforeAssertion', assertion)
|
800
877
|
if (matcher.defer) assertion.run()
|
801
|
-
else JSpec.currentSpec.assertions.push(assertion.run().report())
|
878
|
+
else JSpec.currentSpec.assertions.push(assertion.run().report()), hook('afterAssertion', assertion)
|
802
879
|
return assertion.result
|
803
880
|
}
|
804
881
|
|
@@ -857,9 +934,9 @@
|
|
857
934
|
*/
|
858
935
|
|
859
936
|
extend : function(object, other) {
|
860
|
-
|
861
|
-
|
862
|
-
|
937
|
+
each(other, function(property, value){
|
938
|
+
object[property] = value
|
939
|
+
})
|
863
940
|
},
|
864
941
|
|
865
942
|
/**
|
@@ -942,6 +1019,7 @@
|
|
942
1019
|
stub : function(object, method) {
|
943
1020
|
return {
|
944
1021
|
and_return : function(result) {
|
1022
|
+
hook('stubbing', object, method, result)
|
945
1023
|
JSpec.stubbed.push(object)
|
946
1024
|
var type = object.hasOwnProperty(method) ? '__original__' : '__prototype__'
|
947
1025
|
object[type + method] = object[method]
|
@@ -976,9 +1054,8 @@
|
|
976
1054
|
|
977
1055
|
any : function(object, callback) {
|
978
1056
|
return inject(object, null, function(state, key, value){
|
979
|
-
|
980
|
-
|
981
|
-
value : state
|
1057
|
+
if (state == undefined)
|
1058
|
+
return callIterator(callback, key, value) ? value : state
|
982
1059
|
})
|
983
1060
|
},
|
984
1061
|
|
@@ -993,9 +1070,9 @@
|
|
993
1070
|
*/
|
994
1071
|
|
995
1072
|
select : function(object, callback) {
|
996
|
-
return inject(object, [], function(
|
1073
|
+
return inject(object, [], function(selected, key, value){
|
997
1074
|
if (callIterator(callback, key, value))
|
998
|
-
|
1075
|
+
selected.push(value)
|
999
1076
|
})
|
1000
1077
|
},
|
1001
1078
|
|
@@ -1021,6 +1098,14 @@
|
|
1021
1098
|
*/
|
1022
1099
|
|
1023
1100
|
addMatcher : function(name, body) {
|
1101
|
+
hook('addingMatcher', name, body)
|
1102
|
+
if (name.indexOf(' ') != -1) {
|
1103
|
+
var matchers = name.split(/\s+/)
|
1104
|
+
var prefix = matchers.shift()
|
1105
|
+
each(matchers, function(name) {
|
1106
|
+
JSpec.addMatcher(prefix + '_' + name, body(name))
|
1107
|
+
})
|
1108
|
+
}
|
1024
1109
|
this.matchers[name] = this.normalizeMatcherMessage(this.normalizeMatcherBody(body))
|
1025
1110
|
this.matchers[name].name = name
|
1026
1111
|
},
|
@@ -1035,6 +1120,7 @@
|
|
1035
1120
|
|
1036
1121
|
describe : function(description, body) {
|
1037
1122
|
var suite = new JSpec.Suite(description, body)
|
1123
|
+
hook('addingSuite', suite)
|
1038
1124
|
this.allSuites.push(suite)
|
1039
1125
|
this.suites.push(suite)
|
1040
1126
|
},
|
@@ -1065,6 +1151,7 @@
|
|
1065
1151
|
var matchers = this.matchers
|
1066
1152
|
var context = this.context || this.defaultContext
|
1067
1153
|
var contents = this.contentsOf(body)
|
1154
|
+
hook('evaluatingBody', dsl, matchers, context, contents)
|
1068
1155
|
try { eval('with (dsl){ with (context) { with (matchers) { ' + contents + ' }}}') }
|
1069
1156
|
catch(e) { error(errorMessage, e) }
|
1070
1157
|
},
|
@@ -1078,7 +1165,9 @@
|
|
1078
1165
|
*/
|
1079
1166
|
|
1080
1167
|
preprocess : function(input) {
|
1168
|
+
input = hookImmutable('preprocessing', input)
|
1081
1169
|
return input.
|
1170
|
+
replace(/(\w+)\.(stub|destub)\((.*?)\)$/gm, '$2($1, $3)').
|
1082
1171
|
replace(/describe\s+(.*?)$/gm, 'describe($1, function(){').
|
1083
1172
|
replace(/\sit\s+(.*?)$/gm, ' it($1, function(){').
|
1084
1173
|
replace(/^(?: *)(before_each|after_each|before|after)(?= |\n|$)/gm, 'JSpec.currentSuite.addHook("$1", function(){').
|
@@ -1114,9 +1203,8 @@
|
|
1114
1203
|
*/
|
1115
1204
|
|
1116
1205
|
report : function() {
|
1117
|
-
JSpec.options
|
1118
|
-
|
1119
|
-
new JSpec.formatters.DOM(JSpec, JSpec.options)
|
1206
|
+
hook('reporting', JSpec.options)
|
1207
|
+
new (JSpec.options.formatter || JSpec.formatters.DOM)(JSpec, JSpec.options)
|
1120
1208
|
},
|
1121
1209
|
|
1122
1210
|
/**
|
@@ -1129,6 +1217,7 @@
|
|
1129
1217
|
*/
|
1130
1218
|
|
1131
1219
|
run : function(options) {
|
1220
|
+
if (any(hook('running'), haveStopped)) return this
|
1132
1221
|
if (options) extend(this.options, options)
|
1133
1222
|
if (option('profile')) console.group('Profile')
|
1134
1223
|
each(this.suites, function(suite) { JSpec.runSuite(suite) })
|
@@ -1147,18 +1236,18 @@
|
|
1147
1236
|
this.currentSuite = suite
|
1148
1237
|
this.evalBody(suite.body)
|
1149
1238
|
suite.ran = true
|
1150
|
-
suite.hook('before')
|
1239
|
+
suite.hook('before'), hook('beforeSuite', suite)
|
1151
1240
|
each(suite.specs, function(spec) {
|
1152
|
-
suite.hook('before_each')
|
1241
|
+
suite.hook('before_each'), hook('beforeSpec', spec)
|
1153
1242
|
JSpec.runSpec(spec)
|
1154
|
-
suite.hook('after_each')
|
1243
|
+
suite.hook('after_each'), hook('afterSpec', spec)
|
1155
1244
|
})
|
1156
1245
|
if (suite.hasSuites()) {
|
1157
1246
|
each(suite.suites, function(suite) {
|
1158
1247
|
JSpec.runSuite(suite)
|
1159
1248
|
})
|
1160
1249
|
}
|
1161
|
-
suite.hook('after')
|
1250
|
+
suite.hook('after'), hook('afterSuite', suite)
|
1162
1251
|
this.stats.suitesFinished++
|
1163
1252
|
},
|
1164
1253
|
|
@@ -1202,8 +1291,9 @@
|
|
1202
1291
|
*/
|
1203
1292
|
|
1204
1293
|
requires : function(dependency, message) {
|
1294
|
+
hook('requiring', dependency, message)
|
1205
1295
|
try { eval(dependency) }
|
1206
|
-
catch (e) {
|
1296
|
+
catch (e) { throw 'JSpec depends on ' + dependency + ' ' + message }
|
1207
1297
|
},
|
1208
1298
|
|
1209
1299
|
/**
|
@@ -1246,6 +1336,7 @@
|
|
1246
1336
|
*/
|
1247
1337
|
|
1248
1338
|
post : function(url, data) {
|
1339
|
+
if (any(hook('posting', url, data), haveStopped)) return
|
1249
1340
|
var request = this.xhr()
|
1250
1341
|
request.open('POST', url, false)
|
1251
1342
|
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
|
@@ -1260,6 +1351,7 @@
|
|
1260
1351
|
*/
|
1261
1352
|
|
1262
1353
|
reportToServer : function(url) {
|
1354
|
+
if (any(hook('reportingToServer', url), haveStopped)) return
|
1263
1355
|
JSpec.post(url || 'http://localhost:4444', 'passes=' + JSpec.stats.passes + '&failures=' + JSpec.stats.failures)
|
1264
1356
|
if ('close' in main) main.close()
|
1265
1357
|
},
|
@@ -1297,6 +1389,7 @@
|
|
1297
1389
|
*/
|
1298
1390
|
|
1299
1391
|
load : function(file) {
|
1392
|
+
if (any(hook('loading', file), haveStopped)) return
|
1300
1393
|
if (this.hasXhr()) {
|
1301
1394
|
var request = this.xhr()
|
1302
1395
|
request.open('GET', file, false)
|
@@ -1318,6 +1411,7 @@
|
|
1318
1411
|
*/
|
1319
1412
|
|
1320
1413
|
exec : function(file) {
|
1414
|
+
if (any(hook('executing', file), haveStopped)) return this
|
1321
1415
|
eval('with (JSpec){' + this.preprocess(this.load(file)) + '}')
|
1322
1416
|
return this
|
1323
1417
|
}
|
@@ -1325,31 +1419,11 @@
|
|
1325
1419
|
|
1326
1420
|
// --- Utility functions
|
1327
1421
|
|
1328
|
-
var main
|
1329
|
-
var
|
1330
|
-
var
|
1331
|
-
|
1332
|
-
var
|
1333
|
-
var find = JSpec.any
|
1334
|
-
var last = JSpec.last
|
1335
|
-
var fail = JSpec.fail
|
1336
|
-
var range = JSpec.range
|
1337
|
-
var each = JSpec.each
|
1338
|
-
var option = JSpec.option
|
1339
|
-
var inject = JSpec.inject
|
1340
|
-
var select = JSpec.select
|
1341
|
-
var error = JSpec.error
|
1342
|
-
var escape = JSpec.escape
|
1343
|
-
var extend = JSpec.extend
|
1344
|
-
var puts = JSpec.puts
|
1345
|
-
var hash = JSpec.hash
|
1346
|
-
var query = JSpec.query
|
1347
|
-
var strip = JSpec.strip
|
1348
|
-
var color = JSpec.color
|
1349
|
-
var does = JSpec.does
|
1350
|
-
var addMatchers = JSpec.addMatchers
|
1351
|
-
var callIterator = JSpec.callIterator
|
1352
|
-
var argumentsToArray = JSpec.argumentsToArray
|
1422
|
+
var main = this
|
1423
|
+
var find = JSpec.any
|
1424
|
+
var utils = 'haveStopped stub hookImmutable hook destub map any last fail range each option inject select error escape \
|
1425
|
+
extend puts hash query strip color does addMatchers callIterator argumentsToArray'.split(/\s+/)
|
1426
|
+
while (utils.length) util = utils.shift(), eval('var ' + util + ' = JSpec.' + util)
|
1353
1427
|
if (!main.setTimeout) main.setTimeout = function(callback){ callback() }
|
1354
1428
|
|
1355
1429
|
// --- Matchers
|
data/spec/spec.jquery.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
describe 'jQuery'
|
3
|
-
describe 'sandbox'
|
3
|
+
describe 'sandbox()'
|
4
4
|
before
|
5
5
|
dom = sandbox()
|
6
6
|
end
|
@@ -11,6 +11,13 @@ describe 'jQuery'
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
describe 'element() / elements()'
|
15
|
+
it 'should alias jQuery'
|
16
|
+
element.should.be jQuery
|
17
|
+
elements.should.be jQuery
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
14
21
|
describe 'async'
|
15
22
|
it 'should load mah cookies (textfile)'
|
16
23
|
$.post('async', function(text){
|
data/spec/spec.utils.js
CHANGED
@@ -13,6 +13,14 @@ describe 'Utility'
|
|
13
13
|
object.stubby().should.eql 'Im stubbed'
|
14
14
|
object.toString().should.eql '<No im not>'
|
15
15
|
end
|
16
|
+
|
17
|
+
it 'should allow being called as a core prototype method'
|
18
|
+
foo = { bar : function(){ return 'baz' }}
|
19
|
+
foo.stub('bar').and_return('something else')
|
20
|
+
foo.bar().should.eql 'something else'
|
21
|
+
foo.destub()
|
22
|
+
foo.bar().should.eql 'baz'
|
23
|
+
end
|
16
24
|
end
|
17
25
|
|
18
26
|
describe 'destub()'
|
@@ -140,6 +148,14 @@ describe 'Utility'
|
|
140
148
|
})
|
141
149
|
result.should.eql 'some'
|
142
150
|
end
|
151
|
+
|
152
|
+
describe 'haveStopped'
|
153
|
+
it 'should check if "stop" has been returned by a callback hook'
|
154
|
+
any([true, 'stop'], haveStopped).should.eql 'stop'
|
155
|
+
any([true, true], haveStopped).should.be_null
|
156
|
+
any([true, null], haveStopped).should.be_null
|
157
|
+
end
|
158
|
+
end
|
143
159
|
end
|
144
160
|
|
145
161
|
describe 'select()'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: visionmedia-jspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TJ Holowaychuk
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-06-
|
12
|
+
date: 2009-06-30 00:00:00 -07:00
|
13
13
|
default_executable: jspec
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +22,16 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: 3.2.9
|
24
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: visionmedia-bind
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.2.6
|
34
|
+
version:
|
25
35
|
description: JavaScript BDD Testing Framework
|
26
36
|
email: tj@vision-media.ca
|
27
37
|
executables:
|