assemble_test.dart 7.66 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:args/command_runner.dart';
6
import 'package:flutter_tools/src/artifacts.dart';
7
import 'package:flutter_tools/src/base/file_system.dart';
8 9 10
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/assemble.dart';
11
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
12
import 'package:mockito/mockito.dart';
13
import 'package:flutter_tools/src/globals.dart' as globals;
14

15
import '../../src/common.dart';
16
import '../../src/context.dart';
17
import '../../src/testbed.dart';
18 19

void main() {
20
  FlutterCommandRunner.initFlutterRoot();
21
  Cache.disableLocking();
22 23 24
  final Testbed testbed = Testbed(overrides: <Type, Generator>{
    BuildSystem: ()  => MockBuildSystem(),
    Cache: () => FakeCache(),
25
  });
26

27
  testbed.test('flutter assemble can run a build', () async {
28
    when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
29 30 31
      .thenAnswer((Invocation invocation) async {
        return BuildResult(success: true);
      });
32
    final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
33
    await commandRunner.run(<String>['assemble', '-o Output', 'debug_macos_bundle_flutter_assets']);
34 35 36 37

    expect(testLogger.traceText, contains('build succeeded.'));
  });

38
  testbed.test('flutter assemble can parse defines whose values contain =', () async {
39
    when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
40 41 42 43 44 45
      .thenAnswer((Invocation invocation) async {
        expect((invocation.positionalArguments[1] as Environment).defines, containsPair('FooBar', 'fizz=2'));
        return BuildResult(success: true);
      });
    final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
    await commandRunner.run(<String>['assemble', '-o Output', '-dFooBar=fizz=2', 'debug_macos_bundle_flutter_assets']);
46

47
    expect(testLogger.traceText, contains('build succeeded.'));
48
  });
49

50 51 52 53 54 55 56 57 58 59 60 61 62
  testbed.test('flutter assemble can parse inputs', () async {
    when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
      .thenAnswer((Invocation invocation) async {
        expect((invocation.positionalArguments[1] as Environment).inputs, containsPair('Foo', 'Bar.txt'));
        return BuildResult(success: true);
      });
    final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
    await commandRunner.run(<String>['assemble', '-o Output', '-iFoo=Bar.txt', 'debug_macos_bundle_flutter_assets']);

    expect(testLogger.traceText, contains('build succeeded.'));
  });

  testbed.test('flutter assemble throws ToolExit if not provided with output', () async {
63
    when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
64 65 66
      .thenAnswer((Invocation invocation) async {
        return BuildResult(success: true);
      });
67 68
    final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());

69
    expect(commandRunner.run(<String>['assemble', 'debug_macos_bundle_flutter_assets']),
Dan Field's avatar
Dan Field committed
70
      throwsToolExit());
71
  });
72

73
  testbed.test('flutter assemble throws ToolExit if called with non-existent rule', () async {
74
    when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
75 76 77
      .thenAnswer((Invocation invocation) async {
        return BuildResult(success: true);
      });
78 79
    final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());

80
    expect(commandRunner.run(<String>['assemble', '-o Output', 'undefined']),
Dan Field's avatar
Dan Field committed
81
      throwsToolExit());
82 83
  });

84
  testbed.test('flutter assemble does not log stack traces during build failure', () async {
85
    final StackTrace testStackTrace = StackTrace.current;
86
    when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
87 88 89 90 91 92 93 94
      .thenAnswer((Invocation invocation) async {
        return BuildResult(success: false, exceptions: <String, ExceptionMeasurement>{
          'hello': ExceptionMeasurement('hello', 'bar', testStackTrace),
        });
      });
    final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());

    await expectLater(commandRunner.run(<String>['assemble', '-o Output', 'debug_macos_bundle_flutter_assets']),
Dan Field's avatar
Dan Field committed
95
      throwsToolExit());
96 97
    expect(testLogger.errorText, contains('bar'));
    expect(testLogger.errorText, isNot(contains(testStackTrace.toString())));
98
  });
99

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
  testbed.test('flutter assemble does not inject engine revision with local-engine', () async {
    Environment environment;
    when(globals.artifacts.isLocalEngine).thenReturn(true);
    when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
      .thenAnswer((Invocation invocation) async {
        environment = invocation.positionalArguments[1] as Environment;
        return BuildResult(success: true);
      });
    final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
    await commandRunner.run(<String>['assemble', '-o Output', 'debug_macos_bundle_flutter_assets']);

    expect(environment.engineVersion, isNull);
  }, overrides: <Type, Generator>{
    Artifacts: () => MockLocalEngineArtifacts()
  });

116
  testbed.test('flutter assemble only writes input and output files when the values change', () async {
117
    when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
118 119 120
      .thenAnswer((Invocation invocation) async {
        return BuildResult(
          success: true,
121 122
          inputFiles: <File>[globals.fs.file('foo')..createSync()],
          outputFiles: <File>[globals.fs.file('bar')..createSync()],
123 124
        );
      });
125 126

    final CommandRunner<void> commandRunner = createTestCommandRunner(AssembleCommand());
127 128 129 130 131 132 133
    await commandRunner.run(<String>[
      'assemble',
      '-o Output',
      '--build-outputs=outputs',
      '--build-inputs=inputs',
      'debug_macos_bundle_flutter_assets',
    ]);
134

135 136
    final File inputs = globals.fs.file('inputs');
    final File outputs = globals.fs.file('outputs');
137 138 139 140 141 142
    expect(inputs.readAsStringSync(), contains('foo'));
    expect(outputs.readAsStringSync(), contains('bar'));

    final DateTime theDistantPast = DateTime(1991, 8, 23);
    inputs.setLastModifiedSync(theDistantPast);
    outputs.setLastModifiedSync(theDistantPast);
143 144 145 146 147 148 149
    await commandRunner.run(<String>[
      'assemble',
      '-o Output',
      '--build-outputs=outputs',
      '--build-inputs=inputs',
      'debug_macos_bundle_flutter_assets',
    ]);
150 151 152 153

    expect(inputs.lastModifiedSync(), theDistantPast);
    expect(outputs.lastModifiedSync(), theDistantPast);

154
    when(globals.buildSystem.build(any, any, buildSystemConfig: anyNamed('buildSystemConfig')))
155 156 157
      .thenAnswer((Invocation invocation) async {
        return BuildResult(
          success: true,
158 159
          inputFiles: <File>[globals.fs.file('foo'), globals.fs.file('fizz')..createSync()],
          outputFiles: <File>[globals.fs.file('bar'), globals.fs.file(globals.fs.path.join('.dart_tool', 'fizz2'))..createSync(recursive: true)]);
160
      });
161 162 163 164 165 166 167
    await commandRunner.run(<String>[
      'assemble',
      '-o Output',
      '--build-outputs=outputs',
      '--build-inputs=inputs',
      'debug_macos_bundle_flutter_assets',
    ]);
168 169 170 171

    expect(inputs.readAsStringSync(), contains('foo'));
    expect(inputs.readAsStringSync(), contains('fizz'));
    expect(inputs.lastModifiedSync(), isNot(theDistantPast));
172
  });
173 174 175
}

class MockBuildSystem extends Mock implements BuildSystem {}
176
class MockLocalEngineArtifacts extends Mock implements LocalEngineArtifacts {}