visionmedia-jspec 2.4.3 → 2.5.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,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