Тестовый сгенерированный код 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: Есть ли лучший способ сравнить сгенерированный код с ожиданиями?

0 ответов

Другие вопросы по тегам