npm Version License Build Status Build Status Coverage Status devDependencies Status peerDependencies Status

Chai Immutable

這個外掛為 Chai 提供一組斷言,用於 Facebook 的 JavaScript 集合 Immutable 函式庫

斷言

安裝

Node.js

透過 npmyarn 安裝

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-promiseddirty-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 資料結構 (與 ArrayObject 不同),才被視為 immutable,並正確地與 .equal() 運作。 如需更多資訊,請參閱 issue #24

另請注意,在針對 immutable 資料結構進行測試時,deep.equaleqlequal 的同義詞,因此它們是 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

includecontain 斷言可以用作基於屬性的語言鏈,或用作判斷 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 也會斷言屬性的值等於給定的 valval 可以是 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 類似,sizeOfsize 的別名。

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 資料結構(與 ArrayObject 不同),才能被視為 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);