visionmedia-jspec 2.4.3 → 2.5.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,17 @@
1
1
 
2
+ === 2.5.0 / 2009-07-03
3
+
4
+ * Added contrib in README (thanks to anyone who has helped)
5
+ * Added more shared behavior specs
6
+ * Added Module.DSLs support for extending / adding new DSLs (DSL exchange not yet fully implemented)
7
+ * Added spec to make sure methods like end() will not fail due to the grammar
8
+ * Changed; giving hook precedence to suite hooks (before_each, etc) over module hooks (beforeSuite, etc) ; (thanks mpd)
9
+ * Changed; calls to stub() without and_return() now simply stub an arbitrary method with no return value
10
+ * Changed JSpec.include(); now returns JSpec allowing chaining
11
+ * Fixed having "end" in descriptions which would be replaced with '});'
12
+ * Fixed negation of should.receive('foo') matcher
13
+ * Fixed shared behavior assertion count issue
14
+
2
15
  === 2.4.3 / 2009-07-02
3
16
 
4
17
  * Fixed matcher semicolon matcher issue when using the JSpec grammar
data/Manifest CHANGED
@@ -18,12 +18,14 @@ server/server.rb
18
18
  spec/async
19
19
  spec/env.js
20
20
  spec/jquery-1.3.1.js
21
+ spec/modules.js
21
22
  spec/spec.dom.html
22
23
  spec/spec.grammar-less.js
23
24
  spec/spec.grammar.js
24
25
  spec/spec.jquery.js
25
26
  spec/spec.js
26
27
  spec/spec.matchers.js
28
+ spec/spec.modules.js
27
29
  spec/spec.rhino.js
28
30
  spec/spec.server.html
29
31
  spec/spec.shared-behaviors.js
data/README.rdoc CHANGED
@@ -454,9 +454,13 @@ The following methods or properties are utilized by JSpec:
454
454
  - init : called to initialize a module
455
455
  - utilities : hash of utility functions merged with JSpec.defaultContext
456
456
  - matchers : hash of matchers merged with JSpec's core matchers via JSpec.addMatchers()
457
+ - DSLs : hash of DSL methods; for example DSLs.snake contains before_each, after_each, etc.
458
+ Where as DSLs.camel may contain beforeEach, afterEach, etc.
457
459
 
458
460
  Below is a list of hooks, descriptions, and valid return values which
459
- may simply be implemented as module methods.
461
+ may simply be implemented as module methods. beforeSuite, afterSuite, beforeSpec, and afterSpec have lower
462
+ precedence than before_each, after_each etc within the specs themselves, allowing them to override or undo
463
+ anything that has been done by a Module.
460
464
 
461
465
  - running(options) : started running JSpec with the options passed : returning 'stop' will halt running
462
466
  - loading(file) : loading a file : returning 'stop' will prevent loading
@@ -559,9 +563,6 @@ Run with:
559
563
  * Tabs may cause a parse error. To prevent this use 'soft tabs' (setting in your IDE/Editor)
560
564
  or use JSpec's grammar-less alternative (mentioned above).
561
565
 
562
- * The negation of the should_receive matcher is currently not available. (ex:
563
- foo.should.not.receive('toString()') will not work)
564
-
565
566
  == More Information
566
567
 
567
568
  * Featured article in JSMag: http://www.jsmag.com/main.issues.description/id=21/
@@ -569,6 +570,15 @@ Run with:
569
570
  * Get the TextMate bundle at https://github.com/visionmedia/jspec.tmbundle/tree
570
571
  * For more information consult the JSpec source code documentation or visit http://visionmedia.github.com/jspec
571
572
 
573
+ == Contributors
574
+
575
+ Many ideas and bug reports were contributed by
576
+ the following developers, thankyou for making
577
+ JSpec more enjoyable, and bug free ;)
578
+
579
+ * mpd@jesters-court.ne
580
+ * kevin.gisi@gmail.com
581
+
572
582
  == License
573
583
 
574
584
  (The MIT License)
data/bin/jspec CHANGED
@@ -11,7 +11,7 @@ require 'fileutils'
11
11
  RHINO = 'java org.mozilla.javascript.tools.shell.Main'
12
12
 
13
13
  program :name, 'JSpec'
14
- program :version, '2.4.3'
14
+ program :version, '2.5.0'
15
15
  program :description, 'JavaScript BDD Testing Framework'
16
16
  default_command :bind
17
17
 
data/jspec.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{jspec}
5
- s.version = "2.4.3"
5
+ s.version = "2.5.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-07-02}
9
+ s.date = %q{2009-07-03}
10
10
  s.default_executable = %q{jspec}
11
11
  s.description = %q{JavaScript BDD Testing Framework}
12
12
  s.email = %q{tj@vision-media.ca}
13
13
  s.executables = ["jspec"]
14
14
  s.extra_rdoc_files = ["bin/jspec", "lib/images/bg.png", "lib/images/hr.png", "lib/images/loading.gif", "lib/images/sprites.bg.png", "lib/images/sprites.png", "lib/images/vr.png", "lib/jspec.css", "lib/jspec.jquery.js", "lib/jspec.js", "README.rdoc"]
15
- s.files = ["bin/jspec", "History.rdoc", "jspec.gemspec", "lib/images/bg.png", "lib/images/hr.png", "lib/images/loading.gif", "lib/images/sprites.bg.png", "lib/images/sprites.png", "lib/images/vr.png", "lib/jspec.css", "lib/jspec.jquery.js", "lib/jspec.js", "Manifest", "Rakefile", "README.rdoc", "server/browsers.rb", "server/server.rb", "spec/async", "spec/env.js", "spec/jquery-1.3.1.js", "spec/spec.dom.html", "spec/spec.grammar-less.js", "spec/spec.grammar.js", "spec/spec.jquery.js", "spec/spec.js", "spec/spec.matchers.js", "spec/spec.rhino.js", "spec/spec.server.html", "spec/spec.shared-behaviors.js", "spec/spec.utils.js", "templates/default/History.rdoc", "templates/default/lib/yourlib.core.js", "templates/default/README.rdoc", "templates/default/spec/spec.core.js", "templates/default/spec/spec.dom.html", "templates/default/spec/spec.rhino.js", "templates/default/spec/spec.server.html"]
15
+ s.files = ["bin/jspec", "History.rdoc", "jspec.gemspec", "lib/images/bg.png", "lib/images/hr.png", "lib/images/loading.gif", "lib/images/sprites.bg.png", "lib/images/sprites.png", "lib/images/vr.png", "lib/jspec.css", "lib/jspec.jquery.js", "lib/jspec.js", "Manifest", "Rakefile", "README.rdoc", "server/browsers.rb", "server/server.rb", "spec/async", "spec/env.js", "spec/jquery-1.3.1.js", "spec/modules.js", "spec/spec.dom.html", "spec/spec.grammar-less.js", "spec/spec.grammar.js", "spec/spec.jquery.js", "spec/spec.js", "spec/spec.matchers.js", "spec/spec.modules.js", "spec/spec.rhino.js", "spec/spec.server.html", "spec/spec.shared-behaviors.js", "spec/spec.utils.js", "templates/default/History.rdoc", "templates/default/lib/yourlib.core.js", "templates/default/README.rdoc", "templates/default/spec/spec.core.js", "templates/default/spec/spec.dom.html", "templates/default/spec/spec.rhino.js", "templates/default/spec/spec.server.html"]
16
16
  s.homepage = %q{http://visionmedia.github.com/jspec}
17
17
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Jspec", "--main", "README.rdoc"]
18
18
  s.require_paths = ["lib"]
data/lib/jspec.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  JSpec = {
7
7
 
8
- version : '2.4.3',
8
+ version : '2.5.0',
9
9
  suites : [],
10
10
  modules : [],
11
11
  allSuites : [],
@@ -224,7 +224,7 @@
224
224
  })
225
225
  },
226
226
 
227
- ProxyAssertion : function(object, method, times) {
227
+ ProxyAssertion : function(object, method, times, negate) {
228
228
  var self = this
229
229
  var old = object[method]
230
230
 
@@ -244,13 +244,12 @@
244
244
  'twice' : 2
245
245
  }[times] || times || 1
246
246
 
247
- // TODO: negation
248
-
249
247
  extend(this, {
250
248
  calls : [],
251
249
  message : '',
252
250
  defer : true,
253
251
  passed : false,
252
+ negate : negate,
254
253
  object : object,
255
254
  method : method,
256
255
 
@@ -277,6 +276,18 @@
277
276
  hash(self.expectedResult) != hash(call.result)
278
277
  })
279
278
  },
279
+
280
+ anyResultsPass : function() {
281
+ return any(this.calls, function(call){
282
+ return self.expectedResult.an_instance_of ?
283
+ call.result.constructor == self.expectedResult.an_instance_of:
284
+ hash(self.expectedResult) == hash(call.result)
285
+ })
286
+ },
287
+
288
+ passingResult : function() {
289
+ return this.anyResultsPass().result
290
+ },
280
291
 
281
292
  // Return the failing result
282
293
 
@@ -297,6 +308,21 @@
297
308
  })
298
309
  },
299
310
 
311
+ anyArgsPass : function() {
312
+ return any(this.calls, function(call){
313
+ return any(self.expectedArgs, function(i, arg){
314
+ return arg.an_instance_of ?
315
+ call.args[i].constructor == arg.an_instance_of:
316
+ hash(arg) == hash(call.args[i])
317
+
318
+ })
319
+ })
320
+ },
321
+
322
+ passingArgs : function() {
323
+ return this.anyArgsPass().args
324
+ },
325
+
300
326
  // Return the failing args
301
327
 
302
328
  failingArgs : function() {
@@ -313,23 +339,23 @@
313
339
  // Run the assertion
314
340
 
315
341
  run : function() {
316
- var methodString = 'expected ' + object.toString() + '.' + method + '()'
342
+ var methodString = 'expected ' + object.toString() + '.' + method + '()' + (negate ? ' not' : '' )
317
343
 
318
344
  function times(n) {
319
345
  return n > 2 ? n + ' times' : { 1 : 'once', 2 : 'twice' }[n]
320
346
  }
321
347
 
322
- if (this.calls.length < this.times)
323
- this.message = methodString + ' to be called ' + times(this.times) +
324
- ', but ' + (this.calls.length == 0 ? ' was not called' : ' was called ' + times(this.calls.length))
325
-
326
- if (this.expectedResult && this.anyResultsFail())
348
+ if (this.expectedResult && (negate ? this.anyResultsPass() : this.anyResultsFail()))
327
349
  this.message = methodString + ' to return ' + puts(this.expectedResult) +
328
- ' but got ' + puts(this.failingResult())
329
-
330
- if (this.expectedArgs && this.anyArgsFail())
350
+ ' but ' + (negate ? 'it did' : 'got ' + puts(this.failingResult()))
351
+
352
+ if (this.expectedArgs && (negate ? !this.expectedResult && this.anyArgsPass() : this.anyArgsFail()))
331
353
  this.message = methodString + ' to be called with ' + puts.apply(this, this.expectedArgs) +
332
- ' but was called with ' + puts.apply(this, this.failingArgs())
354
+ ' but was' + (negate ? '' : ' called with ' + puts.apply(this, this.failingArgs()))
355
+
356
+ if (negate ? !this.expectedResult && !this.expectedArgs && this.calls.length == this.times : this.calls.length != this.times)
357
+ this.message = methodString + ' to be called ' + times(this.times) +
358
+ ', but ' + (this.calls.length == 0 ? ' was not called' : ' was called ' + times(this.calls.length))
333
359
 
334
360
  if (!this.message.length)
335
361
  this.passed = true
@@ -552,6 +578,7 @@
552
578
  * Include _object_ which may be a hash or Module instance.
553
579
  *
554
580
  * @param {has, Module} object
581
+ * @return {JSpec}
555
582
  * @api public
556
583
  */
557
584
 
@@ -561,6 +588,12 @@
561
588
  if ('init' in module) module.init()
562
589
  if ('utilities' in module) extend(this.defaultContext, module.utilities)
563
590
  if ('matchers' in module) this.addMatchers(module.matchers)
591
+ if ('DSLs' in module)
592
+ each(module.DSLs, function(name, methods){
593
+ JSpec.DSLs[name] = JSpec.DSLs[name] || {}
594
+ extend(JSpec.DSLs[name], methods)
595
+ })
596
+ return this
564
597
  },
565
598
 
566
599
  /**
@@ -578,7 +611,7 @@
578
611
  args = argumentsToArray(arguments, 1)
579
612
  return inject(JSpec.modules, [], function(results, module){
580
613
  if (typeof module[name] == 'function')
581
- results.push(module[name].apply(module, args))
614
+ results.push(module[name].apply(this, args))
582
615
  })
583
616
  },
584
617
 
@@ -597,7 +630,7 @@
597
630
  hookImmutable : function(name, arg) {
598
631
  return inject(JSpec.modules, arg, function(result, module){
599
632
  if (typeof module[name] == 'function')
600
- return module[name].call(module, result)
633
+ return module[name].call(this, result)
601
634
  })
602
635
  },
603
636
 
@@ -638,6 +671,7 @@
638
671
 
639
672
  copySpecs : function(fromSuite, toSuite) {
640
673
  each(fromSuite.specs, function(spec){
674
+ spec.assertions = []
641
675
  toSuite.specs.push(spec)
642
676
  })
643
677
  },
@@ -885,7 +919,8 @@
885
919
 
886
920
  expect : function(actual) {
887
921
  assert = function(matcher, args, negate) {
888
- var expected = argumentsToArray(args, 1)
922
+ var expected = argumentsToArray(args, 1)
923
+ matcher.negate = negate
889
924
  assertion = new JSpec.Assertion(matcher, actual, expected, negate)
890
925
  hook('beforeAssertion', assertion)
891
926
  if (matcher.defer) assertion.run()
@@ -1031,12 +1066,13 @@
1031
1066
  */
1032
1067
 
1033
1068
  stub : function(object, method) {
1069
+ hook('stubbing', object, method)
1070
+ JSpec.stubbed.push(object)
1071
+ var type = object.hasOwnProperty(method) ? '__original__' : '__prototype__'
1072
+ object[type + method] = object[method]
1073
+ object[method] = function(){}
1034
1074
  return {
1035
1075
  and_return : function(result) {
1036
- hook('stubbing', object, method, result)
1037
- JSpec.stubbed.push(object)
1038
- var type = object.hasOwnProperty(method) ? '__original__' : '__prototype__'
1039
- object[type + method] = object[method]
1040
1076
  object[method] = function(){ return result }
1041
1077
  }
1042
1078
  }
@@ -1185,7 +1221,7 @@
1185
1221
  replace(/describe\s+(.*?)$/gm, 'describe($1, function(){').
1186
1222
  replace(/\sit\s+(.*?)$/gm, ' it($1, function(){').
1187
1223
  replace(/^(?: *)(before_each|after_each|before|after)(?= |\n|$)/gm, 'JSpec.currentSuite.addHook("$1", function(){').
1188
- replace(/end(?=\s|$)/gm, '});').
1224
+ replace(/\bend(?=\s|$)/gm, '});').
1189
1225
  replace(/-\{/g, 'function(){').
1190
1226
  replace(/(\d+)\.\.(\d+)/g, function(_, a, b){ return range(a, b) }).
1191
1227
  replace(/\.should([_\.]not)?[_\.](\w+)(?: |;|$)(.*)$/gm, '.should$1_$2($3)').
@@ -1250,10 +1286,12 @@
1250
1286
  this.currentSuite = suite
1251
1287
  this.evalBody(suite.body)
1252
1288
  suite.ran = true
1253
- suite.hook('before'), hook('beforeSuite', suite)
1289
+ hook('beforeSuite', suite), suite.hook('before')
1254
1290
  each(suite.specs, function(spec) {
1291
+ hook('beforeSpec', spec)
1255
1292
  suite.hook('before_each')
1256
1293
  JSpec.runSpec(spec)
1294
+ hook('afterSpec', spec)
1257
1295
  suite.hook('after_each')
1258
1296
  })
1259
1297
  if (suite.hasSuites()) {
@@ -1261,7 +1299,7 @@
1261
1299
  JSpec.runSuite(suite)
1262
1300
  })
1263
1301
  }
1264
- suite.hook('after'), hook('afterSuite', suite)
1302
+ hook('afterSuite', suite), suite.hook('after')
1265
1303
  this.stats.suitesFinished++
1266
1304
  },
1267
1305
 
@@ -1298,12 +1336,10 @@
1298
1336
  runSpec : function(spec) {
1299
1337
  this.currentSpec = spec
1300
1338
  if (option('profile')) console.time(spec.description)
1301
- hook('beforeSpec', spec)
1302
1339
  try { this.evalBody(spec.body) }
1303
1340
  catch (e) { fail(e) }
1304
- spec.runDeferredAssertions()
1305
- hook('afterSpec', spec)
1306
1341
  if (option('profile')) console.timeEnd(spec.description)
1342
+ spec.runDeferredAssertions()
1307
1343
  destub()
1308
1344
  this.stats.specsFinished++
1309
1345
  this.stats.assertions += spec.assertions.length
@@ -1483,7 +1519,7 @@
1483
1519
  },
1484
1520
 
1485
1521
  receive : { defer : true, match : function(actual, method, times) {
1486
- proxy = new JSpec.ProxyAssertion(actual, method, times)
1522
+ proxy = new JSpec.ProxyAssertion(actual, method, times, this.negate)
1487
1523
  JSpec.currentSpec.assertions.push(proxy)
1488
1524
  return proxy
1489
1525
  }},
data/spec/modules.js ADDED
@@ -0,0 +1,36 @@
1
+
2
+ ExampleModule = {
3
+ utilities : {
4
+ doFoo : function(){ return 'foo' },
5
+ doBar : function(){ return 'bar' }
6
+ },
7
+ randomHook : function(a, b) {
8
+ return [a, b]
9
+ },
10
+ beforeSpec : function() { addedBeforeSpec = true, addedBeforeSpecHook = false },
11
+ afterSpec : function() { addedAfterSpec = true, addedAfterSpecHook = false },
12
+ beforeSuite : function() { addedBeforeSuite = true },
13
+ afterSuite : function() {
14
+ addedAfterSuite = true
15
+ addedBeforeSuite = addedBeforeSpec = addedAfterSpec = false
16
+ },
17
+ matchers : {
18
+ be_foo_bar : function() {
19
+ return true
20
+ }
21
+ },
22
+ DSLs : {
23
+ snake : {
24
+ some_snake_case_stuff : function(){
25
+ return true
26
+ }
27
+ },
28
+ camel : {
29
+ someCamelCaseStuff : function() {
30
+ return true
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ JSpec.include(ExampleModule)
data/spec/spec.dom.html CHANGED
@@ -4,16 +4,18 @@
4
4
  <script src="jquery-1.3.1.js"></script>
5
5
  <script src="../lib/jspec.js"></script>
6
6
  <script src="../lib/jspec.jquery.js"></script>
7
+ <script src="modules.js"></script>
7
8
  <script src="spec.grammar-less.js"></script>
8
9
  <script>
9
10
  function runSuites() {
10
11
  JSpec
11
- .exec('spec.grammar.js')
12
- .exec('spec.js')
13
- .exec('spec.matchers.js')
14
- .exec('spec.utils.js')
15
- .exec('spec.shared-behaviors.js')
16
- .exec('spec.jquery.js')
12
+ .exec('spec.grammar.js')
13
+ .exec('spec.js')
14
+ .exec('spec.matchers.js')
15
+ .exec('spec.utils.js')
16
+ .exec('spec.shared-behaviors.js')
17
+ .exec('spec.jquery.js')
18
+ .exec('spec.modules.js')
17
19
  .run()
18
20
  .report()
19
21
  }
data/spec/spec.grammar.js CHANGED
@@ -16,6 +16,10 @@ describe 'Grammar'
16
16
  true.should.be_true()
17
17
  end
18
18
 
19
+ it 'should not mess up with words like it or append in descriptions'
20
+ -{ element.append().end() }.should.throw_error
21
+ end
22
+
19
23
  it 'should allow semicolons'
20
24
  true.should.be_true;
21
25
  true.should.be_true();
data/spec/spec.js CHANGED
@@ -2,7 +2,7 @@
2
2
  describe 'Negative specs'
3
3
 
4
4
  it 'should fail'
5
- 'test'.should.not_eql 'test'
5
+ 'test'.should.not_eql 'test'
6
6
  end
7
7
 
8
8
  it 'should fail with one faulty assertion'
@@ -286,15 +286,6 @@ describe 'Matchers'
286
286
  addPets : function(a, b) { return ['izzy', a, b] }
287
287
  }
288
288
  end
289
-
290
- it 'should fail when the method does not exist'
291
- person.should.receive('getPets')
292
- end
293
-
294
- it 'should fail when the method is never invoked'
295
- personWithPets.should.receive('getPets')
296
- end
297
-
298
289
  it 'should pass when the method is invoked'
299
290
  personWithPets.should.receive('getPets')
300
291
  personWithPets.getPets()
@@ -310,11 +301,79 @@ describe 'Matchers'
310
301
  personWithPets.getPets()
311
302
  end
312
303
 
304
+ it 'should pass when invoked the expected number of times'
305
+ personWithPets.should.receive('getPets', 'twice').and_return(['izzy'])
306
+ personWithPets.getPets()
307
+ personWithPets.getPets()
308
+ end
309
+
310
+ it 'should pass when a method is invoked with specific arguments'
311
+ personWithPets.should.receive('addPet', 'once').with_args('suki')
312
+ personWithPets.addPet('suki')
313
+ end
314
+
315
+ it 'should pass with multiple arguments'
316
+ personWithPets.should.receive('addPets').with_args('suki', 'max')
317
+ personWithPets.addPets('suki', 'max')
318
+ end
319
+
320
+ it 'should pass with arguments and return value'
321
+ personWithPets.should.receive('addPet').with_args('suki').and_return(['izzy', 'suki'])
322
+ personWithPets.addPet('suki')
323
+ end
324
+
325
+ it 'should pass when argument is the correct type'
326
+ personWithPets.should.receive('addPet').with_args(an_instance_of(String))
327
+ personWithPets.addPet('suki')
328
+ end
329
+
330
+ it 'should pass when return type is correct'
331
+ personWithPets.should.receive('addPet').and_return(an_instance_of(Array))
332
+ personWithPets.addPet('suki')
333
+ end
334
+
335
+ it 'should pass when checking the type of multiple args and return types'
336
+ personWithPets.should.receive('addPets').with_args(an_instance_of(String), an_instance_of(String)).and_return(an_instance_of(Array))
337
+ personWithPets.addPets('suki', 'max')
338
+ end
339
+
340
+ it 'should pass with negation when a method is not called'
341
+ personWithPets.should.not.receive('addPets')
342
+ end
343
+
344
+ it 'should pass with negation with args'
345
+ personWithPets.should.not.receive('addPets').with_args('izzy')
346
+ personWithPets.addPets('max')
347
+ end
348
+
349
+ it 'should pass with negation with return values'
350
+ personWithPets.should.not.receive('addPets').with_args('izzy').and_return('test')
351
+ personWithPets.addPets('izzy')
352
+ end
353
+
354
+ it 'should pass with negation with times'
355
+ personWithPets.should.not.receive('addPets', 'twice')
356
+ personWithPets.addPets('izzy')
357
+ end
358
+
359
+ it 'should fail when the method does not exist'
360
+ person.should.receive('getPets')
361
+ end
362
+
363
+ it 'should fail when the method is never invoked'
364
+ personWithPets.should.receive('getPets')
365
+ end
366
+
313
367
  it 'should fail when improper value is returned'
314
368
  personWithPets.should.receive('getPets').and_return(['niko'])
315
369
  personWithPets.getPets()
316
370
  end
317
371
 
372
+ it 'should fail when checking the type of multiple args and return types'
373
+ personWithPets.should.receive('addPets').with_args(an_instance_of(String), an_instance_of(Array)).and_return(an_instance_of(Array))
374
+ personWithPets.addPets('suki', 'max')
375
+ end
376
+
318
377
  it 'should fail when not invoked the expected number of times'
319
378
  personWithPets.should.receive('getPets', 'twice').and_return(['izzy'])
320
379
  personWithPets.getPets()
@@ -326,71 +385,45 @@ describe 'Matchers'
326
385
  personWithPets.getPets()
327
386
  end
328
387
 
329
- it 'should pass when invoked the expected number of times'
330
- personWithPets.should.receive('getPets', 'twice').and_return(['izzy'])
331
- personWithPets.getPets()
332
- personWithPets.getPets()
333
- end
334
-
335
388
  it 'should fail when not invoked with specific arguments'
336
389
  personWithPets.should.receive('addPet', 'once').with_args('suki')
337
390
  personWithPets.addPet('niko')
338
391
  end
339
392
 
340
- it 'should pass when a method is invoked with specific arguments'
341
- personWithPets.should.receive('addPet', 'once').with_args('suki')
342
- personWithPets.addPet('suki')
343
- end
344
-
345
393
  it 'should fail when expecting multiple arguments'
346
394
  personWithPets.should.receive('addPets').with_args('suki', 'max')
347
395
  personWithPets.addPets('suki')
348
396
  end
349
397
 
350
- it 'should pass with multiple arguments'
351
- personWithPets.should.receive('addPets').with_args('suki', 'max')
352
- personWithPets.addPets('suki', 'max')
353
- end
354
-
355
- it 'should pass with arguments and return value'
356
- personWithPets.should.receive('addPet').with_args('suki').and_return(['izzy', 'suki'])
357
- personWithPets.addPet('suki')
358
- end
359
-
360
398
  it 'should fail when argument is of the wrong type'
361
399
  personWithPets.should.receive('addPet').with_args(an_instance_of(String))
362
400
  personWithPets.addPet(['suki'])
363
401
  end
364
402
 
365
- it 'should pass when argument is the correct type'
366
- personWithPets.should.receive('addPet').with_args(an_instance_of(String))
367
- personWithPets.addPet('suki')
368
- end
369
-
370
403
  it 'should fail when return type is incorrect'
371
404
  personWithPets.should.receive('addPet').and_return(an_instance_of(String))
372
405
  personWithPets.addPet('suki')
373
406
  end
374
407
 
375
- it 'should pass when return type is correct'
376
- personWithPets.should.receive('addPet').and_return(an_instance_of(Array))
377
- personWithPets.addPet('suki')
408
+ it 'should fail with negation when a method is called'
409
+ personWithPets.should.not.receive('addPets')
410
+ personWithPets.addPets('izzy')
378
411
  end
379
-
380
- it 'should fail when checking the type of multiple args and return types'
381
- personWithPets.should.receive('addPets').with_args(an_instance_of(String), an_instance_of(Array)).and_return(an_instance_of(Array))
382
- personWithPets.addPets('suki', 'max')
412
+
413
+ it 'should fail with negation with args'
414
+ personWithPets.should.not.receive('addPets').with_args('izzy')
415
+ personWithPets.addPets('izzy')
383
416
  end
384
-
385
- it 'should pass when checking the type of multiple args and return types'
386
- personWithPets.should.receive('addPets').with_args(an_instance_of(String), an_instance_of(String)).and_return(an_instance_of(Array))
387
- personWithPets.addPets('suki', 'max')
417
+
418
+ it 'should fail with negation with return values'
419
+ personWithPets.should.not.receive('addPets').with_args('izzy').and_return(an_instance_of(Array))
420
+ personWithPets.addPets('izzy')
388
421
  end
389
422
 
390
- it 'should pass when checking for method calls to core prototypes'
391
- array = ['foo', 'bar']
392
- array.should.receive('toString').and_return('foo,bar')
393
- 'array: ' + array
423
+ it 'should fail with negation with times'
424
+ personWithPets.should.not.receive('addPets', 'twice')
425
+ personWithPets.addPets('izzy')
426
+ personWithPets.addPets('max')
394
427
  end
395
428
  end
396
429
 
@@ -0,0 +1,70 @@
1
+
2
+ describe 'JSpec'
3
+ describe 'module'
4
+ describe 'hooks'
5
+ before_each
6
+ addedBeforeSpecHook = true
7
+ end
8
+
9
+ after_each
10
+ addedAfterSpecHook = true
11
+ end
12
+
13
+ it 'should run in context with beforeSpec'
14
+ addedBeforeSpec.should.be_true
15
+ addedAfterSpec.should.be_false
16
+ addedAfterSpecHook.should.be_false
17
+ end
18
+
19
+ it 'should run beforeSpec BEFORE the before_each blocks'
20
+ addedBeforeSpecHook.should.be_true
21
+ end
22
+
23
+ it 'should run in context with afterSpec'
24
+ addedBeforeSpec.should.be_true
25
+ addedAfterSpec.should.be_true
26
+ end
27
+
28
+ it 'should run afterSpec BEFORE after_each blocks'
29
+ addedAfterSpecHook.should.be_true
30
+ end
31
+
32
+ it 'should run in context with beforeSuite'
33
+ addedBeforeSuite.should.be_true
34
+ end
35
+
36
+ describe 'another suite'
37
+ it 'should run in context with afterSuite'
38
+ addedAfterSuite.should.be_true
39
+ end
40
+ end
41
+ end
42
+
43
+ describe '.hook()'
44
+ it 'should invoke hooks, returning an array of results'
45
+ results = hook('randomHook', 'foo', 'bar')
46
+ results.should.eql [['foo', 'bar']]
47
+ end
48
+ end
49
+
50
+ describe '.utilities'
51
+ it 'should be merged with the default utilities'
52
+ doFoo().should.eql 'foo'
53
+ doBar().should.eql 'bar'
54
+ end
55
+ end
56
+
57
+ describe '.matchers'
58
+ it 'should be merged with default matchers'
59
+ 'test'.should.be_foo_bar
60
+ end
61
+ end
62
+
63
+ describe '.DSLs'
64
+ it 'should be merged with default DSLs'
65
+ JSpec.DSLs.snake.some_snake_case_stuff().should.be_true
66
+ JSpec.DSLs.camel.someCamelCaseStuff().should.be_true
67
+ end
68
+ end
69
+ end
70
+ end
data/spec/spec.rhino.js CHANGED
@@ -1,5 +1,6 @@
1
1
 
2
2
  load('lib/jspec.js')
3
+ load('spec/modules.js')
3
4
  load('spec/spec.grammar-less.js')
4
5
 
5
6
  JSpec
@@ -8,5 +9,6 @@ JSpec
8
9
  .exec('spec/spec.matchers.js')
9
10
  .exec('spec/spec.utils.js')
10
11
  .exec('spec/spec.shared-behaviors.js')
12
+ .exec('spec/spec.modules.js')
11
13
  .run({ formatter : JSpec.formatters.Terminal, failuresOnly : true })
12
14
  .report()
@@ -3,6 +3,7 @@
3
3
  <script src="jquery-1.3.1.js"></script>
4
4
  <script src="jspec.js"></script>
5
5
  <script src="jspec.jquery.js"></script>
6
+ <script src="modules.js"></script>
6
7
  <script src="spec.grammar-less.js"></script>
7
8
  <script>
8
9
  function runSuites() {
@@ -13,6 +14,7 @@
13
14
  .exec('spec.utils.js')
14
15
  .exec('spec.shared-behaviors.js')
15
16
  .exec('spec.jquery.js')
17
+ .exec('spec.modules.js')
16
18
  .run()
17
19
  .reportToServer()
18
20
  }
@@ -21,6 +21,7 @@ describe 'Shared Behaviors'
21
21
 
22
22
  it 'should have access to all permissions'
23
23
  user.may('edit pages').should.be_true
24
+ user.may('delete users').should.be_true
24
25
  end
25
26
 
26
27
  describe 'Super Administrator'
@@ -34,7 +35,35 @@ describe 'Shared Behaviors'
34
35
  end
35
36
  end
36
37
  end
37
-
38
+
39
+ describe 'User with toString()'
40
+ before
41
+ user = { toString : function() { return '<User tj>' }}
42
+ end
43
+
44
+ it 'should return &lt;User NAME&gt;'
45
+ user.toString().should.match(/\<User/)
46
+ end
47
+ end
48
+
49
+ describe 'Manager'
50
+ should_behave_like('User')
51
+ should_behave_like('User with toString()')
52
+
53
+ before
54
+ Manager = function(name) { this.name = name }
55
+ Manager.prototype.may = function(perm){ return perm == 'hire' || perm == 'fire' }
56
+ Manager.prototype.toString = function(){ return '<User ' + this.name + '>' }
57
+ user = new Manager('tj')
58
+ end
59
+
60
+ it 'should have access to hire or fire employees'
61
+ user.may('hire').should.be_true
62
+ user.may('fire').should.be_true
63
+ user.may('do anything else').should.be_false
64
+ end
65
+ end
66
+
38
67
  describe 'findSuite'
39
68
  it 'should find a suite by full description'
40
69
  JSpec.findSuite('Shared Behaviors User Administrator').should.be_a JSpec.Suite
data/spec/spec.utils.js CHANGED
@@ -38,6 +38,29 @@ describe 'Utility'
38
38
  foo.destub()
39
39
  foo.bar().should.eql 'baz'
40
40
  end
41
+
42
+ it 'should stub methods starting with an underscore'
43
+ object._foo = function(){ return 'bar' }
44
+ object.stub('_foo').and_return('something else')
45
+ object._foo().should.eql 'something else'
46
+ object.destub()
47
+ object._foo().should.eql 'bar'
48
+ end
49
+
50
+ it 'should stub methods with whitespace'
51
+ object['foo bar'] = function(){ return 'rawr' }
52
+ object.stub('foo bar').and_return('baz')
53
+ object['foo bar']().should.eql 'baz'
54
+ object.destub()
55
+ object['foo bar']().should.eql 'rawr'
56
+ end
57
+
58
+ it 'should stub with arbitrary method when no return value is set'
59
+ object.stub(' super cool ')
60
+ object[' super cool '].should.be_a Function
61
+ destub(object)
62
+ object[' super cool '].should.be_null
63
+ end
41
64
  end
42
65
 
43
66
  describe 'destub()'
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.3
4
+ version: 2.5.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-07-02 00:00:00 -07:00
12
+ date: 2009-07-03 00:00:00 -07:00
13
13
  default_executable: jspec
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -71,12 +71,14 @@ files:
71
71
  - spec/async
72
72
  - spec/env.js
73
73
  - spec/jquery-1.3.1.js
74
+ - spec/modules.js
74
75
  - spec/spec.dom.html
75
76
  - spec/spec.grammar-less.js
76
77
  - spec/spec.grammar.js
77
78
  - spec/spec.jquery.js
78
79
  - spec/spec.js
79
80
  - spec/spec.matchers.js
81
+ - spec/spec.modules.js
80
82
  - spec/spec.rhino.js
81
83
  - spec/spec.server.html
82
84
  - spec/spec.shared-behaviors.js