コアプラグインの概念

プラグインは、ベンダー統合のためだけのものではありません。テスターは、入力データの検証、オブジェクトのスキーマ検証のアサート、DOM要素の適切な動作の確保などを行うためのプラグインを作成できます。APIは柔軟性が高く、同期タスクを単一のアサーションにカプセル化し、テスト全体で再利用できます。

このチュートリアルでは、ChaiのプラグインAPIへのアクセス方法、フラグを使用して言語チェーンを介してデータを転送する方法、最初のアサーション(および詳細なエラーメッセージ)を作成する方法について説明します。ここでは、ヘルパーの作成で、Chai言語チェーンで使用するプロパティとメソッドを作成する方法について説明します。

ユーティリティへのアクセス

Chaiには、アサーションの作成を支援するためのユーティリティが多数用意されていますが、chai エクスポートではこれらを直接提供していません。これらには、単一の関数を引数として受け取る、chaiエクスポートの use メソッドを使用してアクセスできます。

chai.use(function (_chai, utils) {
  // ...
});

使用される関数には、2つのパラメータがスコープに渡されます。1つ目は chai エクスポート、2つ目は多数のユーティリティメソッドを含むオブジェクトです(これについては後で説明します)。

chai エクスポートが含まれているため、複数のテストファイルで使用できるヘルパーを作成したり、ヘルパーをプラグインとしてパッケージ化してコミュニティと共有したりできます。ヘルパーを作成するためのより適切なパターンは次のとおりです…

ヘルパーファイルの場合: test/helpers/model.js

module.exports = function (chai, utils) {
  var Assertion = chai.Assertion;

  // your helpers here
};

実際のテストの場合: test/person.js

var chai = require('chai')
  , chaiModel = require('./helpers/model')
  , expect = chai.expect;

chai.use(chaiModel);

このドキュメントの残りの部分では、この構造を想定します…

  • 外部ファイルのヘルパー
  • chai.AssertionAssertion 変数に割り当てられます
  • すべてのヘルパーは、指示された場所にあるエクスポートされた関数内にあります

Assertion 変数は、アサーションチェーンのコンストラクタになりました。 new Assertion(obj)expect(obj) と同等です。

フラグの使用

アサーションの内部動作に関する最上位のコアコンセプトは、フラグの概念です。各アサーションには、ほとんど任意のフラグ(キーと値のペア)のセットが関連付けられています。Chaiは内部でこれらの少数を使いまが、ストアは開発者が拡張するためにも利用できます。

フラグの使用法

フラグユーティリティは、use 関数内から utils.flag として公開されます。渡される引数の数に応じて、ゲッターまたはセッターとして機能できます。

var myAssert = new Assertion(obj);
utils.flag(myAssert, 'owner', 'me'); // sets key `owner` to `me`
var owner = utils.flag(myAssert, 'owner'); // get key `owner', returns value

オブジェクトフラグ

Chaiの予約済みフラグの中で最も重要なのは、object フラグです。これはアサーションの対象です。

var myAssert = new Assertion('Arthur Dent');
var obj = flag(myAssert, 'object'); // obj === 'Arthur Dent';

このフラグは頻繁に使用されるため、構築されたアサーションの _obj プロパティとしてショートカットが提供されました。

var obj = myAssert._obj; // obj === `Arthur Dent`

次のフラグは、Chaiのコアアサーションで使用されます。これらに干渉すると、副作用が発生する可能性があります。

  • object: (上記参照)
  • ssfi: スタック関数の開始 - コールバックスタックがエラーに表示されないようにするために使用されます。
  • message: assert インターフェースを使用する場合にエラーに含める追加情報。
  • negate: チェーンに .not が含まれている場合に設定されます。
  • deep: チェーンに .deep が含まれている場合に設定されます。 equal および property で使用されます
  • contains: include または contain がプロパティとして使用されている場合に設定されます。 keys の動作を変更します。
  • lengthOf: length がプロパティとして使用されている場合に設定されます。 abovebelow、および within の動作を変更します。

アサーションの作成

言語チェーンにメソッドとプロパティを追加する前に、まずアサーションを呼び出す方法と、失敗した場合の予期される動作を確認する必要があります。

このため、構築された各 Assertion には、単に assert と呼ばれるメソッドがあります。多くのパラメータを受け取り、アサーションが否定されたかどうかによって動作が変化する可能性があります。

基本的なアサーション

まず、Arthurを再び構築し、彼が自分が誰であるかを確認します。

var arthur = new Assertion('Arthur Dent');

arthur.assert(
    arthur._obj === 'Arthur Dent'
  , "expected #{this} to be 'Arthur Dent'"
  , "expected #{this} to not be 'Arthur Dent'"
);

Chaiは最初の引数をチェックします。それが true の場合、アサーションは合格しますが、false の場合、アサーションは失敗し、最初のエラーメッセージは chai.AssertionError の一部としてスローされます。逆に、言語チェーンが否定された場合、false は合格、true は失敗と見なされます。代わりに、2番目のエラーメッセージがスローされたエラーに含まれます。

全体として、assert メソッドは6つの引数を受け入れます

  1. ブール値(真理値テストの結果)
  2. 最初の引数が false の場合に使用される文字列エラーメッセージ
  3. アサーションが否定され、最初の引数が true の場合に使用される文字列エラーメッセージ
  4. (オプション)期待値
  5. (オプション)実際の値。デフォルトは _obj です
  6. (オプション)最初の引数が false の場合に、メッセージに加えて差分を表示するかどうかを示すブール値

エラーメッセージの作成

上記の例からわかるように、Chaiはテンプレートタグを受け入れてエラーメッセージを動的に作成できます。使用すると、これらのテンプレートタグは、問題のオブジェクトの文字列化された置換に置き換えられます。3つのテンプレートタグが利用可能です。

  • #{this}: アサーションの _obj
  • #{exp}: assert で提供された場合の期待値
  • #{act}: 実際の値。デフォルトは _obj ですが、assert で提供された値で上書きできます