visionmedia-jspec 2.3.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.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:
|