// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:flutter_plugin_tools/src/test_command.dart';
import 'package:test/test.dart';

import 'util.dart';

void main() {
  group('$TestCommand', () {
    late CommandRunner<void> runner;
    final RecordingProcessRunner processRunner = RecordingProcessRunner();

    setUp(() {
      initializeFakePackages();
      final TestCommand command = TestCommand(mockPackagesDir, mockFileSystem,
          processRunner: processRunner);

      runner = CommandRunner<void>('test_test', 'Test for $TestCommand');
      runner.addCommand(command);
    });

    tearDown(() {
      cleanupPackages();
      processRunner.recordedCalls.clear();
    });

    test('runs flutter test on each plugin', () async {
      final Directory plugin1Dir =
          createFakePlugin('plugin1', withExtraFiles: <List<String>>[
        <String>['test', 'empty_test.dart'],
      ]);
      final Directory plugin2Dir =
          createFakePlugin('plugin2', withExtraFiles: <List<String>>[
        <String>['test', 'empty_test.dart'],
      ]);

      await runner.run(<String>['test']);

      expect(
        processRunner.recordedCalls,
        orderedEquals(<ProcessCall>[
          ProcessCall(
              'flutter', const <String>['test', '--color'], plugin1Dir.path),
          ProcessCall(
              'flutter', const <String>['test', '--color'], plugin2Dir.path),
        ]),
      );

      cleanupPackages();
    });

    test('skips testing plugins without test directory', () async {
      createFakePlugin('plugin1');
      final Directory plugin2Dir =
          createFakePlugin('plugin2', withExtraFiles: <List<String>>[
        <String>['test', 'empty_test.dart'],
      ]);

      await runner.run(<String>['test']);

      expect(
        processRunner.recordedCalls,
        orderedEquals(<ProcessCall>[
          ProcessCall(
              'flutter', const <String>['test', '--color'], plugin2Dir.path),
        ]),
      );

      cleanupPackages();
    });

    test('runs pub run test on non-Flutter packages', () async {
      final Directory plugin1Dir = createFakePlugin('plugin1',
          isFlutter: true,
          withExtraFiles: <List<String>>[
            <String>['test', 'empty_test.dart'],
          ]);
      final Directory plugin2Dir = createFakePlugin('plugin2',
          isFlutter: false,
          withExtraFiles: <List<String>>[
            <String>['test', 'empty_test.dart'],
          ]);

      await runner.run(<String>['test', '--enable-experiment=exp1']);

      expect(
        processRunner.recordedCalls,
        orderedEquals(<ProcessCall>[
          ProcessCall(
              'flutter',
              const <String>['test', '--color', '--enable-experiment=exp1'],
              plugin1Dir.path),
          ProcessCall('pub', const <String>['get'], plugin2Dir.path),
          ProcessCall(
              'pub',
              const <String>['run', '--enable-experiment=exp1', 'test'],
              plugin2Dir.path),
        ]),
      );

      cleanupPackages();
    });

    test('runs on Chrome for web plugins', () async {
      final Directory pluginDir = createFakePlugin(
        'plugin',
        withExtraFiles: <List<String>>[
          <String>['test', 'empty_test.dart'],
        ],
        isFlutter: true,
        isWebPlugin: true,
      );

      await runner.run(<String>['test']);

      expect(
        processRunner.recordedCalls,
        orderedEquals(<ProcessCall>[
          ProcessCall(
              'flutter',
              const <String>['test', '--color', '--platform=chrome'],
              pluginDir.path),
        ]),
      );
    });

    test('enable-experiment flag', () async {
      final Directory plugin1Dir = createFakePlugin('plugin1',
          isFlutter: true,
          withExtraFiles: <List<String>>[
            <String>['test', 'empty_test.dart'],
          ]);
      final Directory plugin2Dir = createFakePlugin('plugin2',
          isFlutter: false,
          withExtraFiles: <List<String>>[
            <String>['test', 'empty_test.dart'],
          ]);

      await runner.run(<String>['test', '--enable-experiment=exp1']);

      expect(
        processRunner.recordedCalls,
        orderedEquals(<ProcessCall>[
          ProcessCall(
              'flutter',
              const <String>['test', '--color', '--enable-experiment=exp1'],
              plugin1Dir.path),
          ProcessCall('pub', const <String>['get'], plugin2Dir.path),
          ProcessCall(
              'pub',
              const <String>['run', '--enable-experiment=exp1', 'test'],
              plugin2Dir.path),
        ]),
      );

      cleanupPackages();
    });
  });
}
