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 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: