command_output_test.dart 9.54 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
import 'dart:convert';

7
import 'package:flutter_tools/src/base/file_system.dart';
8
import 'package:flutter_tools/src/base/io.dart';
9
import 'package:flutter_tools/src/features.dart';
10 11

import '../src/common.dart';
12
import 'test_utils.dart';
13

14 15 16
// This test file does not use [getLocalEngineArguments] because it is testing
// command output and not using cached artifacts.

17
void main() {
18 19 20
  testWithoutContext('All development tools and deprecated commands are hidden and help text is not verbose', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final ProcessResult result = await processManager.run(<String>[
21 22 23 24
      flutterBin,
      '-h',
      '-v',
    ]);
25

26
    // Development tools.
27
    expect(result.stdout, isNot(contains('update-packages')));
28 29 30 31

    // Deprecated.
    expect(result.stdout, isNot(contains('make-host-app-editable')));

32 33 34 35
    // Only printed by verbose tool.
    expect(result.stdout, isNot(contains('exiting with code 0')));
  });

36 37 38 39 40 41 42 43 44 45 46 47 48 49
  testWithoutContext('Flutter help is shown with -? command line argument', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final ProcessResult result = await processManager.run(<String>[
      flutterBin,
      '-?',
    ]);

    // Development tools.
    expect(result.stdout, contains(
      'Run "flutter help <command>" for more information about a command.\n'
      'Run "flutter help -v" for verbose help output, including less commonly used options.'
    ));
  });

50 51 52
  testWithoutContext('flutter doctor is not verbose', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final ProcessResult result = await processManager.run(<String>[
53 54 55 56 57 58 59
      flutterBin,
      'doctor',
      '-v',
    ]);

    // Only printed by verbose tool.
    expect(result.stdout, isNot(contains('exiting with code 0')));
60
  });
61

62 63 64
  testWithoutContext('flutter doctor -vv super verbose', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final ProcessResult result = await processManager.run(<String>[
65 66 67 68 69 70
      flutterBin,
      'doctor',
      '-vv',
    ]);

    // Check for message only printed in verbose mode.
71
    expect(result.stdout, contains('Shutdown hooks complete'));
72 73
  });

74 75 76
  testWithoutContext('flutter config contains all features', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final ProcessResult result = await processManager.run(<String>[
77 78 79 80 81
      flutterBin,
      'config',
    ]);

    // contains all of the experiments in features.dart
82
    expect((result.stdout as String).split('\n'), containsAll(<Matcher>[
83
      for (final Feature feature in allConfigurableFeatures)
84 85 86 87
        contains(feature.configSetting),
    ]));
  });

88
  testWithoutContext('flutter run --machine uses AppRunLogger', () async {
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    final Directory directory = createResolvedTempDirectorySync('flutter_run_test.')
      .createTempSync('_flutter_run_test.')
      ..createSync(recursive: true);

    try {
      directory
        .childFile('pubspec.yaml')
        .writeAsStringSync('name: foo');
      directory
        .childFile('.packages')
        .writeAsStringSync('\n');
      directory
        .childDirectory('lib')
        .childFile('main.dart')
        .createSync(recursive: true);
104 105
      final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
      final ProcessResult result = await processManager.run(<String>[
106 107 108 109 110 111 112 113 114
        flutterBin,
        'run',
        '--show-test-device', // ensure command can fail to run and hit injection of correct logger.
        '--machine',
        '-v',
        '--no-resident',
      ], workingDirectory: directory.path);
      expect(result.stderr, isNot(contains('Oops; flutter has exited unexpectedly:')));
    } finally {
115
      tryToDelete(directory);
116
    }
117 118
  });

119 120 121
  testWithoutContext('flutter attach --machine uses AppRunLogger', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final ProcessResult result = await processManager.run(<String>[
122 123 124
      flutterBin,
      'attach',
      '--machine',
125
      '-v',
126 127
    ]);

128
    expect(result.stderr, contains('Target file')); // Target file not found, but different paths on Windows and Linux/macOS.
129
  });
130

131 132 133
  testWithoutContext('flutter --version --machine outputs JSON with flutterRoot', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final ProcessResult result = await processManager.run(<String>[
134 135 136 137 138
      flutterBin,
      '--version',
      '--machine',
    ]);

139
    final Map<String, Object?> versionInfo = json.decode(result.stdout
140 141 142
      .toString()
      .replaceAll('Building flutter tool...', '')
      .replaceAll('Waiting for another flutter command to release the startup lock...', '')
143
      .trim()) as Map<String, Object?>;
144 145 146

    expect(versionInfo, containsPair('flutterRoot', isNotNull));
  });
147

148 149
  testWithoutContext('A tool exit is thrown for an invalid debug-url in flutter attach', () async {
    // This test is almost exactly like the next one; update them together please.
150 151 152 153 154 155 156 157
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final String helloWorld = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world');
    final ProcessResult result = await processManager.run(<String>[
      flutterBin,
      '--show-test-device',
      'attach',
      '-d',
      'flutter-tester',
158
      '--debug-url=http://127.0.0.1:3333*/',
159 160
    ], workingDirectory: helloWorld);

161 162 163 164
    expect(
      result,
      const ProcessResultMatcher(exitCode: 1, stderrPattern: 'Invalid `--debug-url`: http://127.0.0.1:3333*/'),
    );
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
  });

  testWithoutContext('--debug-uri is an alias for --debug-url', () async {
    // This text is exactly the same as the previous one but with a "l" turned to an "i".
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final String helloWorld = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world');
    final ProcessResult result = await processManager.run(<String>[
      flutterBin,
      '--show-test-device',
      'attach',
      '-d',
      'flutter-tester',
      '--debug-uri=http://127.0.0.1:3333*/', // "uri" not "url"
    ], workingDirectory: helloWorld);

180 181 182 183 184 185 186 187
    expect(
      result,
      const ProcessResultMatcher(
        exitCode: 1,
        // _"url"_ not "uri"!
        stderrPattern: 'Invalid `--debug-url`: http://127.0.0.1:3333*/',
      ),
    );
188
  });
189 190

  testWithoutContext('will load bootstrap script before starting', () async {
191
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
192 193

    final File bootstrap = fileSystem.file(fileSystem.path.join(
194 195 196 197 198
      getFlutterRoot(),
      'bin',
      'internal',
      platform.isWindows ? 'bootstrap.bat' : 'bootstrap.sh'),
    );
199 200 201 202 203 204 205 206 207 208 209 210

    try {
      bootstrap.writeAsStringSync('echo TESTING 1 2 3');
      final ProcessResult result = await processManager.run(<String>[
        flutterBin,
      ]);

      expect(result.stdout, contains('TESTING 1 2 3'));
    } finally {
      bootstrap.deleteSync();
    }
  });
211 212 213 214 215 216 217 218 219 220 221

  testWithoutContext('Providing sksl bundle with missing file with tool exit', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final String helloWorld = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world');
    final ProcessResult result = await processManager.run(<String>[
      flutterBin,
      'build',
      'apk',
      '--bundle-sksl-path=foo/bar/baz.json', // This file does not exist.
    ], workingDirectory: helloWorld);

222 223 224 225
    expect(result, const ProcessResultMatcher(
      exitCode: 1,
      stderrPattern: 'No SkSL shader bundle found at foo/bar/baz.json'),
    );
226
  });
227 228 229 230 231 232 233 234 235 236 237 238 239 240

  testWithoutContext('flutter attach does not support --release', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final String helloWorld = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world');
    final ProcessResult result = await processManager.run(<String>[
      flutterBin,
      '--show-test-device',
      'attach',
      '--release',
    ], workingDirectory: helloWorld);

    expect(result.exitCode, isNot(0));
    expect(result.stderr, contains('Could not find an option named "release"'));
  });
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257

  testWithoutContext('flutter can report crashes', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final ProcessResult result = await processManager.run(<String>[
      flutterBin,
      'update-packages',
      '--crash',
    ], environment: <String, String>{
      'BOT': 'false',
    });

    expect(result.exitCode, isNot(0));
    expect(result.stderr, contains(
      'Oops; flutter has exited unexpectedly: "Bad state: test crash please ignore.".\n'
      'A crash report has been written to',
    ));
  });
258 259 260 261 262 263 264 265 266 267 268 269

  testWithoutContext('flutter supports trailing args', () async {
    final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
    final String helloWorld = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world');
    final ProcessResult result = await processManager.run(<String>[
      flutterBin,
      'test',
      'test/hello_test.dart',
      '-r',
      'json',
    ], workingDirectory: helloWorld);

270
    expect(result, const ProcessResultMatcher());
271 272
    expect(result.stderr, isEmpty);
  });
273
}