Тестовый сгенерированный код Dart
пролог
Я использую 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);
Это решение может быть подвержено ошибкам, так как я сравниваю поля по строковому представлению. Помимо этого, несоответствие описания очень плохое. Как я могу улучшить свой матчер?
PS: Есть ли лучший способ сравнить сгенерированный код с ожиданиями?