macos_device_test.dart 9.47 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
import 'dart:async';

7
import 'package:file/memory.dart';
8
import 'package:flutter_tools/src/base/file_system.dart';
9
import 'package:flutter_tools/src/base/logger.dart';
10
import 'package:flutter_tools/src/base/os.dart';
11
import 'package:flutter_tools/src/base/platform.dart';
12 13
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
14
import 'package:flutter_tools/src/macos/application_package.dart';
15
import 'package:flutter_tools/src/macos/macos_device.dart';
16
import 'package:flutter_tools/src/macos/macos_workflow.dart';
17
import 'package:flutter_tools/src/project.dart';
18
import 'package:test/fake.dart';
19

20
import '../../src/common.dart';
21
import '../../src/fake_process_manager.dart';
22
import '../../src/fakes.dart';
23

24 25 26 27
final FakePlatform macOS = FakePlatform(
  operatingSystem: 'macos',
);

28
final FakePlatform linux = FakePlatform();
29

30
void main() {
31 32 33 34
  testWithoutContext('default configuration', () async {
    final MacOSDevice device = MacOSDevice(
      processManager: FakeProcessManager.any(),
      logger: BufferLogger.test(),
35
      fileSystem: MemoryFileSystem.test(),
36
      operatingSystemUtils: FakeOperatingSystemUtils(),
37
    );
38
    final FakeMacOSApp package = FakeMacOSApp();
39

40
    expect(await device.targetPlatform, TargetPlatform.darwin);
41
    expect(device.name, 'macOS');
42 43 44 45
    expect(await device.installApp(package), true);
    expect(await device.uninstallApp(package), true);
    expect(await device.isLatestBuildInstalled(package), true);
    expect(await device.isAppInstalled(package), true);
46 47 48 49 50 51
    expect(device.category, Category.desktop);

    expect(device.supportsRuntimeMode(BuildMode.debug), true);
    expect(device.supportsRuntimeMode(BuildMode.profile), true);
    expect(device.supportsRuntimeMode(BuildMode.release), true);
    expect(device.supportsRuntimeMode(BuildMode.jitRelease), false);
52 53
  });

54
  testWithoutContext('Attaches to log reader when running in release mode', () async {
55 56
    final Completer<void> completer = Completer<void>();
    final MacOSDevice device = MacOSDevice(
57
      fileSystem: MemoryFileSystem.test(),
58 59
      processManager: FakeProcessManager.list(<FakeCommand>[
        FakeCommand(
60
          command: const <String>['release/executable'],
61 62
          stdout: 'Hello World\n',
          stderr: 'Goodnight, Moon\n',
63 64 65 66
          completer: completer,
        )
      ]),
      logger: BufferLogger.test(),
67
      operatingSystemUtils: FakeOperatingSystemUtils(),
68
    );
69
    final FakeMacOSApp package = FakeMacOSApp();
70 71

    final LaunchResult result = await device.startApp(
72
      package,
73 74 75 76 77 78
      debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
      prebuiltApplication: true,
    );

    expect(result.started, true);

79
    final DeviceLogReader logReader = device.getLogReader(app: package);
80

81
    expect(logReader.logLines, emitsInAnyOrder(<String>['Hello World', 'Goodnight, Moon']));
82 83
    completer.complete();
  });
84

85 86
  testWithoutContext('No devices listed if platform is unsupported', () async {
    expect(await MacOSDevices(
87
      fileSystem: MemoryFileSystem.test(),
88 89 90
      processManager: FakeProcessManager.any(),
      logger: BufferLogger.test(),
      platform: linux,
91
      operatingSystemUtils: FakeOperatingSystemUtils(),
92 93 94 95 96 97 98 99 100
      macOSWorkflow: MacOSWorkflow(
        featureFlags: TestFeatureFlags(isMacOSEnabled: true),
        platform: linux,
      ),
    ).devices, isEmpty);
  });

  testWithoutContext('No devices listed if platform is supported and feature is disabled', () async {
    final MacOSDevices macOSDevices = MacOSDevices(
101
      fileSystem: MemoryFileSystem.test(),
102 103 104
      processManager: FakeProcessManager.any(),
      logger: BufferLogger.test(),
      platform: macOS,
105
      operatingSystemUtils: FakeOperatingSystemUtils(),
106
      macOSWorkflow: MacOSWorkflow(
107
        featureFlags: TestFeatureFlags(),
108 109 110 111 112 113 114 115 116
        platform: macOS,
      ),
    );

    expect(await macOSDevices.devices, isEmpty);
  });

  testWithoutContext('devices listed if platform is supported and feature is enabled', () async {
    final MacOSDevices macOSDevices = MacOSDevices(
117
      fileSystem: MemoryFileSystem.test(),
118 119 120
      processManager: FakeProcessManager.any(),
      logger: BufferLogger.test(),
      platform: macOS,
121
      operatingSystemUtils: FakeOperatingSystemUtils(),
122 123 124 125 126 127 128 129
      macOSWorkflow: MacOSWorkflow(
        featureFlags: TestFeatureFlags(isMacOSEnabled: true),
        platform: macOS,
      ),
    );

    expect(await macOSDevices.devices, hasLength(1));
  });
130

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
  testWithoutContext('has a well known device id macos', () async {
    final MacOSDevices macOSDevices = MacOSDevices(
      fileSystem: MemoryFileSystem.test(),
      processManager: FakeProcessManager.any(),
      logger: BufferLogger.test(),
      platform: macOS,
      operatingSystemUtils: FakeOperatingSystemUtils(),
      macOSWorkflow: MacOSWorkflow(
        featureFlags: TestFeatureFlags(isMacOSEnabled: true),
        platform: macOS,
      ),
    );

    expect(macOSDevices.wellKnownIds, <String>['macos']);
  });

147 148
  testWithoutContext('can discover devices with a provided timeout', () async {
    final MacOSDevices macOSDevices = MacOSDevices(
149
      fileSystem: MemoryFileSystem.test(),
150 151 152
      processManager: FakeProcessManager.any(),
      logger: BufferLogger.test(),
      platform: macOS,
153
      operatingSystemUtils: FakeOperatingSystemUtils(),
154 155 156 157 158 159 160 161 162 163 164 165
      macOSWorkflow: MacOSWorkflow(
        featureFlags: TestFeatureFlags(isMacOSEnabled: true),
        platform: macOS,
      ),
    );

    // Timeout ignored.
    final List<Device> devices = await macOSDevices.discoverDevices(timeout: const Duration(seconds: 10));

    expect(devices, hasLength(1));
  });

166 167
  testWithoutContext('isSupportedForProject is true with editable host app', () async {
    final FileSystem fileSystem = MemoryFileSystem.test();
168
    final MacOSDevice device = MacOSDevice(
169
      fileSystem: MemoryFileSystem.test(),
170 171
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.any(),
172
      operatingSystemUtils: FakeOperatingSystemUtils(),
173 174
    );

175 176 177 178
    fileSystem.file('pubspec.yaml').createSync();
    fileSystem.file('.packages').createSync();
    fileSystem.directory('macos').createSync();
    final FlutterProject flutterProject = setUpFlutterProject(fileSystem.currentDirectory);
179 180 181 182

    expect(device.isSupportedForProject(flutterProject), true);
  });

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
  testWithoutContext('target platform display name on x86_64', () async {
    final FakeOperatingSystemUtils fakeOperatingSystemUtils =
        FakeOperatingSystemUtils();
    fakeOperatingSystemUtils.hostPlatform = HostPlatform.darwin_x64;
    final MacOSDevice device = MacOSDevice(
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.any(),
      operatingSystemUtils: fakeOperatingSystemUtils,
    );

    expect(await device.targetPlatformDisplayName, 'darwin-x64');
  });

  testWithoutContext('target platform display name on ARM', () async {
    final FakeOperatingSystemUtils fakeOperatingSystemUtils =
        FakeOperatingSystemUtils();
    fakeOperatingSystemUtils.hostPlatform = HostPlatform.darwin_arm;
    final MacOSDevice device = MacOSDevice(
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.any(),
      operatingSystemUtils: fakeOperatingSystemUtils,
    );

    expect(await device.targetPlatformDisplayName, 'darwin-arm64');
  });

211
  testWithoutContext('isSupportedForProject is false with no host app', () async {
212
    final FileSystem fileSystem = MemoryFileSystem.test();
213
    final MacOSDevice device = MacOSDevice(
214
      fileSystem: fileSystem,
215 216
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.any(),
217
      operatingSystemUtils: FakeOperatingSystemUtils(),
218
    );
219 220 221
    fileSystem.file('pubspec.yaml').createSync();
    fileSystem.file('.packages').createSync();
    final FlutterProject flutterProject = setUpFlutterProject(fileSystem.currentDirectory);
222 223 224 225

    expect(device.isSupportedForProject(flutterProject), false);
  });

226
  testWithoutContext('executablePathForDevice uses the correct package executable', () async {
227
    final FakeMacOSApp package = FakeMacOSApp();
228
    final MacOSDevice device = MacOSDevice(
229
      fileSystem: MemoryFileSystem.test(),
230 231
      logger: BufferLogger.test(),
      processManager: FakeProcessManager.any(),
232
      operatingSystemUtils: FakeOperatingSystemUtils(),
233 234 235 236 237
    );
    const String debugPath = 'debug/executable';
    const String profilePath = 'profile/executable';
    const String releasePath = 'release/executable';

238 239 240
    expect(device.executablePathForDevice(package, BuildMode.debug), debugPath);
    expect(device.executablePathForDevice(package, BuildMode.profile), profilePath);
    expect(device.executablePathForDevice(package, BuildMode.release), releasePath);
241 242 243
  });
}

244 245 246 247 248 249 250 251
FlutterProject setUpFlutterProject(Directory directory) {
  final FlutterProjectFactory flutterProjectFactory = FlutterProjectFactory(
    fileSystem: directory.fileSystem,
    logger: BufferLogger.test(),
  );
  return flutterProjectFactory.fromDirectory(directory);
}

252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
class FakeMacOSApp extends Fake implements MacOSApp {
  @override
  String executable(BuildMode buildMode) {
    switch (buildMode) {
      case BuildMode.debug:
        return 'debug/executable';
      case BuildMode.profile:
        return 'profile/executable';
      case BuildMode.release:
        return 'release/executable';
      default:
        throw StateError('');
    }
  }
}