Chai Immutable
這個外掛為 Chai 提供一組斷言,用於 Facebook 的 JavaScript 集合 Immutable 函式庫。
斷言
- BDD API 參考 (Expect / Should)
- TDD API 參考 (Assert)
安裝
Node.js
npm install --save-dev chai-immutable
yarn add --dev chai-immutable
然後您可以像其他 Chai 外掛一樣使用此外掛
const chai = require('chai');
const chaiImmutable = require('chai-immutable');
chai.use(chaiImmutable);
ES6 語法 (需要 Babel 轉譯)
import chai from 'chai';
import chaiImmutable from 'chai-immutable';
chai.use(chaiImmutable);
在瀏覽器中
在載入 Chai 和 Immutable 後載入此外掛。它會自動插入 Chai 並準備好使用
<script src="chai-immutable.js"></script>
將 chai-immutable
與其他外掛一起使用
如果您將此外掛與 chai-as-promised
或 dirty-chai
一起使用,請注意,chai-immutable
必須在它們之前載入。 例如
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const chaiImmutable = require('chai-immutable');
const dirtyChai = require('dirty-chai');
const { expect } = chai;
chai.use(chaiImmutable);
chai.use(chaiAsPromised);
chai.use(dirtyChai);
const { List } = require('immutable');
/* ... */
expect(Promise.resolve(List.of(1, 2, 3))).to.eventually.have.size(3);
expect(true).to.be.true();
BDD API 參考 (Expect / Should)
.empty
斷言 immutable 集合為空。
expect(List()).to.be.empty;
expect(List.of(1, 2, 3)).to.not.be.empty;
.equal(collection)
- @param { Collection } collection
斷言目標的值與 collection
的值相等。 也支援 Chai 原始 equal
方法的別名。
const a = List.of(1, 2, 3);
const b = List.of(1, 2, 3);
expect(a).to.equal(b);
Immutable 資料結構應僅包含其他 immutable 資料結構 (與 Array
和 Object
不同),才被視為 immutable,並正確地與 .equal()
運作。 如需更多資訊,請參閱 issue #24。
另請注意,在針對 immutable 資料結構進行測試時,deep.equal
和 eql
是 equal
的同義詞,因此它們是 equal
的別名。
.referenceEqual(value)
- @param {Collection} value
斷言目標的參考與 collection
的參考相等。 此方法保留 Chai 的 equal
的原始行為。
如需更多詳細資訊,請參閱 issue #210。
const a = List.of(1, 2, 3);
const b = a;
const c = List.of(1, 2, 3);
expect(a).to.referenceEqual(b);
expect(a).to.not.referenceEqual(c);
.include(value)
- @param { Mixed } val
include
和 contain
斷言可以用作基於屬性的語言鏈,或用作判斷 immutable 集合中是否包含值或子集的方法。 當用作語言鏈時,它們會切換 keys
斷言的 contains
旗標。
請注意,在 immutable 資料結構的上下文中,deep.include
的行為與 include
完全相同。
expect(new List([1, 2, 3])).to.include(2);
expect(new List([1, 2, 3])).to.deep.include(2);
expect(new Map({ foo: 'bar', hello: 'world' })).to.include('bar');
expect(new Map({ a: 1, b: 2, c: 3 })).to.include(new Map({ a: 1, b: 2 }));
expect(new Map({ foo: 'bar', hello: 'world' })).to.include.keys('foo');
.keys(key1[, key2[, …]])
-
@param _{ String… Array Object Collection }_ keyN
斷言目標集合具有給定的鍵。
當目標是物件或陣列時,可以提供鍵作為一個或多個字串引數、單一陣列引數、單一物件引數或 immutable 集合。 在最後兩種情況下,只有給定物件/集合中的鍵很重要; 值會被忽略。
expect(new Map({ foo: 1, bar: 2 })).to.have.all.keys('foo', 'bar');
expect(new Map({ foo: 1, bar: 2 })).to.have.all.keys(new List(['bar', 'foo']));
expect(new Map({ foo: 1, bar: 2 })).to.have.all.keys(new Set(['bar', 'foo']));
expect(new Map({ foo: 1, bar: 2 })).to.have.all.keys(new Stack(['bar', 'foo']));
expect(new List(['x', 'y'])).to.have.all.keys(0, 1);
expect(new Map({ foo: 1, bar: 2 })).to.have.all.keys(['foo', 'bar']);
expect(new List(['x', 'y'])).to.have.all.keys([0, 1]);
// Values in the passed object are ignored:
expect(new Map({ foo: 1, bar: 2 })).to.have.all.keys({ bar: 6, foo: 7 });
expect(new Map({ foo: 1, bar: 2 })).to.have.all.keys(
new Map({ bar: 6, foo: 7 })
);
expect(new List(['x', 'y'])).to.have.all.keys({ 0: 4, 1: 5 });
請注意,在 immutable 資料結構的上下文中,deep.property
的行為與 property
完全相同。
預設情況下,目標必須具有所有給定的鍵,且不得更多。 在鏈中較早的位置新增 .any
,僅要求目標至少具有給定的其中一個鍵。 此外,在鏈中較早的位置新增 .not
,以否定 .keys
。 當否定 .keys
時,最好新增 .any
,並在斷言 .keys
而不進行否定時,使用 .all
。
當否定 .keys
時,.any
是首選,因為 .not.any.keys
斷言了輸出的預期,而 .not.all.keys
會建立不確定的預期。
// Recommended; asserts that target doesn't have any of the given keys
expect(new Map({ a: 1, b: 2 })).to.not.have.any.keys('c', 'd');
// Not recommended; asserts that target doesn't have all of the given
// keys but may or may not have some of them
expect(new Map({ a: 1, b: 2 })).to.not.have.all.keys('c', 'd');
當在不進行否定的情況下斷言 .keys
時,.all
是首選,因為 .all.keys
斷言了輸出的預期,而 .any.keys
會建立不確定的預期。
// Recommended; asserts that target has all the given keys
expect(new Map({ a: 1, b: 2 })).to.have.all.keys('a', 'b');
// Not recommended; asserts that target has at least one of the given
// keys but may or may not have more of them
expect(new Map({ a: 1, b: 2 })).to.have.any.keys('a', 'b');
請注意,當鏈中較早的位置沒有出現 .all
或 .any
時,預設會使用 .all
。 但是,最好還是新增 .all
,因為這樣可以提高可讀性。
// Both assertions are identical
expect(new Map({ a: 1, b: 2 })).to.have.all.keys('a', 'b'); // Recommended
expect(new Map({ a: 1, b: 2 })).to.have.keys('a', 'b'); // Not recommended
在鏈中較早的位置新增 .include
,以要求目標的鍵為預期鍵的超集,而不是相同的集合。
// Target object's keys are a superset of ['a', 'b'] but not identical
expect(new Map({ a: 1, b: 2, c: 3 })).to.include.all.keys('a', 'b');
expect(new Map({ a: 1, b: 2, c: 3 })).to.not.have.all.keys('a', 'b');
但是,如果組合 .any
和 .include
,則只有 .any
會生效。 在這種情況下,會忽略 .include
。
// Both assertions are identical
expect(new Map({ a: 1 })).to.have.any.keys('a', 'b');
expect(new Map({ a: 1 })).to.include.any.keys('a', 'b');
別名 .key
可以與 .keys
交替使用。
expect(new Map({ foo: 1 })).to.have.key('foo');
.property(path[, val])
-
@param _{ String Array Iterable }_ path - @param { Mixed } val (選用)
斷言目標具有具有給定 path
的屬性。
expect(new Map({ a: 1 })).to.have.property('a');
當提供 val
時,.property
也會斷言屬性的值等於給定的 val
。val
可以是 immutable 集合。
expect(new Map({ a: 1 })).to.have.property('a', 1);
請注意,在 immutable 資料結構的上下文中,deep.property
的行為與 property
完全相同。
在鏈中較早的位置新增 .nested
,以便在參照巢狀屬性時啟用點和方括號表示法。 Immutable List
也可以用作 nested.property
的起點。
expect(Immutable.fromJS({ a: { b: ['x', 'y'] } })).to.have.nested.property(
'a.b[1]'
);
expect(Immutable.fromJS({ a: { b: ['x', 'y'] } })).to.have.nested.property(
'a.b[1]',
'y'
);
expect(Immutable.fromJS({ a: { b: ['x', 'y'] } })).to.have.nested.property(
['a', 'b', 1],
'y'
);
expect(Immutable.fromJS({ a: { b: ['x', 'y'] } })).to.have.nested.property(
new List(['a', 'b', 1]),
'y'
);
如果 .
或 []
是實際屬性名稱的一部分,則可以透過在它們之前新增兩個反斜線來逸出它們。
expect(Immutable.fromJS({ '.a': { '[b]': 'x' } })).to.have.nested.property(
'\\.a.\\[b\\]'
);
在鏈中較早的位置新增 .not
,以否定 .property
。
expect(new Map({ a: 1 })).to.not.have.property('b');
但是,當提供 val
時,否定 .property
是很危險的。 問題在於,它透過斷言目標在給定 path
上沒有屬性,或在給定鍵 path
上具有屬性,但其值與給定 val
不相等,從而建立了不確定的預期。 最好識別預期的確切輸出,然後編寫一個僅接受該確切輸出的斷言。
當目標預期在給定 path
上沒有屬性時,最好明確地斷言這一點。
expect(new Map({ b: 2 })).to.not.have.property('a'); // Recommended
expect(new Map({ b: 2 })).to.not.have.property('a', 1); // Not recommended
當目標預期在給定鍵 path
上具有屬性時,最好斷言屬性具有預期的值,而不是斷言它沒有許多意外的值之一。
expect(new Map({ a: 3 })).to.have.property('a', 3); // Recommended
expect(new Map({ a: 3 })).to.not.have.property('a', 1); // Not recommended
.property
會將鏈中後續任何斷言的目標變更為原始目標物件中屬性的值。
expect(new Map({ a: 1 }))
.to.have.property('a')
.that.is.a('number');
.size(value)
- @param { Number } size
斷言 immutable 集合具有預期的大小。
expect(List.of(1, 2, 3)).to.have.size(3);
它也可以作為 size
屬性的值比較鏈的前置條件。
expect(List.of(1, 2, 3)).to.have.size.least(3);
expect(List.of(1, 2, 3)).to.have.size.most(3);
expect(List.of(1, 2, 3)).to.have.size.above(2);
expect(List.of(1, 2, 3)).to.have.size.below(4);
expect(List.of(1, 2, 3)).to.have.size.within(2, 4);
與 length
/ lengthOf
類似,sizeOf
是 size
的別名。
expect(List.of(1, 2, 3)).to.have.sizeOf(3);
TDD API 參考 (Assert)
.equal(actual, expected)
- @param { Collection } actual
- @param { Collection } expected
斷言 actual
的值與 expected
的值相等。請注意,在 Immutable 資料結構的上下文中,.strictEqual()
和 .deepEqual()
的斷言行為與 .equal()
完全相同。
const a = List.of(1, 2, 3);
const b = List.of(1, 2, 3);
assert.equal(a, b);
Immutable 資料結構應僅包含其他 Immutable 資料結構(與 Array
和 Object
不同),才能被視為 immutable 並能正確地與 .equal()
、.strictEqual()
或 .deepEqual()
搭配使用。更多資訊請參閱 issue #24。
.referenceEqual(actual, expected)
- @param {Collection} actual
- @param {Collection} expected
斷言 actual
的參考與 expected
的參考相等。此方法保留了 Chai 原生的 equal
行為。
如需更多詳細資訊,請參閱 issue #210。
const a = List.of(1, 2, 3);
const b = a;
const c = List.of(1, 2, 3);
assert.referenceEqual(a, b);
assert.throws(() => assert.referenceEqual(a, c));
.notEqual(actual, expected)
- @param { Collection } actual
- @param { Collection } expected
斷言 actual
的值與 expected
的值不相等。請注意,在 Immutable 資料結構的上下文中,.notStrictEqual()
和 .notDeepEqual()
的斷言行為與 .notEqual()
完全相同。
const a = List.of(1, 2, 3);
const b = List.of(4, 5, 6);
assert.notEqual(a, b);
.notReferenceEqual(actual, expected)
- @param {Collection} actual
- @param {Collection} expected
斷言 actual
的參考與 expected
的參考不相等。此方法保留了 Chai 原生的 notEqual
行為。
如需更多詳細資訊,請參閱 issue #210。
const a = List.of(1, 2, 3);
const b = a;
const c = List.of(1, 2, 3);
assert.throws(() => assert.notReferenceEqual(a, b));
assert.notReferenceEqual(a, c);
.sizeOf(collection, length)
- @param { Collection } collection
- @param { Number } size
斷言 immutable 集合具有預期的大小。
assert.sizeOf(List.of(1, 2, 3), 3);
assert.sizeOf(new List(), 0);