Prolog
I use source_gen to generate Dart code. I'd like to test the output of my generator (using test package). I looked at the tests of source_gen and used json_serializable_test.dart as a template. I can call generate
on my generator and get the result as a String. Now I'd like to test, if classes and methods are generated as I expect. Sadly, this kind of test is missing in json_serializable_test.dart:
expect(output, isNotNull);
// TODO: test the actual output
// print(output);
I modified the helpers (like _getCompilationUnitForString
) to pass a source (instead of always using _testSource
) and get its analyzer elements. Thereby, I can specify the input and expected output of my generator as a file or string and get the analyzer elements of input, output and expected output.
Approach
I came up with this primitive approach to match classes by their name and field declarations:
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);
This solution might be error-prone, since I compare fields by a String representation. Apart from this, the mismatch desciption is very poor. How can I improve my matcher?
Ps: Is there a better way to compare generated code with expectations?