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

Chai Immutable

このプラグインは、Chaiのために、FacebookのJavaScriptコレクション用Immutableライブラリ用のアサーションセットを提供します。

アサーション

インストール

Node.js

npmまたはyarn経由でインストール

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であると見なされ、.equal()に対して正しく動作するためには、他のImmutableデータ構造のみを含める必要があります(ArrayObjectとは異なります)。詳細は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.includeincludeとまったく同じ動作をします。

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 _{文字列… 配列 オブジェクト コレクション}_ key_N_

ターゲットコレクションに指定されたキーがあることをアサートします。

ターゲットがオブジェクトまたは配列の場合、キーは1つ以上の文字列引数、1つの配列引数、1つのオブジェクト引数、またはImmutableコレクションとして提供できます。最後の2つの場合、指定されたオブジェクト/コレクション内のキーのみが重要で、値は無視されます。

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.propertypropertyとまったく同じ動作をします。

デフォルトでは、ターゲットは指定されたキーをすべて持ち、それ以上は持てません。ターゲットが指定されたキーの少なくとも1つを持つ必要がある場合のみ、チェーンの先頭に.anyを追加します。また、.keysを否定するには、チェーンの先頭に.notを追加します。.keysを否定する場合は.anyを追加し、否定せずに.keysをアサートする場合は.allを使用するのが最適な場合が多いです。

.keysを否定する場合、.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.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 _{文字列 配列 反復可能}_ 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.propertypropertyとまったく同じ動作をします。

ネストされたプロパティを参照する際にドット表記とブラケット表記を有効にするには、チェーンの先頭に.nestedを追加します。Immutable Listnested.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'
);

.または[]が実際のプロパティ名の一部である場合、その前に2つのバックスラッシュを追加してエスケープできます。

expect(Immutable.fromJS({ '.a': { '[b]': 'x' } })).to.have.nested.property(
  '\\.a.\\[b\\]'
);

.propertyを否定するには、チェーンの先頭に.notを追加します。

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にプロパティを持つことが期待される場合、多くの予期しない値の1つを持たないことをアサートするのではなく、プロパティが期待される値を持つことをアサートするのが最適な場合が多いです。

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 {数値} 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の値と等価であることをアサートします。.strictEqual().deepEqual()は、イミュータブルデータ構造のコンテキストでは.equal()とまったく同じようにアサートします。

const a = List.of(1, 2, 3);
const b = List.of(1, 2, 3);
assert.equal(a, b);

イミュータブルデータ構造は、イミュータブルであるとみなされ、.equal().strictEqual()、または.deepEqual()に対して適切に動作するためには、他のイミュータブルデータ構造のみを含んでいる必要があります(ArrayObjectとは異なります)。詳細は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の値と等価でないことをアサートします。.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 {数値} size

Immutableコレクションが期待されるサイズを持つことをアサートします。

assert.sizeOf(List.of(1, 2, 3), 3);
assert.sizeOf(new List(), 0);