Некоторое время назад я доработал пакет source_gen_test Кевина Мура и добавил поддержку внешних golden‑файлов. Этот пакет используют, чтобы писать тесты для таких генераторов кода как json_serializable. Для этого используют аннотацию ShouldGenerate
из этого пакета:
@ShouldGenerate( r''' <Dart code to generate> ''', ) @TestAnnotation() class Foo {}
У этого было две проблемы:
-
Тяжело читать, если генерируется много кода.
-
Генерируемый код нельзя проверить на ошибки. Чтобы всё‑таки проверить, нужно копировать этот код во внешний файл и писать тесты на него. Потом эти две копии кода могут разойтись.
Я сделал аннотацию ShouldGenerateFile
, которая позволяет положить ожидаемый код сразу во внешний файл .dart
. Она проверит, что генератор выдаёт именно такой код, и вместе с этим вы можете писать тесты на этот код:
@ShouldGenerateFile( 'goldens/foo.dart', partOfCurrent: true, ) @TestAnnotation() class Foo {}
Реальный пример: enum_map
Реальный пример тестирования генератора таким образом — в пакете enum_map.
Для заданного enum
этот пакет генерирует специализированный класс Map
с гарантией на этапе компиляции, что все константы этого enum
присутствуют там как ключи:
@enumMap enum Fruit { apple, orange, banana } final map = FruitMap( apple: 1, orange: 2, banana: 3, );
В сгенерированном классе больше 190 строк, поэтому хранить его во внешнем файле — единственный разумный способ.
Тест будет вот таким простым:
import 'package:enum_map/enum_map.dart'; import 'package:source_gen_test/annotations.dart'; part 'output.dart'; @ShouldGenerateFile('output.dart', partOfCurrent: true) @enumMap enum Fruit { apple, orange, banana, } // Здесь обычные тесты, чтобы проверить, что класс FruitMap // ведёт себя, как обычный Map.
(На самом деле enum_map использует мой временный форк source_gen_test_golden, потому что мы с Кевином долго обсуждали некоторые мелочи, и мне пришлось опубликовать свой форк как отдельный пакет. Но с тех пор он подтянул мою правку в свой оригинальный пакет, поэтому мой форк больше не поддерживается. Используйте пакет Кевина.)
Между делом я переписал пакет enum_map с использованием макросов, и это убрало саму необходимость таких тестов (пока нет инструментов, чтобы писать golden‑тесты на код, генерируемый макросами, но сгенерированный ими код добавляется в текущую библиотеку и, во‑первых, ломает компиляцию при синтаксических ошибках, а во‑вторых, на него сразу же можно писать тесты без дополнительных инструментов). Поэтому предлагаю опробовать и новый enum_map тоже (см. версию пре‑релиз).
Не пропускайте мои статьи, добавляйтесь в Телеграм‑канал: ainkin_com
Русские переводы реже и с задержкой здесь: ainkin_com_ru
ссылка на оригинал статьи https://habr.com/ru/articles/863118/
Добавить комментарий