OXCみたいなTypeScriptのコードを扱うツールを作ってると、TS(Compiler)のシンタックスエラーを同じように検出したくなる。
そのためのテスト用fixtureとして、TypeScriptリポジトリにあるテストファイルたちを参照してる。
OXCの場合、just submodules
ってコマンドをプロジェクトルートで叩くと、tasks/coverage
配下にクローンされてくるようになってる。
ただ、その使われ方を見てると少しクセがありそうだったので、それをまとめておく。
(DeepWikiがこういうところまでいい感じにまとめてくれたらよかったのに)
tests
ディレクトリ
TypeScript/tests at main · microsoft/TypeScript https://github.com/microsoft/TypeScript/tree/main/tests
このtests
ディレクトリ配下がそれで、
baselines
cases
lib
という3つのディレクトリに分かれてる。
で、ユースケースを見るに、
cases/compiler
cases/conformance
というあたりにあるファイルたちを、いわゆるfixtureとして使うことが多いらしい。
compiler
が基本となるケースで、conformance
は補足としていろんなバリエーションがカバーされてるイメージ。
@
コメント
本題。
ここにあるテストファイルをいろいろ眺めてると、ただの.ts
のコードって感じってのもあれば、@
からはじまるコメントがいっぱい書かれてるのもある。
たとえば、compiler/import_reference-to-type-alias.ts
の場合。
// @Filename: file1.ts
export module App {
export module Services {
export class UserServices {
public getUserName(): string {
return "Bill Gates";
}
}
}
}
// @Filename: file2.ts
// @module: amd
import appJs = require("file1");
import Services = appJs.App.Services;
var x = new Services.UserServices().getUserName();
この@Filename
は、どうやらファイルが分割される想定を表す特別な区切りらしい。
(ちなみに@Filename
だったり@filename
だったり@FileName
だったり、表記は揺れまくってた)
つまり、このimport_reference-to-type-alias.ts
は、単一の.ts
ファイルにはなってるけど、実際はただのテスト定義ファイルで、本当にテストしたいのは、file1.ts
とfile2.ts
をあわせて読み込んだ場合・・・みたいな。
なので、雑に単一の.ts
としてパースしてしまうと、エラーになるべきがならなかったりするので注意しないといけない。
それ以外の@module
などは、お察しの通りでcompilerOptions
になってる。
@jsx
@strictNullChecks
@allowJs
@target
- etc…
ということが、CONTRIBUTING.md
にはうっすら書かれてたけど、実物を見るまで把握できなかったので調べてみたという経緯。
TypeScript/CONTRIBUTING.md at main · microsoft/TypeScript https://github.com/microsoft/TypeScript/blob/main/CONTRIBUTING.md#adding-a-test
あと、これを調べてて気付いたけど、TSにはPlaygroundとは別に、Bug Workbenchってのもあるらしい。
TypeScript: Bug Workbench https://www.typescriptlang.org/dev/bug-workbench/
そしてこれの右パネルのDocsタブを見ると、なんとこの記事に書いてあることが全部書いてあったというオチ・・・!
baselines/reference
ディレクトリ
あとは、特定のテストケースにおいて、TSCがエラーを出力する場合に、どういうエラーになる?というのが定義されてるのがココ。(エラー以外にも、JSにコンパイルした結果や、型、シンボルなんかも置いてある)
このディレクトリを見て、cases/compiler
配下のテスト名と同じ名前で.errors.txt
が置いてあるかどうかを見れば、エラーを出すべきかどうかがわかる。
たとえば、cases/compiler/objectLiteralIndexerErrors.ts
は、エラーが出るのが想定されているので、baselines/reference/objectLiteralIndexerErrors.errors.txt
が存在する、といった感じ。
最後に1つ自戒としての注意点を書いておくと、エラーが出力されてるからといって、ASTが出力されないわけではないってこと。
TSはf(
みたいな入力途中の不完全なコードに対しても、ちゃんとASTを生成してくる。