build_fuchsia_test.dart 8.46 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
// @dart = 2.8

7
import 'package:args/command_runner.dart';
8
import 'package:file/memory.dart';
9
import 'package:file_testing/file_testing.dart';
10
import 'package:flutter_tools/src/base/file_system.dart';
11
import 'package:flutter_tools/src/base/platform.dart';
12 13 14
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build.dart';
15
import 'package:flutter_tools/src/commands/build_fuchsia.dart';
16
import 'package:flutter_tools/src/features.dart';
17 18
import 'package:flutter_tools/src/fuchsia/fuchsia_kernel_compiler.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_pm.dart';
19
import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart';
20 21
import 'package:flutter_tools/src/project.dart';
import 'package:meta/meta.dart';
22
import 'package:test/fake.dart';
23

24 25
import '../../src/common.dart';
import '../../src/context.dart';
26
import '../../src/fakes.dart';
27
import '../../src/test_flutter_command_runner.dart';
28

29
// Defined globally for fakes to use.
30 31
FileSystem fileSystem;

32 33 34
void main() {
  Cache.disableLocking();

35 36 37 38 39 40 41 42 43 44 45
  final Platform linuxPlatform = FakePlatform(
    environment: const <String, String>{
      'FLUTTER_ROOT': '/',
    },
  );
  final Platform windowsPlatform = FakePlatform(
    operatingSystem: 'windows',
    environment: const <String, String>{
      'FLUTTER_ROOT': '/'
    },
  );
46
  FakeFuchsiaSdk fuchsiaSdk;
47 48

  setUp(() {
49
    fuchsiaSdk = FakeFuchsiaSdk();
50
    fileSystem = MemoryFileSystem.test();
51 52
  });

53
  group('Fuchsia build fails gracefully when', () {
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
    testUsingContext('The feature is disabled', () async {
      final BuildCommand command = BuildCommand();
      fileSystem.directory('fuchsia').createSync(recursive: true);
      fileSystem.file('.packages').createSync();
      fileSystem.file('pubspec.yaml').createSync();
      fileSystem.file('lib/main.dart').createSync(recursive: true);

      expect(
        createTestCommandRunner(command).run(const <String>['build', 'fuchsia']),
        throwsToolExit(message: '"build fuchsia" is currently disabled'),
      );
    }, overrides: <Type, Generator>{
      Platform: () => linuxPlatform,
      FileSystem: () => fileSystem,
      ProcessManager: () => FakeProcessManager.any(),
69
      FeatureFlags: () => TestFeatureFlags(),
70
    });
71
    testUsingContext('there is no Fuchsia project', () async {
72
      final BuildCommand command = BuildCommand();
73

74
      expect(
75 76 77
        createTestCommandRunner(command).run(const <String>['build', 'fuchsia']),
        throwsToolExit(),
      );
78 79
    }, overrides: <Type, Generator>{
      Platform: () => linuxPlatform,
80
      FileSystem: () => fileSystem,
81
      ProcessManager: () => FakeProcessManager.any(),
82
      FeatureFlags: () => TestFeatureFlags(isFuchsiaEnabled: true),
83 84 85 86
    });

    testUsingContext('there is no cmx file', () async {
      final BuildCommand command = BuildCommand();
87 88 89
      fileSystem.directory('fuchsia').createSync(recursive: true);
      fileSystem.file('.packages').createSync();
      fileSystem.file('pubspec.yaml').createSync();
90 91

      expect(
92 93 94
        createTestCommandRunner(command).run(const <String>['build', 'fuchsia']),
        throwsToolExit(),
      );
95 96
    }, overrides: <Type, Generator>{
      Platform: () => linuxPlatform,
97
      FileSystem: () => fileSystem,
98
      ProcessManager: () => FakeProcessManager.any(),
99
      FeatureFlags: () => TestFeatureFlags(isFuchsiaEnabled: true),
100 101 102 103 104
    });

    testUsingContext('on Windows platform', () async {
      final BuildCommand command = BuildCommand();
      const String appName = 'app_name';
105 106 107 108 109 110
      fileSystem
        .file(fileSystem.path.join('fuchsia', 'meta', '$appName.cmx'))
        ..createSync(recursive: true)
        ..writeAsStringSync('{}');
      fileSystem.file('.packages').createSync();
      final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
111 112
      pubspecFile.writeAsStringSync('name: $appName');

113
      final bool supported = BuildFuchsiaCommand(verboseHelp: false).supported;
114
      expect(
115
        createTestCommandRunner(command).run(const <String>['build', 'fuchsia']),
116
        supported ? throwsToolExit() : throwsA(isA<UsageException>()),
117
      );
118 119
    }, overrides: <Type, Generator>{
      Platform: () => windowsPlatform,
120
      FileSystem: () => fileSystem,
121
      ProcessManager: () => FakeProcessManager.any(),
122
      FeatureFlags: () => TestFeatureFlags(isFuchsiaEnabled: true),
123 124 125 126 127
    });

    testUsingContext('there is no Fuchsia kernel compiler', () async {
      final BuildCommand command = BuildCommand();
      const String appName = 'app_name';
128 129 130 131 132 133 134
      fileSystem
        .file(fileSystem.path.join('fuchsia', 'meta', '$appName.cmx'))
        ..createSync(recursive: true)
        ..writeAsStringSync('{}');
      fileSystem.file('.packages').createSync();
      fileSystem.file(fileSystem.path.join('lib', 'main.dart')).createSync(recursive: true);
      final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
135
      pubspecFile.writeAsStringSync('name: $appName');
136

137
      expect(
138 139 140
        createTestCommandRunner(command).run(const <String>['build', 'fuchsia']),
        throwsToolExit(),
      );
141 142
    }, overrides: <Type, Generator>{
      Platform: () => linuxPlatform,
143
      FileSystem: () => fileSystem,
144
      ProcessManager: () => FakeProcessManager.any(),
145
      FeatureFlags: () => TestFeatureFlags(isFuchsiaEnabled: true),
146
    });
147 148 149 150 151
  });

  testUsingContext('Fuchsia build parts fit together right', () async {
    final BuildCommand command = BuildCommand();
    const String appName = 'app_name';
152 153
    fileSystem
        .file(fileSystem.path.join('fuchsia', 'meta', '$appName.cmx'))
154 155
        ..createSync(recursive: true)
        ..writeAsStringSync('{}');
156 157 158
    fileSystem.file('.packages').createSync();
    fileSystem.file(fileSystem.path.join('lib', 'main.dart')).createSync(recursive: true);
    final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
159 160 161
    pubspecFile.writeAsStringSync('name: $appName');

    await createTestCommandRunner(command)
162 163 164 165 166 167
      .run(const <String>['build', 'fuchsia']);
    final String farPath = fileSystem.path.join(
      getFuchsiaBuildDirectory(), 'pkg', 'app_name-0.far',
    );

    expect(fileSystem.file(farPath), exists);
168 169
  }, overrides: <Type, Generator>{
    Platform: () => linuxPlatform,
170
    FileSystem: () => fileSystem,
171
    ProcessManager: () => FakeProcessManager.any(),
172
    FuchsiaSdk: () => fuchsiaSdk,
173
    FeatureFlags: () => TestFeatureFlags(isFuchsiaEnabled: true),
174 175 176
  });
}

177
class FakeFuchsiaPM extends Fake implements FuchsiaPM {
178 179 180 181
  String _appName;

  @override
  Future<bool> init(String buildPath, String appName) async {
182
    if (!fileSystem.directory(buildPath).existsSync()) {
183 184
      return false;
    }
185 186
    fileSystem
        .file(fileSystem.path.join(buildPath, 'meta', 'package'))
187 188 189 190 191 192
        .createSync(recursive: true);
    _appName = appName;
    return true;
  }

  @override
193
  Future<bool> build(String buildPath, String manifestPath) async {
194 195
    if (!fileSystem.file(fileSystem.path.join(buildPath, 'meta', 'package')).existsSync() ||
        !fileSystem.file(manifestPath).existsSync()) {
196 197
      return false;
    }
198
    fileSystem.file(fileSystem.path.join(buildPath, 'meta.far')).createSync(recursive: true);
199 200 201 202
    return true;
  }

  @override
203
  Future<bool> archive(String buildPath, String manifestPath) async {
204 205
    if (!fileSystem.file(fileSystem.path.join(buildPath, 'meta', 'package')).existsSync() ||
        !fileSystem.file(manifestPath).existsSync()) {
206 207 208 209 210
      return false;
    }
    if (_appName == null) {
      return false;
    }
211 212
    fileSystem
        .file(fileSystem.path.join(buildPath, '$_appName-0.far'))
213 214 215 216 217
        .createSync(recursive: true);
    return true;
  }
}

218
class FakeFuchsiaKernelCompiler extends Fake implements FuchsiaKernelCompiler {
219 220 221 222 223 224 225 226
  @override
  Future<void> build({
    @required FuchsiaProject fuchsiaProject,
    @required String target, // E.g., lib/main.dart
    BuildInfo buildInfo = BuildInfo.debug,
  }) async {
    final String outDir = getFuchsiaBuildDirectory();
    final String appName = fuchsiaProject.project.manifest.appName;
227 228
    final String manifestPath = fileSystem.path.join(outDir, '$appName.dilpmanifest');
    fileSystem.file(manifestPath).createSync(recursive: true);
229 230
  }
}
231

232
class FakeFuchsiaSdk extends Fake implements FuchsiaSdk {
233
  @override
234
  final FuchsiaPM fuchsiaPM = FakeFuchsiaPM();
235 236 237

  @override
  final FuchsiaKernelCompiler fuchsiaKernelCompiler =
238
      FakeFuchsiaKernelCompiler();
239
}