konacha 0.9.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.
Files changed (51) hide show
  1. data/.gitignore +19 -0
  2. data/Gemfile +7 -0
  3. data/LICENSE +90 -0
  4. data/README.md +199 -0
  5. data/Rakefile +8 -0
  6. data/app/controllers/konacha/specs_controller.rb +22 -0
  7. data/app/models/konacha/spec.rb +25 -0
  8. data/app/views/konacha/specs/index.html.erb +1 -0
  9. data/app/views/konacha/specs/show.html.erb +1 -0
  10. data/app/views/layouts/konacha/specs.html.erb +31 -0
  11. data/config/routes.rb +4 -0
  12. data/konacha.gemspec +30 -0
  13. data/lib/konacha.rb +41 -0
  14. data/lib/konacha/engine.rb +31 -0
  15. data/lib/konacha/runner.rb +151 -0
  16. data/lib/konacha/server.rb +7 -0
  17. data/lib/tasks/konacha.rake +11 -0
  18. data/spec/controllers/specs_controller_spec.rb +46 -0
  19. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  20. data/spec/dummy/app/assets/javascripts/array_sum.js.coffee +4 -0
  21. data/spec/dummy/config.ru +4 -0
  22. data/spec/dummy/config/application.rb +17 -0
  23. data/spec/dummy/config/boot.rb +6 -0
  24. data/spec/dummy/config/environment.rb +5 -0
  25. data/spec/dummy/config/environments/test.rb +29 -0
  26. data/spec/dummy/config/initializers/konacha.rb +3 -0
  27. data/spec/dummy/spec/javascripts/array_sum_cs_spec.js.coffee +8 -0
  28. data/spec/dummy/spec/javascripts/array_sum_js_spec.js +11 -0
  29. data/spec/dummy/spec/javascripts/assert_spec.js.coffee +9 -0
  30. data/spec/dummy/spec/javascripts/failing_spec.js +5 -0
  31. data/spec/dummy/spec/javascripts/spec_helper.js +3 -0
  32. data/spec/dummy/spec/javascripts/spec_helper_spec.js +7 -0
  33. data/spec/dummy/spec/javascripts/subdirectory/subdirectory_spec.js +5 -0
  34. data/spec/dummy/spec/javascripts/templates/hello.jst.ejs +1 -0
  35. data/spec/dummy/spec/javascripts/templating_spec.js +8 -0
  36. data/spec/dummy/spec/javascripts/transactions_spec.js.coffee +7 -0
  37. data/spec/konacha_spec.rb +40 -0
  38. data/spec/models/spec_spec.rb +45 -0
  39. data/spec/runner_spec.rb +36 -0
  40. data/spec/server_spec.rb +41 -0
  41. data/spec/spec_helper.rb +18 -0
  42. data/spec/views/specs/index.html.erb_spec.rb +12 -0
  43. data/spec/views/specs/show.html.erb_spec.rb +10 -0
  44. data/spec/views/specs/specs.html.erb_spec.rb +15 -0
  45. data/vendor/assets/images/konacha.jpg +0 -0
  46. data/vendor/assets/javascripts/chai.js +2007 -0
  47. data/vendor/assets/javascripts/konacha/runner.js +70 -0
  48. data/vendor/assets/javascripts/konacha/server.js +0 -0
  49. data/vendor/assets/javascripts/mocha.js +3290 -0
  50. data/vendor/assets/stylesheets/mocha.css +133 -0
  51. metadata +203 -0
@@ -0,0 +1,5 @@
1
+ describe("spec in subdirectory", function(){
2
+ it("passes", function(){
3
+ (2 + 2).should.equal(4);
4
+ });
5
+ });
@@ -0,0 +1 @@
1
+ <h1>Hello Konacha!</h1>
@@ -0,0 +1,8 @@
1
+ //= require spec_helper
2
+
3
+ describe("templating", function(){
4
+ it("is built in to Sprockets", function(){
5
+ $('#test').html(JST['templates/hello']());
6
+ $('#test h1').text().should.equal('Hello Konacha!');
7
+ });
8
+ });
@@ -0,0 +1,7 @@
1
+ describe "transactions", ->
2
+ it "should add stuff in one test...", ->
3
+ $('#test').append('<h1 id="added">New Stuff</h1>')
4
+ $('#test h1#added').length.should.equal(1)
5
+
6
+ it "... should have been removed before the next starts", ->
7
+ $('#test h1#added').length.should.equal(0)
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Konacha do
4
+ describe ".config" do
5
+ subject { Konacha.config }
6
+
7
+ describe ".interface" do
8
+ it "defaults to :bdd interface" do
9
+ subject.interface.should == :bdd
10
+ end
11
+ end
12
+
13
+ describe ".spec_dir" do
14
+ it "defaults to 'spec/javascripts'" do
15
+ subject.spec_dir.should == "spec/javascripts"
16
+ end
17
+ end
18
+ end
19
+
20
+ describe ".spec_paths" do
21
+ subject { Konacha.spec_paths }
22
+
23
+ it "returns an array of paths relative to spec_dir" do
24
+ subject.should include("array_sum_js_spec.js")
25
+ subject.should include("array_sum_cs_spec.js.coffee")
26
+ end
27
+
28
+ it "includes subdirectories" do
29
+ subject.should include("subdirectory/subdirectory_spec.js")
30
+ end
31
+
32
+ it "does not include spec_helper" do
33
+ subject.should_not include("spec_helper.js")
34
+ end
35
+ end
36
+
37
+ it "can be configured in an initializer" do
38
+ Konacha.config.configured.should == true
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Konacha::Spec do
4
+ describe "#basename" do
5
+ it "is the basename of the path" do
6
+ described_class.new("array_spec.js").basename.should == "array_spec"
7
+ end
8
+
9
+ it "ignores multiple extensions" do
10
+ described_class.new("array_spec.js.coffee").basename.should == "array_spec"
11
+ end
12
+
13
+ it "includes relative path" do
14
+ described_class.new("subdirectory/array_spec.js").basename.should == "subdirectory/array_spec"
15
+ end
16
+ end
17
+
18
+ describe "#url" do
19
+ it "returns a URL path" do
20
+ described_class.new("array_spec.js").url.should == "/array_spec"
21
+ end
22
+ end
23
+
24
+ describe ".all" do
25
+ it "returns an array of specs" do
26
+ Konacha.should_receive(:spec_paths) { ["a_spec.js", "b_spec.js"] }
27
+ all = described_class.all
28
+ all.length.should == 2
29
+ end
30
+ end
31
+
32
+ describe ".find" do
33
+ it "returns the Spec with the given basename" do
34
+ all = [described_class.new("a_spec.js"),
35
+ described_class.new("b_spec.js")]
36
+ described_class.should_receive(:all) { all }
37
+ described_class.find("b_spec").should == all[1]
38
+ end
39
+
40
+ it "returns nil if no such spec exists" do
41
+ described_class.should_receive(:all) { [] }
42
+ described_class.find("b_spec").should be_nil
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Konacha::Runner do
4
+ before do
5
+ Konacha.mode = :runner
6
+ Konacha.config.driver = :selenium_with_firebug
7
+ end
8
+
9
+ let(:runner) { Konacha::Runner.new(:output => buffer) }
10
+ let(:buffer) { StringIO.new }
11
+
12
+ describe "#run" do
13
+ before { runner.run }
14
+
15
+ it "prints results to the output" do
16
+ buffer.rewind
17
+ results = buffer.read
18
+ results.should include(".......F.....")
19
+ results.should include("expected 4 to equal 5")
20
+ results.should include("13 examples, 1 failure")
21
+ end
22
+ end
23
+
24
+ describe "#run_spec" do
25
+ let(:spec) { Konacha::Spec.find("failing_spec") }
26
+ before { runner.spec_runner(spec).run }
27
+
28
+ it "prints results to the output" do
29
+ buffer.rewind
30
+ results = buffer.read
31
+ results.should include('F')
32
+ results.should include("expected 4 to equal 5")
33
+ results.should include("1 examples, 1 failures")
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Konacha::Server, :type => :request do
4
+ def app
5
+ Konacha.application
6
+ end
7
+
8
+ before do
9
+ Konacha.mode = :server
10
+ end
11
+
12
+ it "serves a root page" do
13
+ visit "/"
14
+ page.should have_content("Array#sum (js)")
15
+ page.should have_css(".test.pass")
16
+ end
17
+
18
+ it "serves an individual JavaScript spec" do
19
+ visit "/array_sum_js_spec"
20
+ page.should have_content("Array#sum (js)")
21
+ page.should have_css(".test.pass", :count => 2)
22
+ end
23
+
24
+ it "serves an individual CoffeeScript spec" do
25
+ visit "/array_sum_cs_spec"
26
+ page.should have_content("Array#sum (cs)")
27
+ page.should have_css(".test.pass", :count => 2)
28
+ end
29
+
30
+ it "serves a spec in a subdirectory" do
31
+ visit "/subdirectory/subdirectory_spec"
32
+ page.should have_content("spec in subdirectory")
33
+ page.should have_css(".test.pass")
34
+ end
35
+
36
+ it "supports spec helpers" do
37
+ visit "/spec_helper_spec"
38
+ page.should have_content("two_plus_two")
39
+ page.should have_css(".test.pass")
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+
3
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
4
+ require "rspec/rails"
5
+ require "rspec/autorun"
6
+
7
+ # Requires supporting ruby files with custom matchers and macros, etc,
8
+ # in spec/support/ and its subdirectories.
9
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
10
+
11
+ require "capybara/rails"
12
+ require "capybara/firebug"
13
+
14
+ Capybara.configure do |config|
15
+ config.default_selector = :css
16
+ config.default_driver = :selenium_with_firebug
17
+ config.app = Konacha.application
18
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe "konacha/specs/index" do
4
+ it "renders a script tag for each basename in @specs" do
5
+ a_spec = stub(:basename => "a_spec")
6
+ b_spec = stub(:basename => "b_spec")
7
+ assign(:specs, [a_spec, b_spec])
8
+ render
9
+ rendered.should have_selector("script[src='/assets/a_spec.js']")
10
+ rendered.should have_selector("script[src='/assets/b_spec.js']")
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe "konacha/specs/show" do
4
+ it "renders a script tag for @spec basename" do
5
+ spec = stub(:basename => "spec")
6
+ assign(:spec, spec)
7
+ render
8
+ rendered.should have_selector("script[src='/assets/spec.js']")
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe "layouts/konacha/specs" do
4
+ it "sets up the specified interface" do
5
+ assign(:interface, :tdd)
6
+ render
7
+ rendered.should include('mocha.setup("tdd")')
8
+ end
9
+
10
+ it "includes konacha JS for given mode" do
11
+ assign(:mode, :runner)
12
+ render
13
+ rendered.should have_css("script[src='/assets/konacha/runner.js']")
14
+ end
15
+ end
Binary file
@@ -0,0 +1,2007 @@
1
+ !function (name, definition) {
2
+ if (typeof define == 'function' && typeof define.amd == 'object') define(definition);
3
+ else this[name] = definition();
4
+ }('chai', function () {
5
+
6
+ // CommonJS require()
7
+
8
+ function require(p){
9
+ var path = require.resolve(p)
10
+ , mod = require.modules[path];
11
+ if (!mod) throw new Error('failed to require "' + p + '"');
12
+ if (!mod.exports) {
13
+ mod.exports = {};
14
+ mod.call(mod.exports, mod, mod.exports, require.relative(path));
15
+ }
16
+ return mod.exports;
17
+ }
18
+
19
+ require.modules = {};
20
+
21
+ require.resolve = function (path){
22
+ var orig = path
23
+ , reg = path + '.js'
24
+ , index = path + '/index.js';
25
+ return require.modules[reg] && reg
26
+ || require.modules[index] && index
27
+ || orig;
28
+ };
29
+
30
+ require.register = function (path, fn){
31
+ require.modules[path] = fn;
32
+ };
33
+
34
+ require.relative = function (parent) {
35
+ return function(p){
36
+ if ('.' != p[0]) return require(p);
37
+
38
+ var path = parent.split('/')
39
+ , segs = p.split('/');
40
+ path.pop();
41
+
42
+ for (var i = 0; i < segs.length; i++) {
43
+ var seg = segs[i];
44
+ if ('..' == seg) path.pop();
45
+ else if ('.' != seg) path.push(seg);
46
+ }
47
+
48
+ return require(path.join('/'));
49
+ };
50
+ };
51
+
52
+
53
+ require.register("assertion.js", function(module, exports, require){
54
+ /*!
55
+ * chai
56
+ * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
57
+ * MIT Licensed
58
+ *
59
+ * Primarily a refactor of: should.js
60
+ * https://github.com/visionmedia/should.js
61
+ * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
62
+ * MIT Licensed
63
+ */
64
+
65
+ /**
66
+ * ### BDD Style Introduction
67
+ *
68
+ * The BDD style is exposed through `expect` or `should` interfaces. In both
69
+ * scenarios, you chain together natural language assertions.
70
+ *
71
+ * // expect
72
+ * var expect = require('chai').expect;
73
+ * expect(foo).to.equal('bar');
74
+ *
75
+ * // should
76
+ * var should = require('chai').should();
77
+ * foo.should.equal('bar');
78
+ *
79
+ * #### Differences
80
+ *
81
+ * The `expect` interface provides a function as a starting point for chaining
82
+ * your language assertions. It works on both node.js and in the browser.
83
+ *
84
+ * The `should` interface extends `Object.prototype` to provide a single getter as
85
+ * the starting point for your language assertions. Most browser don't like
86
+ * extensions to `Object.prototype` so it is not recommended for browser use.
87
+ */
88
+
89
+ /*!
90
+ * Module dependencies.
91
+ */
92
+
93
+ var AssertionError = require('./error')
94
+ , eql = require('./utils/eql')
95
+ , inspect = require('./utils/inspect');
96
+
97
+ /*!
98
+ * Module export.
99
+ */
100
+
101
+ module.exports = Assertion;
102
+
103
+ /*!
104
+ * # Assertion Constructor
105
+ *
106
+ * Creates object for chaining.
107
+ *
108
+ * @api private
109
+ */
110
+
111
+ function Assertion (obj, msg, stack) {
112
+ this.ssfi = stack || arguments.callee;
113
+ this.obj = obj;
114
+ this.msg = msg;
115
+ }
116
+
117
+ /*!
118
+ * # .assert(expression, message, negateMessage)
119
+ *
120
+ * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
121
+ *
122
+ * @name assert
123
+ * @param {Philosophical} expression to be tested
124
+ * @param {String} message to display if fails
125
+ * @param {String} negatedMessage to display if negated expression fails
126
+ * @api privage
127
+ */
128
+
129
+ Assertion.prototype.assert = function (expr, msg, negateMsg) {
130
+ var msg = (this.negate ? negateMsg : msg)
131
+ , ok = this.negate ? !expr : expr;
132
+
133
+ if (!ok) {
134
+ throw new AssertionError({
135
+ operator: this.msg,
136
+ message: msg,
137
+ stackStartFunction: this.ssfi
138
+ });
139
+ }
140
+ };
141
+
142
+ /*!
143
+ * # inspect
144
+ *
145
+ * Returns the current object stringified.
146
+ *
147
+ * @name inspect
148
+ * @api private
149
+ */
150
+
151
+ Object.defineProperty(Assertion.prototype, 'inspect',
152
+ { get: function () {
153
+ return inspect(this.obj);
154
+ },
155
+ configurable: true
156
+ });
157
+
158
+ /**
159
+ * # to
160
+ *
161
+ * Language chain.
162
+ *
163
+ * @name to
164
+ * @api public
165
+ */
166
+
167
+ Object.defineProperty(Assertion.prototype, 'to',
168
+ { get: function () {
169
+ return this;
170
+ },
171
+ configurable: true
172
+ });
173
+
174
+ /**
175
+ * # be
176
+ *
177
+ * Language chain.
178
+ *
179
+ * @name be
180
+ * @api public
181
+ */
182
+
183
+ Object.defineProperty(Assertion.prototype, 'be',
184
+ { get: function () {
185
+ return this;
186
+ },
187
+ configurable: true
188
+ });
189
+
190
+ /**
191
+ * # been
192
+ *
193
+ * Language chain. Also tests `tense` to past for addon
194
+ * modules that use the tense feature.
195
+ *
196
+ * @name been
197
+ * @api public
198
+ */
199
+
200
+ Object.defineProperty(Assertion.prototype, 'been',
201
+ { get: function () {
202
+ this.tense = 'past';
203
+ return this;
204
+ },
205
+ configurable: true
206
+ });
207
+
208
+ /**
209
+ * # an
210
+ *
211
+ * Language chain.
212
+ *
213
+ * @name an
214
+ * @api public
215
+ */
216
+
217
+ Object.defineProperty(Assertion.prototype, 'an',
218
+ { get: function () {
219
+ return this;
220
+ },
221
+ configurable: true
222
+ });
223
+ /**
224
+ * # is
225
+ *
226
+ * Language chain.
227
+ *
228
+ * @name is
229
+ * @api public
230
+ */
231
+
232
+ Object.defineProperty(Assertion.prototype, 'is',
233
+ { get: function () {
234
+ return this;
235
+ },
236
+ configurable: true
237
+ });
238
+
239
+ /**
240
+ * # and
241
+ *
242
+ * Language chain.
243
+ *
244
+ * @name and
245
+ * @api public
246
+ */
247
+
248
+ Object.defineProperty(Assertion.prototype, 'and',
249
+ { get: function () {
250
+ return this;
251
+ },
252
+ configurable: true
253
+ });
254
+
255
+ /**
256
+ * # have
257
+ *
258
+ * Language chain.
259
+ *
260
+ * @name have
261
+ * @api public
262
+ */
263
+
264
+ Object.defineProperty(Assertion.prototype, 'have',
265
+ { get: function () {
266
+ return this;
267
+ },
268
+ configurable: true
269
+ });
270
+
271
+ /**
272
+ * # with
273
+ *
274
+ * Language chain.
275
+ *
276
+ * @name with
277
+ * @api public
278
+ */
279
+
280
+ Object.defineProperty(Assertion.prototype, 'with',
281
+ { get: function () {
282
+ return this;
283
+ },
284
+ configurable: true
285
+ });
286
+
287
+ /**
288
+ * # .not
289
+ *
290
+ * Negates any of assertions following in the chain.
291
+ *
292
+ * @name not
293
+ * @api public
294
+ */
295
+
296
+ Object.defineProperty(Assertion.prototype, 'not',
297
+ { get: function () {
298
+ this.negate = true;
299
+ return this;
300
+ },
301
+ configurable: true
302
+ });
303
+
304
+ /**
305
+ * # .ok
306
+ *
307
+ * Assert object truthiness.
308
+ *
309
+ * expect('everthing').to.be.ok;
310
+ * expect(false).to.not.be.ok;
311
+ * expect(undefined).to.not.be.ok;
312
+ * expect(null).to.not.be.ok;
313
+ *
314
+ * @name ok
315
+ * @api public
316
+ */
317
+
318
+ Object.defineProperty(Assertion.prototype, 'ok',
319
+ { get: function () {
320
+ this.assert(
321
+ this.obj
322
+ , 'expected ' + this.inspect + ' to be truthy'
323
+ , 'expected ' + this.inspect + ' to be falsey');
324
+
325
+ return this;
326
+ },
327
+ configurable: true
328
+ });
329
+
330
+ /**
331
+ * # .true
332
+ *
333
+ * Assert object is true
334
+ *
335
+ * @name true
336
+ * @api public
337
+ */
338
+
339
+ Object.defineProperty(Assertion.prototype, 'true',
340
+ { get: function () {
341
+ this.assert(
342
+ true === this.obj
343
+ , 'expected ' + this.inspect + ' to be true'
344
+ , 'expected ' + this.inspect + ' to be false');
345
+
346
+ return this;
347
+ },
348
+ configurable: true
349
+ });
350
+
351
+ /**
352
+ * # .false
353
+ *
354
+ * Assert object is false
355
+ *
356
+ * @name false
357
+ * @api public
358
+ */
359
+
360
+ Object.defineProperty(Assertion.prototype, 'false',
361
+ { get: function () {
362
+ this.assert(
363
+ false === this.obj
364
+ , 'expected ' + this.inspect + ' to be false'
365
+ , 'expected ' + this.inspect + ' to be true');
366
+
367
+ return this;
368
+ },
369
+ configurable: true
370
+ });
371
+
372
+ /**
373
+ * # .exist
374
+ *
375
+ * Assert object exists (null).
376
+ *
377
+ * var foo = 'hi'
378
+ * , bar;
379
+ * expect(foo).to.exist;
380
+ * expect(bar).to.not.exist;
381
+ *
382
+ * @name exist
383
+ * @api public
384
+ */
385
+
386
+ Object.defineProperty(Assertion.prototype, 'exist',
387
+ { get: function () {
388
+ this.assert(
389
+ null != this.obj
390
+ , 'expected ' + this.inspect + ' to exist'
391
+ , 'expected ' + this.inspect + ' to not exist');
392
+
393
+ return this;
394
+ },
395
+ configurable: true
396
+ });
397
+
398
+ /**
399
+ * # .empty
400
+ *
401
+ * Assert object's length to be 0.
402
+ *
403
+ * expect([]).to.be.empty;
404
+ *
405
+ * @name empty
406
+ * @api public
407
+ */
408
+
409
+ Object.defineProperty(Assertion.prototype, 'empty',
410
+ { get: function () {
411
+ new Assertion(this.obj).to.have.property('length');
412
+
413
+ this.assert(
414
+ 0 === this.obj.length
415
+ , 'expected ' + this.inspect + ' to be empty'
416
+ , 'expected ' + this.inspect + ' not to be empty');
417
+
418
+ return this;
419
+ },
420
+ configurable: true
421
+ });
422
+
423
+ /**
424
+ * # .arguments
425
+ *
426
+ * Assert object is an instanceof arguments.
427
+ *
428
+ * function test () {
429
+ * expect(arguments).to.be.arguments;
430
+ * }
431
+ *
432
+ * @name arguments
433
+ * @api public
434
+ */
435
+
436
+ Object.defineProperty(Assertion.prototype, 'arguments',
437
+ { get: function () {
438
+ this.assert(
439
+ '[object Arguments]' == Object.prototype.toString.call(this.obj)
440
+ , 'expected ' + this.inspect + ' to be arguments'
441
+ , 'expected ' + this.inspect + ' to not be arguments');
442
+
443
+ return this;
444
+ },
445
+ configurable: true
446
+ });
447
+
448
+ /**
449
+ * # .equal(value)
450
+ *
451
+ * Assert strict equality.
452
+ *
453
+ * expect('hello').to.equal('hello');
454
+ *
455
+ * @name equal
456
+ * @param {*} value
457
+ * @api public
458
+ */
459
+
460
+ Assertion.prototype.equal = function (val) {
461
+ this.assert(
462
+ val === this.obj
463
+ , 'expected ' + this.inspect + ' to equal ' + inspect(val)
464
+ , 'expected ' + this.inspect + ' to not equal ' + inspect(val));
465
+
466
+ return this;
467
+ };
468
+
469
+ /**
470
+ * # .eql(value)
471
+ *
472
+ * Assert deep equality.
473
+ *
474
+ * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
475
+ *
476
+ * @name eql
477
+ * @param {*} value
478
+ * @api public
479
+ */
480
+
481
+ Assertion.prototype.eql = function (obj) {
482
+ this.assert(
483
+ eql(obj, this.obj)
484
+ , 'expected ' + this.inspect + ' to equal ' + inspect(obj)
485
+ , 'expected ' + this.inspect + ' to not equal ' + inspect(obj));
486
+ return this;
487
+ };
488
+
489
+ /**
490
+ * # .above(value)
491
+ *
492
+ * Assert greater than `value`.
493
+ *
494
+ * expect(10).to.be.above(5);
495
+ *
496
+ * @name above
497
+ * @param {Number} value
498
+ * @api public
499
+ */
500
+
501
+ Assertion.prototype.above = function (val) {
502
+ this.assert(
503
+ this.obj > val
504
+ , 'expected ' + this.inspect + ' to be above ' + val
505
+ , 'expected ' + this.inspect + ' to be below ' + val);
506
+
507
+ return this;
508
+ };
509
+
510
+ /**
511
+ * # .below(value)
512
+ *
513
+ * Assert less than `value`.
514
+ *
515
+ * expect(5).to.be.below(10);
516
+ *
517
+ * @name below
518
+ * @param {Number} value
519
+ * @api public
520
+ */
521
+
522
+ Assertion.prototype.below = function (val) {
523
+ this.assert(
524
+ this.obj < val
525
+ , 'expected ' + this.inspect + ' to be below ' + val
526
+ , 'expected ' + this.inspect + ' to be above ' + val);
527
+
528
+ return this;
529
+ };
530
+
531
+ /**
532
+ * # .within(start, finish)
533
+ *
534
+ * Assert that a number is within a range.
535
+ *
536
+ * expect(7).to.be.within(5,10);
537
+ *
538
+ * @name within
539
+ * @param {Number} start lowerbound inclusive
540
+ * @param {Number} finish upperbound inclusive
541
+ * @api public
542
+ */
543
+
544
+ Assertion.prototype.within = function (start, finish) {
545
+ var range = start + '..' + finish;
546
+
547
+ this.assert(
548
+ this.obj >= start && this.obj <= finish
549
+ , 'expected ' + this.inspect + ' to be within ' + range
550
+ , 'expected ' + this.inspect + ' to not be within ' + range);
551
+
552
+ return this;
553
+ };
554
+
555
+ /**
556
+ * # .a(type)
557
+ *
558
+ * Assert typeof.
559
+ *
560
+ * expect('test').to.be.a('string');
561
+ *
562
+ * @name a
563
+ * @param {String} type
564
+ * @api public
565
+ */
566
+
567
+ Assertion.prototype.a = function (type) {
568
+ this.assert(
569
+ type == typeof this.obj
570
+ , 'expected ' + this.inspect + ' to be a ' + type
571
+ , 'expected ' + this.inspect + ' not to be a ' + type);
572
+
573
+ return this;
574
+ };
575
+
576
+ /**
577
+ * # .instanceof(constructor)
578
+ *
579
+ * Assert instanceof.
580
+ *
581
+ * var Tea = function (name) { this.name = name; }
582
+ * , Chai = new Tea('chai');
583
+ *
584
+ * expect(Chai).to.be.an.instanceOf(Tea);
585
+ *
586
+ * @name instanceof
587
+ * @param {Constructor}
588
+ * @alias instanceOf
589
+ * @api public
590
+ */
591
+
592
+ Assertion.prototype.instanceof = function (constructor) {
593
+ var name = constructor.name;
594
+ this.assert(
595
+ this.obj instanceof constructor
596
+ , 'expected ' + this.inspect + ' to be an instance of ' + name
597
+ , 'expected ' + this.inspect + ' to not be an instance of ' + name);
598
+
599
+ return this;
600
+ };
601
+
602
+ /**
603
+ * # .property(name, [value])
604
+ *
605
+ * Assert that property of `name` exists, optionally with `value`.
606
+ *
607
+ * var obj = { foo: 'bar' }
608
+ * expect(obj).to.have.property('foo');
609
+ * expect(obj).to.have.property('foo', 'bar');
610
+ * expect(obj).to.have.property('foo').to.be.a('string');
611
+ *
612
+ * @name property
613
+ * @param {String} name
614
+ * @param {*} value (optional)
615
+ * @returns value of property for chaining
616
+ * @api public
617
+ */
618
+
619
+ Assertion.prototype.property = function (name, val) {
620
+ if (this.negate && undefined !== val) {
621
+ if (undefined === this.obj[name]) {
622
+ throw new Error(this.inspect + ' has no property ' + inspect(name));
623
+ }
624
+ } else {
625
+ this.assert(
626
+ undefined !== this.obj[name]
627
+ , 'expected ' + this.inspect + ' to have a property ' + inspect(name)
628
+ , 'expected ' + this.inspect + ' to not have property ' + inspect(name));
629
+ }
630
+
631
+ if (undefined !== val) {
632
+ this.assert(
633
+ val === this.obj[name]
634
+ , 'expected ' + this.inspect + ' to have a property ' + inspect(name) + ' of ' +
635
+ inspect(val) + ', but got ' + inspect(this.obj[name])
636
+ , 'expected ' + this.inspect + ' to not have a property ' + inspect(name) + ' of ' + inspect(val));
637
+ }
638
+
639
+ this.obj = this.obj[name];
640
+ return this;
641
+ };
642
+
643
+ /**
644
+ * # .ownProperty(name)
645
+ *
646
+ * Assert that has own property by `name`.
647
+ *
648
+ * expect('test').to.have.ownProperty('length');
649
+ *
650
+ * @name ownProperty
651
+ * @alias haveOwnProperty
652
+ * @param {String} name
653
+ * @api public
654
+ */
655
+
656
+ Assertion.prototype.ownProperty = function (name) {
657
+ this.assert(
658
+ this.obj.hasOwnProperty(name)
659
+ , 'expected ' + this.inspect + ' to have own property ' + inspect(name)
660
+ , 'expected ' + this.inspect + ' to not have own property ' + inspect(name));
661
+ return this;
662
+ };
663
+
664
+ /**
665
+ * # .length(val)
666
+ *
667
+ * Assert that object has expected length.
668
+ *
669
+ * expect([1,2,3]).to.have.length(3);
670
+ * expect('foobar').to.have.length(6);
671
+ *
672
+ * @name length
673
+ * @alias lengthOf
674
+ * @param {Number} length
675
+ * @api public
676
+ */
677
+
678
+ Assertion.prototype.length = function (n) {
679
+ new Assertion(this.obj).to.have.property('length');
680
+ var len = this.obj.length;
681
+
682
+ this.assert(
683
+ len == n
684
+ , 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len
685
+ , 'expected ' + this.inspect + ' to not have a length of ' + len);
686
+
687
+ return this;
688
+ };
689
+
690
+ /**
691
+ * # .match(regexp)
692
+ *
693
+ * Assert that matches regular expression.
694
+ *
695
+ * expect('foobar').to.match(/^foo/);
696
+ *
697
+ * @name match
698
+ * @param {RegExp} RegularExpression
699
+ * @api public
700
+ */
701
+
702
+ Assertion.prototype.match = function (re) {
703
+ this.assert(
704
+ re.exec(this.obj)
705
+ , 'expected ' + this.inspect + ' to match ' + re
706
+ , 'expected ' + this.inspect + ' not to match ' + re);
707
+
708
+ return this;
709
+ };
710
+
711
+ /**
712
+ * # .include(obj)
713
+ *
714
+ * Assert the inclusion of an object in an Array or substring in string.
715
+ *
716
+ * expect([1,2,3]).to.contain(2);
717
+ *
718
+ * @name include
719
+ * @param {Object|String|Number} obj
720
+ * @api public
721
+ */
722
+
723
+ Assertion.prototype.include = function (obj) {
724
+ this.assert(
725
+ ~this.obj.indexOf(obj)
726
+ , 'expected ' + this.inspect + ' to include ' + inspect(obj)
727
+ , 'expected ' + this.inspect + ' to not include ' + inspect(obj));
728
+
729
+ return this;
730
+ };
731
+
732
+ /**
733
+ * # .string(string)
734
+ *
735
+ * Assert inclusion of string in string.
736
+ *
737
+ * expect('foobar').to.include.string('bar');
738
+ *
739
+ * @name string
740
+ * @param {String} string
741
+ * @api public
742
+ */
743
+
744
+ Assertion.prototype.string = function (str) {
745
+ new Assertion(this.obj).is.a('string');
746
+
747
+ this.assert(
748
+ ~this.obj.indexOf(str)
749
+ , 'expected ' + this.inspect + ' to contain ' + inspect(str)
750
+ , 'expected ' + this.inspect + ' to not contain ' + inspect(str));
751
+
752
+ return this;
753
+ };
754
+
755
+
756
+
757
+ /**
758
+ * # contain
759
+ *
760
+ * Toggles the `contain` flag for the `keys` assertion.
761
+ *
762
+ * @name contain
763
+ * @api public
764
+ */
765
+
766
+ Object.defineProperty(Assertion.prototype, 'contain',
767
+ { get: function () {
768
+ this.contains = true;
769
+ return this;
770
+ },
771
+ configurable: true
772
+ });
773
+
774
+ /**
775
+ * # .keys(key1, [key2], [...])
776
+ *
777
+ * Assert exact keys or the inclusing of keys using the `contain` modifier.
778
+ *
779
+ * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
780
+ * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
781
+ *
782
+ * @name keys
783
+ * @alias key
784
+ * @param {String|Array} Keys
785
+ * @api public
786
+ */
787
+
788
+ Assertion.prototype.keys = function(keys) {
789
+ var str
790
+ , ok = true;
791
+
792
+ keys = keys instanceof Array
793
+ ? keys
794
+ : Array.prototype.slice.call(arguments);
795
+
796
+ if (!keys.length) throw new Error('keys required');
797
+
798
+ var actual = Object.keys(this.obj)
799
+ , len = keys.length;
800
+
801
+ // Inclusion
802
+ ok = keys.every(function(key){
803
+ return ~actual.indexOf(key);
804
+ });
805
+
806
+ // Strict
807
+ if (!this.negate && !this.contains) {
808
+ ok = ok && keys.length == actual.length;
809
+ }
810
+
811
+ // Key string
812
+ if (len > 1) {
813
+ keys = keys.map(function(key){
814
+ return inspect(key);
815
+ });
816
+ var last = keys.pop();
817
+ str = keys.join(', ') + ', and ' + last;
818
+ } else {
819
+ str = inspect(keys[0]);
820
+ }
821
+
822
+ // Form
823
+ str = (len > 1 ? 'keys ' : 'key ') + str;
824
+
825
+ // Have / include
826
+ str = (this.contains ? 'contain ' : 'have ') + str;
827
+
828
+ // Assertion
829
+ this.assert(
830
+ ok
831
+ , 'expected ' + this.inspect + ' to ' + str
832
+ , 'expected ' + this.inspect + ' to not ' + str);
833
+
834
+ return this;
835
+ }
836
+
837
+ /**
838
+ * # .throw(constructor)
839
+ *
840
+ * Assert that a function will throw a specific type of error.
841
+ *
842
+ * var fn = function () { throw new ReferenceError(''); }
843
+ * expect(fn).to.throw(ReferenceError);
844
+ *
845
+ * @name throw
846
+ * @alias throws
847
+ * @alias Throw
848
+ * @param {ErrorConstructor} constructor
849
+ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
850
+ * @api public
851
+ */
852
+
853
+ Assertion.prototype.throw = function (constructor) {
854
+ new Assertion(this.obj).is.a('function');
855
+
856
+ var thrown = false;
857
+
858
+ try {
859
+ this.obj();
860
+ } catch (err) {
861
+ if (constructor && 'function' === typeof constructor && constructor.constructor != RegExp) {
862
+ this.assert(
863
+ err instanceof constructor && err.name == constructor.name
864
+ , 'expected ' + this.inspect + ' to throw ' + constructor.name + ' but a ' + err.name + ' was thrown'
865
+ , 'expected ' + this.inspect + ' to not throw ' + constructor.name );
866
+ return this;
867
+ } else if (constructor && constructor instanceof RegExp) {
868
+ this.assert(
869
+ constructor.exec(err.message)
870
+ , 'expected ' + this.inspect + ' to throw error matching ' + constructor + ' but got ' + inspect(err.message)
871
+ , 'expected ' + this.inspect + ' to throw error not matching ' + constructor);
872
+ return this;
873
+ } else {
874
+ thrown = true;
875
+ }
876
+ }
877
+
878
+ var name = (constructor ? constructor.name : 'an error');
879
+
880
+ this.assert(
881
+ thrown === true
882
+ , 'expected ' + this.inspect + ' to throw ' + name
883
+ , 'expected ' + this.inspect + ' to not throw ' + name);
884
+
885
+ return this;
886
+ };
887
+
888
+ /*!
889
+ * Aliases.
890
+ */
891
+
892
+ (function alias(name, as){
893
+ Assertion.prototype[as] = Assertion.prototype[name];
894
+ return alias;
895
+ })
896
+ ('length', 'lengthOf')
897
+ ('keys', 'key')
898
+ ('ownProperty', 'haveOwnProperty')
899
+ ('above', 'greaterThan')
900
+ ('below', 'lessThan')
901
+ ('throw', 'throws')
902
+ ('throw', 'Throw') // for troublesome browsers
903
+ ('instanceof', 'instanceOf');
904
+
905
+ }); // module: assertion.js
906
+
907
+ require.register("chai.js", function(module, exports, require){
908
+ /*!
909
+ * chai
910
+ * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
911
+ * MIT Licensed
912
+ */
913
+
914
+ var used = [];
915
+ var exports = module.exports = {};
916
+
917
+ exports.version = '0.3.3';
918
+
919
+ exports.Assertion = require('./assertion');
920
+ exports.AssertionError = require('./error');
921
+
922
+ exports.inspect = require('./utils/inspect');
923
+
924
+ exports.use = function (fn) {
925
+ if (!~used.indexOf(fn)) {
926
+ fn(this);
927
+ used.push(fn);
928
+ }
929
+
930
+ return this;
931
+ };
932
+
933
+ exports.fail = function (actual, expected, message, operator, stackStartFunction) {
934
+ throw new exports.AssertionError({
935
+ message: message,
936
+ actual: actual,
937
+ expected: expected,
938
+ operator: operator,
939
+ stackStartFunction: stackStartFunction
940
+ });
941
+ };
942
+
943
+ var expect = require('./interface/expect');
944
+ exports.use(expect);
945
+
946
+ var should = require('./interface/should');
947
+ exports.use(should);
948
+
949
+ var assert = require('./interface/assert');
950
+ exports.use(assert);
951
+
952
+ }); // module: chai.js
953
+
954
+ require.register("error.js", function(module, exports, require){
955
+ /*!
956
+ * chai
957
+ * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
958
+ * MIT Licensed
959
+ */
960
+
961
+ var fail = require('./chai').fail;
962
+
963
+ module.exports = AssertionError;
964
+
965
+ /*!
966
+ * Inspired by node.js assert module
967
+ * https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js
968
+ */
969
+ function AssertionError (options) {
970
+ options = options || {};
971
+ this.name = 'AssertionError';
972
+ this.message = options.message;
973
+ this.actual = options.actual;
974
+ this.expected = options.expected;
975
+ this.operator = options.operator;
976
+ var stackStartFunction = options.stackStartFunction || fail;
977
+
978
+ if (Error.captureStackTrace) {
979
+ Error.captureStackTrace(this, stackStartFunction);
980
+ }
981
+ }
982
+
983
+ AssertionError.prototype.__proto__ = Error.prototype;
984
+
985
+ AssertionError.prototype.summary = function() {
986
+ var str = '';
987
+
988
+ if (this.operator) {
989
+ str += 'In: \'' + this.operator + '\'\n\t';
990
+ }
991
+
992
+ str += '' + this.name + (this.message ? ': ' + this.message : '');
993
+
994
+ return str;
995
+ };
996
+
997
+ AssertionError.prototype.details = function() {
998
+ return this.summary();
999
+ };
1000
+
1001
+ AssertionError.prototype.toString = function() {
1002
+ return this.summary();
1003
+ };
1004
+ }); // module: error.js
1005
+
1006
+ require.register("interface/assert.js", function(module, exports, require){
1007
+ /*!
1008
+ * chai
1009
+ * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
1010
+ * MIT Licensed
1011
+ */
1012
+
1013
+ /**
1014
+ * ### TDD Style Introduction
1015
+ *
1016
+ * The TDD style is exposed through `assert` interfaces. This provides
1017
+ * the classic assert.`test` notation, similiar to that packaged with
1018
+ * node.js. This assert module, however, provides several additional
1019
+ * tests and is browser compatible.
1020
+ *
1021
+ * // assert
1022
+ * var assert = require('chai').assert;
1023
+ * , foo = 'bar';
1024
+ *
1025
+ * assert.typeOf(foo, 'string');
1026
+ * assert.equal(foo, 'bar');
1027
+ */
1028
+
1029
+ module.exports = function (chai) {
1030
+ /*!
1031
+ * Chai dependencies.
1032
+ */
1033
+ var Assertion = chai.Assertion
1034
+ , inspect = chai.inspect;
1035
+
1036
+ /*!
1037
+ * Module export.
1038
+ */
1039
+
1040
+ var assert = chai.assert = {};
1041
+
1042
+ /**
1043
+ * # .ok(object, [message])
1044
+ *
1045
+ * Assert object is truthy.
1046
+ *
1047
+ * assert.ok('everthing', 'everything is ok');
1048
+ * assert.ok(false, 'this will fail');
1049
+ *
1050
+ * @name ok
1051
+ * @param {*} object to test
1052
+ * @param {String} message
1053
+ * @api public
1054
+ */
1055
+
1056
+ assert.ok = function (val, msg) {
1057
+ new Assertion(val, msg).is.ok;
1058
+ };
1059
+
1060
+ /**
1061
+ * # .equal(actual, expected, [message])
1062
+ *
1063
+ * Assert strict equality.
1064
+ *
1065
+ * assert.equal(3, 3, 'these numbers are equal');
1066
+ *
1067
+ * @name equal
1068
+ * @param {*} actual
1069
+ * @param {*} expected
1070
+ * @param {String} message
1071
+ * @api public
1072
+ */
1073
+
1074
+ assert.equal = function (act, exp, msg) {
1075
+ var test = new Assertion(act, msg);
1076
+
1077
+ test.assert(
1078
+ exp == test.obj
1079
+ , 'expected ' + test.inspect + ' to equal ' + inspect(exp)
1080
+ , 'expected ' + test.inspect + ' to not equal ' + inspect(exp));
1081
+ };
1082
+
1083
+ /**
1084
+ * # .notEqual(actual, expected, [message])
1085
+ *
1086
+ * Assert not equal.
1087
+ *
1088
+ * assert.notEqual(3, 4, 'these numbers are not equal');
1089
+ *
1090
+ * @name notEqual
1091
+ * @param {*} actual
1092
+ * @param {*} expected
1093
+ * @param {String} message
1094
+ * @api public
1095
+ */
1096
+
1097
+ assert.notEqual = function (act, exp, msg) {
1098
+ var test = new Assertion(act, msg);
1099
+
1100
+ test.assert(
1101
+ exp != test.obj
1102
+ , 'expected ' + test.inspect + ' to equal ' + inspect(exp)
1103
+ , 'expected ' + test.inspect + ' to not equal ' + inspect(exp));
1104
+ };
1105
+
1106
+ /**
1107
+ * # .strictEqual(actual, expected, [message])
1108
+ *
1109
+ * Assert strict equality.
1110
+ *
1111
+ * assert.strictEqual(true, true, 'these booleans are strictly equal');
1112
+ *
1113
+ * @name strictEqual
1114
+ * @param {*} actual
1115
+ * @param {*} expected
1116
+ * @param {String} message
1117
+ * @api public
1118
+ */
1119
+
1120
+ assert.strictEqual = function (act, exp, msg) {
1121
+ new Assertion(act, msg).to.equal(exp);
1122
+ };
1123
+
1124
+ /**
1125
+ * # .notStrictEqual(actual, expected, [message])
1126
+ *
1127
+ * Assert strict equality.
1128
+ *
1129
+ * assert.notStrictEqual(1, true, 'these booleans are not strictly equal');
1130
+ *
1131
+ * @name notStrictEqual
1132
+ * @param {*} actual
1133
+ * @param {*} expected
1134
+ * @param {String} message
1135
+ * @api public
1136
+ */
1137
+
1138
+ assert.notStrictEqual = function (act, exp, msg) {
1139
+ new Assertion(act, msg).to.not.equal(exp);
1140
+ };
1141
+
1142
+ /**
1143
+ * # .deepEqual(actual, expected, [message])
1144
+ *
1145
+ * Assert not deep equality.
1146
+ *
1147
+ * assert.deepEqual({ tea: 'green' }, { tea: 'green' });
1148
+ *
1149
+ * @name deepEqual
1150
+ * @param {*} actual
1151
+ * @param {*} expected
1152
+ * @param {String} message
1153
+ * @api public
1154
+ */
1155
+
1156
+ assert.deepEqual = function (act, exp, msg) {
1157
+ new Assertion(act, msg).to.eql(exp);
1158
+ };
1159
+
1160
+ /**
1161
+ * # .notDeepEqual(actual, expected, [message])
1162
+ *
1163
+ * Assert not deep equality.
1164
+ *
1165
+ * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
1166
+ *
1167
+ * @name notDeepEqual
1168
+ * @param {*} actual
1169
+ * @param {*} expected
1170
+ * @param {String} message
1171
+ * @api public
1172
+ */
1173
+
1174
+ assert.notDeepEqual = function (act, exp, msg) {
1175
+ new Assertion(act, msg).to.not.eql(exp);
1176
+ };
1177
+
1178
+ /**
1179
+ * # .isTrue(value, [message])
1180
+ *
1181
+ * Assert `value` is true.
1182
+ *
1183
+ * var tea_served = true;
1184
+ * assert.isTrue(tea_served, 'the tea has been served');
1185
+ *
1186
+ * @name isTrue
1187
+ * @param {Boolean} value
1188
+ * @param {String} message
1189
+ * @api public
1190
+ */
1191
+
1192
+ assert.isTrue = function (val, msg) {
1193
+ new Assertion(val, msg).is.true;
1194
+ };
1195
+
1196
+ /**
1197
+ * # .isFalse(value, [message])
1198
+ *
1199
+ * Assert `value` is false.
1200
+ *
1201
+ * var tea_served = false;
1202
+ * assert.isFalse(tea_served, 'no tea yet? hmm...');
1203
+ *
1204
+ * @name isFalse
1205
+ * @param {Boolean} value
1206
+ * @param {String} message
1207
+ * @api public
1208
+ */
1209
+
1210
+ assert.isFalse = function (val, msg) {
1211
+ new Assertion(val, msg).is.false;
1212
+ };
1213
+
1214
+ /**
1215
+ * # .isNull(value, [message])
1216
+ *
1217
+ * Assert `value` is null.
1218
+ *
1219
+ * assert.isNull(err, 'no errors');
1220
+ *
1221
+ * @name isNull
1222
+ * @param {*} value
1223
+ * @param {String} message
1224
+ * @api public
1225
+ */
1226
+
1227
+ assert.isNull = function (val, msg) {
1228
+ new Assertion(val, msg).to.not.exist;
1229
+ };
1230
+
1231
+ /**
1232
+ * # .isNotNull(value, [message])
1233
+ *
1234
+ * Assert `value` is not null.
1235
+ *
1236
+ * var tea = 'tasty chai';
1237
+ * assert.isNotNull(tea, 'great, time for tea!');
1238
+ *
1239
+ * @name isNotNull
1240
+ * @param {*} value
1241
+ * @param {String} message
1242
+ * @api public
1243
+ */
1244
+
1245
+ assert.isNotNull = function (val, msg) {
1246
+ new Assertion(val, msg).to.exist;
1247
+ };
1248
+
1249
+ /**
1250
+ * # .isUndefined(value, [message])
1251
+ *
1252
+ * Assert `value` is undefined.
1253
+ *
1254
+ * assert.isUndefined(tea, 'no tea defined');
1255
+ *
1256
+ * @name isUndefined
1257
+ * @param {*} value
1258
+ * @param {String} message
1259
+ * @api public
1260
+ */
1261
+
1262
+ assert.isUndefined = function (val, msg) {
1263
+ new Assertion(val, msg).to.equal(undefined);
1264
+ };
1265
+
1266
+ /**
1267
+ * # .isFunction(value, [message])
1268
+ *
1269
+ * Assert `value` is a function.
1270
+ *
1271
+ * var serve_tea = function () { return 'cup of tea'; };
1272
+ * assert.isFunction(serve_tea, 'great, we can have tea now');
1273
+ *
1274
+ * @name isFunction
1275
+ * @param {Function} value
1276
+ * @param {String} message
1277
+ * @api public
1278
+ */
1279
+
1280
+ assert.isFunction = function (val, msg) {
1281
+ new Assertion(val, msg).to.be.a('function');
1282
+ };
1283
+
1284
+ /**
1285
+ * # .isObject(value, [message])
1286
+ *
1287
+ * Assert `value` is an object.
1288
+ *
1289
+ * var selection = { name: 'Chai', serve: 'with spices' };
1290
+ * assert.isObject(selection, 'tea selection is an object');
1291
+ *
1292
+ * @name isObject
1293
+ * @param {Object} value
1294
+ * @param {String} message
1295
+ * @api public
1296
+ */
1297
+
1298
+ assert.isObject = function (val, msg) {
1299
+ new Assertion(val, msg).to.be.a('object');
1300
+ };
1301
+
1302
+ /**
1303
+ * # .isArray(value, [message])
1304
+ *
1305
+ * Assert `value` is an instance of Array.
1306
+ *
1307
+ * var menu = [ 'green', 'chai', 'oolong' ];
1308
+ * assert.isArray(menu, 'what kind of tea do we want?');
1309
+ *
1310
+ * @name isArray
1311
+ * @param {*} value
1312
+ * @param {String} message
1313
+ * @api public
1314
+ */
1315
+
1316
+ assert.isArray = function (val, msg) {
1317
+ new Assertion(val, msg).to.be.instanceof(Array);
1318
+ };
1319
+
1320
+ /**
1321
+ * # .isString(value, [message])
1322
+ *
1323
+ * Assert `value` is a string.
1324
+ *
1325
+ * var teaorder = 'chai';
1326
+ * assert.isString(tea_order, 'order placed');
1327
+ *
1328
+ * @name isString
1329
+ * @param {String} value
1330
+ * @param {String} message
1331
+ * @api public
1332
+ */
1333
+
1334
+ assert.isString = function (val, msg) {
1335
+ new Assertion(val, msg).to.be.a('string');
1336
+ };
1337
+
1338
+ /**
1339
+ * # .isNumber(value, [message])
1340
+ *
1341
+ * Assert `value` is a number
1342
+ *
1343
+ * var cups = 2;
1344
+ * assert.isNumber(cups, 'how many cups');
1345
+ *
1346
+ * @name isNumber
1347
+ * @param {Number} value
1348
+ * @param {String} message
1349
+ * @api public
1350
+ */
1351
+
1352
+ assert.isNumber = function (val, msg) {
1353
+ new Assertion(val, msg).to.be.instanceof(Number);
1354
+ };
1355
+
1356
+ /**
1357
+ * # .isBoolean(value, [message])
1358
+ *
1359
+ * Assert `value` is a boolean
1360
+ *
1361
+ * var teaready = true
1362
+ * , teaserved = false;
1363
+ *
1364
+ * assert.isBoolean(tea_ready, 'is the tea ready');
1365
+ * assert.isBoolean(tea_served, 'has tea been served');
1366
+ *
1367
+ * @name isBoolean
1368
+ * @param {*} value
1369
+ * @param {String} message
1370
+ * @api public
1371
+ */
1372
+
1373
+ assert.isBoolean = function (val, msg) {
1374
+ new Assertion(val, msg).to.be.a('boolean');
1375
+ };
1376
+
1377
+ /**
1378
+ * # .typeOf(value, name, [message])
1379
+ *
1380
+ * Assert typeof `value` is `name`.
1381
+ *
1382
+ * assert.typeOf('tea', 'string', 'we have a string');
1383
+ *
1384
+ * @name typeOf
1385
+ * @param {*} value
1386
+ * @param {String} typeof name
1387
+ * @param {String} message
1388
+ * @api public
1389
+ */
1390
+
1391
+ assert.typeOf = function (val, type, msg) {
1392
+ new Assertion(val, msg).to.be.a(type);
1393
+ };
1394
+
1395
+ /**
1396
+ * # .instanceOf(object, constructor, [message])
1397
+ *
1398
+ * Assert `value` is instanceof `constructor`.
1399
+ *
1400
+ * var Tea = function (name) { this.name = name; }
1401
+ * , Chai = new Tea('chai');
1402
+ *
1403
+ * assert.instanceOf(Chai, Tea, 'chai is an instance of tea');
1404
+ *
1405
+ * @name instanceOf
1406
+ * @param {Object} object
1407
+ * @param {Constructor} constructor
1408
+ * @param {String} message
1409
+ * @api public
1410
+ */
1411
+
1412
+ assert.instanceOf = function (val, type, msg) {
1413
+ new Assertion(val, msg).to.be.instanceof(type);
1414
+ };
1415
+
1416
+ /**
1417
+ * # .include(value, includes, [message])
1418
+ *
1419
+ * Assert the inclusion of an object in another. Works
1420
+ * for strings and arrays.
1421
+ *
1422
+ * assert.include('foobar', 'bar', 'foobar contains string `var`);
1423
+ * assert.include([ 1, 2, 3], 3, 'array contains value);
1424
+ *
1425
+ * @name include
1426
+ * @param {Array|String} value
1427
+ * @param {*} includes
1428
+ * @param {String} message
1429
+ * @api public
1430
+ */
1431
+
1432
+ assert.include = function (exp, inc, msg) {
1433
+ var obj = new Assertion(exp, msg);
1434
+
1435
+ if (Array.isArray(exp)) {
1436
+ obj.to.include(inc);
1437
+ } else if ('string' === typeof exp) {
1438
+ obj.to.contain.string(inc);
1439
+ }
1440
+ };
1441
+
1442
+ /**
1443
+ * # .match(value, regex, [message])
1444
+ *
1445
+ * Assert that `value` matches regular expression.
1446
+ *
1447
+ * assert.match('foobar', /^foo/, 'Regexp matches');
1448
+ *
1449
+ * @name match
1450
+ * @param {*} value
1451
+ * @param {RegExp} RegularExpression
1452
+ * @param {String} message
1453
+ * @api public
1454
+ */
1455
+
1456
+ assert.match = function (exp, re, msg) {
1457
+ new Assertion(exp, msg).to.match(re);
1458
+ };
1459
+
1460
+ /**
1461
+ * # .length(value, constructor, [message])
1462
+ *
1463
+ * Assert that object has expected length.
1464
+ *
1465
+ * assert.length([1,2,3], 3, 'Array has length of 3');
1466
+ * assert.length('foobar', 5, 'String has length of 6');
1467
+ *
1468
+ * @name length
1469
+ * @param {*} value
1470
+ * @param {Number} length
1471
+ * @param {String} message
1472
+ * @api public
1473
+ */
1474
+
1475
+ assert.length = function (exp, len, msg) {
1476
+ new Assertion(exp, msg).to.have.length(len);
1477
+ };
1478
+
1479
+ /**
1480
+ * # .throws(function, [constructor/regexp], [message])
1481
+ *
1482
+ * Assert that a function will throw a specific
1483
+ * type of error.
1484
+ *
1485
+ * assert.throw(fn, ReferenceError, 'function throw reference error');
1486
+ *
1487
+ * @name throws
1488
+ * @alias throw
1489
+ * @param {Function} function to test
1490
+ * @param {ErrorConstructor} constructor
1491
+ * @param {String} message
1492
+ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
1493
+ * @api public
1494
+ */
1495
+
1496
+ assert.throws = function (fn, type, msg) {
1497
+ if ('string' === typeof type) {
1498
+ msg = type;
1499
+ type = null;
1500
+ }
1501
+
1502
+ new Assertion(fn, msg).to.throw(type);
1503
+ };
1504
+
1505
+ /**
1506
+ * # .doesNotThrow(function, [constructor/regexp], [message])
1507
+ *
1508
+ * Assert that a function will throw a specific
1509
+ * type of error.
1510
+ *
1511
+ * var fn = function (err) { if (err) throw Error(err) };
1512
+ * assert.doesNotThrow(fn, Error, 'function throw reference error');
1513
+ *
1514
+ * @name doesNotThrow
1515
+ * @param {Function} function to test
1516
+ * @param {ErrorConstructor} constructor
1517
+ * @param {String} message
1518
+ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
1519
+ * @api public
1520
+ */
1521
+
1522
+ assert.doesNotThrow = function (fn, type, msg) {
1523
+ if ('string' === typeof type) {
1524
+ msg = type;
1525
+ type = null;
1526
+ }
1527
+
1528
+ new Assertion(fn, msg).to.not.throw(type);
1529
+ };
1530
+
1531
+ /*!
1532
+ * Undocumented / untested
1533
+ */
1534
+
1535
+ assert.ifError = function (val, msg) {
1536
+ new Assertion(val, msg).to.not.be.ok;
1537
+ };
1538
+
1539
+ /*!
1540
+ * Aliases.
1541
+ */
1542
+
1543
+ (function alias(name, as){
1544
+ assert[as] = assert[name];
1545
+ return alias;
1546
+ })
1547
+ ('length', 'lengthOf')
1548
+ ('throws', 'throw');
1549
+ };
1550
+
1551
+ }); // module: interface/assert.js
1552
+
1553
+ require.register("interface/expect.js", function(module, exports, require){
1554
+ /*!
1555
+ * chai
1556
+ * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
1557
+ * MIT Licensed
1558
+ */
1559
+
1560
+ module.exports = function (chai) {
1561
+ chai.expect = function (val, message) {
1562
+ return new chai.Assertion(val, message);
1563
+ };
1564
+ };
1565
+
1566
+
1567
+ }); // module: interface/expect.js
1568
+
1569
+ require.register("interface/should.js", function(module, exports, require){
1570
+ /*!
1571
+ * chai
1572
+ * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
1573
+ * MIT Licensed
1574
+ */
1575
+
1576
+ module.exports = function (chai) {
1577
+ var Assertion = chai.Assertion;
1578
+
1579
+ chai.should = function () {
1580
+ // modify Object.prototype to have `should`
1581
+ Object.defineProperty(Object.prototype, 'should', {
1582
+ set: function(){},
1583
+ get: function(){
1584
+ if (this instanceof String || this instanceof Number) {
1585
+ return new Assertion(this.constructor(this));
1586
+ } else if (this instanceof Boolean) {
1587
+ return new Assertion(this == true);
1588
+ }
1589
+ return new Assertion(this);
1590
+ },
1591
+ configurable: true
1592
+ });
1593
+
1594
+ var should = {};
1595
+
1596
+ should.equal = function (val1, val2) {
1597
+ new Assertion(val1).to.equal(val2);
1598
+ };
1599
+
1600
+ should.throw = function (fn, err) {
1601
+ new Assertion(fn).to.throw(err);
1602
+ };
1603
+
1604
+ should.exist = function (val) {
1605
+ new Assertion(val).to.exist;
1606
+ }
1607
+
1608
+ // negation
1609
+ should.not = {}
1610
+
1611
+ should.not.equal = function (val1, val2) {
1612
+ new Assertion(val1).to.not.equal(val2);
1613
+ };
1614
+
1615
+ should.not.throw = function (fn, err) {
1616
+ new Assertion(fn).to.not.throw(err);
1617
+ };
1618
+
1619
+ should.not.exist = function (val) {
1620
+ new Assertion(val).to.not.exist;
1621
+ }
1622
+
1623
+ return should;
1624
+ };
1625
+ };
1626
+
1627
+ }); // module: interface/should.js
1628
+
1629
+ require.register("utils/eql.js", function(module, exports, require){
1630
+ // This is directly from Node.js assert
1631
+ // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js
1632
+
1633
+
1634
+ module.exports = _deepEqual;
1635
+
1636
+ // For browser implementation
1637
+ if (!Buffer) {
1638
+ var Buffer = {
1639
+ isBuffer: function () {
1640
+ return false;
1641
+ }
1642
+ };
1643
+ }
1644
+
1645
+ function _deepEqual(actual, expected) {
1646
+ // 7.1. All identical values are equivalent, as determined by ===.
1647
+ if (actual === expected) {
1648
+ return true;
1649
+
1650
+ } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
1651
+ if (actual.length != expected.length) return false;
1652
+
1653
+ for (var i = 0; i < actual.length; i++) {
1654
+ if (actual[i] !== expected[i]) return false;
1655
+ }
1656
+
1657
+ return true;
1658
+
1659
+ // 7.2. If the expected value is a Date object, the actual value is
1660
+ // equivalent if it is also a Date object that refers to the same time.
1661
+ } else if (actual instanceof Date && expected instanceof Date) {
1662
+ return actual.getTime() === expected.getTime();
1663
+
1664
+ // 7.3. Other pairs that do not both pass typeof value == 'object',
1665
+ // equivalence is determined by ==.
1666
+ } else if (typeof actual != 'object' && typeof expected != 'object') {
1667
+ return actual === expected;
1668
+
1669
+ // 7.4. For all other Object pairs, including Array objects, equivalence is
1670
+ // determined by having the same number of owned properties (as verified
1671
+ // with Object.prototype.hasOwnProperty.call), the same set of keys
1672
+ // (although not necessarily the same order), equivalent values for every
1673
+ // corresponding key, and an identical 'prototype' property. Note: this
1674
+ // accounts for both named and indexed properties on Arrays.
1675
+ } else {
1676
+ return objEquiv(actual, expected);
1677
+ }
1678
+ }
1679
+
1680
+ function isUndefinedOrNull(value) {
1681
+ return value === null || value === undefined;
1682
+ }
1683
+
1684
+ function isArguments(object) {
1685
+ return Object.prototype.toString.call(object) == '[object Arguments]';
1686
+ }
1687
+
1688
+ function objEquiv(a, b) {
1689
+ if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
1690
+ return false;
1691
+ // an identical 'prototype' property.
1692
+ if (a.prototype !== b.prototype) return false;
1693
+ //~~~I've managed to break Object.keys through screwy arguments passing.
1694
+ // Converting to array solves the problem.
1695
+ if (isArguments(a)) {
1696
+ if (!isArguments(b)) {
1697
+ return false;
1698
+ }
1699
+ a = pSlice.call(a);
1700
+ b = pSlice.call(b);
1701
+ return _deepEqual(a, b);
1702
+ }
1703
+ try {
1704
+ var ka = Object.keys(a),
1705
+ kb = Object.keys(b),
1706
+ key, i;
1707
+ } catch (e) {//happens when one is a string literal and the other isn't
1708
+ return false;
1709
+ }
1710
+ // having the same number of owned properties (keys incorporates
1711
+ // hasOwnProperty)
1712
+ if (ka.length != kb.length)
1713
+ return false;
1714
+ //the same set of keys (although not necessarily the same order),
1715
+ ka.sort();
1716
+ kb.sort();
1717
+ //~~~cheap key test
1718
+ for (i = ka.length - 1; i >= 0; i--) {
1719
+ if (ka[i] != kb[i])
1720
+ return false;
1721
+ }
1722
+ //equivalent values for every corresponding key, and
1723
+ //~~~possibly expensive deep test
1724
+ for (i = ka.length - 1; i >= 0; i--) {
1725
+ key = ka[i];
1726
+ if (!_deepEqual(a[key], b[key])) return false;
1727
+ }
1728
+ return true;
1729
+ }
1730
+ }); // module: utils/eql.js
1731
+
1732
+ require.register("utils/inspect.js", function(module, exports, require){
1733
+ // This is (almost) directly from Node.js utils
1734
+ // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
1735
+
1736
+ module.exports = inspect;
1737
+
1738
+ /**
1739
+ * Echos the value of a value. Trys to print the value out
1740
+ * in the best way possible given the different types.
1741
+ *
1742
+ * @param {Object} obj The object to print out.
1743
+ * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
1744
+ * properties of objects.
1745
+ * @param {Number} depth Depth in which to descend in object. Default is 2.
1746
+ * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
1747
+ * output. Default is false (no coloring).
1748
+ */
1749
+ function inspect(obj, showHidden, depth, colors) {
1750
+ var ctx = {
1751
+ showHidden: showHidden,
1752
+ seen: [],
1753
+ stylize: function (str) { return str; }
1754
+ };
1755
+ return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
1756
+ }
1757
+
1758
+ function formatValue(ctx, value, recurseTimes) {
1759
+ // Provide a hook for user-specified inspect functions.
1760
+ // Check that value is an object with an inspect function on it
1761
+ if (value && typeof value.inspect === 'function' &&
1762
+ // Filter out the util module, it's inspect function is special
1763
+ value.inspect !== exports.inspect &&
1764
+ // Also filter out any prototype objects using the circular check.
1765
+ !(value.constructor && value.constructor.prototype === value)) {
1766
+ return value.inspect(recurseTimes);
1767
+ }
1768
+
1769
+ // Primitive types cannot have properties
1770
+ var primitive = formatPrimitive(ctx, value);
1771
+ if (primitive) {
1772
+ return primitive;
1773
+ }
1774
+
1775
+ // Look up the keys of the object.
1776
+ var visibleKeys = Object.keys(value);
1777
+ var keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : visibleKeys;
1778
+
1779
+ // Some type of object without properties can be shortcutted.
1780
+ if (keys.length === 0) {
1781
+ if (typeof value === 'function') {
1782
+ var name = value.name ? ': ' + value.name : '';
1783
+ return ctx.stylize('[Function' + name + ']', 'special');
1784
+ }
1785
+ if (isRegExp(value)) {
1786
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
1787
+ }
1788
+ if (isDate(value)) {
1789
+ return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
1790
+ }
1791
+ if (isError(value)) {
1792
+ return formatError(value);
1793
+ }
1794
+ }
1795
+
1796
+ var base = '', array = false, braces = ['{', '}'];
1797
+
1798
+ // Make Array say that they are Array
1799
+ if (isArray(value)) {
1800
+ array = true;
1801
+ braces = ['[', ']'];
1802
+ }
1803
+
1804
+ // Make functions say that they are functions
1805
+ if (typeof value === 'function') {
1806
+ var n = value.name ? ': ' + value.name : '';
1807
+ base = ' [Function' + n + ']';
1808
+ }
1809
+
1810
+ // Make RegExps say that they are RegExps
1811
+ if (isRegExp(value)) {
1812
+ base = ' ' + RegExp.prototype.toString.call(value);
1813
+ }
1814
+
1815
+ // Make dates with properties first say the date
1816
+ if (isDate(value)) {
1817
+ base = ' ' + Date.prototype.toUTCString.call(value);
1818
+ }
1819
+
1820
+ // Make error with message first say the error
1821
+ if (isError(value)) {
1822
+ base = ' ' + formatError(value);
1823
+ }
1824
+
1825
+ if (keys.length === 0 && (!array || value.length == 0)) {
1826
+ return braces[0] + base + braces[1];
1827
+ }
1828
+
1829
+ if (recurseTimes < 0) {
1830
+ if (isRegExp(value)) {
1831
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
1832
+ } else {
1833
+ return ctx.stylize('[Object]', 'special');
1834
+ }
1835
+ }
1836
+
1837
+ ctx.seen.push(value);
1838
+
1839
+ var output;
1840
+ if (array) {
1841
+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
1842
+ } else {
1843
+ output = keys.map(function(key) {
1844
+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
1845
+ });
1846
+ }
1847
+
1848
+ ctx.seen.pop();
1849
+
1850
+ return reduceToSingleString(output, base, braces);
1851
+ }
1852
+
1853
+
1854
+ function formatPrimitive(ctx, value) {
1855
+ switch (typeof value) {
1856
+ case 'undefined':
1857
+ return ctx.stylize('undefined', 'undefined');
1858
+
1859
+ case 'string':
1860
+ var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
1861
+ .replace(/'/g, "\\'")
1862
+ .replace(/\\"/g, '"') + '\'';
1863
+ return ctx.stylize(simple, 'string');
1864
+
1865
+ case 'number':
1866
+ return ctx.stylize('' + value, 'number');
1867
+
1868
+ case 'boolean':
1869
+ return ctx.stylize('' + value, 'boolean');
1870
+ }
1871
+ // For some reason typeof null is "object", so special case here.
1872
+ if (value === null) {
1873
+ return ctx.stylize('null', 'null');
1874
+ }
1875
+ }
1876
+
1877
+
1878
+ function formatError(value) {
1879
+ return '[' + Error.prototype.toString.call(value) + ']';
1880
+ }
1881
+
1882
+
1883
+ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
1884
+ var output = [];
1885
+ for (var i = 0, l = value.length; i < l; ++i) {
1886
+ if (Object.prototype.hasOwnProperty.call(value, String(i))) {
1887
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
1888
+ String(i), true));
1889
+ } else {
1890
+ output.push('');
1891
+ }
1892
+ }
1893
+ keys.forEach(function(key) {
1894
+ if (!key.match(/^\d+$/)) {
1895
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
1896
+ key, true));
1897
+ }
1898
+ });
1899
+ return output;
1900
+ }
1901
+
1902
+
1903
+ function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
1904
+ var name, str;
1905
+ if (value.__lookupGetter__) {
1906
+ if (value.__lookupGetter__(key)) {
1907
+ if (value.__lookupSetter__(key)) {
1908
+ str = ctx.stylize('[Getter/Setter]', 'special');
1909
+ } else {
1910
+ str = ctx.stylize('[Getter]', 'special');
1911
+ }
1912
+ } else {
1913
+ if (value.__lookupSetter__(key)) {
1914
+ str = ctx.stylize('[Setter]', 'special');
1915
+ }
1916
+ }
1917
+ }
1918
+ if (visibleKeys.indexOf(key) < 0) {
1919
+ name = '[' + key + ']';
1920
+ }
1921
+ if (!str) {
1922
+ if (ctx.seen.indexOf(value[key]) < 0) {
1923
+ if (recurseTimes === null) {
1924
+ str = formatValue(ctx, value[key], null);
1925
+ } else {
1926
+ str = formatValue(ctx, value[key], recurseTimes - 1);
1927
+ }
1928
+ if (str.indexOf('\n') > -1) {
1929
+ if (array) {
1930
+ str = str.split('\n').map(function(line) {
1931
+ return ' ' + line;
1932
+ }).join('\n').substr(2);
1933
+ } else {
1934
+ str = '\n' + str.split('\n').map(function(line) {
1935
+ return ' ' + line;
1936
+ }).join('\n');
1937
+ }
1938
+ }
1939
+ } else {
1940
+ str = ctx.stylize('[Circular]', 'special');
1941
+ }
1942
+ }
1943
+ if (typeof name === 'undefined') {
1944
+ if (array && key.match(/^\d+$/)) {
1945
+ return str;
1946
+ }
1947
+ name = JSON.stringify('' + key);
1948
+ if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
1949
+ name = name.substr(1, name.length - 2);
1950
+ name = ctx.stylize(name, 'name');
1951
+ } else {
1952
+ name = name.replace(/'/g, "\\'")
1953
+ .replace(/\\"/g, '"')
1954
+ .replace(/(^"|"$)/g, "'");
1955
+ name = ctx.stylize(name, 'string');
1956
+ }
1957
+ }
1958
+
1959
+ return name + ': ' + str;
1960
+ }
1961
+
1962
+
1963
+ function reduceToSingleString(output, base, braces) {
1964
+ var numLinesEst = 0;
1965
+ var length = output.reduce(function(prev, cur) {
1966
+ numLinesEst++;
1967
+ if (cur.indexOf('\n') >= 0) numLinesEst++;
1968
+ return prev + cur.length + 1;
1969
+ }, 0);
1970
+
1971
+ if (length > 60) {
1972
+ return braces[0] +
1973
+ (base === '' ? '' : base + '\n ') +
1974
+ ' ' +
1975
+ output.join(',\n ') +
1976
+ ' ' +
1977
+ braces[1];
1978
+ }
1979
+
1980
+ return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
1981
+ }
1982
+
1983
+ function isArray(ar) {
1984
+ return Array.isArray(ar) ||
1985
+ (typeof ar === 'object' && objectToString(ar) === '[object Array]');
1986
+ }
1987
+
1988
+ function isRegExp(re) {
1989
+ return typeof re === 'object' && objectToString(re) === '[object RegExp]';
1990
+ }
1991
+
1992
+ function isDate(d) {
1993
+ return typeof d === 'object' && objectToString(d) === '[object Date]';
1994
+ }
1995
+
1996
+ function isError(e) {
1997
+ return typeof e === 'object' && objectToString(e) === '[object Error]';
1998
+ }
1999
+
2000
+ function objectToString(o) {
2001
+ return Object.prototype.toString.call(o);
2002
+ }
2003
+ }); // module: utils/inspect.js
2004
+
2005
+
2006
+ return require('chai');
2007
+ });