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 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.3.1'
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. You will need
62
- supply [path] if your specs do not reside in this location. `run --bind` is
63
- the default sub-command of jspec so you may simply execute `jspec` in order
64
- to bind execution of your specs when a file is altered.
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 to be
67
- spec/spec.js unless specified. See examples below for using the --rhino switch.'
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
- begin
83
- require 'bind'
84
- options.default :browsers => %w( Safari ), :paths => ['lib/**/*.js', 'spec/**/*.js']
85
-
86
- # Actions
87
- if options.rhino
88
- spec = args.shift || 'spec/spec.rhino.js'
89
- action = lambda { rhino spec }
90
- elsif options.server
91
- spec = args.shift || 'spec/spec.server.html'
92
- action = lambda { start_server options, spec }
93
- else
94
- spec = args.shift || 'spec/spec.dom.html'
95
- action = Bind::Actions::RefreshBrowsers.new spec, *options.browsers
96
- end
97
-
98
- # Binding
99
- if options.bind
100
- listener = Bind::Listener.new :paths => options.paths, :interval => 1, :actions => [action], :debug => $stdout
101
- listener.run!
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.3.1"
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-25}
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
- (function(){
5
-
6
- // --- Dependencies
7
-
8
- JSpec.requires('jQuery', 'when using jspec.jquery.js')
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
- JSpec.addMatchers({
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.3.1',
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
- each(other, function(property, value){
861
- object[property] = value
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
- return state ? state :
980
- callIterator(callback, key, value) ?
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(memo, key, value){
1073
+ return inject(object, [], function(selected, key, value){
997
1074
  if (callIterator(callback, key, value))
998
- memo.push(value)
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.formatter ?
1118
- new JSpec.options.formatter(JSpec, JSpec.options):
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) { error('JSpec depends on ' + dependency + ' ' + message) }
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 = this
1329
- var stub = JSpec.stub
1330
- var destub = JSpec.destub
1331
- var map = JSpec.map
1332
- var any = JSpec.any
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.3.1
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-25 00:00:00 -07:00
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: