chai-iterator: 反復可能なオブジェクトに対するアサーション
コンテンツ
概要
chai-iterator は Chai アサーションライブラリを、反復可能な オブジェクトをテストするためのメソッドで拡張しています。 ES2015 仕様 で導入された反復可能なオブジェクトには @@iterator
メソッドがあり、これにより for...of
ループを使用してオブジェクトを反復処理できます。多数の組み込み 型がデフォルトで反復可能である一方、カスタム反復可能オブジェクト も定義できます。chai-iterator を使用すると、こうしたオブジェクトをすべて簡単にテストできます。
chai-iterator は不要な場合があります
配列スプレッド構文 は、多くの場合反復可能なものをテストする最適な方法です。ただし、chai-iterator は非常に長い(または無限)反復可能なもののうち、一部をテストするときに非常に役立ちます。
基本的な使用方法
Chai Iterator を使用して行えるアサーションの非常に包括的なサンプルを以下に示します。 expect
または assert
を簡単に使用できますが、ここでは Chai の should()
アサーションスタイル を使用して、単に違いを示します。
[2, 3, 5].should.be.iterable;
[2, 3, 5].should.iterate.over([2, 3, 5]);
[2, 3, 5].should.iterate.from([2, 3]);
[2, 3, 5].should.iterate.until([3, 5]);
[2, 3, 5].should.iterate.for.lengthOf(3);
[2, 3, 5].should.iterate.for.length.above(2);
[2, 3, 5].should.iterate.for.length.below(4);
[2, 3, 5].should.iterate.for.length.of.at.least(3);
[2, 3, 5].should.iterate.for.length.of.at.most(3);
[2, 3, 5].should.iterate.for.length.within(2, 4);
[2, 3, 5].should.not.iterate.over([1, 2, 3]);
[{n: 2}, {n: 3}].should.deep.iterate.from([{n: 2}]);
配列に限定しません。反復可能なオブジェクトはどれでもテストできます。
'abcde'.should.iterate.until(['c', 'd', 'e']);
そして、任意の反復可能なものを期待される値として渡すこともできます。
'abcde'.should.iterate.until('cde');
ユーザー定義の反復可能オブジェクト
chai-iterator は、以下の クラス で構築されたオブジェクトなど、ユーザー定義の反復可能オブジェクト をテストするために最適に使用できます。
class Count {
constructor(start=0, step=1) {
this.start = start;
this.step = step;
}
*[Symbol.iterator]() {
for (let n = this.start; true; n += this.step) {
yield n;
}
}
}
Count.prototype[@@iterator]()
によって生成されるシーケンスは無限であり、値をいつまでも生成し続けます。それでも from()
アサーションを安全に使用できます。期待される反復可能処理が完了するとすぐに終了するためです。
let tens = new Count(10, 10);
tens.should.be.iterable;
tens.should.iterate.from([10, 20, 30]);
tens.should.iterate.from([10, 20, 30, 40, 50]);
無限のシーケンスに対して over()
または until()
を使用しようとしないでください。前者は常に失敗し、後者は決して停止しません。
ジェネレーターと反復処理
フィボナッチ数列を生成しましょうフィボナッチ数列. ジェネレータ関数とは、Generator
オブジェクト、つまり反復子を兼ねたイテラブルを返す、単なる関数にすぎません。他のイテラブルと同様にGenerator
をテストできます。
function* fibonacci() {
for (let [x, y] = [1, 1]; true; [x, y] = [y, x + y]) {
yield x;
}
}
fibonacci().should.iterate.from([1, 1, 2, 3, 5]);
ただし注意してください。イテレータは過去に戻ることができません。値が生成されると、それは永遠に失われます。したがって、以降の主張が通ります。
let fiborator = fibonacci();
fiborator.should.iterate.from([1, 1, 2, 3, 5]);
fiborator.should.iterate.from([8, 13, 21, 34]);
主張ごとに新しいGenerator
を構築する方が、通常はより適切です。
fibonacci().should.iterate.from([1, 1, 2, 3, 5]);
fibonacci().should.iterate.from([1, 1, 2, 3, 5, 8, 13]);
互換性
chai-iteratorでは、Symbol.iterator
が環境で利用可能である必要があります。 Nodeでは、バージョンがv4.0以降である必要があります。ほとんどのブラウザの最新バージョンは互換性がありますが、Webに直面するプロジェクトではほぼ確実にポリフィルを使用する必要があります。
Symbol.iterator
をネイティブでサポートしていない環境では、バベルポリフィルが1つのオプションです。より必要最小限に、次のようにcore-jsライブラリから2つのサブモジュールだけで済ますことができます。
require('core-js/es6/symbol');
require('core-js/fn/symbol/iterator');
インストール
npmを使用してchai-iteratorをインストールします。そしてもちろんChaiをインストールしてください。
npm install --save chai chai-iterator
セットアップ
chai-iteratorはNodeモジュール、AMDモジュールとしてインポートするか、HTML<script>
タグに含めることができます。TypeScriptユーザーの場合は、宣言がパッケージにインストールされます。
ノード
Nodeのchai-iteratorを設定するには、バージョンがv4.0以降であることを確認してください。以前のバージョンでは@@iterator
メソッドのサポートがありません。
const chai = require('chai');
const chaiIterator = require('chai-iterator');
chai.use(chaiIterator);
AMD
chai-iteratorは次のようにAMDモジュール内に設定できます。
define((require, exports, module) => {
let chai = require('chai');
let chaiIterator = require('chai-iterator');
chai.use(chaiIterator);
});
HTMLスクリプトタグ
chai-iteratorには<script>
タグから含めることができます。 chai.js
の後にロードされると、Chaiは自動的にそれを使用します。
<script src="chai.js"></script>
<script src="chai-iterator.js"></script>
タイプスクリプト
TypeScript宣言はパッケージに含まれています。それらを使用するには、chai-iteratorがnpmでインストールされていることを確認し、宣言とその依存関係をtypingsを介してインストールします。chaiの宣言もインストールしてください。
typings install --save-dev npm~chai npm:chai-iterator
コンパイラオプションで、"target"
を"es6"
に設定するか、少なくともlib.es6.d.ts
への参照を含めてください。これで以下は機能するようになります。
import chai = require("chai");
import chaiIterator = require("chai-iterator");
chai.use(chaiIterator);
[2, 3, 5].should.iterate.over([2, 3, 5]);
Expect/Should API
アサーション
反復可能
iterate.over()
iterate.from()
iterate.until()
iterate.for.lengthOf()
iterate.for.length.above()
iterate.for.length.below()
iterate.for.length.of.at.least()
iterate.for.length.of.at.most()
iterate.for.length.within()
反復可能
ターゲットが反復可能オブジェクト、つまり@@iterator
メソッドを持つことをアサートします。
expect([2, 3, 5]).to.be.iterable;
expect('abcdefg').to.be.iterable;
expect(12345).not.to.be.iterable;
iterate.over(expected)
ターゲットが与えられたシーケンスの値を反復することをアサートします。deep
フラグを設定して値を比較する際にディープイコールを使用します。
Param | タイプ | 説明 |
---|---|---|
expected | object |
反復可能オブジェクト。 |
expect([2, 3, 5]).to.iterate.over([2, 3, 5]);
expect('abcdefg').to.itetate.over('abcdefg');
expect([2, 3, 5]).not.to.iterate.over([2, 3]);
expect([{n: 2}, {n: 3}]).to.deep.iterate.over([{n: 2}, {n: 3}]);
iterate.from(expected)
ターゲットが与えられたシーケンスの値を反復し始めることをアサートします。deep
フラグを設定して値を比較する際にディープイコールを使用します。
Param | タイプ | 説明 |
---|---|---|
expected | object |
反復可能オブジェクト。 |
expect([2, 3, 5]).to.iterate.from([2, 3]);
expect('abcdefg').to.iterate.from('abc');
expect([2, 3, 5]).not.to.iterate.from([3, 5]);
expect([{n: 2}, {n: 3}]).to.deep.iterate.from([{n: 2}]);
iterate.until(expected)
ターゲットが与えられたシーケンスの値で反復を終了することをアサートします。deep
フラグを設定して値を比較する際にディープイコールを使用します。
Param | タイプ | 説明 |
---|---|---|
expected | object |
反復可能オブジェクト。 |
expect([2, 3, 5]).to.iterate.until([3, 5]);
expect('abcdefg').to.iterate.until('efg');
expect([2, 3, 5]).not.to.iterate.until([2, 3]);
expect([{n: 2}, {n: 3}]).to.deep.iterate.until([{n: 3}]);
iterate.for.lengthOf(n)
ターゲットが正確にnの値を返すことをアサートします。
Param | タイプ | 説明 |
---|---|---|
n | number |
正の整数 |
expect([2, 3, 5]).to.iterate.for.lengthOf(3);
expect('abcdefg').to.iterate.for.lengthOf(7);
expect([2, 3, 5]).not.to.iterate.for.lengthOf(7);
iterate.for.length.above(n)
ターゲットがn以上の値を返すことをアサートします。
Param | タイプ | 説明 |
---|---|---|
n | number |
正の整数 |
expect([2, 3, 5]).to.iterate.for.length.above(2);
expect('abcdefg').to.iterate.for.length.above(5);
expect([2, 3, 5]).not.to.iterate.for.length.above(3);
iterate.for.length.below(n)
ターゲットがn未満の値を返すことをアサートします。
Param | タイプ | 説明 |
---|---|---|
n | number |
正の整数 |
expect([2, 3, 5]).to.iterate.for.length.below(4);
expect('abcdefg').to.iterate.for.length.below(10);
expect([2, 3, 5]).not.to.iterate.for.length.below(3);
iterate.for.length.of.at.least(n)
ターゲットが少なくともnの値を返すことをアサートします。
Param | タイプ | 説明 |
---|---|---|
n | number |
正の整数 |
expect([2, 3, 5]).to.iterate.for.length.of.at.least(2);
expect([2, 3, 5]).to.iterate.for.length.of.at.least(3);
expect([2, 3, 5]).not.to.iterate.for.length.of.at.least(4);
反復.for.長さ.of.最大(n)
ターゲットがn個の値で反復することをアサートします。
Param | タイプ | 説明 |
---|---|---|
n | number |
正の整数 |
expect([2, 3, 5]).to.iterate.for.length.of.at.most(4);
expect([2, 3, 5]).to.iterate.for.length.of.at.most(3);
expect([2, 3, 5]).not.to.iterate.for.length.of.at.most(2);
反復.for.長さ.範囲内(最小, 最大)
ターゲットが最小と最大の値の間、両端を含むで反復することをアサートします。
Param | タイプ | 説明 |
---|---|---|
最小 | number |
正の整数 |
最大 | number |
正の整数 |
expect([2, 3, 5]).to.iterate.for.length.within(2, 4);
expect([2, 3, 5]).to.iterate.for.length.within(3, 3);
expect([2, 3, 5]).not.to.iterate.for.length.within(4, 7);
Assert API
アサーション
反復可能である()
反復可能でない()
反復する()
反復しない()
深層反復する()
深層反復しない()
から反復する()
から反復しない()
まで深層反復する()
まで深層反復しない()
反復するまで()
反復しないまで()
深層反復するまで()
深層反復しないまで()
長さは()
パラメータ
アサートメソッドのパラメータを以下に示します。
Param | タイプ | 説明 |
---|---|---|
値 | 任意 |
任意の値です。 |
expected | object |
反復可能オブジェクト。 |
n | number |
正の整数です。 |
メッセージ | 文字列 |
エラー時に表示するオプションのメッセージです。 |
反復可能である(値, [メッセージ])
値が反復可能なオブジェクト、つまり、@@iterator
メソッドを持つオブジェクトであることをアサートします。
assert.isIterable([2, 3, 5]);
assert.isIterable('abcdefg');
反復可能でない(値, [メッセージ])
値が反復可能なオブジェクトではなく、@@iterator
メソッドを持たないことをアサートします。
assert.isNotIterable(235);
assert.isNotIterable(true);
反復する(値, 期待値, [メッセージ])
値が与えられた値のシーケンスを正確に反復することをアサートします。
assert.iteratesOver([2, 3, 5], [2, 3, 5]);
assert.iteratesOver('abcdefg', 'abcdefg');
反復しない(値, 期待値, [メッセージ])
値が与えられた値のシーケンスを正確に反復しないことをアサートします。
assert.doesNotIterateOver([2, 3, 5], [1, 2, 3]);
assert.doesNotIterateOver('abcdefg', 'abc');
深層反復する(値, 期待値, [メッセージ])
値が与えられた値のシーケンスを正確に反復し、かつ深い等価性を使用することをアサートします。
assert.deepIteratesOver([{n: 2}, {n: 3}], [{n: 2}, {n: 3}]);
assert.deepIteratesOver([[0, 2], [1, 3]], [[0, 2], [1, 3]]);
深層反復しない(値, 期待値, [メッセージ])
値が与えられた値のシーケンスを正確に反復せず、かつ深い等価性を使用することをアサートします。
assert.doesNotDeepIterateOver([{n: 2}, {n: 3}], [{n: 5}, {n: 7}]);
assert.doesNotDeepIterateOver([[0, 2], [1, 3]], [[1, 3], [0, 2]]);
iteratesFrom(value、 expected、 [message])
値が与えられた値のシーケンスで反復を開始することをアサートします。
assert.iteratesFrom([2, 3, 5], [2, 3, 5]);
assert.iteratesFrom([2, 3, 5], [2, 3]);
assert.iteratesFrom('abcdefg', 'abc');
assert.iteratesFrom('abcdefg', '');
doesNotIterateFrom(value、 expected、 [message])
値が与えられた値のシーケンスで反復を開始しないことをアサートします。
assert.doesNotIterateFrom([2, 3, 5], [3, 5]);
assert.doesNotIterateFrom('abcdefg', 'cdef');
deepIteratesFrom(value、 expected、 [message])
値が与えられた値のシーケンスで反復を開始することを、深い等価性を使用してアサートします。
assert.deepIteratesFrom([{n: 2}, {n: 3}], [{n: 2}]);
assert.deepIteratesFrom([[0, 2], [1, 3]], [[0, 2]]);
doesNotDeepIterateFrom(value、 expected、 [message])
値が与えられた値のシーケンスで反復を開始しないことを、深い等価性を使用してアサートします。
assert.doesNotDeepIterateFrom([{n: 2}, {n: 3}], [{n: 5}]);
assert.doesNotDeepIterateFrom([[0, 2], [1, 3]], [[1, 3]]);
iteratesUntil(value、 expected、 [message])
値が与えられた値のシーケンスで反復を終了することをアサートします。
assert.iteratesUntil([2, 3, 5], [2, 3, 5]);
assert.iteratesUntil([2, 3, 5], [3, 5]);
assert.iteratesUntil('abcdefg', 'efg');
assert.iteratesUntil('abcdefg', '');
doesNotIterateUntil(value、 expected、 [message])
値が与えられた値のシーケンスで反復を終了しないことをアサートします。
assert.doesNotIterateUntil([2, 3, 5], [2, 3]);
assert.doesNotIterateUntil('abcdefg', 'cdef');
deepIteratesUntil(value、 expected、 [message])
値が与えられた値のシーケンスで反復を終了することを、深い等価性を使用してアサートします。
assert.deepIteratesUntil([{n: 2}, {n: 3}], [{n: 3}]);
assert.deepIteratesUntil([[0, 2], [1, 3]], [[1, 3]]);
doesNotDeepIterateUntil(value、 expected、 [message])
値が与えられた値のシーケンスで反復を終了しないことを、深い等価性を使用してアサートします。
assert.doesNotDeepIterateUntil([{n: 2}, {n: 3}], [{n: 5}]);
assert.doesNotDeepIterateUntil([[0, 2], [1, 3]], [[0, 2]]);
lengthOf(value、 n、 [message])
イテラブルが与えられた数の値を生成することをアサートします。valueがイテラブルオブジェクトでない場合、または「'length'
」プロパティがある場合、Chaiの内蔵のassert.lengthOf()
が使用されます。
function* range(min=0, max=Infinity, step=1) {
for (let n = min; n < max; n += step) {
yield n;
}
}
assert.lengthOf(range(0, 10), 10);
assert.lengthOf(range(6, 42), 36);
ライセンス
Copyright © 2016~2017 Akim McMath。[MIT License][ライセンス]の下でライセンスされています。