@@ -526,4 +526,249 @@ void main() {
526526 });
527527 });
528528 });
529+
530+ group ('WebAppOptions' , () {
531+ late WebAppOptions options;
532+
533+ group ('correctly encodes Flutter build invocation' , () {
534+ test ('with minimal configuration' , () {
535+ const flutterOpts = FlutterAppOptions (
536+ command: flutterCommand,
537+ target: 'patrol_test/app_test.dart' ,
538+ buildMode: BuildMode .debug,
539+ flavor: null ,
540+ buildName: null ,
541+ buildNumber: null ,
542+ dartDefines: {},
543+ dartDefineFromFilePaths: [],
544+ );
545+
546+ options = const WebAppOptions (
547+ flutter: flutterOpts,
548+ );
549+
550+ final flutterInvocation = options.toFlutterBuildInvocation ();
551+
552+ expect (
553+ flutterInvocation,
554+ equals ([
555+ 'flutter' ,
556+ 'build' ,
557+ 'web' ,
558+ '--target=patrol_test/app_test.dart' ,
559+ '--debug' ,
560+ ]),
561+ );
562+ });
563+
564+ test ('with release build mode' , () {
565+ const flutterOpts = FlutterAppOptions (
566+ command: flutterCommand,
567+ target: 'integration_test/app_test.dart' ,
568+ buildMode: BuildMode .release,
569+ flavor: null ,
570+ buildName: null ,
571+ buildNumber: null ,
572+ dartDefines: {},
573+ dartDefineFromFilePaths: [],
574+ );
575+
576+ options = const WebAppOptions (
577+ flutter: flutterOpts,
578+ );
579+
580+ final flutterInvocation = options.toFlutterBuildInvocation ();
581+
582+ expect (
583+ flutterInvocation,
584+ equals ([
585+ 'flutter' ,
586+ 'build' ,
587+ 'web' ,
588+ '--target=integration_test/app_test.dart' ,
589+ '--release' ,
590+ ]),
591+ );
592+ });
593+
594+ test ('with dart defines' , () {
595+ const flutterOpts = FlutterAppOptions (
596+ command: flutterCommand,
597+ target: 'patrol_test/app_test.dart' ,
598+ buildMode: BuildMode .debug,
599+ flavor: null ,
600+ buildName: null ,
601+ buildNumber: null ,
602+ dartDefines: {
603+ 'EMAIL' : 'user@example.com' ,
604+ 'PASSWORD' : 'ny4ncat' ,
605+ 'API_KEY' : 'secret123' ,
606+ },
607+ dartDefineFromFilePaths: [],
608+ );
609+
610+ options = const WebAppOptions (
611+ flutter: flutterOpts,
612+ );
613+
614+ final flutterInvocation = options.toFlutterBuildInvocation ();
615+
616+ expect (
617+ flutterInvocation,
618+ equals ([
619+ 'flutter' ,
620+ 'build' ,
621+ 'web' ,
622+ '--target=patrol_test/app_test.dart' ,
623+ '--debug' ,
624+ '--dart-define=EMAIL=user@example.com' ,
625+ '--dart-define=PASSWORD=ny4ncat' ,
626+ '--dart-define=API_KEY=secret123' ,
627+ ]),
628+ );
629+ });
630+
631+ test ('with dart define from file paths' , () {
632+ const flutterOpts = FlutterAppOptions (
633+ command: flutterCommand,
634+ target: 'patrol_test/app_test.dart' ,
635+ buildMode: BuildMode .release,
636+ flavor: null ,
637+ buildName: null ,
638+ buildNumber: null ,
639+ dartDefines: {},
640+ dartDefineFromFilePaths: ['defines.json' , 'secrets.env' ],
641+ );
642+
643+ options = const WebAppOptions (
644+ flutter: flutterOpts,
645+ );
646+
647+ final flutterInvocation = options.toFlutterBuildInvocation ();
648+
649+ expect (
650+ flutterInvocation,
651+ equals ([
652+ 'flutter' ,
653+ 'build' ,
654+ 'web' ,
655+ '--target=patrol_test/app_test.dart' ,
656+ '--release' ,
657+ '--dart-define-from-file=defines.json' ,
658+ '--dart-define-from-file=secrets.env' ,
659+ ]),
660+ );
661+ });
662+
663+ test ('with both dart defines and dart define from file' , () {
664+ const flutterOpts = FlutterAppOptions (
665+ command: flutterCommand,
666+ target: 'patrol_test/web_test.dart' ,
667+ buildMode: BuildMode .profile,
668+ flavor: null ,
669+ buildName: null ,
670+ buildNumber: null ,
671+ dartDefines: {
672+ 'ENV' : 'production' ,
673+ 'DEBUG_MODE' : 'false' ,
674+ },
675+ dartDefineFromFilePaths: ['config.json' ],
676+ );
677+
678+ options = const WebAppOptions (
679+ flutter: flutterOpts,
680+ );
681+
682+ final flutterInvocation = options.toFlutterBuildInvocation ();
683+
684+ expect (
685+ flutterInvocation,
686+ equals ([
687+ 'flutter' ,
688+ 'build' ,
689+ 'web' ,
690+ '--target=patrol_test/web_test.dart' ,
691+ '--profile' ,
692+ '--dart-define=ENV=production' ,
693+ '--dart-define=DEBUG_MODE=false' ,
694+ '--dart-define-from-file=config.json' ,
695+ ]),
696+ );
697+ });
698+
699+ test ('with custom flutter command arguments' , () {
700+ const customFlutterCommand = FlutterCommand (
701+ 'flutter' ,
702+ ['--verbose' , '--no-pub' ],
703+ );
704+
705+ const flutterOpts = FlutterAppOptions (
706+ command: customFlutterCommand,
707+ target: 'test/my_test.dart' ,
708+ buildMode: BuildMode .debug,
709+ flavor: null ,
710+ buildName: null ,
711+ buildNumber: null ,
712+ dartDefines: {},
713+ dartDefineFromFilePaths: [],
714+ );
715+
716+ options = const WebAppOptions (
717+ flutter: flutterOpts,
718+ );
719+
720+ final flutterInvocation = options.toFlutterBuildInvocation ();
721+
722+ expect (
723+ flutterInvocation,
724+ equals ([
725+ 'flutter' ,
726+ '--verbose' ,
727+ '--no-pub' ,
728+ 'build' ,
729+ 'web' ,
730+ '--target=test/my_test.dart' ,
731+ '--debug' ,
732+ ]),
733+ );
734+ });
735+
736+ test ('flavor is ignored for web builds' , () {
737+ // Note: Web builds don't support flavors, so this should be handled
738+ // by not including --flavor in the command
739+ const flutterOpts = FlutterAppOptions (
740+ command: flutterCommand,
741+ target: 'patrol_test/app_test.dart' ,
742+ buildMode: BuildMode .release,
743+ flavor: 'production' , // This should be ignored for web
744+ buildName: null ,
745+ buildNumber: null ,
746+ dartDefines: {},
747+ dartDefineFromFilePaths: [],
748+ );
749+
750+ options = const WebAppOptions (
751+ flutter: flutterOpts,
752+ );
753+
754+ final flutterInvocation = options.toFlutterBuildInvocation ();
755+
756+ // Verify that --flavor is NOT included in the invocation
757+ expect (
758+ flutterInvocation,
759+ equals ([
760+ 'flutter' ,
761+ 'build' ,
762+ 'web' ,
763+ '--target=patrol_test/app_test.dart' ,
764+ '--release' ,
765+ ]),
766+ );
767+ expect (
768+ flutterInvocation,
769+ isNot (contains ('--flavor' )),
770+ );
771+ });
772+ });
773+ });
529774}
0 commit comments