flutter_validator_test.dart 9.68 KB
Newer Older
1 2 3 4
// Copyright 2014 The Flutter Authors. All rights reserved.
// 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 8 9 10 11 12
import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/doctor.dart';
13
import 'package:flutter_tools/src/doctor_validator.dart';
14
import 'package:flutter_tools/src/version.dart';
15
import 'package:test/fake.dart';
16 17

import '../src/common.dart';
18
import '../src/fake_process_manager.dart';
19
import '../src/fakes.dart';
20

21 22 23 24 25 26 27 28 29 30 31 32
/// Matches a doctor validation result.
Matcher _matchDoctorValidation({
  ValidationType validationType,
  String statusInfo,
  dynamic messages
}) {
  return const TypeMatcher<ValidationResult>()
      .having((ValidationResult result) => result.type, 'type', validationType)
      .having((ValidationResult result) => result.statusInfo, 'statusInfo', statusInfo)
      .having((ValidationResult result) => result.messages, 'messages', messages);
}

33 34 35
void main() {
  testWithoutContext('FlutterValidator shows an error message if gen_snapshot is '
    'downloaded and exits with code 1', () async {
36 37 38
    final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
      frameworkVersion: '1.0.0',
    );
39 40 41 42 43 44 45 46
    final MemoryFileSystem fileSystem = MemoryFileSystem.test();
    final Artifacts artifacts = Artifacts.test();
    final FlutterValidator flutterValidator = FlutterValidator(
      platform: FakePlatform(
        localeName: 'en_US.UTF-8',
        environment: <String, String>{},
      ),
      flutterVersion: () => flutterVersion,
47
        devToolsVersion: () => '2.8.0',
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
      userMessages: UserMessages(),
      artifacts: artifacts,
      fileSystem: fileSystem,
      flutterRoot: () => 'sdk/flutter',
      operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['Artifact.genSnapshot'],
          exitCode: 1,
        )
      ])
    );
    fileSystem.file(artifacts.getArtifactPath(Artifact.genSnapshot)).createSync(recursive: true);


63
    expect(await flutterValidator.validate(), _matchDoctorValidation(
64
      validationType: ValidationType.partial,
65
      statusInfo: 'Channel unknown, 1.0.0, on Linux, locale en_US.UTF-8',
66 67 68 69 70 71 72 73 74 75 76 77 78
      messages: containsAll(const <ValidationMessage>[
        ValidationMessage.error(
          'Downloaded executables cannot execute on host.\n'
          'See https://github.com/flutter/flutter/issues/6207 for more information\n'
          'On Debian/Ubuntu/Mint: sudo apt-get install lib32stdc++6\n'
          'On Fedora: dnf install libstdc++.i686\n'
          'On Arch: pacman -S lib32-gcc-libs\n',
        ),
      ])),
    );
  });

  testWithoutContext('FlutterValidator does not run gen_snapshot binary check if it is not already downloaded', () async {
79 80 81
    final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
      frameworkVersion: '1.0.0',
    );
82 83 84 85 86 87
    final FlutterValidator flutterValidator = FlutterValidator(
      platform: FakePlatform(
        operatingSystem: 'windows',
        localeName: 'en_US.UTF-8',
        environment: <String, String>{},
      ),
88
      flutterVersion: () => flutterVersion,
89
      devToolsVersion: () => '2.8.0',
90 91 92 93
      userMessages: UserMessages(),
      artifacts: Artifacts.test(),
      fileSystem: MemoryFileSystem.test(),
      operatingSystemUtils: FakeOperatingSystemUtils(name: 'Windows'),
94
      processManager: FakeProcessManager.empty(),
95 96 97 98 99
      flutterRoot: () => 'sdk/flutter',
    );

    // gen_snapshot is downloaded on demand, and the doctor should not
    // fail if the gen_snapshot binary is not present.
100
    expect(await flutterValidator.validate(), _matchDoctorValidation(
101
      validationType: ValidationType.installed,
102
      statusInfo: 'Channel unknown, 1.0.0, on Windows, locale en_US.UTF-8',
103 104 105 106 107 108 109
      messages: anything,
    ));
  });

  testWithoutContext('FlutterValidator handles exception thrown by version checking', () async {
    final FlutterValidator flutterValidator = FlutterValidator(
      platform: FakePlatform(operatingSystem: 'windows', localeName: 'en_US.UTF-8'),
110
      flutterVersion: () => FakeThrowingFlutterVersion(),
111
      devToolsVersion: () => '2.8.0',
112 113 114 115
      userMessages: UserMessages(),
      artifacts: Artifacts.test(),
      fileSystem: MemoryFileSystem.test(),
      operatingSystemUtils: FakeOperatingSystemUtils(name: 'Windows'),
116
      processManager: FakeProcessManager.empty(),
117 118 119
      flutterRoot: () => 'sdk/flutter',
    );

120
    expect(await flutterValidator.validate(), _matchDoctorValidation(
121 122
      validationType: ValidationType.partial,
      statusInfo: 'Channel unknown, 0.0.0, on Windows, locale en_US.UTF-8',
123
      messages: containsAll(const <ValidationMessage>[
124 125 126
        ValidationMessage('Flutter version 0.0.0 at sdk/flutter'),
        ValidationMessage.error('version error'),
      ]),
127
    ));
128 129 130
  });

  testWithoutContext('FlutterValidator shows mirrors on pub and flutter cloud storage', () async {
131 132 133
    final FakeFlutterVersion flutterVersion = FakeFlutterVersion(
      frameworkVersion: '1.0.0',
    );
134 135 136 137 138 139 140 141 142 143 144 145 146
    final Platform platform = FakePlatform(
      operatingSystem: 'windows',
      localeName: 'en_US.UTF-8',
      environment: <String, String>{
        'PUB_HOSTED_URL': 'https://example.com/pub',
        'FLUTTER_STORAGE_BASE_URL': 'https://example.com/flutter',
      },
    );
    final MemoryFileSystem fileSystem = MemoryFileSystem.test();
    final Artifacts artifacts = Artifacts.test();
    final FlutterValidator flutterValidator = FlutterValidator(
      platform: platform,
      flutterVersion: () => flutterVersion,
147
        devToolsVersion: () => '2.8.0',
148 149 150 151 152 153 154 155
      userMessages: UserMessages(),
      artifacts: artifacts,
      fileSystem: fileSystem,
      processManager: FakeProcessManager.any(),
      operatingSystemUtils: FakeOperatingSystemUtils(name: 'Windows'),
      flutterRoot: () => 'sdk/flutter'
    );

156
    expect(await flutterValidator.validate(), _matchDoctorValidation(
157
      validationType: ValidationType.installed,
158
      statusInfo: 'Channel unknown, 1.0.0, on Windows, locale en_US.UTF-8',
159 160 161 162 163 164
      messages: containsAll(const <ValidationMessage>[
        ValidationMessage('Pub download mirror https://example.com/pub'),
        ValidationMessage('Flutter download mirror https://example.com/flutter'),
      ])
    ));
  });
165 166 167 168 169 170 171 172 173 174

  testWithoutContext('FlutterValidator shows FLUTTER_GIT_URL environment variable when set', () async {
    final FlutterValidator flutterValidator = FlutterValidator(
      platform: FakePlatform(
        localeName: 'en_US.UTF-8',
        environment: <String, String> {
          'FLUTTER_GIT_URL': 'https://githubmirror.com/flutter.git',
        },
      ),
      flutterVersion: () => FakeFlutterVersion(frameworkVersion: '1.0.0'),
175
      devToolsVersion: () => '2.8.0',
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
      userMessages: UserMessages(),
      artifacts: Artifacts.test(),
      fileSystem: MemoryFileSystem.test(),
      processManager: FakeProcessManager.any(),
      operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
      flutterRoot: () => 'sdk/flutter',
    );

    expect(await flutterValidator.validate(), _matchDoctorValidation(
      validationType: ValidationType.installed,
      statusInfo: 'Channel unknown, 1.0.0, on Linux, locale en_US.UTF-8',
      messages: contains(const ValidationMessage('FLUTTER_GIT_URL = https://githubmirror.com/flutter.git')),
    ));
  });

  group('FlutterValidator shows flutter upstream remote', () {
    testWithoutContext('default url', () async {
      final FlutterValidator flutterValidator = FlutterValidator(
        platform: FakePlatform(localeName: 'en_US.UTF-8'),
        flutterVersion: () => FakeFlutterVersion(frameworkVersion: '1.0.0'),
196
        devToolsVersion: () => '2.8.0',
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
        userMessages: UserMessages(),
        artifacts: Artifacts.test(),
        fileSystem: MemoryFileSystem.test(),
        processManager: FakeProcessManager.any(),
        operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
        flutterRoot: () => 'sdk/flutter',
      );

      expect(await flutterValidator.validate(), _matchDoctorValidation(
        validationType: ValidationType.installed,
        statusInfo: 'Channel unknown, 1.0.0, on Linux, locale en_US.UTF-8',
        messages: contains(const ValidationMessage('Upstream repository https://github.com/flutter/flutter.git')),
      ));
    });

    testWithoutContext('unknown url if upstream is null', () async {
      final FlutterValidator flutterValidator = FlutterValidator(
        platform: FakePlatform(localeName: 'en_US.UTF-8'),
        flutterVersion: () => FakeFlutterVersion(
          frameworkVersion: '1.0.0',
          repositoryUrl: null,
        ),
219
        devToolsVersion: () => '2.8.0',
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
        userMessages: UserMessages(),
        artifacts: Artifacts.test(),
        fileSystem: MemoryFileSystem.test(),
        processManager: FakeProcessManager.any(),
        operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
        flutterRoot: () => 'sdk/flutter',
      );

      expect(await flutterValidator.validate(), _matchDoctorValidation(
        validationType: ValidationType.installed,
        statusInfo: 'Channel unknown, 1.0.0, on Linux, locale en_US.UTF-8',
        messages: contains(const ValidationMessage('Upstream repository unknown')),
      ));
    });
  });
235 236 237 238 239 240 241 242
}

class FakeOperatingSystemUtils extends Fake implements OperatingSystemUtils {
  FakeOperatingSystemUtils({this.name});

  @override
  final String name;
}
243 244

class FakeThrowingFlutterVersion extends FakeFlutterVersion {
245 246 247 248
  @override
  String get frameworkCommitDate {
    throw VersionCheckError('version error');
  }
249
}