macos_device_test.dart 9.48 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
          completer: completer,
64
        ),
65 66
      ]),
      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
      macOSWorkflow: MacOSWorkflow(
        featureFlags: TestFeatureFlags(isMacOSEnabled: true),
        platform: linux,
      ),
96
    ).devices(), isEmpty);
97 98 99 100
  });

  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
        platform: macOS,
      ),
    );

112
    expect(await macOSDevices.devices(), isEmpty);
113 114 115 116
  });

  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
      macOSWorkflow: MacOSWorkflow(
        featureFlags: TestFeatureFlags(isMacOSEnabled: true),
        platform: macOS,
      ),
    );

128
    expect(await macOSDevices.devices(), hasLength(1));
129
  });
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
  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();
200
    fakeOperatingSystemUtils.hostPlatform = HostPlatform.darwin_arm64;
201 202 203 204 205 206 207 208 209 210
    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, BuildInfo.debug), debugPath);
    expect(device.executablePathForDevice(package, BuildInfo.profile), profilePath);
    expect(device.executablePathForDevice(package, BuildInfo.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
class FakeMacOSApp extends Fake implements MacOSApp {
  @override
254 255 256
  String executable(BuildInfo buildInfo) {
    switch (buildInfo) {
      case BuildInfo.debug:
257
        return 'debug/executable';
258
      case BuildInfo.profile:
259
        return 'profile/executable';
260
      case BuildInfo.release:
261 262 263 264 265 266
        return 'release/executable';
      default:
        throw StateError('');
    }
  }
}