mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
201 lines
7.9 KiB
Dart
201 lines
7.9 KiB
Dart
// Copyright 2015 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io' hide File;
|
|
|
|
import 'package:args/command_runner.dart';
|
|
import 'package:file/memory.dart';
|
|
import 'package:flutter_tools/src/base/file_system.dart';
|
|
import 'package:flutter_tools/src/cache.dart';
|
|
import 'package:flutter_tools/src/commands/channel.dart';
|
|
import 'package:flutter_tools/src/version.dart';
|
|
import 'package:mockito/mockito.dart';
|
|
import 'package:process/process.dart';
|
|
|
|
import 'src/common.dart';
|
|
import 'src/context.dart';
|
|
|
|
Process createMockProcess({int exitCode = 0, String stdout = '', String stderr = ''}) {
|
|
final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable(<List<int>>[
|
|
utf8.encode(stdout),
|
|
]);
|
|
final Stream<List<int>> stderrStream = Stream<List<int>>.fromIterable(<List<int>>[
|
|
utf8.encode(stderr),
|
|
]);
|
|
final Process process = MockProcess();
|
|
|
|
when(process.stdout).thenAnswer((_) => stdoutStream);
|
|
when(process.stderr).thenAnswer((_) => stderrStream);
|
|
when(process.exitCode).thenAnswer((_) => Future<int>.value(exitCode));
|
|
return process;
|
|
}
|
|
|
|
void main() {
|
|
group('channel', () {
|
|
final MockProcessManager mockProcessManager = MockProcessManager();
|
|
|
|
setUpAll(() {
|
|
Cache.disableLocking();
|
|
});
|
|
|
|
testUsingContext('list', () async {
|
|
final ChannelCommand command = ChannelCommand();
|
|
final CommandRunner<void> runner = createTestCommandRunner(command);
|
|
await runner.run(<String>['channel']);
|
|
expect(testLogger.errorText, hasLength(0));
|
|
// The bots may return an empty list of channels (network hiccup?)
|
|
// and when run locally the list of branches might be different
|
|
// so we check for the header text rather than any specific channel name.
|
|
expect(testLogger.statusText, contains('Flutter channels:'));
|
|
});
|
|
|
|
testUsingContext('removes duplicates', () async {
|
|
final Process process = createMockProcess(
|
|
stdout: 'origin/dev\n'
|
|
'origin/beta\n'
|
|
'upstream/dev\n'
|
|
'upstream/beta\n');
|
|
when(mockProcessManager.start(
|
|
<String>['git', 'branch', '-r'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).thenAnswer((_) => Future<Process>.value(process));
|
|
|
|
final ChannelCommand command = ChannelCommand();
|
|
final CommandRunner<void> runner = createTestCommandRunner(command);
|
|
await runner.run(<String>['channel']);
|
|
|
|
verify(mockProcessManager.start(
|
|
<String>['git', 'branch', '-r'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).called(1);
|
|
|
|
expect(testLogger.errorText, hasLength(0));
|
|
|
|
// format the status text for a simpler assertion.
|
|
final Iterable<String> rows = testLogger.statusText
|
|
.split('\n')
|
|
.map((String line) => line.trim())
|
|
.where((String line) => line?.isNotEmpty == true)
|
|
.skip(1); // remove `Flutter channels:` line
|
|
|
|
expect(rows, <String>['dev', 'beta']);
|
|
}, overrides: <Type, Generator>{
|
|
ProcessManager: () => mockProcessManager,
|
|
});
|
|
|
|
testUsingContext('can switch channels', () async {
|
|
when(mockProcessManager.start(
|
|
<String>['git', 'fetch'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).thenAnswer((_) => Future<Process>.value(createMockProcess()));
|
|
when(mockProcessManager.start(
|
|
<String>['git', 'show-ref', '--verify', '--quiet', 'refs/heads/beta'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).thenAnswer((_) => Future<Process>.value(createMockProcess()));
|
|
when(mockProcessManager.start(
|
|
<String>['git', 'checkout', 'beta', '--'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).thenAnswer((_) => Future<Process>.value(createMockProcess()));
|
|
|
|
final ChannelCommand command = ChannelCommand();
|
|
final CommandRunner<void> runner = createTestCommandRunner(command);
|
|
await runner.run(<String>['channel', 'beta']);
|
|
|
|
verify(mockProcessManager.start(
|
|
<String>['git', 'fetch'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).called(1);
|
|
verify(mockProcessManager.start(
|
|
<String>['git', 'show-ref', '--verify', '--quiet', 'refs/heads/beta'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).called(1);
|
|
verify(mockProcessManager.start(
|
|
<String>['git', 'checkout', 'beta', '--'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).called(1);
|
|
|
|
expect(testLogger.statusText, contains("Switching to flutter channel 'beta'..."));
|
|
expect(testLogger.errorText, hasLength(0));
|
|
}, overrides: <Type, Generator>{
|
|
ProcessManager: () => mockProcessManager,
|
|
FileSystem: () => MemoryFileSystem(),
|
|
});
|
|
|
|
// This verifies that bug https://github.com/flutter/flutter/issues/21134
|
|
// doesn't return.
|
|
testUsingContext('removes version stamp file when switching channels', () async {
|
|
when(mockProcessManager.start(
|
|
<String>['git', 'fetch'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).thenAnswer((_) => Future<Process>.value(createMockProcess()));
|
|
when(mockProcessManager.start(
|
|
<String>['git', 'show-ref', '--verify', '--quiet', 'refs/heads/beta'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).thenAnswer((_) => Future<Process>.value(createMockProcess()));
|
|
when(mockProcessManager.start(
|
|
<String>['git', 'checkout', 'beta', '--'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).thenAnswer((_) => Future<Process>.value(createMockProcess()));
|
|
|
|
final File versionCheckFile = Cache.instance.getStampFileFor(
|
|
VersionCheckStamp.kFlutterVersionCheckStampFile,
|
|
);
|
|
|
|
/// Create a bogus "leftover" version check file to make sure it gets
|
|
/// removed when the channel changes. The content doesn't matter.
|
|
versionCheckFile.createSync(recursive: true);
|
|
versionCheckFile.writeAsStringSync('''
|
|
{
|
|
"lastTimeVersionWasChecked": "2151-08-29 10:17:30.763802",
|
|
"lastKnownRemoteVersion": "2151-09-26 15:56:19.000Z"
|
|
}
|
|
''');
|
|
|
|
final ChannelCommand command = ChannelCommand();
|
|
final CommandRunner<void> runner = createTestCommandRunner(command);
|
|
await runner.run(<String>['channel', 'beta']);
|
|
|
|
verify(mockProcessManager.start(
|
|
<String>['git', 'fetch'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).called(1);
|
|
verify(mockProcessManager.start(
|
|
<String>['git', 'show-ref', '--verify', '--quiet', 'refs/heads/beta'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).called(1);
|
|
verify(mockProcessManager.start(
|
|
<String>['git', 'checkout', 'beta', '--'],
|
|
workingDirectory: anyNamed('workingDirectory'),
|
|
environment: anyNamed('environment'),
|
|
)).called(1);
|
|
|
|
expect(testLogger.statusText, isNot(contains('A new version of Flutter')));
|
|
expect(testLogger.errorText, hasLength(0));
|
|
expect(versionCheckFile.existsSync(), isFalse);
|
|
}, overrides: <Type, Generator>{
|
|
ProcessManager: () => mockProcessManager,
|
|
FileSystem: () => MemoryFileSystem(),
|
|
});
|
|
});
|
|
}
|
|
|
|
class MockProcessManager extends Mock implements ProcessManager {}
|
|
|
|
class MockProcess extends Mock implements Process {}
|