プロローグ
source_genを使用してDartコードを生成します。ジェネレーターの出力をテストしたい (テストパッケージを使用)。source_genのテストを見て、json_serializable_test.dartをテンプレートとして使用しました。generate
ジェネレーターを呼び出して、結果を文字列として取得できます。クラスとメソッドが期待どおりに生成されるかどうかをテストしたいと思います。残念ながら、この種のテストはjson_serializable_test.dartにありません:
expect(output, isNotNull);
// TODO: test the actual output
// print(output);
ヘルパー ( など_getCompilationUnitForString
) を変更して、(常に を使用するのではなく) ソースを渡し、_testSource
そのアナライザー要素を取得します。これにより、ジェネレーターの入力と期待される出力をファイルまたは文字列として指定し、入力、出力、および期待される出力のアナライザー要素を取得できます。
アプローチ
名前とフィールド宣言によってクラスを一致させるために、この原始的なアプローチを思い付きました。
import 'package:analyzer/src/generated/element.dart';
import 'package:source_gen/src/utils.dart';
import 'package:test/test.dart';
Matcher equalsClass(expected) => new ClassMatcher(expected);
class ClassMatcher extends Matcher {
final ClassElementImpl _expected;
const ClassMatcher(this._expected);
@override
Description describe(Description description) => description
.add('same class implementation as ')
.addDescriptionOf(_expected);
@override
Description describeMismatch(ClassElementImpl item, Description description,
Map matchState, bool verbose) => description
.add('${friendlyNameForElement(item)}')
.add(' differs from ')
.add('${friendlyNameForElement(_expected)}');
@override
bool matches(ClassElementImpl item, Map matchState) {
return (item.displayName == _expected.displayName) &&
unorderedEquals(_mapFields(item.fields))
.matches(_mapFields(_expected.fields), matchState);
}
}
Iterable _mapFields(List<FieldElement> fields) => fields
.map(friendlyNameForElement);
String 表現でフィールドを比較するため、このソリューションはエラーが発生しやすい可能性があります。これとは別に、ミスマッチの説明は非常に貧弱です。マッチャーを改善するにはどうすればよいですか?
Ps: 生成されたコードを期待値と比較するためのより良い方法はありますか?