set_builder 2.0.0.beta2 → 2.0.0.beta3

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -6
  3. data/Rakefile +2 -2
  4. data/init.rb +1 -1
  5. data/lib/assets/javascripts/set_builder.js +122 -125
  6. data/lib/set_builder/constraint.rb +66 -50
  7. data/lib/set_builder/errors/trait_not_found.rb +3 -0
  8. data/lib/set_builder/modifier/adverb.rb +4 -4
  9. data/lib/set_builder/modifier/base.rb +74 -67
  10. data/lib/set_builder/modifier/verb.rb +1 -16
  11. data/lib/set_builder/modifier.rb +49 -49
  12. data/lib/set_builder/modifier_collection.rb +16 -16
  13. data/lib/set_builder/modifiers/date_preposition.rb +6 -48
  14. data/lib/set_builder/modifiers/number_preposition.rb +4 -25
  15. data/lib/set_builder/modifiers/string_preposition.rb +9 -43
  16. data/lib/set_builder/modifiers.rb +3 -3
  17. data/lib/set_builder/set.rb +48 -8
  18. data/lib/set_builder/trait.rb +75 -49
  19. data/lib/set_builder/traits.rb +13 -4
  20. data/lib/set_builder/value_map.rb +30 -30
  21. data/lib/set_builder/version.rb +1 -1
  22. data/lib/set_builder.rb +8 -7
  23. data/set_builder.gemspec +4 -2
  24. data/spec/commands/example_command.rb +2 -2
  25. data/spec/lib/jspec.css +4 -4
  26. data/spec/lib/jspec.growl.js +11 -11
  27. data/spec/lib/jspec.jquery.js +14 -14
  28. data/spec/lib/jspec.js +210 -210
  29. data/spec/lib/jspec.nodejs.js +2 -2
  30. data/spec/lib/jspec.shell.js +11 -11
  31. data/spec/lib/jspec.timers.js +23 -23
  32. data/spec/rhino.js +1 -1
  33. data/spec/server.rb +1 -1
  34. data/spec/unit/array.spec.js +9 -9
  35. data/spec/unit/set_builder.spec.js +71 -82
  36. data/spec/unit/spec.helper.js +1 -0
  37. data/test/constraint_test.rb +84 -0
  38. data/test/date_preposition_test.rb +17 -7
  39. data/test/modifier_test.rb +26 -1
  40. data/test/set_test.rb +51 -28
  41. data/test/string_preposition_test.rb +10 -9
  42. data/test/test_helper.rb +17 -15
  43. data/test/trait_test.rb +49 -30
  44. data/test/traits_test.rb +35 -30
  45. data/test/value_map_test.rb +1 -1
  46. metadata +37 -15
  47. data/lib/set_builder/query_builders/string.rb +0 -0
  48. data/test/inflector_test.rb +0 -27
data/spec/lib/jspec.js CHANGED
@@ -35,9 +35,9 @@
35
35
  */
36
36
 
37
37
  defaultContext : {
38
-
38
+
39
39
  /**
40
- * Return an object used for proxy assertions.
40
+ * Return an object used for proxy assertions.
41
41
  * This object is used to indicate that an object
42
42
  * should be an instance of _object_, not the constructor
43
43
  * itself.
@@ -46,11 +46,11 @@
46
46
  * @return {hash}
47
47
  * @api public
48
48
  */
49
-
49
+
50
50
  an_instance_of : function(constructor) {
51
51
  return { an_instance_of : constructor }
52
52
  },
53
-
53
+
54
54
  /**
55
55
  * Load fixture at _path_.
56
56
  *
@@ -63,14 +63,14 @@
63
63
  * @return {string}
64
64
  * @api public
65
65
  */
66
-
66
+
67
67
  fixture : function(path) {
68
68
  if (JSpec.cache[path]) return JSpec.cache[path]
69
- return JSpec.cache[path] =
69
+ return JSpec.cache[path] =
70
70
  JSpec.tryLoading(JSpec.options.fixturePath + '/' + path) ||
71
71
  JSpec.tryLoading(JSpec.options.fixturePath + '/' + path + '.html')
72
72
  },
73
-
73
+
74
74
  /**
75
75
  * Load json fixture at _path_.
76
76
  *
@@ -83,7 +83,7 @@
83
83
  * @return {object}
84
84
  * @api public
85
85
  */
86
-
86
+
87
87
  json_fixture: function(path) {
88
88
  if (!JSpec.cache['json:' + path])
89
89
  JSpec.cache['json:' + path] =
@@ -98,12 +98,12 @@
98
98
  },
99
99
 
100
100
  // --- Objects
101
-
101
+
102
102
  reporters : {
103
-
103
+
104
104
  /**
105
105
  * Report to server.
106
- *
106
+ *
107
107
  * Options:
108
108
  * - uri specific uri to report to.
109
109
  * - verbose weither or not to output messages
@@ -111,7 +111,7 @@
111
111
  *
112
112
  * @api public
113
113
  */
114
-
114
+
115
115
  Server : function(results, options) {
116
116
  var uri = options.uri || 'http://' + window.location.host + '/results'
117
117
  JSpec.post(uri, {
@@ -130,7 +130,7 @@
130
130
  'fail',
131
131
  assertions: map(spec.assertions, function(assertion){
132
132
  return {
133
- passed: assertion.passed
133
+ passed: assertion.passed
134
134
  }
135
135
  })
136
136
  }
@@ -157,14 +157,14 @@
157
157
  failuresOnly = option('failuresOnly'),
158
158
  classes = results.stats.failures ? 'has-failures' : ''
159
159
  if (!report) throw 'JSpec requires the element #' + id + ' to output its reports'
160
-
160
+
161
161
  function bodyContents(body) {
162
162
  return JSpec.
163
163
  escape(JSpec.contentsOf(body)).
164
164
  replace(/^ */gm, function(a){ return (new Array(Math.round(a.length / 3))).join(' ') }).
165
165
  replace(/\r\n|\r|\n/gm, '<br/>')
166
166
  }
167
-
167
+
168
168
  report.innerHTML = '<div id="jspec-report" class="' + classes + '"><div class="heading"> \
169
169
  <span class="passes">Passes: <em>' + results.stats.passes + '</em></span> \
170
170
  <span class="failures">Failures: <em>' + results.stats.failures + '</em></span> \
@@ -180,7 +180,7 @@
180
180
  (spec.passed() && !failuresOnly) ?
181
181
  '<td class="pass">' + escape(spec.description)+ '</td><td>' + spec.assertionsGraph() + '</td>' :
182
182
  !spec.passed() ?
183
- '<td class="fail">' + escape(spec.description) +
183
+ '<td class="fail">' + escape(spec.description) +
184
184
  map(spec.failures(), function(a){ return '<em>' + escape(a.message) + '</em>' }).join('') +
185
185
  '</td><td>' + spec.assertionsGraph() + '</td>' :
186
186
  '') +
@@ -188,23 +188,23 @@
188
188
  }).join('') + '</tr>'
189
189
  }).join('') + '</table></div>'
190
190
  },
191
-
191
+
192
192
  /**
193
193
  * Terminal reporter.
194
194
  *
195
195
  * @api public
196
196
  */
197
-
197
+
198
198
  Terminal : function(results, options) {
199
199
  var failuresOnly = option('failuresOnly')
200
- print(color("\n Passes: ", 'bold') + color(results.stats.passes, 'green') +
200
+ print(color("\n Passes: ", 'bold') + color(results.stats.passes, 'green') +
201
201
  color(" Failures: ", 'bold') + color(results.stats.failures, 'red') +
202
202
  color(" Duration: ", 'bold') + color(results.duration, 'green') + " ms \n")
203
-
203
+
204
204
  function indent(string) {
205
205
  return string.replace(/^(.)/gm, ' $1')
206
206
  }
207
-
207
+
208
208
  each(results.allSuites, function(suite) {
209
209
  var displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran
210
210
  if (displaySuite && suite.isExecutable()) {
@@ -218,17 +218,17 @@
218
218
  else if (spec.passed() && !failuresOnly)
219
219
  print(color(' ' + spec.description, 'green') + assertionsGraph)
220
220
  else if (!spec.passed())
221
- print(color(' ' + spec.description, 'red') + assertionsGraph +
221
+ print(color(' ' + spec.description, 'red') + assertionsGraph +
222
222
  "\n" + indent(map(spec.failures(), function(a){ return a.message }).join("\n")) + "\n")
223
223
  })
224
224
  print("")
225
225
  }
226
226
  })
227
-
227
+
228
228
  quit(results.stats.failures)
229
229
  }
230
230
  },
231
-
231
+
232
232
  Assertion : function(matcher, actual, expected, negate) {
233
233
  extend(this, {
234
234
  message: '',
@@ -237,19 +237,19 @@
237
237
  negate: negate,
238
238
  matcher: matcher,
239
239
  expected: expected,
240
-
240
+
241
241
  // Report assertion results
242
-
242
+
243
243
  report : function() {
244
- if (JSpec.assert)
244
+ if (JSpec.assert)
245
245
  this.passed ? JSpec.stats.passes++ : JSpec.stats.failures++
246
246
  return this
247
247
  },
248
-
248
+
249
249
  // Run the assertion
250
-
250
+
251
251
  run : function() {
252
- // TODO: remove unshifting
252
+ // TODO: remove unshifting
253
253
  expected.unshift(actual)
254
254
  this.result = matcher.match.apply(this, expected)
255
255
  this.passed = negate ? !this.result : this.result
@@ -258,27 +258,27 @@
258
258
  }
259
259
  })
260
260
  },
261
-
261
+
262
262
  ProxyAssertion : function(object, method, times, negate) {
263
263
  var self = this,
264
264
  old = object[method]
265
-
265
+
266
266
  // Proxy
267
-
267
+
268
268
  object[method] = function(){
269
269
  var args = toArray(arguments),
270
270
  result = old.apply(object, args)
271
271
  self.calls.push({ args : args, result : result })
272
272
  return result
273
273
  }
274
-
274
+
275
275
  // Times
276
-
276
+
277
277
  this.times = {
278
278
  once : 1,
279
279
  twice : 2
280
280
  }[times] || times || 1
281
-
281
+
282
282
  extend(this, {
283
283
  calls: [],
284
284
  message: '',
@@ -287,23 +287,23 @@
287
287
  negate: negate,
288
288
  object: object,
289
289
  method: method,
290
-
290
+
291
291
  // Proxy return value
292
-
292
+
293
293
  and_return : function(result) {
294
294
  this.expectedResult = result
295
295
  return this
296
296
  },
297
-
297
+
298
298
  // Proxy arguments passed
299
-
299
+
300
300
  with_args : function() {
301
301
  this.expectedArgs = toArray(arguments)
302
302
  return this
303
303
  },
304
-
304
+
305
305
  // Check if any calls have failing results
306
-
306
+
307
307
  anyResultsFail : function() {
308
308
  return any(this.calls, function(call){
309
309
  return self.expectedResult.an_instance_of ?
@@ -311,9 +311,9 @@
311
311
  !equal(self.expectedResult, call.result)
312
312
  })
313
313
  },
314
-
314
+
315
315
  // Check if any calls have passing results
316
-
316
+
317
317
  anyResultsPass : function() {
318
318
  return any(this.calls, function(call){
319
319
  return self.expectedResult.an_instance_of ?
@@ -321,21 +321,21 @@
321
321
  equal(self.expectedResult, call.result)
322
322
  })
323
323
  },
324
-
324
+
325
325
  // Return the passing result
326
-
326
+
327
327
  passingResult : function() {
328
328
  return this.anyResultsPass().result
329
329
  },
330
330
 
331
331
  // Return the failing result
332
-
332
+
333
333
  failingResult : function() {
334
334
  return this.anyResultsFail().result
335
335
  },
336
-
336
+
337
337
  // Check if any arguments fail
338
-
338
+
339
339
  anyArgsFail : function() {
340
340
  return any(this.calls, function(call){
341
341
  return any(self.expectedArgs, function(i, arg){
@@ -343,73 +343,73 @@
343
343
  return arg.an_instance_of ?
344
344
  call.args[i].constructor != arg.an_instance_of:
345
345
  !equal(arg, call.args[i])
346
-
346
+
347
347
  })
348
348
  })
349
349
  },
350
-
350
+
351
351
  // Check if any arguments pass
352
-
352
+
353
353
  anyArgsPass : function() {
354
354
  return any(this.calls, function(call){
355
355
  return any(self.expectedArgs, function(i, arg){
356
356
  return arg.an_instance_of ?
357
357
  call.args[i].constructor == arg.an_instance_of:
358
358
  equal(arg, call.args[i])
359
-
359
+
360
360
  })
361
361
  })
362
362
  },
363
-
363
+
364
364
  // Return the passing args
365
-
365
+
366
366
  passingArgs : function() {
367
367
  return this.anyArgsPass().args
368
368
  },
369
-
369
+
370
370
  // Return the failing args
371
-
371
+
372
372
  failingArgs : function() {
373
373
  return this.anyArgsFail().args
374
374
  },
375
-
375
+
376
376
  // Report assertion results
377
-
377
+
378
378
  report : function() {
379
- if (JSpec.assert)
379
+ if (JSpec.assert)
380
380
  this.passed ? ++JSpec.stats.passes : ++JSpec.stats.failures
381
381
  return this
382
382
  },
383
-
383
+
384
384
  // Run the assertion
385
-
385
+
386
386
  run : function() {
387
387
  var methodString = 'expected ' + object.toString() + '.' + method + '()' + (negate ? ' not' : '' )
388
-
388
+
389
389
  function times(n) {
390
390
  return n > 2 ? n + ' times' : { 1: 'once', 2: 'twice' }[n]
391
391
  }
392
-
392
+
393
393
  if (this.expectedResult != null && (negate ? this.anyResultsPass() : this.anyResultsFail()))
394
- this.message = methodString + ' to return ' + puts(this.expectedResult) +
395
- ' but ' + (negate ? 'it did' : 'got ' + puts(this.failingResult()))
394
+ this.message = methodString + ' to return ' + puts(this.expectedResult) +
395
+ ' but ' + (negate ? 'it did' : 'got ' + puts(this.failingResult()))
396
396
 
397
397
  if (this.expectedArgs && (negate ? !this.expectedResult && this.anyArgsPass() : this.anyArgsFail()))
398
398
  this.message = methodString + ' to be called with ' + puts.apply(this, this.expectedArgs) +
399
399
  ' but was' + (negate ? '' : ' called with ' + puts.apply(this, this.failingArgs()))
400
400
 
401
401
  if (negate ? !this.expectedResult && !this.expectedArgs && this.calls.length >= this.times : this.calls.length != this.times)
402
- this.message = methodString + ' to be called ' + times(this.times) +
402
+ this.message = methodString + ' to be called ' + times(this.times) +
403
403
  ', but ' + (this.calls.length == 0 ? ' was not called' : ' was called ' + times(this.calls.length))
404
-
405
- if (!this.message.length)
404
+
405
+ if (!this.message.length)
406
406
  this.passed = true
407
-
407
+
408
408
  return this
409
409
  }
410
410
  })
411
411
  },
412
-
412
+
413
413
  /**
414
414
  * Specification Suite block object.
415
415
  *
@@ -427,11 +427,11 @@
427
427
  sharedBehaviors: [],
428
428
  specs: [],
429
429
  ran: false,
430
- shared: isShared,
431
- hooks: { 'before' : [], 'after' : [],
430
+ shared: isShared,
431
+ hooks: { 'before' : [], 'after' : [],
432
432
  'before_each' : [], 'after_each' : [],
433
433
  'before_nested' : [], 'after_nested' : []},
434
-
434
+
435
435
  // Add a spec to the suite
436
436
 
437
437
  addSpec : function(description, body) {
@@ -456,7 +456,7 @@
456
456
  },
457
457
 
458
458
  // Add a hook to the suite
459
-
459
+
460
460
  addHook : function(hook, body) {
461
461
  this.hooks[hook].push(body)
462
462
  },
@@ -486,7 +486,7 @@
486
486
  // Check if nested suites are present
487
487
 
488
488
  hasSuites : function() {
489
- return this.suites.length
489
+ return this.suites.length
490
490
  },
491
491
 
492
492
  // Check if this suite has specs
@@ -499,7 +499,7 @@
499
499
 
500
500
  passed : function() {
501
501
  return !any(this.specs, function(spec){
502
- return !spec.passed()
502
+ return !spec.passed()
503
503
  })
504
504
  },
505
505
 
@@ -512,7 +512,7 @@
512
512
  }
513
513
  })
514
514
  },
515
-
515
+
516
516
  /**
517
517
  * Specification block object.
518
518
  *
@@ -526,29 +526,29 @@
526
526
  body: body,
527
527
  description: description,
528
528
  assertions: [],
529
-
529
+
530
530
  // Add passing assertion
531
-
531
+
532
532
  pass : function(message) {
533
533
  this.assertions.push({ passed: true, message: message })
534
534
  if (JSpec.assert) ++JSpec.stats.passes
535
535
  },
536
-
536
+
537
537
  // Add failing assertion
538
-
538
+
539
539
  fail : function(message) {
540
540
  this.assertions.push({ passed: false, message: message })
541
541
  if (JSpec.assert) ++JSpec.stats.failures
542
542
  },
543
-
543
+
544
544
  // Run deferred assertions
545
-
545
+
546
546
  runDeferredAssertions : function() {
547
547
  each(this.assertions, function(assertion){
548
548
  if (assertion.defer) assertion.run().report(), hook('afterAssertion', assertion)
549
549
  })
550
550
  },
551
-
551
+
552
552
  // Find first failing assertion
553
553
 
554
554
  failure : function() {
@@ -586,17 +586,17 @@
586
586
  }
587
587
  })
588
588
  },
589
-
589
+
590
590
  Module : function(methods) {
591
591
  extend(this, methods)
592
592
  },
593
-
593
+
594
594
  JSON : {
595
-
595
+
596
596
  /**
597
597
  * Generic sequences.
598
598
  */
599
-
599
+
600
600
  meta : {
601
601
  '\b' : '\\b',
602
602
  '\t' : '\\t',
@@ -606,13 +606,13 @@
606
606
  '"' : '\\"',
607
607
  '\\' : '\\\\'
608
608
  },
609
-
609
+
610
610
  /**
611
611
  * Escapable sequences.
612
612
  */
613
-
613
+
614
614
  escapable : /[\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
615
-
615
+
616
616
  /**
617
617
  * JSON encode _object_.
618
618
  *
@@ -620,7 +620,7 @@
620
620
  * @return {string}
621
621
  * @api private
622
622
  */
623
-
623
+
624
624
  encode : function(object) {
625
625
  var self = this
626
626
  if (object == undefined || object == null) return 'null'
@@ -634,7 +634,7 @@
634
634
  '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4)
635
635
  }) + '"' :
636
636
  '"' + object + '"'
637
- case 'object':
637
+ case 'object':
638
638
  if (object.constructor == Array)
639
639
  return '[' + map(object, function(val){
640
640
  return self.encode(val)
@@ -647,9 +647,9 @@
647
647
  return 'null'
648
648
  }
649
649
  },
650
-
650
+
651
651
  // --- DSLs
652
-
652
+
653
653
  DSLs : {
654
654
  snake : {
655
655
  expect : function(actual){
@@ -667,15 +667,15 @@
667
667
  before : function(body) {
668
668
  return JSpec.currentSuite.addHook('before', body)
669
669
  },
670
-
670
+
671
671
  after : function(body) {
672
672
  return JSpec.currentSuite.addHook('after', body)
673
673
  },
674
-
674
+
675
675
  before_each : function(body) {
676
676
  return JSpec.currentSuite.addHook('before_each', body)
677
677
  },
678
-
678
+
679
679
  after_each : function(body) {
680
680
  return JSpec.currentSuite.addHook('after_each', body)
681
681
  },
@@ -687,7 +687,7 @@
687
687
  after_nested : function(body){
688
688
  return JSpec.currentSuite.addhook('after_nested', body)
689
689
  },
690
-
690
+
691
691
  shared_behaviors_for : function(description, body){
692
692
  return JSpec.currentSuite.addSuite(description, body, true)
693
693
  },
@@ -699,7 +699,7 @@
699
699
  },
700
700
 
701
701
  // --- Methods
702
-
702
+
703
703
  /**
704
704
  * Check if _value_ is 'stop'. For use as a
705
705
  * utility callback function.
@@ -708,11 +708,11 @@
708
708
  * @return {bool}
709
709
  * @api public
710
710
  */
711
-
711
+
712
712
  haveStopped : function(value) {
713
713
  return value === 'stop'
714
714
  },
715
-
715
+
716
716
  /**
717
717
  * Include _object_ which may be a hash or Module instance.
718
718
  *
@@ -720,7 +720,7 @@
720
720
  * @return {JSpec}
721
721
  * @api public
722
722
  */
723
-
723
+
724
724
  include : function(object) {
725
725
  var module = object.constructor == JSpec.Module ? object : new JSpec.Module(object)
726
726
  this.modules.push(module)
@@ -735,7 +735,7 @@
735
735
  })
736
736
  return this
737
737
  },
738
-
738
+
739
739
  /**
740
740
  * Add a module hook _name_, which is immediately
741
741
  * called per module with the _args_ given. An array of
@@ -746,7 +746,7 @@
746
746
  * @return {array}
747
747
  * @api private
748
748
  */
749
-
749
+
750
750
  hook : function(name, args) {
751
751
  args = toArray(arguments, 1)
752
752
  return inject(JSpec.modules, [], function(results, module){
@@ -754,7 +754,7 @@
754
754
  results.push(JSpec.evalHook(module, name, args))
755
755
  })
756
756
  },
757
-
757
+
758
758
  /**
759
759
  * Eval _module_ hook _name_ with _args_. Evaluates in context
760
760
  * to the module itself, JSpec, and JSpec.context.
@@ -765,31 +765,31 @@
765
765
  * @return {mixed}
766
766
  * @api private
767
767
  */
768
-
768
+
769
769
  evalHook : function(module, name, args) {
770
770
  hook('evaluatingHookBody', module, name)
771
771
  return module[name].apply(module, args)
772
772
  },
773
-
773
+
774
774
  /**
775
775
  * Same as hook() however accepts only one _arg_ which is
776
776
  * considered immutable. This function passes the arg
777
777
  * to the first module, then passes the return value of the last
778
- * module called, to the following module.
778
+ * module called, to the following module.
779
779
  *
780
780
  * @param {string} name
781
781
  * @param {mixed} arg
782
782
  * @return {mixed}
783
783
  * @api private
784
784
  */
785
-
785
+
786
786
  hookImmutable : function(name, arg) {
787
787
  return inject(JSpec.modules, arg, function(result, module){
788
788
  if (typeof module[name] == 'function')
789
789
  return JSpec.evalHook(module, name, [result])
790
790
  })
791
791
  },
792
-
792
+
793
793
  /**
794
794
  * Find a shared example suite by its description or name.
795
795
  * First searches parent tree of suites for shared behavior
@@ -799,7 +799,7 @@
799
799
  * @return {Suite}
800
800
  * @api private
801
801
  */
802
-
802
+
803
803
  findSharedBehavior : function(description) {
804
804
  var behavior
805
805
  return (behavior = JSpec.findLocalSharedBehavior(description))
@@ -815,7 +815,7 @@
815
815
  * @return {Suite}
816
816
  * @api private
817
817
  */
818
-
818
+
819
819
  findLocalSharedBehavior : function(description) {
820
820
  var behavior,
821
821
  currentSuite = JSpec.currentSuite.suite
@@ -834,11 +834,11 @@
834
834
  * @return {Suite}
835
835
  * @api private
836
836
  */
837
-
837
+
838
838
  findGlobalSharedBehavior : function(description) {
839
839
  return find(JSpec.suites, JSpec.suiteDescriptionPredicate(description))
840
840
  },
841
-
841
+
842
842
  /**
843
843
  * Build a predicate that will match a suite based on name or description
844
844
  *
@@ -846,7 +846,7 @@
846
846
  * @return {function}
847
847
  * @api private
848
848
  */
849
-
849
+
850
850
  suiteDescriptionPredicate : function(description) {
851
851
  return function(suite){
852
852
  return suite.name === description ||
@@ -861,7 +861,7 @@
861
861
  * @param {string} description
862
862
  * @api public
863
863
  */
864
-
864
+
865
865
  shareBehaviorsOf : function(description) {
866
866
  var suite = JSpec.findSharedBehavior(description)
867
867
  if (suite)
@@ -869,8 +869,8 @@
869
869
  else
870
870
  throw new Error("failed to find shared behaviors named `" + description + "'")
871
871
  },
872
-
873
-
872
+
873
+
874
874
  /**
875
875
  * Convert arguments to an array.
876
876
  *
@@ -879,11 +879,11 @@
879
879
  * @return {array}
880
880
  * @api public
881
881
  */
882
-
882
+
883
883
  toArray : function(arguments, offset) {
884
884
  return Array.prototype.slice.call(arguments, offset || 0)
885
885
  },
886
-
886
+
887
887
  /**
888
888
  * Return ANSI-escaped colored string.
889
889
  *
@@ -892,7 +892,7 @@
892
892
  * @return {string}
893
893
  * @api public
894
894
  */
895
-
895
+
896
896
  color : function(string, color) {
897
897
  if (option('disableColors')) {
898
898
  return string
@@ -910,22 +910,22 @@
910
910
  }[color] + 'm' + string + "\u001B[0m"
911
911
  }
912
912
  },
913
-
913
+
914
914
  /**
915
915
  * Default matcher message callback.
916
916
  *
917
917
  * @api private
918
918
  */
919
-
919
+
920
920
  defaultMatcherMessage : function(actual, expected, negate, name) {
921
- return 'expected ' + puts(actual) + ' to ' +
922
- (negate ? 'not ' : '') +
921
+ return 'expected ' + puts(actual) + ' to ' +
922
+ (negate ? 'not ' : '') +
923
923
  name.replace(/_/g, ' ') +
924
924
  ' ' + (expected.length > 1 ?
925
925
  puts.apply(this, expected.slice(1)) :
926
926
  '')
927
927
  },
928
-
928
+
929
929
  /**
930
930
  * Normalize a matcher message.
931
931
  *
@@ -936,45 +936,45 @@
936
936
  * @return {hash}
937
937
  * @api public
938
938
  */
939
-
939
+
940
940
  normalizeMatcherMessage : function(matcher) {
941
- if (typeof matcher.message != 'function')
941
+ if (typeof matcher.message != 'function')
942
942
  matcher.message = this.defaultMatcherMessage
943
943
  return matcher
944
944
  },
945
-
945
+
946
946
  /**
947
947
  * Normalize a matcher body
948
- *
948
+ *
949
949
  * This process allows the following conversions until
950
950
  * the matcher is in its final normalized hash state.
951
951
  *
952
952
  * - '==' becomes 'actual == expected'
953
953
  * - 'actual == expected' becomes 'return actual == expected'
954
- * - function(actual, expected) { return actual == expected } becomes
954
+ * - function(actual, expected) { return actual == expected } becomes
955
955
  * { match : function(actual, expected) { return actual == expected }}
956
956
  *
957
957
  * @param {mixed} body
958
958
  * @return {hash}
959
959
  * @api public
960
960
  */
961
-
961
+
962
962
  normalizeMatcherBody : function(body) {
963
963
  var captures
964
964
  switch (body.constructor) {
965
965
  case String:
966
966
  if (captures = body.match(/^alias (\w+)/)) return JSpec.matchers[last(captures)]
967
967
  if (body.length < 4) body = 'actual ' + body + ' expected'
968
- return { match: function(actual, expected) { return eval(body) }}
969
-
968
+ return { match: function(actual, expected) { return eval(body) }}
969
+
970
970
  case Function:
971
971
  return { match: body }
972
-
972
+
973
973
  default:
974
974
  return body
975
975
  }
976
976
  },
977
-
977
+
978
978
  /**
979
979
  * Get option value. This method first checks if
980
980
  * the option key has been set via the query string,
@@ -984,12 +984,12 @@
984
984
  * @return {mixed}
985
985
  * @api public
986
986
  */
987
-
987
+
988
988
  option : function(key) {
989
989
  return (value = query(key)) !== null ? value :
990
990
  JSpec.options[key] || null
991
991
  },
992
-
992
+
993
993
  /**
994
994
  * Check if object _a_, is equal to object _b_.
995
995
  *
@@ -998,7 +998,7 @@
998
998
  * @return {bool}
999
999
  * @api private
1000
1000
  */
1001
-
1001
+
1002
1002
  equal: function(a, b) {
1003
1003
  if (typeof a != typeof b) return
1004
1004
  if (a === b) return true
@@ -1057,14 +1057,14 @@
1057
1057
  if (object.nodeName && object.outerHTML) return object.outerHTML
1058
1058
  if (object.nodeName) return document.createElement('div').appendChild(object).parentNode.innerHTML
1059
1059
  switch (object.constructor) {
1060
- case Function: return object.name || object
1061
- case String:
1060
+ case Function: return object.name || object
1061
+ case String:
1062
1062
  return '"' + object
1063
1063
  .replace(/"/g, '\\"')
1064
1064
  .replace(/\n/g, '\\n')
1065
1065
  .replace(/\t/g, '\\t')
1066
1066
  + '"'
1067
- case Array:
1067
+ case Array:
1068
1068
  return inject(object, '[', function(b, v){
1069
1069
  return b + ', ' + puts(v)
1070
1070
  }).replace('[,', '[') + ' ]'
@@ -1074,7 +1074,7 @@
1074
1074
  if (k == '__hit__') return b
1075
1075
  return b + ', ' + k + ': ' + (v && v.__hit__ ? '<circular reference>' : puts(v))
1076
1076
  }).replace('{,', '{') + ' }'
1077
- default:
1077
+ default:
1078
1078
  return object.toString()
1079
1079
  }
1080
1080
  },
@@ -1114,12 +1114,12 @@
1114
1114
  .replace(/>/gmi, '&gt;')
1115
1115
  .replace(/</gmi, '&lt;')
1116
1116
  },
1117
-
1117
+
1118
1118
  /**
1119
1119
  * Perform an assertion without reporting.
1120
1120
  *
1121
1121
  * This method is primarily used for internal
1122
- * matchers in order retain DRYness. May be invoked
1122
+ * matchers in order retain DRYness. May be invoked
1123
1123
  * like below:
1124
1124
  *
1125
1125
  * does('foo', 'eql', 'foo')
@@ -1134,7 +1134,7 @@
1134
1134
  * @return {mixed}
1135
1135
  * @api private
1136
1136
  */
1137
-
1137
+
1138
1138
  does : function(actual, matcher, expected) {
1139
1139
  var assertion = new JSpec.Assertion(JSpec.matchers[matcher], actual, toArray(arguments, 2))
1140
1140
  return assertion.run().result
@@ -1155,22 +1155,22 @@
1155
1155
  expect : function(actual) {
1156
1156
  function assert(matcher, args, negate) {
1157
1157
  var expected = toArray(args, 1)
1158
- matcher.negate = negate
1158
+ matcher.negate = negate
1159
1159
  var assertion = new JSpec.Assertion(matcher, actual, expected, negate)
1160
1160
  hook('beforeAssertion', assertion)
1161
1161
  if (matcher.defer) assertion.run()
1162
1162
  else JSpec.currentSpec.assertions.push(assertion.run().report()), hook('afterAssertion', assertion)
1163
1163
  return assertion.result
1164
1164
  }
1165
-
1165
+
1166
1166
  function to(matcher) {
1167
1167
  return assert(matcher, arguments, false)
1168
1168
  }
1169
-
1169
+
1170
1170
  function not_to(matcher) {
1171
1171
  return assert(matcher, arguments, true)
1172
1172
  }
1173
-
1173
+
1174
1174
  return {
1175
1175
  to : to,
1176
1176
  should : to,
@@ -1193,7 +1193,7 @@
1193
1193
  replace(new RegExp('[' + (chars || '\\s') + ']*$'), '').
1194
1194
  replace(new RegExp('^[' + (chars || '\\s') + ']*'), '')
1195
1195
  },
1196
-
1196
+
1197
1197
  /**
1198
1198
  * Call an iterator callback with arguments a, or b
1199
1199
  * depending on the arity of the callback.
@@ -1204,11 +1204,11 @@
1204
1204
  * @return {mixed}
1205
1205
  * @api private
1206
1206
  */
1207
-
1207
+
1208
1208
  callIterator : function(callback, a, b) {
1209
1209
  return callback.length == 1 ? callback(b) : callback(a, b)
1210
1210
  },
1211
-
1211
+
1212
1212
  /**
1213
1213
  * Extend an object with another.
1214
1214
  *
@@ -1216,13 +1216,13 @@
1216
1216
  * @param {object} other
1217
1217
  * @api public
1218
1218
  */
1219
-
1219
+
1220
1220
  extend : function(object, other) {
1221
1221
  each(other, function(property, value){
1222
1222
  object[property] = value
1223
1223
  })
1224
1224
  },
1225
-
1225
+
1226
1226
  /**
1227
1227
  * Iterate an object, invoking the given callback.
1228
1228
  *
@@ -1237,7 +1237,7 @@
1237
1237
  for (var i = 0, len = object.length; i < len; ++i)
1238
1238
  callIterator(callback, i, object[i])
1239
1239
  else
1240
- for (var key in object)
1240
+ for (var key in object)
1241
1241
  if (object.hasOwnProperty(key))
1242
1242
  callIterator(callback, key, object[key])
1243
1243
  },
@@ -1261,7 +1261,7 @@
1261
1261
  })
1262
1262
  return memo
1263
1263
  },
1264
-
1264
+
1265
1265
  /**
1266
1266
  * Destub _object_'s _method_. When no _method_ is passed
1267
1267
  * all stubbed methods are destubbed. When no arguments
@@ -1272,7 +1272,7 @@
1272
1272
  * @param {string} method
1273
1273
  * @api public
1274
1274
  */
1275
-
1275
+
1276
1276
  destub : function(object, method) {
1277
1277
  var captures
1278
1278
  if (method) {
@@ -1293,9 +1293,9 @@
1293
1293
  while (JSpec.stubbed.length)
1294
1294
  destub(JSpec.stubbed.shift())
1295
1295
  },
1296
-
1296
+
1297
1297
  /**
1298
- * Stub _object_'s _method_.
1298
+ * Stub _object_'s _method_.
1299
1299
  *
1300
1300
  * stub(foo, 'toString').and_return('bar')
1301
1301
  *
@@ -1304,10 +1304,10 @@
1304
1304
  * @return {hash}
1305
1305
  * @api public
1306
1306
  */
1307
-
1307
+
1308
1308
  stub : function(object, method) {
1309
1309
  hook('stubbing', object, method)
1310
-
1310
+
1311
1311
  //unbind any stub already present on this method
1312
1312
  JSpec.destub(object, method);
1313
1313
  JSpec.stubbed.push(object)
@@ -1322,7 +1322,7 @@
1322
1322
  }
1323
1323
  }
1324
1324
  },
1325
-
1325
+
1326
1326
  /**
1327
1327
  * Map callback return values.
1328
1328
  *
@@ -1337,7 +1337,7 @@
1337
1337
  memo.push(callIterator(callback, key, value))
1338
1338
  })
1339
1339
  },
1340
-
1340
+
1341
1341
  /**
1342
1342
  * Returns the first matching expression or null.
1343
1343
  *
@@ -1346,14 +1346,14 @@
1346
1346
  * @return {mixed}
1347
1347
  * @api public
1348
1348
  */
1349
-
1349
+
1350
1350
  any : function(object, callback) {
1351
1351
  return inject(object, null, function(state, key, value){
1352
1352
  if (state == undefined)
1353
1353
  return callIterator(callback, key, value) ? value : state
1354
1354
  })
1355
1355
  },
1356
-
1356
+
1357
1357
  /**
1358
1358
  * Returns an array of values collected when the callback
1359
1359
  * given evaluates to true.
@@ -1363,7 +1363,7 @@
1363
1363
  * @return {array}
1364
1364
  * @api public
1365
1365
  */
1366
-
1366
+
1367
1367
  select : function(object, callback) {
1368
1368
  return inject(object, [], function(selected, key, value){
1369
1369
  if (callIterator(callback, key, value))
@@ -1380,10 +1380,10 @@
1380
1380
 
1381
1381
  addMatchers : function(matchers) {
1382
1382
  each(matchers, function(name, body){
1383
- JSpec.addMatcher(name, body)
1383
+ JSpec.addMatcher(name, body)
1384
1384
  })
1385
1385
  },
1386
-
1386
+
1387
1387
  /**
1388
1388
  * Define a matcher.
1389
1389
  *
@@ -1391,7 +1391,7 @@
1391
1391
  * @param {hash, function, string} body
1392
1392
  * @api public
1393
1393
  */
1394
-
1394
+
1395
1395
  addMatcher : function(name, body) {
1396
1396
  hook('addingMatcher', name, body)
1397
1397
  if (name.indexOf(' ') != -1) {
@@ -1404,7 +1404,7 @@
1404
1404
  this.matchers[name] = this.normalizeMatcherMessage(this.normalizeMatcherBody(body))
1405
1405
  this.matchers[name].name = name
1406
1406
  },
1407
-
1407
+
1408
1408
  /**
1409
1409
  * Add a root suite to JSpec.
1410
1410
  *
@@ -1412,14 +1412,14 @@
1412
1412
  * @param {body} function
1413
1413
  * @api public
1414
1414
  */
1415
-
1415
+
1416
1416
  describe : function(description, body) {
1417
1417
  var suite = new JSpec.Suite(description, body, false)
1418
1418
  hook('addingSuite', suite)
1419
1419
  this.allSuites.push(suite)
1420
1420
  this.suites.push(suite)
1421
1421
  },
1422
-
1422
+
1423
1423
  /**
1424
1424
  * Add a shared example suite to JSpec.
1425
1425
  *
@@ -1427,7 +1427,7 @@
1427
1427
  * @param {body} function
1428
1428
  * @api public
1429
1429
  */
1430
-
1430
+
1431
1431
  shared_behaviors_for : function(description, body) {
1432
1432
  var suite = new JSpec.Suite(description, body, true)
1433
1433
  hook('addingSuite', suite)
@@ -1442,7 +1442,7 @@
1442
1442
  * @return {string}
1443
1443
  * @api public
1444
1444
  */
1445
-
1445
+
1446
1446
  contentsOf : function(body) {
1447
1447
  return body.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1]
1448
1448
  },
@@ -1511,7 +1511,7 @@
1511
1511
  },
1512
1512
 
1513
1513
  /**
1514
- * Report on the results.
1514
+ * Report on the results.
1515
1515
  *
1516
1516
  * @api public
1517
1517
  */
@@ -1538,7 +1538,7 @@
1538
1538
  each(this.suites, function(suite) { JSpec.runSuite(suite) })
1539
1539
  return this
1540
1540
  },
1541
-
1541
+
1542
1542
  /**
1543
1543
  * Run a suite.
1544
1544
  *
@@ -1569,25 +1569,25 @@
1569
1569
  this.stats.suitesFinished++
1570
1570
  }
1571
1571
  },
1572
-
1572
+
1573
1573
  /**
1574
1574
  * Report a failure for the current spec.
1575
1575
  *
1576
1576
  * @param {string} message
1577
1577
  * @api public
1578
1578
  */
1579
-
1579
+
1580
1580
  fail : function(message) {
1581
1581
  JSpec.currentSpec.fail(message)
1582
1582
  },
1583
-
1583
+
1584
1584
  /**
1585
1585
  * Report a passing assertion for the current spec.
1586
1586
  *
1587
1587
  * @param {string} message
1588
1588
  * @api public
1589
1589
  */
1590
-
1590
+
1591
1591
  pass : function(message) {
1592
1592
  JSpec.currentSpec.pass(message)
1593
1593
  },
@@ -1650,7 +1650,7 @@
1650
1650
  * @param {string} data
1651
1651
  * @api private
1652
1652
  */
1653
-
1653
+
1654
1654
  post : function(uri, data) {
1655
1655
  if (any(hook('posting', uri, data), haveStopped)) return
1656
1656
  var request = this.xhr()
@@ -1669,18 +1669,18 @@
1669
1669
  * @return {XMLHttpRequest, ActiveXObject}
1670
1670
  * @api private
1671
1671
  */
1672
-
1672
+
1673
1673
  xhr : function() {
1674
1674
  return this.ieXhr() || new JSpec.request
1675
1675
  },
1676
-
1676
+
1677
1677
  /**
1678
1678
  * Return Microsoft piece of crap ActiveXObject.
1679
1679
  *
1680
1680
  * @return {ActiveXObject}
1681
1681
  * @api public
1682
1682
  */
1683
-
1683
+
1684
1684
  ieXhr : function() {
1685
1685
  function object(str) {
1686
1686
  try { return new ActiveXObject(str) } catch(e) {}
@@ -1690,18 +1690,18 @@
1690
1690
  object('Msxml2.XMLHTTP') ||
1691
1691
  object('Microsoft.XMLHTTP')
1692
1692
  },
1693
-
1693
+
1694
1694
  /**
1695
1695
  * Check for HTTP request support.
1696
1696
  *
1697
1697
  * @return {bool}
1698
1698
  * @api private
1699
1699
  */
1700
-
1700
+
1701
1701
  hasXhr : function() {
1702
1702
  return JSpec.request || 'ActiveXObject' in main
1703
1703
  },
1704
-
1704
+
1705
1705
  /**
1706
1706
  * Try loading _file_ returning the contents
1707
1707
  * string or null. Chain to locate / read a file.
@@ -1710,7 +1710,7 @@
1710
1710
  * @return {string}
1711
1711
  * @api public
1712
1712
  */
1713
-
1713
+
1714
1714
  tryLoading : function(file) {
1715
1715
  try { return JSpec.load(file) } catch (e) {}
1716
1716
  },
@@ -1732,9 +1732,9 @@
1732
1732
  var request = this.xhr()
1733
1733
  request.open('GET', file, false)
1734
1734
  request.send(null)
1735
- if (request.readyState == 4 &&
1736
- (request.status == 0 ||
1737
- request.status.toString().charAt(0) == 2))
1735
+ if (request.readyState == 4 &&
1736
+ (request.status == 0 ||
1737
+ request.status.toString().charAt(0) == 2))
1738
1738
  return request.responseText
1739
1739
  }
1740
1740
  else
@@ -1755,9 +1755,9 @@
1755
1755
  return this
1756
1756
  }
1757
1757
  }
1758
-
1758
+
1759
1759
  // --- Node.js support
1760
-
1760
+
1761
1761
  if (typeof GLOBAL === 'object' && typeof exports === 'object') {
1762
1762
  var fs = require('fs')
1763
1763
  quit = process.exit
@@ -1772,7 +1772,7 @@
1772
1772
  if (typeof Johnson === 'object') {
1773
1773
  quit = function () {}
1774
1774
  }
1775
-
1775
+
1776
1776
  // --- Utility functions
1777
1777
 
1778
1778
  var main = this,
@@ -1805,13 +1805,13 @@
1805
1805
  have_length : "actual.length == expected",
1806
1806
  be_within : "actual >= expected[0] && actual <= last(expected)",
1807
1807
  have_length_within : "actual.length >= expected[0] && actual.length <= last(expected)",
1808
-
1808
+
1809
1809
  receive : { defer : true, match : function(actual, method, times) {
1810
1810
  var proxy = new JSpec.ProxyAssertion(actual, method, times, this.negate)
1811
1811
  JSpec.currentSpec.assertions.push(proxy)
1812
1812
  return proxy
1813
1813
  }},
1814
-
1814
+
1815
1815
  be_empty : function(actual) {
1816
1816
  if (actual.constructor == Object && actual.length == undefined)
1817
1817
  for (var key in actual)
@@ -1823,18 +1823,18 @@
1823
1823
  for (var state = true, i = 1; i < arguments.length; i++) {
1824
1824
  var arg = arguments[i]
1825
1825
  switch (actual.constructor) {
1826
- case String:
1826
+ case String:
1827
1827
  case Number:
1828
1828
  case RegExp:
1829
1829
  case Function:
1830
1830
  state = actual.toString().indexOf(arg) !== -1
1831
1831
  break
1832
-
1832
+
1833
1833
  case Object:
1834
1834
  state = arg in actual
1835
1835
  break
1836
-
1837
- case Array:
1836
+
1837
+ case Array:
1838
1838
  state = any(actual, function(value){ return equal(value, arg) })
1839
1839
  break
1840
1840
  }
@@ -1872,31 +1872,31 @@
1872
1872
  return 'expected ' + exception + (negate ? ' not ' : '' ) +
1873
1873
  ' to be thrown, but ' + (this.e ? 'got ' + puts(this.e) : 'nothing was')
1874
1874
  }},
1875
-
1875
+
1876
1876
  have : function(actual, length, property) {
1877
1877
  return actual[property] == null ? false : actual[property].length == length
1878
1878
  },
1879
-
1879
+
1880
1880
  have_at_least : function(actual, length, property) {
1881
1881
  return actual[property] == null ? (length === 0) : actual[property].length >= length
1882
1882
  },
1883
-
1883
+
1884
1884
  have_at_most :function(actual, length, property) {
1885
1885
  return actual[property] == null || actual[property].length <= length
1886
1886
  },
1887
-
1887
+
1888
1888
  have_within : function(actual, range, property) {
1889
1889
  var length = actual[property] == undefined ? 0 : actual[property].length
1890
1890
  return length >= range.shift() && length <= range.pop()
1891
1891
  },
1892
-
1892
+
1893
1893
  have_prop : function(actual, property, value) {
1894
1894
  var actualVal = actual[property], actualType = typeof actualVal
1895
1895
  return (actualType == 'function' || actualType == 'undefined') ? false :
1896
1896
  typeof value === 'undefined' ||
1897
1897
  does(actual[property],'eql',value)
1898
1898
  },
1899
-
1899
+
1900
1900
  have_property : function(actual, property, value) {
1901
1901
  var actualVal = actual[property], actualType = typeof actualVal
1902
1902
  return (actualType == 'function' || actualType == 'undefined') ? false :
@@ -1904,5 +1904,5 @@
1904
1904
  value === actualVal
1905
1905
  }
1906
1906
  })
1907
-
1907
+
1908
1908
  })()