konacha 1.2.2 → 1.2.3

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.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # master
2
2
 
3
+ # 1.2.3
4
+
5
+ * Update mocha (1.1.0) and chai (1.0.4)
6
+ * Traverse symlinked directories when discovering specs
7
+
3
8
  # 1.2.2
4
9
 
5
10
  * Update chai (1.0.3)
@@ -17,7 +17,7 @@ the asset pipeline and engines.}
17
17
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  gem.name = "konacha"
19
19
  gem.require_paths = ["lib"]
20
- gem.version = "1.2.2"
20
+ gem.version = "1.2.3"
21
21
 
22
22
  gem.add_dependency "rails", "~> 3.1"
23
23
  gem.add_dependency "capybara"
@@ -33,7 +33,7 @@ module Konacha
33
33
  end
34
34
 
35
35
  def spec_paths
36
- Dir[File.join(spec_root, "**/*{_spec,_test}.*")].map do |path|
36
+ Dir[File.join(spec_root, "**{,/*/**}/*{_spec,_test}.*")].map do |path|
37
37
  path.gsub(File.join(spec_root, ''), '')
38
38
  end
39
39
  end
@@ -23,6 +23,26 @@ describe Konacha do
23
23
  subject.should include("subdirectory/subdirectory_spec.js")
24
24
  end
25
25
 
26
+ it "traverses symlinked directories" do
27
+ begin
28
+ # Create a directory with specs outside of 'spec/javascripts'.
29
+ Dir.mkdir "spec/dummy/app/external_specs"
30
+ File.new "spec/dummy/app/external_specs/my_spec.js", "w"
31
+
32
+ # Symlink it into 'spec/javascripts'.
33
+ File.symlink "../../app/external_specs/", "spec/dummy/spec/javascripts/external_specs"
34
+
35
+ subject.should include("external_specs/my_spec.js")
36
+
37
+ File.unlink "spec/dummy/spec/javascripts/external_specs"
38
+ rescue NotImplementedError
39
+ # Don't test this on platforms that don't support symlinking.
40
+ end
41
+
42
+ File.unlink "spec/dummy/app/external_specs/my_spec.js"
43
+ Dir.unlink "spec/dummy/app/external_specs"
44
+ end
45
+
26
46
  it "does not include spec_helper" do
27
47
  subject.should_not include("spec_helper.js")
28
48
  end
@@ -305,11 +305,11 @@ Assertion.addChainableMethod('a', an);
305
305
  * @api public
306
306
  */
307
307
 
308
- function includeChainingBehavior() {
308
+ function includeChainingBehavior () {
309
309
  flag(this, 'contains', true);
310
310
  }
311
311
 
312
- function include(val) {
312
+ function include (val) {
313
313
  var obj = flag(this, 'object')
314
314
  this.assert(
315
315
  ~obj.indexOf(val)
@@ -527,24 +527,22 @@ Object.defineProperty(Assertion.prototype, 'empty',
527
527
  * }
528
528
  *
529
529
  * @name arguments
530
+ * @alias Arguments
530
531
  * @api public
531
532
  */
532
533
 
533
- Object.defineProperty(Assertion.prototype, 'arguments',
534
- { get: function () {
535
- var obj = flag(this, 'object');
536
- this.assert(
537
- '[object Arguments]' == Object.prototype.toString.call(obj)
538
- , 'expected #{this} to be arguments'
539
- , 'expected #{this} to not be arguments'
540
- , '[object Arguments]'
541
- , Object.prototype.toString.call(obj)
542
- );
534
+ function checkArguments () {
535
+ var obj = flag(this, 'object')
536
+ , type = Object.prototype.toString.call(obj);
537
+ this.assert(
538
+ '[object Arguments]' === type
539
+ , 'expected #{this} to be arguments but got ' + type
540
+ , 'expected #{this} to not be arguments'
541
+ );
542
+ }
543
543
 
544
- return this;
545
- }
546
- , configurable: true
547
- });
544
+ Assertion.addProperty('arguments', checkArguments);
545
+ Assertion.addProperty('Arguments', checkArguments);
548
546
 
549
547
  /**
550
548
  * ### .equal(value)
@@ -1042,9 +1040,16 @@ Assertion.prototype.Throw = function (constructor, msg) {
1042
1040
  *
1043
1041
  * Asserts that the object or class target will respond to a method.
1044
1042
  *
1043
+ * Klass.prototype.bar = function(){};
1045
1044
  * expect(Klass).to.respondTo('bar');
1046
1045
  * expect(obj).to.respondTo('bar');
1047
1046
  *
1047
+ * To check if a constructor will respond to a static function,
1048
+ * set the `itself` flag.
1049
+ *
1050
+ * Klass.baz = function(){};
1051
+ * expect(Klass).itself.to.respondTo('baz');
1052
+ *
1048
1053
  * @name respondTo
1049
1054
  * @param {String} method
1050
1055
  * @api public
@@ -1052,7 +1057,8 @@ Assertion.prototype.Throw = function (constructor, msg) {
1052
1057
 
1053
1058
  Assertion.prototype.respondTo = function (method) {
1054
1059
  var obj = flag(this, 'object')
1055
- , context = ('function' === typeof obj)
1060
+ , itself = flag(this, 'itself')
1061
+ , context = ('function' === typeof obj && !itself)
1056
1062
  ? obj.prototype[method]
1057
1063
  : obj[method];
1058
1064
 
@@ -1067,6 +1073,29 @@ Assertion.prototype.respondTo = function (method) {
1067
1073
  return this;
1068
1074
  };
1069
1075
 
1076
+ /**
1077
+ * ### .itself
1078
+ *
1079
+ * Sets the `itself` flag, later used by the `respondTo` assertion.
1080
+ *
1081
+ * function Foo() {}
1082
+ * Foo.bar = function() {}
1083
+ * Foo.prototype.baz = function() {}
1084
+ *
1085
+ * expect(Foo).itself.to.respondTo('bar');
1086
+ * expect(Foo).itself.not.to.respondTo('baz');
1087
+ *
1088
+ * @name itself
1089
+ * @api public
1090
+ */
1091
+ Object.defineProperty(Assertion.prototype, 'itself',
1092
+ { get: function () {
1093
+ flag(this, 'itself', true);
1094
+ return this;
1095
+ }
1096
+ , configurable: true
1097
+ });
1098
+
1070
1099
  /**
1071
1100
  * ### .satisfy(method)
1072
1101
  *
@@ -1183,7 +1212,7 @@ var used = []
1183
1212
  * Chai version
1184
1213
  */
1185
1214
 
1186
- exports.version = '1.0.3';
1215
+ exports.version = '1.0.4';
1187
1216
 
1188
1217
  /*!
1189
1218
  * Primary `Assertion` prototype
@@ -2336,9 +2365,8 @@ var transferFlags = require('./transferFlags');
2336
2365
  */
2337
2366
 
2338
2367
  module.exports = function (ctx, name, method, chainingBehavior) {
2339
- if (typeof chainingBehavior !== 'function') {
2368
+ if (typeof chainingBehavior !== 'function')
2340
2369
  chainingBehavior = function () { };
2341
- }
2342
2370
 
2343
2371
  Object.defineProperty(ctx, name,
2344
2372
  { get: function () {
@@ -2352,20 +2380,15 @@ module.exports = function (ctx, name, method, chainingBehavior) {
2352
2380
  // Re-enumerate every time to better accomodate plugins.
2353
2381
  var asserterNames = Object.getOwnPropertyNames(ctx);
2354
2382
  asserterNames.forEach(function (asserterName) {
2355
- var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);
2356
-
2357
- // Avoid trying to overwrite things that we can't, like `length`
2358
- // and `arguments`.
2359
- var functionProtoPD = Object.getOwnPropertyDescriptor(Function.prototype, asserterName);
2360
- if (functionProtoPD && !functionProtoPD.configurable) {
2361
- return;
2362
- }
2363
-
2383
+ var pd = Object.getOwnPropertyDescriptor(ctx, asserterName)
2384
+ , functionProtoPD = Object.getOwnPropertyDescriptor(Function.prototype, asserterName);
2385
+ // Avoid trying to overwrite things that we can't, like `length` and `arguments`.
2386
+ if (functionProtoPD && !functionProtoPD.configurable) return;
2387
+ if (asserterName === 'arguments') return; // @see chaijs/chai/issues/69
2364
2388
  Object.defineProperty(assert, asserterName, pd);
2365
2389
  });
2366
2390
 
2367
2391
  transferFlags(this, assert);
2368
-
2369
2392
  return assert;
2370
2393
  }
2371
2394
  , configurable: true
@@ -3000,7 +3023,7 @@ function formatValue(ctx, value, recurseTimes) {
3000
3023
 
3001
3024
  // Make error with message first say the error
3002
3025
  if (isError(value)) {
3003
- base = ' ' + formatError(value);
3026
+ return formatError(value);
3004
3027
  }
3005
3028
 
3006
3029
  if (keys.length === 0 && (!array || value.length == 0)) {
@@ -3181,6 +3204,7 @@ function isError(e) {
3181
3204
  function objectToString(o) {
3182
3205
  return Object.prototype.toString.call(o);
3183
3206
  }
3207
+
3184
3208
  }); // module: utils/inspect.js
3185
3209
 
3186
3210
  require.register("utils/overwriteMethod.js", function(module, exports, require){
@@ -80,7 +80,7 @@ function isArray(obj) {
80
80
  /**
81
81
  * Event emitter constructor.
82
82
  *
83
- * @api public.
83
+ * @api public
84
84
  */
85
85
 
86
86
  function EventEmitter(){};
@@ -188,7 +188,7 @@ EventEmitter.prototype.removeAllListeners = function (name) {
188
188
  /**
189
189
  * Gets all listeners for a certain event.
190
190
  *
191
- * @api publci
191
+ * @api public
192
192
  */
193
193
 
194
194
  EventEmitter.prototype.listeners = function (name) {
@@ -560,7 +560,7 @@ module.exports = function(suite){
560
560
  * and/or tests.
561
561
  */
562
562
 
563
- context.describe = function(title, fn){
563
+ context.describe = context.context = function(title, fn){
564
564
  var suite = Suite.create(suites[0], title);
565
565
  suites.unshift(suite);
566
566
  fn();
@@ -870,7 +870,7 @@ exports = module.exports = Mocha;
870
870
  * Library version.
871
871
  */
872
872
 
873
- exports.version = '1.0.3';
873
+ exports.version = '1.1.0';
874
874
 
875
875
  /**
876
876
  * Expose internals.
@@ -908,6 +908,7 @@ function image(name) {
908
908
  * - `globals` array of accepted globals
909
909
  * - `timeout` timeout in milliseconds
910
910
  * - `ignoreLeaks` ignore global leaks
911
+ * - `grep` string or regexp to filter tests with
911
912
  *
912
913
  * @param {Object} options
913
914
  * @api public
@@ -917,6 +918,7 @@ function Mocha(options) {
917
918
  options = options || {};
918
919
  this.files = [];
919
920
  this.options = options;
921
+ this.grep(options.grep);
920
922
  this.suite = new exports.Suite('', new exports.Context);
921
923
  this.ui(options.ui);
922
924
  this.reporter(options.reporter);
@@ -1003,6 +1005,21 @@ Mocha.prototype.growl = function(runner, reporter) {
1003
1005
  });
1004
1006
  };
1005
1007
 
1008
+ /**
1009
+ * Add regexp to grep for to the options object
1010
+ *
1011
+ * @param {RegExp} or {String} re
1012
+ * @return {Mocha}
1013
+ * @api public
1014
+ */
1015
+
1016
+ Mocha.prototype.grep = function(re){
1017
+ this.options.grep = 'string' == typeof re
1018
+ ? new RegExp(re)
1019
+ : re;
1020
+ return this;
1021
+ };
1022
+
1006
1023
  /**
1007
1024
  * Run tests and invoke `fn()` when complete.
1008
1025
  *
@@ -1023,7 +1040,6 @@ Mocha.prototype.run = function(fn){
1023
1040
  if (options.growl) this.growl(runner, reporter);
1024
1041
  return runner.run(fn);
1025
1042
  };
1026
-
1027
1043
  }); // module: mocha.js
1028
1044
 
1029
1045
  require.register("reporters/base.js", function(module, exports, require){
@@ -1035,6 +1051,16 @@ require.register("reporters/base.js", function(module, exports, require){
1035
1051
  var tty = require('browser/tty')
1036
1052
  , diff = require('browser/diff');
1037
1053
 
1054
+ /**
1055
+ * Save timer references to avoid Sinon interfering (see GH-237).
1056
+ */
1057
+
1058
+ var Date = global.Date
1059
+ , setTimeout = global.setTimeout
1060
+ , setInterval = global.setInterval
1061
+ , clearTimeout = global.clearTimeout
1062
+ , clearInterval = global.clearInterval;
1063
+
1038
1064
  /**
1039
1065
  * Check if both stdio streams are associated with a tty.
1040
1066
  */
@@ -1351,7 +1377,7 @@ function pad(str, len) {
1351
1377
 
1352
1378
  function errorDiff(err, type) {
1353
1379
  return diff['diff' + type](err.actual, err.expected).map(function(str){
1354
- if (str.value == '\n') str.value = '<newline>\n';
1380
+ if (/^(\n+)$/.test(str.value)) str.value = Array(++RegExp.$1.length).join('<newline>');
1355
1381
  if (str.added) return colorLines('diff added', str.value);
1356
1382
  if (str.removed) return colorLines('diff removed', str.value);
1357
1383
  return str.value;
@@ -1577,6 +1603,16 @@ var Base = require('./base')
1577
1603
  , Progress = require('../browser/progress')
1578
1604
  , escape = utils.escape;
1579
1605
 
1606
+ /**
1607
+ * Save timer references to avoid Sinon interfering (see GH-237).
1608
+ */
1609
+
1610
+ var Date = global.Date
1611
+ , setTimeout = global.setTimeout
1612
+ , setInterval = global.setInterval
1613
+ , clearTimeout = global.clearTimeout
1614
+ , clearInterval = global.clearInterval;
1615
+
1580
1616
  /**
1581
1617
  * Expose `Doc`.
1582
1618
  */
@@ -1614,7 +1650,8 @@ function HTML(runner) {
1614
1650
  , failures = items[2].getElementsByTagName('em')[0]
1615
1651
  , duration = items[3].getElementsByTagName('em')[0]
1616
1652
  , canvas = stat.getElementsByTagName('canvas')[0]
1617
- , stack = [root]
1653
+ , report = fragment('<ul id="report"></ul>')
1654
+ , stack = [report]
1618
1655
  , progress
1619
1656
  , ctx
1620
1657
 
@@ -1626,6 +1663,7 @@ function HTML(runner) {
1626
1663
  if (!root) return error('#mocha div missing, add it to your document');
1627
1664
 
1628
1665
  root.appendChild(stat);
1666
+ root.appendChild(report);
1629
1667
 
1630
1668
  if (progress) progress.size(40);
1631
1669
 
@@ -1633,11 +1671,12 @@ function HTML(runner) {
1633
1671
  if (suite.root) return;
1634
1672
 
1635
1673
  // suite
1636
- var el = fragment('<div class="suite"><h1>%s</h1></div>', suite.title);
1674
+ var url = location.origin + location.pathname + '?grep=^' + utils.escapeRegexp(suite.fullTitle());
1675
+ var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, suite.title);
1637
1676
 
1638
1677
  // container
1639
1678
  stack[0].appendChild(el);
1640
- stack.unshift(document.createElement('div'));
1679
+ stack.unshift(document.createElement('ul'));
1641
1680
  el.appendChild(stack[0]);
1642
1681
  });
1643
1682
 
@@ -1663,11 +1702,11 @@ function HTML(runner) {
1663
1702
 
1664
1703
  // test
1665
1704
  if ('passed' == test.state) {
1666
- var el = fragment('<div class="test pass %e"><h2>%e<span class="duration">%ems</span></h2></div>', test.speed, test.title, test.duration);
1705
+ var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span></h2></li>', test.speed, test.title, test.duration);
1667
1706
  } else if (test.pending) {
1668
- var el = fragment('<div class="test pass pending"><h2>%e</h2></div>', test.title);
1707
+ var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
1669
1708
  } else {
1670
- var el = fragment('<div class="test fail"><h2>%e</h2></div>', test.title);
1709
+ var el = fragment('<li class="test fail"><h2>%e</h2></li>', test.title);
1671
1710
  var str = test.err.stack || test.err.toString();
1672
1711
 
1673
1712
  // FF / Opera do not add the message
@@ -2702,23 +2741,23 @@ function Teamcity(runner) {
2702
2741
  });
2703
2742
 
2704
2743
  runner.on('test', function(test) {
2705
- console.log("##teamcity[testStarted name='%s']", escape(test.fullTitle()));
2744
+ console.log("##teamcity[testStarted name='" + escape(test.fullTitle()) + "']");
2706
2745
  });
2707
2746
 
2708
2747
  runner.on('fail', function(test, err) {
2709
- console.log("##teamcity[testFailed name='%s' message='%s']", escape(test.fullTitle()), escape(err.message));
2748
+ console.log("##teamcity[testFailed name='" + escape(test.fullTitle()) + "' message='" + escape(err.message) + "']");
2710
2749
  });
2711
2750
 
2712
2751
  runner.on('pending', function(test) {
2713
- console.log("##teamcity[testIgnored name='%s' message='pending']", escape(test.fullTitle()));
2752
+ console.log("##teamcity[testIgnored name='" + escape(test.fullTitle()) + "' message='pending']");
2714
2753
  });
2715
2754
 
2716
2755
  runner.on('test end', function(test) {
2717
- console.log("##teamcity[testFinished name='%s' duration='%s']", escape(test.fullTitle()), test.duration);
2756
+ console.log("##teamcity[testFinished name='" + escape(test.fullTitle()) + "' duration='" + test.duration + "']");
2718
2757
  });
2719
2758
 
2720
2759
  runner.on('end', function() {
2721
- console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='%s']", stats.duration);
2760
+ console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='" + stats.duration + "']");
2722
2761
  });
2723
2762
  }
2724
2763
 
@@ -2727,8 +2766,18 @@ function Teamcity(runner) {
2727
2766
  */
2728
2767
 
2729
2768
  function escape(str) {
2730
- return str.replace(/'/g, "|'");
2769
+ return str
2770
+ .replace(/\|/g, "||")
2771
+ .replace(/\n/g, "|n")
2772
+ .replace(/\r/g, "|r")
2773
+ .replace(/\[/g, "|[")
2774
+ .replace(/\]/g, "|]")
2775
+ .replace(/\u0085/g, "|x")
2776
+ .replace(/\u2028/g, "|l")
2777
+ .replace(/\u2029/g, "|p")
2778
+ .replace(/'/g, "|'");
2731
2779
  }
2780
+
2732
2781
  }); // module: reporters/teamcity.js
2733
2782
 
2734
2783
  require.register("reporters/xunit.js", function(module, exports, require){
@@ -2741,6 +2790,16 @@ var Base = require('./base')
2741
2790
  , utils = require('../utils')
2742
2791
  , escape = utils.escape;
2743
2792
 
2793
+ /**
2794
+ * Save timer references to avoid Sinon interfering (see GH-237).
2795
+ */
2796
+
2797
+ var Date = global.Date
2798
+ , setTimeout = global.setTimeout
2799
+ , setInterval = global.setInterval
2800
+ , clearTimeout = global.clearTimeout
2801
+ , clearInterval = global.clearInterval;
2802
+
2744
2803
  /**
2745
2804
  * Expose `XUnit`.
2746
2805
  */
@@ -2847,6 +2906,16 @@ require.register("runnable.js", function(module, exports, require){
2847
2906
  var EventEmitter = require('browser/events').EventEmitter
2848
2907
  , debug = require('browser/debug')('runnable');
2849
2908
 
2909
+ /**
2910
+ * Save timer references to avoid Sinon interfering (see GH-237).
2911
+ */
2912
+
2913
+ var Date = global.Date
2914
+ , setTimeout = global.setTimeout
2915
+ , setInterval = global.setInterval
2916
+ , clearTimeout = global.clearTimeout
2917
+ , clearInterval = global.clearInterval;
2918
+
2850
2919
  /**
2851
2920
  * Expose `Runnable`.
2852
2921
  */
@@ -3151,6 +3220,9 @@ Runner.prototype.checkGlobals = function(test){
3151
3220
  Runner.prototype.fail = function(test, err){
3152
3221
  ++this.failures;
3153
3222
  test.state = 'failed';
3223
+ if ('string' == typeof err) {
3224
+ err = new Error('the string "' + err + '" was thrown, throw an Error :)');
3225
+ }
3154
3226
  this.emit('fail', test, err);
3155
3227
  };
3156
3228
 
@@ -3978,6 +4050,7 @@ exports.files = function(dir, ret){
3978
4050
  *
3979
4051
  * @param {String} str
3980
4052
  * @return {String}
4053
+ * @api private
3981
4054
  */
3982
4055
 
3983
4056
  exports.slug = function(str){
@@ -3986,6 +4059,18 @@ exports.slug = function(str){
3986
4059
  .replace(/ +/g, '-')
3987
4060
  .replace(/[^-\w]/g, '');
3988
4061
  };
4062
+
4063
+ /**
4064
+ * Escape regular expression characters in `str`.
4065
+ *
4066
+ * @param {String} str
4067
+ * @return {String}
4068
+ * @api private
4069
+ */
4070
+
4071
+ exports.escapeRegexp = function(str){
4072
+ return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
4073
+ };
3989
4074
  }); // module: utils.js
3990
4075
  /**
3991
4076
  * Node shims.
@@ -4,7 +4,16 @@ body {
4
4
  padding: 60px 50px;
5
5
  }
6
6
 
7
- #mocha h1, h2 {
7
+ #mocha ul, #mocha li {
8
+ margin: 0;
9
+ padding: 0;
10
+ }
11
+
12
+ #mocha ul {
13
+ list-style: none;
14
+ }
15
+
16
+ #mocha h1, #mocha h2 {
8
17
  margin: 0;
9
18
  }
10
19
 
@@ -14,6 +23,15 @@ body {
14
23
  font-weight: 200;
15
24
  }
16
25
 
26
+ #mocha h1 a {
27
+ text-decoration: none;
28
+ color: inherit;
29
+ }
30
+
31
+ #mocha h1 a:hover {
32
+ text-decoration: underline;
33
+ }
34
+
17
35
  #mocha .suite .suite h1 {
18
36
  margin-top: 0;
19
37
  font-size: .8em;
@@ -62,6 +80,7 @@ body {
62
80
  display: block;
63
81
  float: left;
64
82
  margin-right: 5px;
83
+ color: #00d6b2;
65
84
  }
66
85
 
67
86
  #mocha .test.pass .duration {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: konacha
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-29 00:00:00.000000000 Z
12
+ date: 2012-06-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -224,15 +224,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
224
224
  - - ! '>='
225
225
  - !ruby/object:Gem::Version
226
226
  version: '0'
227
+ segments:
228
+ - 0
229
+ hash: 2642027270440006025
227
230
  required_rubygems_version: !ruby/object:Gem::Requirement
228
231
  none: false
229
232
  requirements:
230
233
  - - ! '>='
231
234
  - !ruby/object:Gem::Version
232
235
  version: '0'
236
+ segments:
237
+ - 0
238
+ hash: 2642027270440006025
233
239
  requirements: []
234
240
  rubyforge_project:
235
- rubygems_version: 1.8.23
241
+ rubygems_version: 1.8.24
236
242
  signing_key:
237
243
  specification_version: 3
238
244
  summary: Unit-test your Rails JavaScript with the mocha test framework and chai assertion