TypeScript で mocha + power-assert + espower-typescript でテストを行う際に、プロジェクトルートディレクトリに tsconfig.json を置かないでテストをする方法が espower-typescript 公式のドキュメントに記載されていなかったので、まとめました。
ディレクトリ構成例
今回、テストを行うディレクトリ構成と説明を以下に示します。
PROJECT_ROOT
├── dist
│ └── hoge.js
└── test
└── foo.ts
└── tsconfig.json
- dist
- テストされる JavaScript が有るディレクトリ
- test
- テストする TypeScript が有るディレクトリ。tsconfig.json はここにある
espower-typescript の guess.js で行っていること
本題に入る前に、 espower-typescript の guess.js で行っている処理を確認します。
mocha で espower-typescript を使用してテストする際の最も有名なコマンドは下記のものだと思います。
$ mocha --compilers ts:espower-typescript/guess test/**/*.ts
このコマンドで呼び出される、guess.js の処理はおおむね以下のように処理されています。
- カレントディレクトリにある package.json の解析
- テストディレクトリなどの設定取得
- カレントディレクトリにある tsconfig.json の解析
- TypeScript コンパイラオプションなどの設定取得
- index.js にカレントディレクトリのパス、TypeScript コンパイラオプションの情報を渡し実行
テストを実行する際はほぼプロジェクトルートディレクトリで行われると思うので、カレントディレクトリはプロジェクトルートディレクトリに読み替えることが出来ます。
この時、手順 2においてプロジェクトルートディレクトリに tsconfig.json が存在しないため null
が返ってきてしまいコンパイラオプションを取得できず、テスト実行に失敗してしまいます。
ローダの設定とテストの呼び出し方
espower-typescript では、espower-babel と同じやり方で guess.js を使わずにテストを行うことが出来ます。以下はローダの動作設定が書かれた JavaScript ファイルです。注意点としては、parseTsConfig(config)
内で Typescript モジュールを呼び出すため、espower-typescript 内で使用されている Typescript モジュールのパスを設定する必要があります。
'use strict';
/*
espower-typescript のローダ
https://github.com/power-assert-js/espower-babel#more-customization を基に作成
*/
const path = require('path');
const fs = require('fs');
const espowerTsPath = require.resolve('espower-typescript');
const ts = require(`${path.relative(__dirname, path.dirname(espowerTsPath))}/node_modules/typescript`)
const tsconfigDir = 'test';
let tsconfigPath = `${tsconfigDir}/tsconfig.json`;
let tsconfigBasepath = null;
let compilerOptions = null;
if (tsconfigPath) {
compilerOptions = parseTsConfig(tsconfigPath);
tsconfigBasepath = path.dirname(tsconfigPath);
}
require('espower-typescript')({
// directory where match starts with
cwd: tsconfigPath,
// glob pattern using minimatch module
pattern: 'test/**/*.ts',
// options for espower module
espowerOptions: {
patterns: [
'assert(value, [message])',
'assert.ok(value, [message])',
'assert.equal(actual, expected, [message])',
'assert.notEqual(actual, expected, [message])',
'assert.strictEqual(actual, expected, [message])',
'assert.notStrictEqual(actual, expected, [message])',
'assert.deepEqual(actual, expected, [message])',
'assert.notDeepEqual(actual, expected, [message])'
]
},
compilerOptions : compilerOptions
});
function parseTsConfig(tsconfigPath) {
var parsed = ts.parseConfigFileTextToJson(tsconfigPath, fs.readFileSync(tsconfigPath, 'utf8'));
if (parsed.error) {
throw new Error(parsed.error.messageText);
}
if (!parsed.config || !parsed.config.compilerOptions) {
return null;
}
return parsed.config.compilerOptions;
}
テストの呼び出し方は以下のようなコマンドになります。
$ mocha --require ./src/test/espower-typescript-loader src/test/**.ts
テンプレート例
まとめ
以上をまとめると、下記のようになります。
- tsconfig.json をプロジェクトルートディレクトリ以外に設置した場合は、espower-typescript を使用して呼び出すときにローダを作成する必要がある。
- tsconfig.json をプロジェクトルートディレクトリに置かず、用途ごと(開発用、テスト用)に分けることが可能になる。