ende 0.5.6 → 0.5.7

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/component.json +2 -2
  3. data/components/component/bind/{0.0.1 → 1.0.0}/component.json +1 -1
  4. data/components/component/bind/{0.0.1 → 1.0.0}/index.js +1 -2
  5. data/components/component/jquery/1.0.0/component.json +10 -0
  6. data/components/component/jquery/1.0.0/index.js +10308 -0
  7. data/components/component/matches-selector/{0.1.2 → 0.1.4}/component.json +1 -1
  8. data/components/component/matches-selector/{0.1.2 → 0.1.4}/index.js +0 -0
  9. data/components/indefinido/advisable/master/component.json +1 -1
  10. data/components/indefinido/indemma/master/component.json +4 -7
  11. data/components/indefinido/indemma/master/lib/record.js +7 -2
  12. data/components/indefinido/indemma/master/lib/record/dirtyable.js +15 -6
  13. data/components/indefinido/indemma/master/lib/record/scopable.js +1 -1
  14. data/components/indefinido/observable/es6-modules/component.json +1 -1
  15. data/components/indefinido/observable/es6-modules/lib/legacy/schedulerable.js +8 -3
  16. data/components/indefinido/observable/es6-modules/lib/observable.js +0 -1
  17. data/components/indefinido/observable/es6-modules/lib/observable/observation.js +2 -2
  18. data/components/paulmillr/es6-shim/{0.10.1 → 0.14.0}/component.json +1 -1
  19. data/components/paulmillr/es6-shim/{0.10.1 → 0.14.0}/es6-shim.js +151 -102
  20. data/components/pluma/assimilate/{0.3.0 → 0.4.0}/component.json +2 -2
  21. data/components/pluma/assimilate/{0.3.0 → 0.4.0}/dist/assimilate.js +1 -1
  22. data/lib/assets/javascripts/aura/extensions/rivets.js.coffee +12 -6
  23. data/lib/assets/javascripts/config/load_components.js.coffee +1 -1
  24. data/lib/assets/javascripts/ende.js.coffee +1 -1
  25. data/lib/ende/version.rb +1 -1
  26. data/vendor/assets/component/build.css +112 -0
  27. data/vendor/assets/components/ende_build.js +20357 -19584
  28. metadata +13 -84
  29. data/components/chaijs/assertion-error/1.0.0/component.json +0 -18
  30. data/components/chaijs/assertion-error/1.0.0/index.js +0 -110
  31. data/components/chaijs/chai/1.9.1/.gitignore +0 -22
  32. data/components/chaijs/chai/1.9.1/.mailmap +0 -1
  33. data/components/chaijs/chai/1.9.1/.npmignore +0 -14
  34. data/components/chaijs/chai/1.9.1/.travis.yml +0 -14
  35. data/components/chaijs/chai/1.9.1/CONTRIBUTING.md +0 -173
  36. data/components/chaijs/chai/1.9.1/History.md +0 -895
  37. data/components/chaijs/chai/1.9.1/Makefile +0 -93
  38. data/components/chaijs/chai/1.9.1/README.md +0 -99
  39. data/components/chaijs/chai/1.9.1/ReleaseNotes.md +0 -482
  40. data/components/chaijs/chai/1.9.1/bower.json +0 -27
  41. data/components/chaijs/chai/1.9.1/chai.js +0 -4782
  42. data/components/chaijs/chai/1.9.1/component.json +0 -50
  43. data/components/chaijs/chai/1.9.1/index.js +0 -1
  44. data/components/chaijs/chai/1.9.1/karma.conf.js +0 -28
  45. data/components/chaijs/chai/1.9.1/karma.sauce.js +0 -41
  46. data/components/chaijs/chai/1.9.1/lib/chai.js +0 -87
  47. data/components/chaijs/chai/1.9.1/lib/chai/assertion.js +0 -130
  48. data/components/chaijs/chai/1.9.1/lib/chai/config.js +0 -50
  49. data/components/chaijs/chai/1.9.1/lib/chai/core/assertions.js +0 -1314
  50. data/components/chaijs/chai/1.9.1/lib/chai/interface/assert.js +0 -1056
  51. data/components/chaijs/chai/1.9.1/lib/chai/interface/expect.js +0 -12
  52. data/components/chaijs/chai/1.9.1/lib/chai/interface/should.js +0 -78
  53. data/components/chaijs/chai/1.9.1/lib/chai/utils/addChainableMethod.js +0 -111
  54. data/components/chaijs/chai/1.9.1/lib/chai/utils/addMethod.js +0 -43
  55. data/components/chaijs/chai/1.9.1/lib/chai/utils/addProperty.js +0 -40
  56. data/components/chaijs/chai/1.9.1/lib/chai/utils/flag.js +0 -32
  57. data/components/chaijs/chai/1.9.1/lib/chai/utils/getActual.js +0 -18
  58. data/components/chaijs/chai/1.9.1/lib/chai/utils/getEnumerableProperties.js +0 -25
  59. data/components/chaijs/chai/1.9.1/lib/chai/utils/getMessage.js +0 -49
  60. data/components/chaijs/chai/1.9.1/lib/chai/utils/getName.js +0 -20
  61. data/components/chaijs/chai/1.9.1/lib/chai/utils/getPathValue.js +0 -102
  62. data/components/chaijs/chai/1.9.1/lib/chai/utils/getProperties.js +0 -35
  63. data/components/chaijs/chai/1.9.1/lib/chai/utils/index.js +0 -114
  64. data/components/chaijs/chai/1.9.1/lib/chai/utils/inspect.js +0 -320
  65. data/components/chaijs/chai/1.9.1/lib/chai/utils/objDisplay.js +0 -49
  66. data/components/chaijs/chai/1.9.1/lib/chai/utils/overwriteChainableMethod.js +0 -53
  67. data/components/chaijs/chai/1.9.1/lib/chai/utils/overwriteMethod.js +0 -51
  68. data/components/chaijs/chai/1.9.1/lib/chai/utils/overwriteProperty.js +0 -54
  69. data/components/chaijs/chai/1.9.1/lib/chai/utils/test.js +0 -26
  70. data/components/chaijs/chai/1.9.1/lib/chai/utils/transferFlags.js +0 -44
  71. data/components/chaijs/chai/1.9.1/lib/chai/utils/type.js +0 -45
  72. data/components/chaijs/chai/1.9.1/package.json +0 -42
  73. data/components/chaijs/chai/1.9.1/sauce.browsers.js +0 -128
  74. data/components/chaijs/chai/1.9.1/support/sauce/sauce_connect_block.sh +0 -7
  75. data/components/chaijs/chai/1.9.1/support/sauce/sauce_connect_setup.sh +0 -53
  76. data/components/chaijs/chai/1.9.1/test/assert.js +0 -638
  77. data/components/chaijs/chai/1.9.1/test/auth/.gitkeep +0 -0
  78. data/components/chaijs/chai/1.9.1/test/bootstrap/index.js +0 -22
  79. data/components/chaijs/chai/1.9.1/test/bootstrap/karma.js +0 -22
  80. data/components/chaijs/chai/1.9.1/test/configuration.js +0 -133
  81. data/components/chaijs/chai/1.9.1/test/display/errors.js +0 -14
  82. data/components/chaijs/chai/1.9.1/test/display/message.js +0 -47
  83. data/components/chaijs/chai/1.9.1/test/expect.js +0 -814
  84. data/components/chaijs/chai/1.9.1/test/globalShould.js +0 -15
  85. data/components/chaijs/chai/1.9.1/test/plugins.js +0 -24
  86. data/components/chaijs/chai/1.9.1/test/should.js +0 -744
  87. data/components/chaijs/chai/1.9.1/test/utilities.js +0 -309
  88. data/components/chaijs/deep-eql/0.1.3/component.json +0 -20
  89. data/components/chaijs/deep-eql/0.1.3/lib/eql.js +0 -257
  90. data/components/chaijs/type-detect/0.1.1/component.json +0 -18
  91. data/components/chaijs/type-detect/0.1.1/lib/type.js +0 -142
  92. data/components/component/classes/1.2.1/component.json +0 -19
  93. data/components/component/classes/1.2.1/index.js +0 -184
  94. data/components/component/domify/1.2.2/component.json +0 -22
  95. data/components/component/domify/1.2.2/index.js +0 -87
  96. data/components/component/event/0.1.3/component.json +0 -13
  97. data/components/component/event/0.1.3/index.js +0 -35
  98. data/components/component/jquery/1.9.1/component.json +0 -14
  99. data/components/component/jquery/1.9.1/index.js +0 -9601
  100. data/components/component/query/0.0.3/component.json +0 -23
  101. data/components/component/query/0.0.3/index.js +0 -21
  102. data/lib/tasks/.gitkeep +0 -0
@@ -1,50 +0,0 @@
1
- {
2
- "name": "chai",
3
- "version": "1.9.1",
4
- "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.",
5
- "license": "MIT",
6
- "keywords": [
7
- "test",
8
- "assertion",
9
- "assert",
10
- "testing",
11
- "chai"
12
- ],
13
- "main": "index.js",
14
- "scripts": [
15
- "index.js",
16
- "lib/chai.js",
17
- "lib/chai/assertion.js",
18
- "lib/chai/config.js",
19
- "lib/chai/core/assertions.js",
20
- "lib/chai/interface/assert.js",
21
- "lib/chai/interface/expect.js",
22
- "lib/chai/interface/should.js",
23
- "lib/chai/utils/addChainableMethod.js",
24
- "lib/chai/utils/addMethod.js",
25
- "lib/chai/utils/addProperty.js",
26
- "lib/chai/utils/flag.js",
27
- "lib/chai/utils/getActual.js",
28
- "lib/chai/utils/getEnumerableProperties.js",
29
- "lib/chai/utils/getMessage.js",
30
- "lib/chai/utils/getName.js",
31
- "lib/chai/utils/getPathValue.js",
32
- "lib/chai/utils/getProperties.js",
33
- "lib/chai/utils/index.js",
34
- "lib/chai/utils/inspect.js",
35
- "lib/chai/utils/objDisplay.js",
36
- "lib/chai/utils/overwriteMethod.js",
37
- "lib/chai/utils/overwriteProperty.js",
38
- "lib/chai/utils/overwriteChainableMethod.js",
39
- "lib/chai/utils/test.js",
40
- "lib/chai/utils/transferFlags.js",
41
- "lib/chai/utils/type.js"
42
- ],
43
- "dependencies": {
44
- "chaijs/assertion-error": "1.0.0",
45
- "chaijs/deep-eql": "0.1.3"
46
- },
47
- "development": {},
48
- "repository": "chaijs/chai",
49
- "repo": "chaijs/chai"
50
- }
@@ -1 +0,0 @@
1
- module.exports = require('./lib/chai');
@@ -1,28 +0,0 @@
1
- module.exports = function(config) {
2
- config.set({
3
- frameworks: [ 'mocha' ]
4
- , files: [
5
- 'build/build.js'
6
- , 'test/bootstrap/karma.js'
7
- , 'test/*.js'
8
- ]
9
- , reporters: [ 'progress' ]
10
- , colors: true
11
- , logLevel: config.LOG_INFO
12
- , autoWatch: false
13
- , browsers: [ 'PhantomJS' ]
14
- , browserDisconnectTimeout: 10000
15
- , browserDisconnectTolerance: 2
16
- , browserNoActivityTimeout: 20000
17
- , singleRun: true
18
- });
19
-
20
- switch (process.env.CHAI_TEST_ENV) {
21
- case 'sauce':
22
- require('./karma.sauce')(config);
23
- break;
24
- default:
25
- // ...
26
- break;
27
- };
28
- };
@@ -1,41 +0,0 @@
1
- var version = require('./package.json').version;
2
- var ts = new Date().getTime();
3
-
4
- module.exports = function(config) {
5
- var auth;
6
-
7
- try {
8
- auth = require('./test/auth/index');
9
- } catch(ex) {
10
- auth = {};
11
- auth.SAUCE_USERNAME = process.env.SAUCE_USERNAME || null;
12
- auth.SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY || null;
13
- }
14
-
15
- if (!auth.SAUCE_USERNAME || !auth.SAUCE_ACCESS_KEY) return;
16
- if (process.env.SKIP_SAUCE) return;
17
-
18
- var branch = process.env.TRAVIS_BRANCH || 'local'
19
- var browserConfig = require('./sauce.browsers');
20
- var browsers = Object.keys(browserConfig);
21
- var tags = [ 'chaijs_' + version, auth.SAUCE_USERNAME + '@' + branch ];
22
- var tunnel = process.env.TRAVIS_JOB_NUMBER || ts;
23
-
24
- if (process.env.TRAVIS_JOB_NUMBER) {
25
- tags.push('travis@' + process.env.TRAVIS_JOB_NUMBER);
26
- }
27
-
28
- config.browsers = config.browsers.concat(browsers);
29
- config.customLaunchers = browserConfig;
30
- config.reporters.push('saucelabs');
31
- config.transports = [ 'xhr-polling' ];
32
-
33
- config.sauceLabs = {
34
- username: auth.SAUCE_USERNAME
35
- , accessKey: auth.SAUCE_ACCESS_KEY
36
- , startConnect: true
37
- , tags: tags
38
- , testName: 'ChaiJS'
39
- , tunnelIdentifier: tunnel
40
- };
41
- };
@@ -1,87 +0,0 @@
1
- /*!
2
- * chai
3
- * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
4
- * MIT Licensed
5
- */
6
-
7
- var used = []
8
- , exports = module.exports = {};
9
-
10
- /*!
11
- * Chai version
12
- */
13
-
14
- exports.version = '1.9.1';
15
-
16
- /*!
17
- * Assertion Error
18
- */
19
-
20
- exports.AssertionError = require('assertion-error');
21
-
22
- /*!
23
- * Utils for plugins (not exported)
24
- */
25
-
26
- var util = require('./chai/utils');
27
-
28
- /**
29
- * # .use(function)
30
- *
31
- * Provides a way to extend the internals of Chai
32
- *
33
- * @param {Function}
34
- * @returns {this} for chaining
35
- * @api public
36
- */
37
-
38
- exports.use = function (fn) {
39
- if (!~used.indexOf(fn)) {
40
- fn(this, util);
41
- used.push(fn);
42
- }
43
-
44
- return this;
45
- };
46
-
47
- /*!
48
- * Configuration
49
- */
50
-
51
- var config = require('./chai/config');
52
- exports.config = config;
53
-
54
- /*!
55
- * Primary `Assertion` prototype
56
- */
57
-
58
- var assertion = require('./chai/assertion');
59
- exports.use(assertion);
60
-
61
- /*!
62
- * Core Assertions
63
- */
64
-
65
- var core = require('./chai/core/assertions');
66
- exports.use(core);
67
-
68
- /*!
69
- * Expect interface
70
- */
71
-
72
- var expect = require('./chai/interface/expect');
73
- exports.use(expect);
74
-
75
- /*!
76
- * Should interface
77
- */
78
-
79
- var should = require('./chai/interface/should');
80
- exports.use(should);
81
-
82
- /*!
83
- * Assert interface
84
- */
85
-
86
- var assert = require('./chai/interface/assert');
87
- exports.use(assert);
@@ -1,130 +0,0 @@
1
- /*!
2
- * chai
3
- * http://chaijs.com
4
- * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
5
- * MIT Licensed
6
- */
7
-
8
- var config = require('./config');
9
-
10
- module.exports = function (_chai, util) {
11
- /*!
12
- * Module dependencies.
13
- */
14
-
15
- var AssertionError = _chai.AssertionError
16
- , flag = util.flag;
17
-
18
- /*!
19
- * Module export.
20
- */
21
-
22
- _chai.Assertion = Assertion;
23
-
24
- /*!
25
- * Assertion Constructor
26
- *
27
- * Creates object for chaining.
28
- *
29
- * @api private
30
- */
31
-
32
- function Assertion (obj, msg, stack) {
33
- flag(this, 'ssfi', stack || arguments.callee);
34
- flag(this, 'object', obj);
35
- flag(this, 'message', msg);
36
- }
37
-
38
- Object.defineProperty(Assertion, 'includeStack', {
39
- get: function() {
40
- console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
41
- return config.includeStack;
42
- },
43
- set: function(value) {
44
- console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
45
- config.includeStack = value;
46
- }
47
- });
48
-
49
- Object.defineProperty(Assertion, 'showDiff', {
50
- get: function() {
51
- console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
52
- return config.showDiff;
53
- },
54
- set: function(value) {
55
- console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
56
- config.showDiff = value;
57
- }
58
- });
59
-
60
- Assertion.addProperty = function (name, fn) {
61
- util.addProperty(this.prototype, name, fn);
62
- };
63
-
64
- Assertion.addMethod = function (name, fn) {
65
- util.addMethod(this.prototype, name, fn);
66
- };
67
-
68
- Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
69
- util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
70
- };
71
-
72
- Assertion.overwriteProperty = function (name, fn) {
73
- util.overwriteProperty(this.prototype, name, fn);
74
- };
75
-
76
- Assertion.overwriteMethod = function (name, fn) {
77
- util.overwriteMethod(this.prototype, name, fn);
78
- };
79
-
80
- Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {
81
- util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
82
- };
83
-
84
- /*!
85
- * ### .assert(expression, message, negateMessage, expected, actual)
86
- *
87
- * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
88
- *
89
- * @name assert
90
- * @param {Philosophical} expression to be tested
91
- * @param {String} message to display if fails
92
- * @param {String} negatedMessage to display if negated expression fails
93
- * @param {Mixed} expected value (remember to check for negation)
94
- * @param {Mixed} actual (optional) will default to `this.obj`
95
- * @api private
96
- */
97
-
98
- Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
99
- var ok = util.test(this, arguments);
100
- if (true !== showDiff) showDiff = false;
101
- if (true !== config.showDiff) showDiff = false;
102
-
103
- if (!ok) {
104
- var msg = util.getMessage(this, arguments)
105
- , actual = util.getActual(this, arguments);
106
- throw new AssertionError(msg, {
107
- actual: actual
108
- , expected: expected
109
- , showDiff: showDiff
110
- }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));
111
- }
112
- };
113
-
114
- /*!
115
- * ### ._obj
116
- *
117
- * Quick reference to stored `actual` value for plugin developers.
118
- *
119
- * @api private
120
- */
121
-
122
- Object.defineProperty(Assertion.prototype, '_obj',
123
- { get: function () {
124
- return flag(this, 'object');
125
- }
126
- , set: function (val) {
127
- flag(this, 'object', val);
128
- }
129
- });
130
- };
@@ -1,50 +0,0 @@
1
- module.exports = {
2
-
3
- /**
4
- * ### config.includeStack
5
- *
6
- * User configurable property, influences whether stack trace
7
- * is included in Assertion error message. Default of false
8
- * suppresses stack trace in the error message.
9
- *
10
- * chai.config.includeStack = true; // enable stack on error
11
- *
12
- * @param {Boolean}
13
- * @api public
14
- */
15
-
16
- includeStack: false,
17
-
18
- /**
19
- * ### config.showDiff
20
- *
21
- * User configurable property, influences whether or not
22
- * the `showDiff` flag should be included in the thrown
23
- * AssertionErrors. `false` will always be `false`; `true`
24
- * will be true when the assertion has requested a diff
25
- * be shown.
26
- *
27
- * @param {Boolean}
28
- * @api public
29
- */
30
-
31
- showDiff: true,
32
-
33
- /**
34
- * ### config.truncateThreshold
35
- *
36
- * User configurable property, sets length threshold for actual and
37
- * expected values in assertion errors. If this threshold is exceeded,
38
- * the value is truncated.
39
- *
40
- * Set it to zero if you want to disable truncating altogether.
41
- *
42
- * chai.config.truncateThreshold = 0; // disable truncating
43
- *
44
- * @param {Number}
45
- * @api public
46
- */
47
-
48
- truncateThreshold: 40
49
-
50
- };
@@ -1,1314 +0,0 @@
1
- /*!
2
- * chai
3
- * http://chaijs.com
4
- * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
5
- * MIT Licensed
6
- */
7
-
8
- module.exports = function (chai, _) {
9
- var Assertion = chai.Assertion
10
- , toString = Object.prototype.toString
11
- , flag = _.flag;
12
-
13
- /**
14
- * ### Language Chains
15
- *
16
- * The following are provided as chainable getters to
17
- * improve the readability of your assertions. They
18
- * do not provide testing capabilities unless they
19
- * have been overwritten by a plugin.
20
- *
21
- * **Chains**
22
- *
23
- * - to
24
- * - be
25
- * - been
26
- * - is
27
- * - that
28
- * - and
29
- * - has
30
- * - have
31
- * - with
32
- * - at
33
- * - of
34
- * - same
35
- *
36
- * @name language chains
37
- * @api public
38
- */
39
-
40
- [ 'to', 'be', 'been'
41
- , 'is', 'and', 'has', 'have'
42
- , 'with', 'that', 'at'
43
- , 'of', 'same' ].forEach(function (chain) {
44
- Assertion.addProperty(chain, function () {
45
- return this;
46
- });
47
- });
48
-
49
- /**
50
- * ### .not
51
- *
52
- * Negates any of assertions following in the chain.
53
- *
54
- * expect(foo).to.not.equal('bar');
55
- * expect(goodFn).to.not.throw(Error);
56
- * expect({ foo: 'baz' }).to.have.property('foo')
57
- * .and.not.equal('bar');
58
- *
59
- * @name not
60
- * @api public
61
- */
62
-
63
- Assertion.addProperty('not', function () {
64
- flag(this, 'negate', true);
65
- });
66
-
67
- /**
68
- * ### .deep
69
- *
70
- * Sets the `deep` flag, later used by the `equal` and
71
- * `property` assertions.
72
- *
73
- * expect(foo).to.deep.equal({ bar: 'baz' });
74
- * expect({ foo: { bar: { baz: 'quux' } } })
75
- * .to.have.deep.property('foo.bar.baz', 'quux');
76
- *
77
- * @name deep
78
- * @api public
79
- */
80
-
81
- Assertion.addProperty('deep', function () {
82
- flag(this, 'deep', true);
83
- });
84
-
85
- /**
86
- * ### .a(type)
87
- *
88
- * The `a` and `an` assertions are aliases that can be
89
- * used either as language chains or to assert a value's
90
- * type.
91
- *
92
- * // typeof
93
- * expect('test').to.be.a('string');
94
- * expect({ foo: 'bar' }).to.be.an('object');
95
- * expect(null).to.be.a('null');
96
- * expect(undefined).to.be.an('undefined');
97
- *
98
- * // language chain
99
- * expect(foo).to.be.an.instanceof(Foo);
100
- *
101
- * @name a
102
- * @alias an
103
- * @param {String} type
104
- * @param {String} message _optional_
105
- * @api public
106
- */
107
-
108
- function an (type, msg) {
109
- if (msg) flag(this, 'message', msg);
110
- type = type.toLowerCase();
111
- var obj = flag(this, 'object')
112
- , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
113
-
114
- this.assert(
115
- type === _.type(obj)
116
- , 'expected #{this} to be ' + article + type
117
- , 'expected #{this} not to be ' + article + type
118
- );
119
- }
120
-
121
- Assertion.addChainableMethod('an', an);
122
- Assertion.addChainableMethod('a', an);
123
-
124
- /**
125
- * ### .include(value)
126
- *
127
- * The `include` and `contain` assertions can be used as either property
128
- * based language chains or as methods to assert the inclusion of an object
129
- * in an array or a substring in a string. When used as language chains,
130
- * they toggle the `contain` flag for the `keys` assertion.
131
- *
132
- * expect([1,2,3]).to.include(2);
133
- * expect('foobar').to.contain('foo');
134
- * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
135
- *
136
- * @name include
137
- * @alias contain
138
- * @param {Object|String|Number} obj
139
- * @param {String} message _optional_
140
- * @api public
141
- */
142
-
143
- function includeChainingBehavior () {
144
- flag(this, 'contains', true);
145
- }
146
-
147
- function include (val, msg) {
148
- if (msg) flag(this, 'message', msg);
149
- var obj = flag(this, 'object');
150
- var expected = false;
151
- if (_.type(obj) === 'array' && _.type(val) === 'object') {
152
- for (var i in obj) {
153
- if (_.eql(obj[i], val)) {
154
- expected = true;
155
- break;
156
- }
157
- }
158
- } else if (_.type(val) === 'object') {
159
- if (!flag(this, 'negate')) {
160
- for (var k in val) new Assertion(obj).property(k, val[k]);
161
- return;
162
- }
163
- var subset = {}
164
- for (var k in val) subset[k] = obj[k]
165
- expected = _.eql(subset, val);
166
- } else {
167
- expected = obj && ~obj.indexOf(val)
168
- }
169
- this.assert(
170
- expected
171
- , 'expected #{this} to include ' + _.inspect(val)
172
- , 'expected #{this} to not include ' + _.inspect(val));
173
- }
174
-
175
- Assertion.addChainableMethod('include', include, includeChainingBehavior);
176
- Assertion.addChainableMethod('contain', include, includeChainingBehavior);
177
-
178
- /**
179
- * ### .ok
180
- *
181
- * Asserts that the target is truthy.
182
- *
183
- * expect('everthing').to.be.ok;
184
- * expect(1).to.be.ok;
185
- * expect(false).to.not.be.ok;
186
- * expect(undefined).to.not.be.ok;
187
- * expect(null).to.not.be.ok;
188
- *
189
- * @name ok
190
- * @api public
191
- */
192
-
193
- Assertion.addProperty('ok', function () {
194
- this.assert(
195
- flag(this, 'object')
196
- , 'expected #{this} to be truthy'
197
- , 'expected #{this} to be falsy');
198
- });
199
-
200
- /**
201
- * ### .true
202
- *
203
- * Asserts that the target is `true`.
204
- *
205
- * expect(true).to.be.true;
206
- * expect(1).to.not.be.true;
207
- *
208
- * @name true
209
- * @api public
210
- */
211
-
212
- Assertion.addProperty('true', function () {
213
- this.assert(
214
- true === flag(this, 'object')
215
- , 'expected #{this} to be true'
216
- , 'expected #{this} to be false'
217
- , this.negate ? false : true
218
- );
219
- });
220
-
221
- /**
222
- * ### .false
223
- *
224
- * Asserts that the target is `false`.
225
- *
226
- * expect(false).to.be.false;
227
- * expect(0).to.not.be.false;
228
- *
229
- * @name false
230
- * @api public
231
- */
232
-
233
- Assertion.addProperty('false', function () {
234
- this.assert(
235
- false === flag(this, 'object')
236
- , 'expected #{this} to be false'
237
- , 'expected #{this} to be true'
238
- , this.negate ? true : false
239
- );
240
- });
241
-
242
- /**
243
- * ### .null
244
- *
245
- * Asserts that the target is `null`.
246
- *
247
- * expect(null).to.be.null;
248
- * expect(undefined).not.to.be.null;
249
- *
250
- * @name null
251
- * @api public
252
- */
253
-
254
- Assertion.addProperty('null', function () {
255
- this.assert(
256
- null === flag(this, 'object')
257
- , 'expected #{this} to be null'
258
- , 'expected #{this} not to be null'
259
- );
260
- });
261
-
262
- /**
263
- * ### .undefined
264
- *
265
- * Asserts that the target is `undefined`.
266
- *
267
- * expect(undefined).to.be.undefined;
268
- * expect(null).to.not.be.undefined;
269
- *
270
- * @name undefined
271
- * @api public
272
- */
273
-
274
- Assertion.addProperty('undefined', function () {
275
- this.assert(
276
- undefined === flag(this, 'object')
277
- , 'expected #{this} to be undefined'
278
- , 'expected #{this} not to be undefined'
279
- );
280
- });
281
-
282
- /**
283
- * ### .exist
284
- *
285
- * Asserts that the target is neither `null` nor `undefined`.
286
- *
287
- * var foo = 'hi'
288
- * , bar = null
289
- * , baz;
290
- *
291
- * expect(foo).to.exist;
292
- * expect(bar).to.not.exist;
293
- * expect(baz).to.not.exist;
294
- *
295
- * @name exist
296
- * @api public
297
- */
298
-
299
- Assertion.addProperty('exist', function () {
300
- this.assert(
301
- null != flag(this, 'object')
302
- , 'expected #{this} to exist'
303
- , 'expected #{this} to not exist'
304
- );
305
- });
306
-
307
-
308
- /**
309
- * ### .empty
310
- *
311
- * Asserts that the target's length is `0`. For arrays, it checks
312
- * the `length` property. For objects, it gets the count of
313
- * enumerable keys.
314
- *
315
- * expect([]).to.be.empty;
316
- * expect('').to.be.empty;
317
- * expect({}).to.be.empty;
318
- *
319
- * @name empty
320
- * @api public
321
- */
322
-
323
- Assertion.addProperty('empty', function () {
324
- var obj = flag(this, 'object')
325
- , expected = obj;
326
-
327
- if (Array.isArray(obj) || 'string' === typeof object) {
328
- expected = obj.length;
329
- } else if (typeof obj === 'object') {
330
- expected = Object.keys(obj).length;
331
- }
332
-
333
- this.assert(
334
- !expected
335
- , 'expected #{this} to be empty'
336
- , 'expected #{this} not to be empty'
337
- );
338
- });
339
-
340
- /**
341
- * ### .arguments
342
- *
343
- * Asserts that the target is an arguments object.
344
- *
345
- * function test () {
346
- * expect(arguments).to.be.arguments;
347
- * }
348
- *
349
- * @name arguments
350
- * @alias Arguments
351
- * @api public
352
- */
353
-
354
- function checkArguments () {
355
- var obj = flag(this, 'object')
356
- , type = Object.prototype.toString.call(obj);
357
- this.assert(
358
- '[object Arguments]' === type
359
- , 'expected #{this} to be arguments but got ' + type
360
- , 'expected #{this} to not be arguments'
361
- );
362
- }
363
-
364
- Assertion.addProperty('arguments', checkArguments);
365
- Assertion.addProperty('Arguments', checkArguments);
366
-
367
- /**
368
- * ### .equal(value)
369
- *
370
- * Asserts that the target is strictly equal (`===`) to `value`.
371
- * Alternately, if the `deep` flag is set, asserts that
372
- * the target is deeply equal to `value`.
373
- *
374
- * expect('hello').to.equal('hello');
375
- * expect(42).to.equal(42);
376
- * expect(1).to.not.equal(true);
377
- * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });
378
- * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });
379
- *
380
- * @name equal
381
- * @alias equals
382
- * @alias eq
383
- * @alias deep.equal
384
- * @param {Mixed} value
385
- * @param {String} message _optional_
386
- * @api public
387
- */
388
-
389
- function assertEqual (val, msg) {
390
- if (msg) flag(this, 'message', msg);
391
- var obj = flag(this, 'object');
392
- if (flag(this, 'deep')) {
393
- return this.eql(val);
394
- } else {
395
- this.assert(
396
- val === obj
397
- , 'expected #{this} to equal #{exp}'
398
- , 'expected #{this} to not equal #{exp}'
399
- , val
400
- , this._obj
401
- , true
402
- );
403
- }
404
- }
405
-
406
- Assertion.addMethod('equal', assertEqual);
407
- Assertion.addMethod('equals', assertEqual);
408
- Assertion.addMethod('eq', assertEqual);
409
-
410
- /**
411
- * ### .eql(value)
412
- *
413
- * Asserts that the target is deeply equal to `value`.
414
- *
415
- * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
416
- * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);
417
- *
418
- * @name eql
419
- * @alias eqls
420
- * @param {Mixed} value
421
- * @param {String} message _optional_
422
- * @api public
423
- */
424
-
425
- function assertEql(obj, msg) {
426
- if (msg) flag(this, 'message', msg);
427
- this.assert(
428
- _.eql(obj, flag(this, 'object'))
429
- , 'expected #{this} to deeply equal #{exp}'
430
- , 'expected #{this} to not deeply equal #{exp}'
431
- , obj
432
- , this._obj
433
- , true
434
- );
435
- }
436
-
437
- Assertion.addMethod('eql', assertEql);
438
- Assertion.addMethod('eqls', assertEql);
439
-
440
- /**
441
- * ### .above(value)
442
- *
443
- * Asserts that the target is greater than `value`.
444
- *
445
- * expect(10).to.be.above(5);
446
- *
447
- * Can also be used in conjunction with `length` to
448
- * assert a minimum length. The benefit being a
449
- * more informative error message than if the length
450
- * was supplied directly.
451
- *
452
- * expect('foo').to.have.length.above(2);
453
- * expect([ 1, 2, 3 ]).to.have.length.above(2);
454
- *
455
- * @name above
456
- * @alias gt
457
- * @alias greaterThan
458
- * @param {Number} value
459
- * @param {String} message _optional_
460
- * @api public
461
- */
462
-
463
- function assertAbove (n, msg) {
464
- if (msg) flag(this, 'message', msg);
465
- var obj = flag(this, 'object');
466
- if (flag(this, 'doLength')) {
467
- new Assertion(obj, msg).to.have.property('length');
468
- var len = obj.length;
469
- this.assert(
470
- len > n
471
- , 'expected #{this} to have a length above #{exp} but got #{act}'
472
- , 'expected #{this} to not have a length above #{exp}'
473
- , n
474
- , len
475
- );
476
- } else {
477
- this.assert(
478
- obj > n
479
- , 'expected #{this} to be above ' + n
480
- , 'expected #{this} to be at most ' + n
481
- );
482
- }
483
- }
484
-
485
- Assertion.addMethod('above', assertAbove);
486
- Assertion.addMethod('gt', assertAbove);
487
- Assertion.addMethod('greaterThan', assertAbove);
488
-
489
- /**
490
- * ### .least(value)
491
- *
492
- * Asserts that the target is greater than or equal to `value`.
493
- *
494
- * expect(10).to.be.at.least(10);
495
- *
496
- * Can also be used in conjunction with `length` to
497
- * assert a minimum length. The benefit being a
498
- * more informative error message than if the length
499
- * was supplied directly.
500
- *
501
- * expect('foo').to.have.length.of.at.least(2);
502
- * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);
503
- *
504
- * @name least
505
- * @alias gte
506
- * @param {Number} value
507
- * @param {String} message _optional_
508
- * @api public
509
- */
510
-
511
- function assertLeast (n, msg) {
512
- if (msg) flag(this, 'message', msg);
513
- var obj = flag(this, 'object');
514
- if (flag(this, 'doLength')) {
515
- new Assertion(obj, msg).to.have.property('length');
516
- var len = obj.length;
517
- this.assert(
518
- len >= n
519
- , 'expected #{this} to have a length at least #{exp} but got #{act}'
520
- , 'expected #{this} to have a length below #{exp}'
521
- , n
522
- , len
523
- );
524
- } else {
525
- this.assert(
526
- obj >= n
527
- , 'expected #{this} to be at least ' + n
528
- , 'expected #{this} to be below ' + n
529
- );
530
- }
531
- }
532
-
533
- Assertion.addMethod('least', assertLeast);
534
- Assertion.addMethod('gte', assertLeast);
535
-
536
- /**
537
- * ### .below(value)
538
- *
539
- * Asserts that the target is less than `value`.
540
- *
541
- * expect(5).to.be.below(10);
542
- *
543
- * Can also be used in conjunction with `length` to
544
- * assert a maximum length. The benefit being a
545
- * more informative error message than if the length
546
- * was supplied directly.
547
- *
548
- * expect('foo').to.have.length.below(4);
549
- * expect([ 1, 2, 3 ]).to.have.length.below(4);
550
- *
551
- * @name below
552
- * @alias lt
553
- * @alias lessThan
554
- * @param {Number} value
555
- * @param {String} message _optional_
556
- * @api public
557
- */
558
-
559
- function assertBelow (n, msg) {
560
- if (msg) flag(this, 'message', msg);
561
- var obj = flag(this, 'object');
562
- if (flag(this, 'doLength')) {
563
- new Assertion(obj, msg).to.have.property('length');
564
- var len = obj.length;
565
- this.assert(
566
- len < n
567
- , 'expected #{this} to have a length below #{exp} but got #{act}'
568
- , 'expected #{this} to not have a length below #{exp}'
569
- , n
570
- , len
571
- );
572
- } else {
573
- this.assert(
574
- obj < n
575
- , 'expected #{this} to be below ' + n
576
- , 'expected #{this} to be at least ' + n
577
- );
578
- }
579
- }
580
-
581
- Assertion.addMethod('below', assertBelow);
582
- Assertion.addMethod('lt', assertBelow);
583
- Assertion.addMethod('lessThan', assertBelow);
584
-
585
- /**
586
- * ### .most(value)
587
- *
588
- * Asserts that the target is less than or equal to `value`.
589
- *
590
- * expect(5).to.be.at.most(5);
591
- *
592
- * Can also be used in conjunction with `length` to
593
- * assert a maximum length. The benefit being a
594
- * more informative error message than if the length
595
- * was supplied directly.
596
- *
597
- * expect('foo').to.have.length.of.at.most(4);
598
- * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);
599
- *
600
- * @name most
601
- * @alias lte
602
- * @param {Number} value
603
- * @param {String} message _optional_
604
- * @api public
605
- */
606
-
607
- function assertMost (n, msg) {
608
- if (msg) flag(this, 'message', msg);
609
- var obj = flag(this, 'object');
610
- if (flag(this, 'doLength')) {
611
- new Assertion(obj, msg).to.have.property('length');
612
- var len = obj.length;
613
- this.assert(
614
- len <= n
615
- , 'expected #{this} to have a length at most #{exp} but got #{act}'
616
- , 'expected #{this} to have a length above #{exp}'
617
- , n
618
- , len
619
- );
620
- } else {
621
- this.assert(
622
- obj <= n
623
- , 'expected #{this} to be at most ' + n
624
- , 'expected #{this} to be above ' + n
625
- );
626
- }
627
- }
628
-
629
- Assertion.addMethod('most', assertMost);
630
- Assertion.addMethod('lte', assertMost);
631
-
632
- /**
633
- * ### .within(start, finish)
634
- *
635
- * Asserts that the target is within a range.
636
- *
637
- * expect(7).to.be.within(5,10);
638
- *
639
- * Can also be used in conjunction with `length` to
640
- * assert a length range. The benefit being a
641
- * more informative error message than if the length
642
- * was supplied directly.
643
- *
644
- * expect('foo').to.have.length.within(2,4);
645
- * expect([ 1, 2, 3 ]).to.have.length.within(2,4);
646
- *
647
- * @name within
648
- * @param {Number} start lowerbound inclusive
649
- * @param {Number} finish upperbound inclusive
650
- * @param {String} message _optional_
651
- * @api public
652
- */
653
-
654
- Assertion.addMethod('within', function (start, finish, msg) {
655
- if (msg) flag(this, 'message', msg);
656
- var obj = flag(this, 'object')
657
- , range = start + '..' + finish;
658
- if (flag(this, 'doLength')) {
659
- new Assertion(obj, msg).to.have.property('length');
660
- var len = obj.length;
661
- this.assert(
662
- len >= start && len <= finish
663
- , 'expected #{this} to have a length within ' + range
664
- , 'expected #{this} to not have a length within ' + range
665
- );
666
- } else {
667
- this.assert(
668
- obj >= start && obj <= finish
669
- , 'expected #{this} to be within ' + range
670
- , 'expected #{this} to not be within ' + range
671
- );
672
- }
673
- });
674
-
675
- /**
676
- * ### .instanceof(constructor)
677
- *
678
- * Asserts that the target is an instance of `constructor`.
679
- *
680
- * var Tea = function (name) { this.name = name; }
681
- * , Chai = new Tea('chai');
682
- *
683
- * expect(Chai).to.be.an.instanceof(Tea);
684
- * expect([ 1, 2, 3 ]).to.be.instanceof(Array);
685
- *
686
- * @name instanceof
687
- * @param {Constructor} constructor
688
- * @param {String} message _optional_
689
- * @alias instanceOf
690
- * @api public
691
- */
692
-
693
- function assertInstanceOf (constructor, msg) {
694
- if (msg) flag(this, 'message', msg);
695
- var name = _.getName(constructor);
696
- this.assert(
697
- flag(this, 'object') instanceof constructor
698
- , 'expected #{this} to be an instance of ' + name
699
- , 'expected #{this} to not be an instance of ' + name
700
- );
701
- };
702
-
703
- Assertion.addMethod('instanceof', assertInstanceOf);
704
- Assertion.addMethod('instanceOf', assertInstanceOf);
705
-
706
- /**
707
- * ### .property(name, [value])
708
- *
709
- * Asserts that the target has a property `name`, optionally asserting that
710
- * the value of that property is strictly equal to `value`.
711
- * If the `deep` flag is set, you can use dot- and bracket-notation for deep
712
- * references into objects and arrays.
713
- *
714
- * // simple referencing
715
- * var obj = { foo: 'bar' };
716
- * expect(obj).to.have.property('foo');
717
- * expect(obj).to.have.property('foo', 'bar');
718
- *
719
- * // deep referencing
720
- * var deepObj = {
721
- * green: { tea: 'matcha' }
722
- * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
723
- * };
724
-
725
- * expect(deepObj).to.have.deep.property('green.tea', 'matcha');
726
- * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
727
- * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
728
- *
729
- * You can also use an array as the starting point of a `deep.property`
730
- * assertion, or traverse nested arrays.
731
- *
732
- * var arr = [
733
- * [ 'chai', 'matcha', 'konacha' ]
734
- * , [ { tea: 'chai' }
735
- * , { tea: 'matcha' }
736
- * , { tea: 'konacha' } ]
737
- * ];
738
- *
739
- * expect(arr).to.have.deep.property('[0][1]', 'matcha');
740
- * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');
741
- *
742
- * Furthermore, `property` changes the subject of the assertion
743
- * to be the value of that property from the original object. This
744
- * permits for further chainable assertions on that property.
745
- *
746
- * expect(obj).to.have.property('foo')
747
- * .that.is.a('string');
748
- * expect(deepObj).to.have.property('green')
749
- * .that.is.an('object')
750
- * .that.deep.equals({ tea: 'matcha' });
751
- * expect(deepObj).to.have.property('teas')
752
- * .that.is.an('array')
753
- * .with.deep.property('[2]')
754
- * .that.deep.equals({ tea: 'konacha' });
755
- *
756
- * @name property
757
- * @alias deep.property
758
- * @param {String} name
759
- * @param {Mixed} value (optional)
760
- * @param {String} message _optional_
761
- * @returns value of property for chaining
762
- * @api public
763
- */
764
-
765
- Assertion.addMethod('property', function (name, val, msg) {
766
- if (msg) flag(this, 'message', msg);
767
-
768
- var descriptor = flag(this, 'deep') ? 'deep property ' : 'property '
769
- , negate = flag(this, 'negate')
770
- , obj = flag(this, 'object')
771
- , value = flag(this, 'deep')
772
- ? _.getPathValue(name, obj)
773
- : obj[name];
774
-
775
- if (negate && undefined !== val) {
776
- if (undefined === value) {
777
- msg = (msg != null) ? msg + ': ' : '';
778
- throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
779
- }
780
- } else {
781
- this.assert(
782
- undefined !== value
783
- , 'expected #{this} to have a ' + descriptor + _.inspect(name)
784
- , 'expected #{this} to not have ' + descriptor + _.inspect(name));
785
- }
786
-
787
- if (undefined !== val) {
788
- this.assert(
789
- val === value
790
- , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
791
- , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'
792
- , val
793
- , value
794
- );
795
- }
796
-
797
- flag(this, 'object', value);
798
- });
799
-
800
-
801
- /**
802
- * ### .ownProperty(name)
803
- *
804
- * Asserts that the target has an own property `name`.
805
- *
806
- * expect('test').to.have.ownProperty('length');
807
- *
808
- * @name ownProperty
809
- * @alias haveOwnProperty
810
- * @param {String} name
811
- * @param {String} message _optional_
812
- * @api public
813
- */
814
-
815
- function assertOwnProperty (name, msg) {
816
- if (msg) flag(this, 'message', msg);
817
- var obj = flag(this, 'object');
818
- this.assert(
819
- obj.hasOwnProperty(name)
820
- , 'expected #{this} to have own property ' + _.inspect(name)
821
- , 'expected #{this} to not have own property ' + _.inspect(name)
822
- );
823
- }
824
-
825
- Assertion.addMethod('ownProperty', assertOwnProperty);
826
- Assertion.addMethod('haveOwnProperty', assertOwnProperty);
827
-
828
- /**
829
- * ### .length(value)
830
- *
831
- * Asserts that the target's `length` property has
832
- * the expected value.
833
- *
834
- * expect([ 1, 2, 3]).to.have.length(3);
835
- * expect('foobar').to.have.length(6);
836
- *
837
- * Can also be used as a chain precursor to a value
838
- * comparison for the length property.
839
- *
840
- * expect('foo').to.have.length.above(2);
841
- * expect([ 1, 2, 3 ]).to.have.length.above(2);
842
- * expect('foo').to.have.length.below(4);
843
- * expect([ 1, 2, 3 ]).to.have.length.below(4);
844
- * expect('foo').to.have.length.within(2,4);
845
- * expect([ 1, 2, 3 ]).to.have.length.within(2,4);
846
- *
847
- * @name length
848
- * @alias lengthOf
849
- * @param {Number} length
850
- * @param {String} message _optional_
851
- * @api public
852
- */
853
-
854
- function assertLengthChain () {
855
- flag(this, 'doLength', true);
856
- }
857
-
858
- function assertLength (n, msg) {
859
- if (msg) flag(this, 'message', msg);
860
- var obj = flag(this, 'object');
861
- new Assertion(obj, msg).to.have.property('length');
862
- var len = obj.length;
863
-
864
- this.assert(
865
- len == n
866
- , 'expected #{this} to have a length of #{exp} but got #{act}'
867
- , 'expected #{this} to not have a length of #{act}'
868
- , n
869
- , len
870
- );
871
- }
872
-
873
- Assertion.addChainableMethod('length', assertLength, assertLengthChain);
874
- Assertion.addMethod('lengthOf', assertLength, assertLengthChain);
875
-
876
- /**
877
- * ### .match(regexp)
878
- *
879
- * Asserts that the target matches a regular expression.
880
- *
881
- * expect('foobar').to.match(/^foo/);
882
- *
883
- * @name match
884
- * @param {RegExp} RegularExpression
885
- * @param {String} message _optional_
886
- * @api public
887
- */
888
-
889
- Assertion.addMethod('match', function (re, msg) {
890
- if (msg) flag(this, 'message', msg);
891
- var obj = flag(this, 'object');
892
- this.assert(
893
- re.exec(obj)
894
- , 'expected #{this} to match ' + re
895
- , 'expected #{this} not to match ' + re
896
- );
897
- });
898
-
899
- /**
900
- * ### .string(string)
901
- *
902
- * Asserts that the string target contains another string.
903
- *
904
- * expect('foobar').to.have.string('bar');
905
- *
906
- * @name string
907
- * @param {String} string
908
- * @param {String} message _optional_
909
- * @api public
910
- */
911
-
912
- Assertion.addMethod('string', function (str, msg) {
913
- if (msg) flag(this, 'message', msg);
914
- var obj = flag(this, 'object');
915
- new Assertion(obj, msg).is.a('string');
916
-
917
- this.assert(
918
- ~obj.indexOf(str)
919
- , 'expected #{this} to contain ' + _.inspect(str)
920
- , 'expected #{this} to not contain ' + _.inspect(str)
921
- );
922
- });
923
-
924
-
925
- /**
926
- * ### .keys(key1, [key2], [...])
927
- *
928
- * Asserts that the target has exactly the given keys, or
929
- * asserts the inclusion of some keys when using the
930
- * `include` or `contain` modifiers.
931
- *
932
- * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
933
- * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
934
- *
935
- * @name keys
936
- * @alias key
937
- * @param {String...|Array} keys
938
- * @api public
939
- */
940
-
941
- function assertKeys (keys) {
942
- var obj = flag(this, 'object')
943
- , str
944
- , ok = true;
945
-
946
- keys = keys instanceof Array
947
- ? keys
948
- : Array.prototype.slice.call(arguments);
949
-
950
- if (!keys.length) throw new Error('keys required');
951
-
952
- var actual = Object.keys(obj)
953
- , len = keys.length;
954
-
955
- // Inclusion
956
- ok = keys.every(function(key){
957
- return ~actual.indexOf(key);
958
- });
959
-
960
- // Strict
961
- if (!flag(this, 'negate') && !flag(this, 'contains')) {
962
- ok = ok && keys.length == actual.length;
963
- }
964
-
965
- // Key string
966
- if (len > 1) {
967
- keys = keys.map(function(key){
968
- return _.inspect(key);
969
- });
970
- var last = keys.pop();
971
- str = keys.join(', ') + ', and ' + last;
972
- } else {
973
- str = _.inspect(keys[0]);
974
- }
975
-
976
- // Form
977
- str = (len > 1 ? 'keys ' : 'key ') + str;
978
-
979
- // Have / include
980
- str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
981
-
982
- // Assertion
983
- this.assert(
984
- ok
985
- , 'expected #{this} to ' + str
986
- , 'expected #{this} to not ' + str
987
- );
988
- }
989
-
990
- Assertion.addMethod('keys', assertKeys);
991
- Assertion.addMethod('key', assertKeys);
992
-
993
- /**
994
- * ### .throw(constructor)
995
- *
996
- * Asserts that the function target will throw a specific error, or specific type of error
997
- * (as determined using `instanceof`), optionally with a RegExp or string inclusion test
998
- * for the error's message.
999
- *
1000
- * var err = new ReferenceError('This is a bad function.');
1001
- * var fn = function () { throw err; }
1002
- * expect(fn).to.throw(ReferenceError);
1003
- * expect(fn).to.throw(Error);
1004
- * expect(fn).to.throw(/bad function/);
1005
- * expect(fn).to.not.throw('good function');
1006
- * expect(fn).to.throw(ReferenceError, /bad function/);
1007
- * expect(fn).to.throw(err);
1008
- * expect(fn).to.not.throw(new RangeError('Out of range.'));
1009
- *
1010
- * Please note that when a throw expectation is negated, it will check each
1011
- * parameter independently, starting with error constructor type. The appropriate way
1012
- * to check for the existence of a type of error but for a message that does not match
1013
- * is to use `and`.
1014
- *
1015
- * expect(fn).to.throw(ReferenceError)
1016
- * .and.not.throw(/good function/);
1017
- *
1018
- * @name throw
1019
- * @alias throws
1020
- * @alias Throw
1021
- * @param {ErrorConstructor} constructor
1022
- * @param {String|RegExp} expected error message
1023
- * @param {String} message _optional_
1024
- * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
1025
- * @returns error for chaining (null if no error)
1026
- * @api public
1027
- */
1028
-
1029
- function assertThrows (constructor, errMsg, msg) {
1030
- if (msg) flag(this, 'message', msg);
1031
- var obj = flag(this, 'object');
1032
- new Assertion(obj, msg).is.a('function');
1033
-
1034
- var thrown = false
1035
- , desiredError = null
1036
- , name = null
1037
- , thrownError = null;
1038
-
1039
- if (arguments.length === 0) {
1040
- errMsg = null;
1041
- constructor = null;
1042
- } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
1043
- errMsg = constructor;
1044
- constructor = null;
1045
- } else if (constructor && constructor instanceof Error) {
1046
- desiredError = constructor;
1047
- constructor = null;
1048
- errMsg = null;
1049
- } else if (typeof constructor === 'function') {
1050
- name = constructor.prototype.name || constructor.name;
1051
- if (name === 'Error' && constructor !== Error) {
1052
- name = (new constructor()).name;
1053
- }
1054
- } else {
1055
- constructor = null;
1056
- }
1057
-
1058
- try {
1059
- obj();
1060
- } catch (err) {
1061
- // first, check desired error
1062
- if (desiredError) {
1063
- this.assert(
1064
- err === desiredError
1065
- , 'expected #{this} to throw #{exp} but #{act} was thrown'
1066
- , 'expected #{this} to not throw #{exp}'
1067
- , (desiredError instanceof Error ? desiredError.toString() : desiredError)
1068
- , (err instanceof Error ? err.toString() : err)
1069
- );
1070
-
1071
- flag(this, 'object', err);
1072
- return this;
1073
- }
1074
-
1075
- // next, check constructor
1076
- if (constructor) {
1077
- this.assert(
1078
- err instanceof constructor
1079
- , 'expected #{this} to throw #{exp} but #{act} was thrown'
1080
- , 'expected #{this} to not throw #{exp} but #{act} was thrown'
1081
- , name
1082
- , (err instanceof Error ? err.toString() : err)
1083
- );
1084
-
1085
- if (!errMsg) {
1086
- flag(this, 'object', err);
1087
- return this;
1088
- }
1089
- }
1090
-
1091
- // next, check message
1092
- var message = 'object' === _.type(err) && "message" in err
1093
- ? err.message
1094
- : '' + err;
1095
-
1096
- if ((message != null) && errMsg && errMsg instanceof RegExp) {
1097
- this.assert(
1098
- errMsg.exec(message)
1099
- , 'expected #{this} to throw error matching #{exp} but got #{act}'
1100
- , 'expected #{this} to throw error not matching #{exp}'
1101
- , errMsg
1102
- , message
1103
- );
1104
-
1105
- flag(this, 'object', err);
1106
- return this;
1107
- } else if ((message != null) && errMsg && 'string' === typeof errMsg) {
1108
- this.assert(
1109
- ~message.indexOf(errMsg)
1110
- , 'expected #{this} to throw error including #{exp} but got #{act}'
1111
- , 'expected #{this} to throw error not including #{act}'
1112
- , errMsg
1113
- , message
1114
- );
1115
-
1116
- flag(this, 'object', err);
1117
- return this;
1118
- } else {
1119
- thrown = true;
1120
- thrownError = err;
1121
- }
1122
- }
1123
-
1124
- var actuallyGot = ''
1125
- , expectedThrown = name !== null
1126
- ? name
1127
- : desiredError
1128
- ? '#{exp}' //_.inspect(desiredError)
1129
- : 'an error';
1130
-
1131
- if (thrown) {
1132
- actuallyGot = ' but #{act} was thrown'
1133
- }
1134
-
1135
- this.assert(
1136
- thrown === true
1137
- , 'expected #{this} to throw ' + expectedThrown + actuallyGot
1138
- , 'expected #{this} to not throw ' + expectedThrown + actuallyGot
1139
- , (desiredError instanceof Error ? desiredError.toString() : desiredError)
1140
- , (thrownError instanceof Error ? thrownError.toString() : thrownError)
1141
- );
1142
-
1143
- flag(this, 'object', thrownError);
1144
- };
1145
-
1146
- Assertion.addMethod('throw', assertThrows);
1147
- Assertion.addMethod('throws', assertThrows);
1148
- Assertion.addMethod('Throw', assertThrows);
1149
-
1150
- /**
1151
- * ### .respondTo(method)
1152
- *
1153
- * Asserts that the object or class target will respond to a method.
1154
- *
1155
- * Klass.prototype.bar = function(){};
1156
- * expect(Klass).to.respondTo('bar');
1157
- * expect(obj).to.respondTo('bar');
1158
- *
1159
- * To check if a constructor will respond to a static function,
1160
- * set the `itself` flag.
1161
- *
1162
- * Klass.baz = function(){};
1163
- * expect(Klass).itself.to.respondTo('baz');
1164
- *
1165
- * @name respondTo
1166
- * @param {String} method
1167
- * @param {String} message _optional_
1168
- * @api public
1169
- */
1170
-
1171
- Assertion.addMethod('respondTo', function (method, msg) {
1172
- if (msg) flag(this, 'message', msg);
1173
- var obj = flag(this, 'object')
1174
- , itself = flag(this, 'itself')
1175
- , context = ('function' === _.type(obj) && !itself)
1176
- ? obj.prototype[method]
1177
- : obj[method];
1178
-
1179
- this.assert(
1180
- 'function' === typeof context
1181
- , 'expected #{this} to respond to ' + _.inspect(method)
1182
- , 'expected #{this} to not respond to ' + _.inspect(method)
1183
- );
1184
- });
1185
-
1186
- /**
1187
- * ### .itself
1188
- *
1189
- * Sets the `itself` flag, later used by the `respondTo` assertion.
1190
- *
1191
- * function Foo() {}
1192
- * Foo.bar = function() {}
1193
- * Foo.prototype.baz = function() {}
1194
- *
1195
- * expect(Foo).itself.to.respondTo('bar');
1196
- * expect(Foo).itself.not.to.respondTo('baz');
1197
- *
1198
- * @name itself
1199
- * @api public
1200
- */
1201
-
1202
- Assertion.addProperty('itself', function () {
1203
- flag(this, 'itself', true);
1204
- });
1205
-
1206
- /**
1207
- * ### .satisfy(method)
1208
- *
1209
- * Asserts that the target passes a given truth test.
1210
- *
1211
- * expect(1).to.satisfy(function(num) { return num > 0; });
1212
- *
1213
- * @name satisfy
1214
- * @param {Function} matcher
1215
- * @param {String} message _optional_
1216
- * @api public
1217
- */
1218
-
1219
- Assertion.addMethod('satisfy', function (matcher, msg) {
1220
- if (msg) flag(this, 'message', msg);
1221
- var obj = flag(this, 'object');
1222
- this.assert(
1223
- matcher(obj)
1224
- , 'expected #{this} to satisfy ' + _.objDisplay(matcher)
1225
- , 'expected #{this} to not satisfy' + _.objDisplay(matcher)
1226
- , this.negate ? false : true
1227
- , matcher(obj)
1228
- );
1229
- });
1230
-
1231
- /**
1232
- * ### .closeTo(expected, delta)
1233
- *
1234
- * Asserts that the target is equal `expected`, to within a +/- `delta` range.
1235
- *
1236
- * expect(1.5).to.be.closeTo(1, 0.5);
1237
- *
1238
- * @name closeTo
1239
- * @param {Number} expected
1240
- * @param {Number} delta
1241
- * @param {String} message _optional_
1242
- * @api public
1243
- */
1244
-
1245
- Assertion.addMethod('closeTo', function (expected, delta, msg) {
1246
- if (msg) flag(this, 'message', msg);
1247
- var obj = flag(this, 'object');
1248
- this.assert(
1249
- Math.abs(obj - expected) <= delta
1250
- , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
1251
- , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
1252
- );
1253
- });
1254
-
1255
- function isSubsetOf(subset, superset, cmp) {
1256
- return subset.every(function(elem) {
1257
- if (!cmp) return superset.indexOf(elem) !== -1;
1258
-
1259
- return superset.some(function(elem2) {
1260
- return cmp(elem, elem2);
1261
- });
1262
- })
1263
- }
1264
-
1265
- /**
1266
- * ### .members(set)
1267
- *
1268
- * Asserts that the target is a superset of `set`,
1269
- * or that the target and `set` have the same strictly-equal (===) members.
1270
- * Alternately, if the `deep` flag is set, set members are compared for deep
1271
- * equality.
1272
- *
1273
- * expect([1, 2, 3]).to.include.members([3, 2]);
1274
- * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);
1275
- *
1276
- * expect([4, 2]).to.have.members([2, 4]);
1277
- * expect([5, 2]).to.not.have.members([5, 2, 1]);
1278
- *
1279
- * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);
1280
- *
1281
- * @name members
1282
- * @param {Array} set
1283
- * @param {String} message _optional_
1284
- * @api public
1285
- */
1286
-
1287
- Assertion.addMethod('members', function (subset, msg) {
1288
- if (msg) flag(this, 'message', msg);
1289
- var obj = flag(this, 'object');
1290
-
1291
- new Assertion(obj).to.be.an('array');
1292
- new Assertion(subset).to.be.an('array');
1293
-
1294
- var cmp = flag(this, 'deep') ? _.eql : undefined;
1295
-
1296
- if (flag(this, 'contains')) {
1297
- return this.assert(
1298
- isSubsetOf(subset, obj, cmp)
1299
- , 'expected #{this} to be a superset of #{act}'
1300
- , 'expected #{this} to not be a superset of #{act}'
1301
- , obj
1302
- , subset
1303
- );
1304
- }
1305
-
1306
- this.assert(
1307
- isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)
1308
- , 'expected #{this} to have the same members as #{act}'
1309
- , 'expected #{this} to not have the same members as #{act}'
1310
- , obj
1311
- , subset
1312
- );
1313
- });
1314
- };