downgrade_test.dart 8.41 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 13 14
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/downgrade.dart';
import 'package:flutter_tools/src/persistent_tool_state.dart';
15
import 'package:test/fake.dart';
16 17 18

import '../../src/common.dart';
import '../../src/context.dart';
19
import '../../src/fakes.dart';
20
import '../../src/test_flutter_command_runner.dart';
21 22 23 24

void main() {
  FileSystem fileSystem;
  BufferLogger bufferLogger;
25
  FakeTerminal terminal;
26
  ProcessManager processManager;
27
  FakeStdio stdio;
28 29 30 31 32 33 34 35 36 37

  setUpAll(() {
    Cache.disableLocking();
  });

  tearDownAll(() {
    Cache.enableLocking();
  });

  setUp(() {
38
    stdio = FakeStdio();
39
    processManager = FakeProcessManager.any();
40
    terminal = FakeTerminal();
41
    fileSystem = MemoryFileSystem.test();
42
    bufferLogger = BufferLogger.test(terminal: terminal);
43 44 45
  });

  testUsingContext('Downgrade exits on unknown channel', () async {
46
    final FakeFlutterVersion fakeFlutterVersion = FakeFlutterVersion(channel: 'unknown');
47 48 49 50 51 52
    fileSystem.currentDirectory.childFile('.flutter_tool_state')
      .writeAsStringSync('{"last-active-master-version":"invalid"}');
    final DowngradeCommand command = DowngradeCommand(
      persistentToolState: PersistentToolState.test(directory: fileSystem.currentDirectory, logger: bufferLogger),
      processManager: processManager,
      terminal: terminal,
53
      stdio: stdio,
54
      flutterVersion: fakeFlutterVersion,
55 56 57 58 59 60 61 62
      logger: bufferLogger,
    );

    expect(createTestCommandRunner(command).run(const <String>['downgrade']),
      throwsToolExit(message: 'Flutter is not currently on a known channel.'));
  });

  testUsingContext('Downgrade exits on no recorded version', () async {
63
    final FakeFlutterVersion fakeFlutterVersion = FakeFlutterVersion(channel: 'dev');
64 65 66 67 68 69 70 71 72 73 74 75 76 77
    fileSystem.currentDirectory.childFile('.flutter_tool_state')
      .writeAsStringSync('{"last-active-master-version":"abcd"}');
    final DowngradeCommand command = DowngradeCommand(
      persistentToolState: PersistentToolState.test(directory: fileSystem.currentDirectory, logger: bufferLogger),
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'git', 'describe', '--tags', 'abcd'
          ],
          exitCode: 0,
          stdout: 'v1.2.3'
        )
      ]),
      terminal: terminal,
78
      stdio: stdio,
79
      flutterVersion: fakeFlutterVersion,
80 81 82 83 84 85 86 87 88 89 90 91
      logger: bufferLogger,
    );

    expect(createTestCommandRunner(command).run(const <String>['downgrade']),
      throwsToolExit(message:
        'There is no previously recorded version for channel "dev".\n'
        'Channel "master" was previously on: v1.2.3.'
      ),
    );
  });

  testUsingContext('Downgrade exits on unknown recorded version', () async {
92
    final FakeFlutterVersion fakeFlutterVersion = FakeFlutterVersion(channel: 'master');
93 94 95 96 97 98 99 100 101 102 103 104 105
    fileSystem.currentDirectory.childFile('.flutter_tool_state')
      .writeAsStringSync('{"last-active-master-version":"invalid"}');
    final DowngradeCommand command = DowngradeCommand(
      persistentToolState: PersistentToolState.test(directory: fileSystem.currentDirectory, logger: bufferLogger),
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'git', 'describe', '--tags', 'invalid'
          ],
          exitCode: 1,
        )
      ]),
      terminal: terminal,
106
      stdio: stdio,
107
      flutterVersion: fakeFlutterVersion,
108 109 110 111 112 113 114 115
      logger: bufferLogger,
    );

    expect(createTestCommandRunner(command).run(const <String>['downgrade']),
      throwsToolExit(message: 'Failed to parse version for downgrade'));
  });

   testUsingContext('Downgrade prompts for user input when terminal is attached - y', () async {
116
    final FakeFlutterVersion fakeFlutterVersion = FakeFlutterVersion(channel: 'master');
117
    stdio.hasTerminal = true;
118 119 120 121 122 123
    fileSystem.currentDirectory.childFile('.flutter_tool_state')
      .writeAsStringSync('{"last-active-master-version":"g6b00b5e88"}');
    final DowngradeCommand command = DowngradeCommand(
      persistentToolState: PersistentToolState.test(directory: fileSystem.currentDirectory, logger: bufferLogger),
      processManager: processManager,
      terminal: terminal,
124
      stdio: stdio,
125
      flutterVersion: fakeFlutterVersion,
126 127 128
      logger: bufferLogger,
    );

129
    terminal.addPrompt(const <String>['y', 'n'], 'y');
130 131 132 133 134 135 136

    await createTestCommandRunner(command).run(const <String>['downgrade']);

    expect(bufferLogger.statusText, contains('Success'));
  });

   testUsingContext('Downgrade prompts for user input when terminal is attached - n', () async {
137
    final FakeFlutterVersion fakeFlutterVersion = FakeFlutterVersion(channel: 'master');
138
    stdio.hasTerminal = true;
139 140 141 142 143 144
    fileSystem.currentDirectory.childFile('.flutter_tool_state')
      .writeAsStringSync('{"last-active-master-version":"g6b00b5e88"}');
    final DowngradeCommand command = DowngradeCommand(
      persistentToolState: PersistentToolState.test(directory: fileSystem.currentDirectory, logger: bufferLogger),
      processManager: processManager,
      terminal: terminal,
145
      stdio: stdio,
146
      flutterVersion: fakeFlutterVersion,
147 148 149
      logger: bufferLogger,
    );

150
    terminal.addPrompt(const <String>['y', 'n'], 'n');
151 152 153 154 155 156 157

    await createTestCommandRunner(command).run(const <String>['downgrade']);

    expect(bufferLogger.statusText, isNot(contains('Success')));
  });

  testUsingContext('Downgrade does not prompt when there is no terminal', () async {
158
    final FakeFlutterVersion fakeFlutterVersion = FakeFlutterVersion(channel: 'master');
159
    stdio.hasTerminal = false;
160 161 162 163 164 165 166 167 168
    fileSystem.currentDirectory.childFile('.flutter_tool_state')
      .writeAsStringSync('{"last-active-master-version":"g6b00b5e88"}');
    final DowngradeCommand command = DowngradeCommand(
      persistentToolState: PersistentToolState.test(
        directory: fileSystem.currentDirectory,
        logger: bufferLogger,
      ),
      processManager: processManager,
      terminal: terminal,
169
      stdio: stdio,
170
      flutterVersion: fakeFlutterVersion,
171 172 173 174 175 176 177 178 179
      logger: bufferLogger,
    );

    await createTestCommandRunner(command).run(const <String>['downgrade']);

    expect(bufferLogger.statusText, contains('Success'));
  });

  testUsingContext('Downgrade performs correct git commands', () async {
180
    final FakeFlutterVersion fakeFlutterVersion = FakeFlutterVersion(channel: 'master');
181
    stdio.hasTerminal = false;
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
    fileSystem.currentDirectory.childFile('.flutter_tool_state')
      .writeAsStringSync('{"last-active-master-version":"g6b00b5e88"}');
    final DowngradeCommand command = DowngradeCommand(
      persistentToolState: PersistentToolState.test(
        directory: fileSystem.currentDirectory,
        logger: bufferLogger,
      ),
      processManager: FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>[
            'git', 'describe', '--tags', 'g6b00b5e88'
          ],
          stdout: 'v1.2.3',
        ),
        const FakeCommand(
          command: <String>[
            'git', 'reset', '--hard', 'g6b00b5e88'
          ],
        ),
        const FakeCommand(
          command: <String>[
            'git', 'checkout', 'master', '--'
          ]
        ),
      ]),
      terminal: terminal,
208
      stdio: stdio,
209
      flutterVersion: fakeFlutterVersion,
210 211 212 213 214 215 216 217 218
      logger: bufferLogger,
    );

    await createTestCommandRunner(command).run(const <String>['downgrade']);

    expect(bufferLogger.statusText, contains('Success'));
  });
}

219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
class FakeTerminal extends Fake implements Terminal {
  @override
  bool usesTerminalUi = false;

  void addPrompt(List<String> characters, String selected) {
    _characters = characters;
    _selected = selected;
  }

  List<String> _characters;
  String _selected;

  @override
  Future<String> promptForCharInput(List<String> acceptedCharacters, {Logger logger, String prompt, int defaultChoiceIndex, bool displayAcceptedCharacters = true}) async {
    expect(acceptedCharacters, _characters);
    return _selected;
  }
}

class FakeStdio extends Fake implements Stdio {
  @override
  bool hasTerminal = true;
}