diff --git a/lib/src/commands/create/commands/flutter_plugin.dart b/lib/src/commands/create/commands/flutter_plugin.dart index 69862f82b..b80d940f9 100644 --- a/lib/src/commands/create/commands/flutter_plugin.dart +++ b/lib/src/commands/create/commands/flutter_plugin.dart @@ -41,5 +41,6 @@ class CreateFlutterPlugin({ TemplateVarResolvers get templateVarResolvers => { ...super.templateVarResolvers, 'platforms': () => argResults['platforms'] as List, + 'dart_fix_output': () => true, }; } diff --git a/lib/src/commands/create/templates/template.dart b/lib/src/commands/create/templates/template.dart index ae3d1a7f8..fe5ec6ddd 100644 --- a/lib/src/commands/create/templates/template.dart +++ b/lib/src/commands/create/templates/template.dart @@ -19,6 +19,12 @@ abstract class const Template({ /// {@macro template} this; + /// The [bundle] vars intentionally left to the template's default value. + /// + /// Every bundle var must either be passed by the `very_good create` + /// subcommand that uses this template or be listed here. + Set get defaultedVars => const {}; + /// Callback invoked after template generation has completed. Future onGenerateComplete(Logger logger, Directory outputDir); } diff --git a/lib/src/commands/create/templates/very_good_flame_game/very_good_flame_game_template.dart b/lib/src/commands/create/templates/very_good_flame_game/very_good_flame_game_template.dart index d179bda83..0d4860985 100644 --- a/lib/src/commands/create/templates/very_good_flame_game/very_good_flame_game_template.dart +++ b/lib/src/commands/create/templates/very_good_flame_game/very_good_flame_game_template.dart @@ -16,6 +16,11 @@ class VeryGoodFlameGameTemplate() extends Template { help: 'Generate a Very Good Flame game.', ); + /// `application_id` is derived from `org_name` and `project_name` by the + /// template when omitted. + @override + Set get defaultedVars => const {'application_id'}; + @override Future onGenerateComplete(Logger logger, Directory outputDir) async { if (await installFlutterPackages(logger, outputDir)) { diff --git a/test/src/commands/create/commands/flutter_plugin_test.dart b/test/src/commands/create/commands/flutter_plugin_test.dart index c1a6fb192..7f18703f4 100644 --- a/test/src/commands/create/commands/flutter_plugin_test.dart +++ b/test/src/commands/create/commands/flutter_plugin_test.dart @@ -219,6 +219,7 @@ void main() { 'publishable': false, 'workspace': false, 'platforms': ['android', 'ios', 'windows'], + 'dart_fix_output': true, }, onVarsChanged: any(named: 'onVarsChanged'), ), @@ -233,6 +234,7 @@ void main() { 'publishable': false, 'workspace': false, 'platforms': ['android', 'ios', 'windows'], + 'dart_fix_output': true, }, logger: logger, ), diff --git a/test/src/commands/create/template_vars_test.dart b/test/src/commands/create/template_vars_test.dart new file mode 100644 index 000000000..799e1056f --- /dev/null +++ b/test/src/commands/create/template_vars_test.dart @@ -0,0 +1,68 @@ +import 'package:mason/mason.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:test/test.dart'; +import 'package:very_good_cli/src/commands/create/commands/commands.dart'; +import 'package:very_good_cli/src/commands/create/create.dart'; + +class _MockLogger extends Mock implements Logger; + +void main() { + group('template vars', () { + final subcommands = CreateCommand(logger: _MockLogger()).subcommands.values + .toSet() + .cast(); + + for (final subcommand in subcommands) { + final templates = switch (subcommand) { + MultiTemplates(:final templates) => templates, + _ => [subcommand.template], + }; + + for (final template in templates) { + final bundle = template.bundle; + final bundleVars = bundle.vars.keys.toSet(); + final handledVars = subcommand.templateVarResolvers.keys.toSet(); + final defaultedVars = template.defaultedVars; + final source = + 'very_good create ${subcommand.name} ' + '(template "${template.name}", bundle "${bundle.name}")'; + + group('${subcommand.name} ${template.name}', () { + test('handles every bundle var', () { + expect( + bundleVars.difference(handledVars).difference(defaultedVars), + isEmpty, + reason: + '$source does not pass these bundle vars. Add them to ' + "${subcommand.runtimeType}'s templateVarResolvers, or to " + "${template.runtimeType}'s defaultedVars to keep the " + 'template default.', + ); + }); + + test('only passes vars declared by the bundle', () { + expect( + handledVars.difference(bundleVars), + isEmpty, + reason: + '$source passes these vars, but the bundle does not ' + 'declare them. Remove them from ' + "${subcommand.runtimeType}'s templateVarResolvers.", + ); + }); + + test('only defaults vars declared by the bundle', () { + expect( + defaultedVars.difference(bundleVars), + isEmpty, + reason: + '$source defaults these vars, but the bundle does not ' + 'declare them. Remove them from ' + "${template.runtimeType}'s defaultedVars.", + ); + }); + }); + } + } + }); +}