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

import 'package:file/memory.dart';
6 7
import 'package:platform/platform.dart';

8 9 10 11 12 13 14
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_kernel_compiler.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_pm.dart';
15
import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart';
16 17 18
import 'package:flutter_tools/src/project.dart';
import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart';
19
import 'package:process/process.dart';
20
import 'package:flutter_tools/src/globals.dart' as globals;
21

22 23 24
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/mocks.dart';
25 26 27 28 29 30

void main() {
  Cache.disableLocking();

  MockPlatform linuxPlatform;
  MockPlatform windowsPlatform;
31
  MockFuchsiaSdk fuchsiaSdk;
32 33 34 35

  setUp(() {
    linuxPlatform = MockPlatform();
    windowsPlatform = MockPlatform();
36
    fuchsiaSdk = MockFuchsiaSdk();
37 38

    when(linuxPlatform.isLinux).thenReturn(true);
39
    when(linuxPlatform.isWindows).thenReturn(false);
40
    when(linuxPlatform.isMacOS).thenReturn(false);
41 42 43 44 45
    when(windowsPlatform.isWindows).thenReturn(true);
    when(windowsPlatform.isLinux).thenReturn(false);
    when(windowsPlatform.isMacOS).thenReturn(false);
  });

46
  group('Fuchsia build fails gracefully when', () {
47
    testUsingContext('there is no Fuchsia project', () async {
48 49 50 51 52 53 54 55
      final BuildCommand command = BuildCommand();
      applyMocksToCommand(command);
      expect(
          createTestCommandRunner(command)
              .run(const <String>['build', 'fuchsia']),
          throwsA(isInstanceOf<ToolExit>()));
    }, overrides: <Type, Generator>{
      Platform: () => linuxPlatform,
56
      FileSystem: () => MemoryFileSystem(),
57
      ProcessManager: () => FakeProcessManager.any(),
58 59 60 61 62
    });

    testUsingContext('there is no cmx file', () async {
      final BuildCommand command = BuildCommand();
      applyMocksToCommand(command);
63 64 65
      globals.fs.directory('fuchsia').createSync(recursive: true);
      globals.fs.file('.packages').createSync();
      globals.fs.file('pubspec.yaml').createSync();
66 67 68 69 70 71 72

      expect(
          createTestCommandRunner(command)
              .run(const <String>['build', 'fuchsia']),
          throwsA(isInstanceOf<ToolExit>()));
    }, overrides: <Type, Generator>{
      Platform: () => linuxPlatform,
73
      FileSystem: () => MemoryFileSystem(),
74
      ProcessManager: () => FakeProcessManager.any(),
75 76 77 78 79 80
    });

    testUsingContext('on Windows platform', () async {
      final BuildCommand command = BuildCommand();
      applyMocksToCommand(command);
      const String appName = 'app_name';
81 82
      globals.fs
          .file(globals.fs.path.join('fuchsia', 'meta', '$appName.cmx'))
83 84
          ..createSync(recursive: true)
          ..writeAsStringSync('{}');
85 86
      globals.fs.file('.packages').createSync();
      final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync();
87 88 89 90 91 92 93 94
      pubspecFile.writeAsStringSync('name: $appName');

      expect(
          createTestCommandRunner(command)
              .run(const <String>['build', 'fuchsia']),
          throwsA(isInstanceOf<ToolExit>()));
    }, overrides: <Type, Generator>{
      Platform: () => windowsPlatform,
95
      FileSystem: () => MemoryFileSystem(),
96
      ProcessManager: () => FakeProcessManager.any(),
97 98 99 100 101 102
    });

    testUsingContext('there is no Fuchsia kernel compiler', () async {
      final BuildCommand command = BuildCommand();
      applyMocksToCommand(command);
      const String appName = 'app_name';
103 104
      globals.fs
          .file(globals.fs.path.join('fuchsia', 'meta', '$appName.cmx'))
105 106
          ..createSync(recursive: true)
          ..writeAsStringSync('{}');
107 108 109
      globals.fs.file('.packages').createSync();
      globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
      final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync();
110 111 112 113 114 115 116
      pubspecFile.writeAsStringSync('name: $appName');
      expect(
          createTestCommandRunner(command)
              .run(const <String>['build', 'fuchsia']),
          throwsA(isInstanceOf<ToolExit>()));
    }, overrides: <Type, Generator>{
      Platform: () => linuxPlatform,
117
      FileSystem: () => MemoryFileSystem(),
118
      ProcessManager: () => FakeProcessManager.any(),
119
    });
120 121 122 123 124 125
  });

  testUsingContext('Fuchsia build parts fit together right', () async {
    final BuildCommand command = BuildCommand();
    applyMocksToCommand(command);
    const String appName = 'app_name';
126 127
    globals.fs
        .file(globals.fs.path.join('fuchsia', 'meta', '$appName.cmx'))
128 129
        ..createSync(recursive: true)
        ..writeAsStringSync('{}');
130 131 132
    globals.fs.file('.packages').createSync();
    globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
    final File pubspecFile = globals.fs.file('pubspec.yaml')..createSync();
133 134 135 136 137
    pubspecFile.writeAsStringSync('name: $appName');

    await createTestCommandRunner(command)
        .run(const <String>['build', 'fuchsia']);
    final String farPath =
138 139
        globals.fs.path.join(getFuchsiaBuildDirectory(), 'pkg', 'app_name-0.far');
    expect(globals.fs.file(farPath).existsSync(), isTrue);
140 141
  }, overrides: <Type, Generator>{
    Platform: () => linuxPlatform,
142
    FileSystem: () => MemoryFileSystem(),
143
    ProcessManager: () => FakeProcessManager.any(),
144
    FuchsiaSdk: () => fuchsiaSdk,
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
  });
}

class MockPlatform extends Mock implements Platform {
  @override
  Map<String, String> environment = <String, String>{
    'FLUTTER_ROOT': '/',
  };
}

class MockFuchsiaPM extends Mock implements FuchsiaPM {
  String _appName;

  @override
  Future<bool> init(String buildPath, String appName) async {
160
    if (!globals.fs.directory(buildPath).existsSync()) {
161 162
      return false;
    }
163 164
    globals.fs
        .file(globals.fs.path.join(buildPath, 'meta', 'package'))
165 166 167 168 169 170 171
        .createSync(recursive: true);
    _appName = appName;
    return true;
  }

  @override
  Future<bool> genkey(String buildPath, String outKeyPath) async {
172
    if (!globals.fs.file(globals.fs.path.join(buildPath, 'meta', 'package')).existsSync()) {
173 174
      return false;
    }
175
    globals.fs.file(outKeyPath).createSync(recursive: true);
176 177 178 179
    return true;
  }

  @override
180
  Future<bool> build(String buildPath, String keyPath, String manifestPath) async {
181 182 183
    if (!globals.fs.file(globals.fs.path.join(buildPath, 'meta', 'package')).existsSync() ||
        !globals.fs.file(keyPath).existsSync() ||
        !globals.fs.file(manifestPath).existsSync()) {
184 185
      return false;
    }
186
    globals.fs.file(globals.fs.path.join(buildPath, 'meta.far')).createSync(recursive: true);
187 188 189 190
    return true;
  }

  @override
191
  Future<bool> archive(String buildPath, String keyPath, String manifestPath) async {
192 193 194
    if (!globals.fs.file(globals.fs.path.join(buildPath, 'meta', 'package')).existsSync() ||
        !globals.fs.file(keyPath).existsSync() ||
        !globals.fs.file(manifestPath).existsSync()) {
195 196 197 198 199
      return false;
    }
    if (_appName == null) {
      return false;
    }
200 201
    globals.fs
        .file(globals.fs.path.join(buildPath, '$_appName-0.far'))
202 203 204 205 206 207 208 209 210 211 212 213 214 215
        .createSync(recursive: true);
    return true;
  }
}

class MockFuchsiaKernelCompiler extends Mock implements FuchsiaKernelCompiler {
  @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;
216 217
    final String manifestPath = globals.fs.path.join(outDir, '$appName.dilpmanifest');
    globals.fs.file(manifestPath).createSync(recursive: true);
218 219
  }
}
220 221 222 223 224 225 226 227 228

class MockFuchsiaSdk extends Mock implements FuchsiaSdk {
  @override
  final FuchsiaPM fuchsiaPM = MockFuchsiaPM();

  @override
  final FuchsiaKernelCompiler fuchsiaKernelCompiler =
      MockFuchsiaKernelCompiler();
}