flutter_tester_test.dart 6.84 KB
Newer Older
1 2 3 4 5 6 7 8
// Copyright 2018 The Chromium 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 'dart:async';

import 'package:file/file.dart';
import 'package:file/memory.dart';
9
import 'package:flutter_tools/src/artifacts.dart';
10 11 12
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
13
import 'package:flutter_tools/src/compile.dart';
14 15
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/tester/flutter_tester.dart';
16
import 'package:mockito/mockito.dart';
17 18 19 20 21 22 23 24 25 26
import 'package:process/process.dart';

import '../src/common.dart';
import '../src/context.dart';
import '../src/mocks.dart';

void main() {
  MemoryFileSystem fs;

  setUp(() {
27
    fs = MemoryFileSystem();
28 29 30 31 32 33 34 35
  });

  group('FlutterTesterApp', () {
    testUsingContext('fromCurrentDirectory', () async {
      const String projectPath = '/home/my/projects/my_project';
      await fs.directory(projectPath).create(recursive: true);
      fs.currentDirectory = projectPath;

36
      final FlutterTesterApp app = FlutterTesterApp.fromCurrentDirectory();
37
      expect(app.name, 'my_project');
38
      expect(app.packagesFile.path, fs.path.join(projectPath, '.packages'));
39 40 41 42 43 44 45 46 47 48 49
    }, overrides: <Type, Generator>{
      FileSystem: () => fs,
    });
  });

  group('FlutterTesterDevices', () {
    tearDown(() {
      FlutterTesterDevices.showFlutterTesterDevice = false;
    });

    testUsingContext('no device', () async {
50
      final FlutterTesterDevices discoverer = FlutterTesterDevices();
51 52 53 54 55 56 57

      final List<Device> devices = await discoverer.devices;
      expect(devices, isEmpty);
    });

    testUsingContext('has device', () async {
      FlutterTesterDevices.showFlutterTesterDevice = true;
58
      final FlutterTesterDevices discoverer = FlutterTesterDevices();
59 60 61 62 63

      final List<Device> devices = await discoverer.devices;
      expect(devices, hasLength(1));

      final Device device = devices.single;
64
      expect(device, isInstanceOf<FlutterTesterDevice>());
65 66 67 68 69 70 71 72 73
      expect(device.id, 'flutter-tester');
    });
  });

  group('FlutterTesterDevice', () {
    FlutterTesterDevice device;
    List<String> logLines;

    setUp(() {
74
      device = FlutterTesterDevice('flutter-tester');
75 76 77 78 79 80 81 82 83

      logLines = <String>[];
      device.getLogReader().logLines.listen(logLines.add);
    });

    testUsingContext('getters', () async {
      expect(device.id, 'flutter-tester');
      expect(await device.isLocalEmulator, isFalse);
      expect(device.name, 'Flutter test device');
84
      expect(device.portForwarder, isNot(isNull));
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
      expect(await device.targetPlatform, TargetPlatform.tester);

      expect(await device.installApp(null), isTrue);
      expect(await device.isAppInstalled(null), isFalse);
      expect(await device.isLatestBuildInstalled(null), isFalse);
      expect(await device.uninstallApp(null), isTrue);

      expect(device.isSupported(), isTrue);
    });

    group('startApp', () {
      String flutterRoot;
      String flutterTesterPath;

      String projectPath;
      String mainPath;

102 103
      MockArtifacts mockArtifacts;
      MockKernelCompiler mockKernelCompiler;
104 105 106 107
      MockProcessManager mockProcessManager;
      MockProcess mockProcess;

      final Map<Type, Generator> startOverrides = <Type, Generator>{
108
        Platform: () => FakePlatform(operatingSystem: 'linux'),
109
        FileSystem: () => fs,
110
        Cache: () => Cache(rootOverride: fs.directory(flutterRoot)),
111
        ProcessManager: () => mockProcessManager,
112 113
        KernelCompiler: () => mockKernelCompiler,
        Artifacts: () => mockArtifacts,
114 115 116 117 118 119 120 121 122 123 124 125 126 127
      };

      setUp(() {
        flutterRoot = fs.path.join('home', 'me', 'flutter');
        flutterTesterPath = fs.path.join(flutterRoot, 'bin', 'cache',
            'artifacts', 'engine', 'linux-x64', 'flutter_tester');

        final File flutterTesterFile = fs.file(flutterTesterPath);
        flutterTesterFile.parent.createSync(recursive: true);
        flutterTesterFile.writeAsBytesSync(const <int>[]);

        projectPath = fs.path.join('home', 'me', 'hello');
        mainPath = fs.path.join(projectPath, 'lin', 'main.dart');

128
        mockProcessManager = MockProcessManager();
129 130
        mockProcessManager.processFactory =
            (List<String> commands) => mockProcess;
131

132
        mockArtifacts = MockArtifacts();
133 134 135 136
        final String artifactPath = fs.path.join(flutterRoot, 'artifact');
        fs.file(artifactPath).createSync(recursive: true);
        when(mockArtifacts.getArtifactPath(any)).thenReturn(artifactPath);

137
        mockKernelCompiler = MockKernelCompiler();
138 139 140 141 142
      });

      testUsingContext('not debug', () async {
        final LaunchResult result = await device.startApp(null,
            mainPath: mainPath,
143
            debuggingOptions: DebuggingOptions.disabled(const BuildInfo(BuildMode.release, null)));
144 145 146 147 148 149 150 151
        expect(result.started, isFalse);
      }, overrides: startOverrides);

      testUsingContext('no flutter_tester', () async {
        fs.file(flutterTesterPath).deleteSync();
        expect(() async {
          await device.startApp(null,
              mainPath: mainPath,
152
              debuggingOptions: DebuggingOptions.disabled(const BuildInfo(BuildMode.debug, null)));
153 154 155 156 157
        }, throwsToolExit());
      }, overrides: startOverrides);

      testUsingContext('start', () async {
        final Uri observatoryUri = Uri.parse('http://127.0.0.1:6666/');
158 159
        mockProcess = MockProcess(
            stdout: Stream<List<int>>.fromIterable(<List<int>>[
160 161 162 163 164 165 166
          '''
Observatory listening on $observatoryUri
Hello!
'''
              .codeUnits
        ]));

167 168 169 170 171
        when(mockKernelCompiler.compile(
          sdkRoot: anyNamed('sdkRoot'),
          incrementalCompilerByteStorePath: anyNamed('incrementalCompilerByteStorePath'),
          mainPath: anyNamed('mainPath'),
          outputFilePath: anyNamed('outputFilePath'),
172
          depFilePath: anyNamed('depFilePath'),
173 174 175 176 177 178 179
          trackWidgetCreation: anyNamed('trackWidgetCreation'),
          extraFrontEndOptions: anyNamed('extraFrontEndOptions'),
          fileSystemRoots: anyNamed('fileSystemRoots'),
          fileSystemScheme: anyNamed('fileSystemScheme'),
          packagesPath: anyNamed('packagesPath'),
        )).thenAnswer((_) async {
          fs.file('$mainPath.dill').createSync(recursive: true);
180
          return CompilerOutput('$mainPath.dill', 0);
181 182
        });

183 184
        final LaunchResult result = await device.startApp(null,
            mainPath: mainPath,
185
            debuggingOptions: DebuggingOptions.enabled(const BuildInfo(BuildMode.debug, null)));
186 187 188 189 190 191 192 193
        expect(result.started, isTrue);
        expect(result.observatoryUri, observatoryUri);

        expect(logLines.last, 'Hello!');
      }, overrides: startOverrides);
    });
  });
}
194 195 196

class MockArtifacts extends Mock implements Artifacts {}
class MockKernelCompiler extends Mock implements KernelCompiler {}