mirror of
https://github.com/flutter/flutter
synced 2024-08-27 12:00:58 +00:00
Enable avoid_print
lint. (#91332)
This commit is contained in:
parent
3c6c2aa50a
commit
cb378edc9e
|
@ -71,8 +71,8 @@ linter:
|
|||
- avoid_init_to_null
|
||||
# - avoid_js_rounded_ints # only useful when targeting JS runtime
|
||||
- avoid_null_checks_in_equality_operators
|
||||
# - avoid_positional_boolean_parameters # not yet tested
|
||||
# - avoid_print # not yet tested
|
||||
# - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it
|
||||
- avoid_print
|
||||
# - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356)
|
||||
# - avoid_redundant_argument_values # not yet tested
|
||||
- avoid_relative_lib_imports
|
||||
|
|
5
dev/analysis_options.yaml
Normal file
5
dev/analysis_options.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
include: ../analysis_options.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
avoid_print: false # We use prints as debugging tools here all the time.
|
|
@ -0,0 +1,7 @@
|
|||
[0-9]+:[0-9]+ [+]0: Local passes non-existent baseline for new test, null expectation *
|
||||
*No expectations provided by Skia Gold for test: library.flutter.new_golden_test.1. This may be a new test. If this is an unexpected result, check https://flutter-gold.skia.org.
|
||||
*Validate image output found at flutter/test/library/
|
||||
[0-9]+:[0-9]+ [+]0 ~1: Local passes non-existent baseline for new test, empty expectation *
|
||||
*No expectations provided by Skia Gold for test: library.flutter.new_golden_test.2. This may be a new test. If this is an unexpected result, check https://flutter-gold.skia.org.
|
||||
*Validate image output found at flutter/test/library/
|
||||
[0-9]+:[0-9]+ [+]0 ~2: All tests skipped. *
|
77
dev/automated_tests/flutter_test/flutter_gold_test.dart
Normal file
77
dev/automated_tests/flutter_test/flutter_gold_test.dart
Normal file
|
@ -0,0 +1,77 @@
|
|||
// 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.
|
||||
|
||||
// See also packages/flutter_goldens/test/flutter_goldens_test.dart
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_goldens/flutter_goldens.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
|
||||
// 1x1 colored pixel
|
||||
const List<int> _kFailPngBytes = <int>[137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0,
|
||||
13, 73, 72, 68, 82, 0, 0, 0, 1, 0, 0, 0, 1, 8, 6, 0, 0, 0, 31, 21, 196, 137,
|
||||
0, 0, 0, 13, 73, 68, 65, 84, 120, 1, 99, 249, 207, 240, 255, 63, 0, 7, 18, 3,
|
||||
2, 164, 147, 160, 197, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130];
|
||||
|
||||
void main() {
|
||||
final MemoryFileSystem fs = MemoryFileSystem();
|
||||
final Directory basedir = fs.directory('flutter/test/library/')
|
||||
..createSync(recursive: true);
|
||||
final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient()
|
||||
..expectationForTestValues['flutter.new_golden_test.1'] = '';
|
||||
final FlutterLocalFileComparator comparator = FlutterLocalFileComparator(
|
||||
basedir.uri,
|
||||
fakeSkiaClient,
|
||||
fs: fs,
|
||||
platform: FakePlatform(
|
||||
environment: <String, String>{'FLUTTER_ROOT': '/flutter'},
|
||||
operatingSystem: 'macos'
|
||||
),
|
||||
);
|
||||
|
||||
test('Local passes non-existent baseline for new test, null expectation', () async {
|
||||
expect(
|
||||
await comparator.compare(
|
||||
Uint8List.fromList(_kFailPngBytes),
|
||||
Uri.parse('flutter.new_golden_test.1'),
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
|
||||
test('Local passes non-existent baseline for new test, empty expectation', () async {
|
||||
expect(
|
||||
await comparator.compare(
|
||||
Uint8List.fromList(_kFailPngBytes),
|
||||
Uri.parse('flutter.new_golden_test.2'),
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// See also packages/flutter_goldens/test/flutter_goldens_test.dart
|
||||
class FakeSkiaGoldClient extends Fake implements SkiaGoldClient {
|
||||
Map<String, String> expectationForTestValues = <String, String>{};
|
||||
Object? getExpectationForTestThrowable;
|
||||
@override
|
||||
Future<String> getExpectationForTest(String testName) async {
|
||||
if (getExpectationForTestThrowable != null) {
|
||||
throw getExpectationForTestThrowable!;
|
||||
}
|
||||
return expectationForTestValues[testName] ?? '';
|
||||
}
|
||||
|
||||
Map<String, List<int>> imageBytesValues = <String, List<int>>{};
|
||||
@override
|
||||
Future<List<int>> getImageBytes(String imageHash) async => imageBytesValues[imageHash]!;
|
||||
|
||||
Map<String, String> cleanTestNameValues = <String, String>{};
|
||||
@override
|
||||
String cleanTestName(String fileName) => cleanTestNameValues[fileName] ?? '';
|
||||
}
|
|
@ -8,5 +8,5 @@ import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
|||
void main() {
|
||||
test('working directory is the root of this package', () {
|
||||
expect(Directory.current.path, endsWith('automated_tests'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ dependencies:
|
|||
sdk: flutter
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_goldens:
|
||||
sdk: flutter
|
||||
integration_test:
|
||||
sdk: flutter
|
||||
test: 1.17.12
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
# Use the analysis options settings from the top level of the repo (not
|
||||
# the ones from above, which include the `public_member_api_docs` rule).
|
||||
|
||||
include: ../../../analysis_options.yaml
|
||||
include: ../../analysis_options.yaml
|
||||
|
||||
analyzer:
|
||||
exclude:
|
||||
# Ignore protoc generated files
|
||||
# Ignore protoc generated files
|
||||
- "lib/src/proto/*"
|
||||
|
||||
linter:
|
||||
rules:
|
||||
avoid_catches_without_on_clauses: true
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
# Use the analysis options settings from the top level of the repo (not
|
||||
# the ones from above, which include the `public_member_api_docs` rule).
|
||||
|
||||
include: ../../../analysis_options.yaml
|
||||
include: ../../analysis_options.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
include: ../../analysis_options.yaml
|
||||
include: ../analysis_options.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
# Take our settings from the repo's main analysis_options.yaml file, but add
|
||||
# an exclude for the build directory.
|
||||
|
||||
include: ../../../analysis_options.yaml
|
||||
include: ../../analysis_options.yaml
|
||||
|
||||
analyzer:
|
||||
exclude:
|
||||
|
|
|
@ -47,7 +47,7 @@ class AutocompleteBasicExample extends StatelessWidget {
|
|||
});
|
||||
},
|
||||
onSelected: (String selection) {
|
||||
print('You just selected $selection');
|
||||
debugPrint('You just selected $selection');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ class AutocompleteBasicUserExample extends StatelessWidget {
|
|||
});
|
||||
},
|
||||
onSelected: (User selection) {
|
||||
print('You just selected ${_displayStringForOption(selection)}');
|
||||
debugPrint('You just selected ${_displayStringForOption(selection)}');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class MyStatelessWidget extends StatelessWidget {
|
|||
child: InkWell(
|
||||
splashColor: Colors.blue.withAlpha(30),
|
||||
onTap: () {
|
||||
print('Card tapped.');
|
||||
debugPrint('Card tapped.');
|
||||
},
|
||||
child: const SizedBox(
|
||||
width: 300,
|
||||
|
|
|
@ -59,7 +59,7 @@ class LinkedLabelCheckbox extends StatelessWidget {
|
|||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
print('Label has been tapped.');
|
||||
debugPrint('Label has been tapped.');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
@ -45,7 +45,7 @@ class MyStatelessWidget extends StatelessWidget {
|
|||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
print('FAB pressed.');
|
||||
debugPrint('FAB pressed.');
|
||||
},
|
||||
tooltip: 'Increment',
|
||||
child: const Icon(Icons.add),
|
||||
|
|
|
@ -34,7 +34,7 @@ class MyStatelessWidget extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return OutlinedButton(
|
||||
onPressed: () {
|
||||
print('Received click');
|
||||
debugPrint('Received click');
|
||||
},
|
||||
child: const Text('Click Me'),
|
||||
);
|
||||
|
|
|
@ -64,7 +64,7 @@ class LinkedLabelRadio extends StatelessWidget {
|
|||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
print('Label has been tapped.');
|
||||
debugPrint('Label has been tapped.');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
@ -59,7 +59,7 @@ class LinkedLabelSwitch extends StatelessWidget {
|
|||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
print('Label has been tapped.');
|
||||
debugPrint('Label has been tapped.');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
@ -54,7 +54,7 @@ class _MyStatefulWidgetState extends State<MyStatefulWidget> {
|
|||
constraints: BoxConstraints.tight(const Size(200, 50)),
|
||||
child: TextFormField(
|
||||
onSaved: (String? value) {
|
||||
print('Value for field $index saved as "$value"');
|
||||
debugPrint('Value for field $index saved as "$value"');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
@ -92,13 +92,13 @@ class MyAction extends Action<MyIntent> {
|
|||
@override
|
||||
void addActionListener(ActionListenerCallback listener) {
|
||||
super.addActionListener(listener);
|
||||
print('Action Listener was added');
|
||||
debugPrint('Action Listener was added');
|
||||
}
|
||||
|
||||
@override
|
||||
void removeActionListener(ActionListenerCallback listener) {
|
||||
super.removeActionListener(listener);
|
||||
print('Action Listener was removed');
|
||||
debugPrint('Action Listener was removed');
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -34,7 +34,7 @@ class Model {
|
|||
|
||||
int save() {
|
||||
if (isDirty.value) {
|
||||
print('Saved Data: ${data.value}');
|
||||
debugPrint('Saved Data: ${data.value}');
|
||||
isDirty.value = false;
|
||||
}
|
||||
return data.value;
|
||||
|
|
|
@ -57,21 +57,21 @@ class _ColorfulButtonState extends State<ColorfulButton> {
|
|||
|
||||
KeyEventResult _handleKeyPress(FocusNode node, RawKeyEvent event) {
|
||||
if (event is RawKeyDownEvent) {
|
||||
print('Focus node ${node.debugLabel} got key event: ${event.logicalKey}');
|
||||
debugPrint('Focus node ${node.debugLabel} got key event: ${event.logicalKey}');
|
||||
if (event.logicalKey == LogicalKeyboardKey.keyR) {
|
||||
print('Changing color to red.');
|
||||
debugPrint('Changing color to red.');
|
||||
setState(() {
|
||||
_color = Colors.red;
|
||||
});
|
||||
return KeyEventResult.handled;
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.keyG) {
|
||||
print('Changing color to green.');
|
||||
debugPrint('Changing color to green.');
|
||||
setState(() {
|
||||
_color = Colors.green;
|
||||
});
|
||||
return KeyEventResult.handled;
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.keyB) {
|
||||
print('Changing color to blue.');
|
||||
debugPrint('Changing color to blue.');
|
||||
setState(() {
|
||||
_color = Colors.blue;
|
||||
});
|
||||
|
|
|
@ -38,21 +38,21 @@ class _MyStatefulWidgetState extends State<MyStatefulWidget> {
|
|||
|
||||
KeyEventResult _handleKeyPress(FocusNode node, RawKeyEvent event) {
|
||||
if (event is RawKeyDownEvent) {
|
||||
print('Focus node ${node.debugLabel} got key event: ${event.logicalKey}');
|
||||
debugPrint('Focus node ${node.debugLabel} got key event: ${event.logicalKey}');
|
||||
if (event.logicalKey == LogicalKeyboardKey.keyR) {
|
||||
print('Changing color to red.');
|
||||
debugPrint('Changing color to red.');
|
||||
setState(() {
|
||||
_color = Colors.red;
|
||||
});
|
||||
return KeyEventResult.handled;
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.keyG) {
|
||||
print('Changing color to green.');
|
||||
debugPrint('Changing color to green.');
|
||||
setState(() {
|
||||
_color = Colors.green;
|
||||
});
|
||||
return KeyEventResult.handled;
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.keyB) {
|
||||
print('Changing color to blue.');
|
||||
debugPrint('Changing color to blue.');
|
||||
setState(() {
|
||||
_color = Colors.blue;
|
||||
});
|
||||
|
|
|
@ -115,7 +115,7 @@ class _MyStatefulWidgetState extends State<MyStatefulWidget> {
|
|||
// This button would be not visible, but still focusable from
|
||||
// the foreground pane without the FocusScope.
|
||||
ElevatedButton(
|
||||
onPressed: () => print('You pressed the other button!'),
|
||||
onPressed: () => debugPrint('You pressed the other button!'),
|
||||
child: const Text('ANOTHER BUTTON TO FOCUS'),
|
||||
),
|
||||
DefaultTextStyle(
|
||||
|
|
|
@ -68,7 +68,7 @@ class _OrderedButtonState<T> extends State<OrderedButton<T>> {
|
|||
|
||||
void _handleOnPressed() {
|
||||
focusNode.requestFocus();
|
||||
print('Button ${widget.name} pressed.');
|
||||
debugPrint('Button ${widget.name} pressed.');
|
||||
debugDumpFocusTree();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class DemoButton extends StatelessWidget {
|
|||
final double order;
|
||||
|
||||
void _handleOnPressed() {
|
||||
print('Button $name pressed.');
|
||||
debugPrint('Button $name pressed.');
|
||||
debugDumpFocusTree();
|
||||
}
|
||||
|
||||
|
|
|
@ -122,10 +122,10 @@ class _IVBuilderExampleState extends State<_IVBuilderExample> {
|
|||
cellWidth: _cellWidth,
|
||||
builder: (BuildContext context, int row, int column) {
|
||||
if (!_isCellVisible(row, column, viewport)) {
|
||||
print('removing cell ($row, $column)');
|
||||
debugPrint('removing cell ($row, $column)');
|
||||
return Container(height: _cellHeight);
|
||||
}
|
||||
print('building cell ($row, $column)');
|
||||
debugPrint('building cell ($row, $column)');
|
||||
return Container(
|
||||
height: _cellHeight,
|
||||
color: row % 2 + column % 2 == 1
|
||||
|
|
|
@ -45,9 +45,9 @@ class MyStatelessWidget extends StatelessWidget {
|
|||
body: NotificationListener<ScrollNotification>(
|
||||
onNotification: (ScrollNotification scrollNotification) {
|
||||
if (scrollNotification is ScrollStartNotification) {
|
||||
print('Scrolling has started');
|
||||
debugPrint('Scrolling has started');
|
||||
} else if (scrollNotification is ScrollEndNotification) {
|
||||
print('Scrolling has ended');
|
||||
debugPrint('Scrolling has ended');
|
||||
}
|
||||
// Return true to cancel the notification bubbling.
|
||||
return true;
|
||||
|
|
|
@ -98,7 +98,7 @@ Future<void> main() async {
|
|||
final HttpServer httpServer =
|
||||
await HttpServer.bindSecure('localhost', 0, serverContext);
|
||||
final int port = httpServer.port;
|
||||
print('Listening on port $port.');
|
||||
debugPrint('Listening on port $port.');
|
||||
|
||||
// Initializes bindings before using any platform channels.
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
@ -193,7 +193,7 @@ class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
|
|||
).toList();
|
||||
final DateTime started = DateTime.now();
|
||||
Future.wait(futures).then((_) {
|
||||
print(
|
||||
debugPrint(
|
||||
'===image_list=== all loaded in ${DateTime.now().difference(started).inMilliseconds}ms.',
|
||||
);
|
||||
});
|
||||
|
|
|
@ -47,8 +47,8 @@ class Calculator {
|
|||
final int n = result.length;
|
||||
onResultListener('Decoded $n results');
|
||||
} catch (e, stack) {
|
||||
print('Invalid JSON file: $e');
|
||||
print(stack);
|
||||
debugPrint('Invalid JSON file: $e');
|
||||
debugPrint('$stack');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// This file implements debugPrint in terms of print, so avoiding
|
||||
// calling "print" is sort of a non-starter here...
|
||||
// ignore_for_file: avoid_print
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ class FakeTextChannel implements MethodChannel {
|
|||
|
||||
void validateOutgoingMethodCalls(List<MethodCall> calls) {
|
||||
expect(outgoingCalls.length, calls.length);
|
||||
final StringBuffer output = StringBuffer();
|
||||
bool hasError = false;
|
||||
for (int i = 0; i < calls.length; i++) {
|
||||
final ByteData outgoingData = codec.encodeMethodCall(outgoingCalls[i]);
|
||||
|
@ -50,7 +51,7 @@ class FakeTextChannel implements MethodChannel {
|
|||
final String expectedString = utf8.decode(expectedData.buffer.asUint8List());
|
||||
|
||||
if (outgoingString != expectedString) {
|
||||
print(
|
||||
output.writeln(
|
||||
'Index $i did not match:\n'
|
||||
' actual: $outgoingString\n'
|
||||
' expected: $expectedString',
|
||||
|
@ -59,7 +60,7 @@ class FakeTextChannel implements MethodChannel {
|
|||
}
|
||||
}
|
||||
if (hasError) {
|
||||
fail('Calls did not match.');
|
||||
fail('Calls did not match:\n$output');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ void checkTree(WidgetTester tester, List<BoxDecoration> expectedDecorations) {
|
|||
}
|
||||
expect(child, isNull);
|
||||
} catch (e) {
|
||||
print(renderObject.toStringDeep());
|
||||
debugPrint(renderObject.toStringDeep());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ void checkTree(WidgetTester tester, List<TestParentData> expectedParentData) {
|
|||
}
|
||||
expect(child, isNull);
|
||||
} catch (e) {
|
||||
print(renderObject.toStringDeep());
|
||||
debugPrint(renderObject.toStringDeep());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
5
packages/flutter/test_private/analysis_options.yaml
Normal file
5
packages/flutter/test_private/analysis_options.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
include: ../analysis_options.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
avoid_print: false # This is a CLI tool, so printing to the console is fine.
|
|
@ -50,7 +50,7 @@ class VMServiceFlutterDriver extends FlutterDriver {
|
|||
// TODO(awdavies): Use something other than print. On fuchsia
|
||||
// `stderr`/`stdout` appear to have issues working correctly.
|
||||
driverLog = (String source, String message) {
|
||||
print('$source: $message');
|
||||
print('$source: $message'); // ignore: avoid_print
|
||||
};
|
||||
fuchsiaModuleTarget ??= Platform.environment['FUCHSIA_MODULE_TARGET'];
|
||||
if (fuchsiaModuleTarget == null) {
|
||||
|
|
|
@ -222,11 +222,7 @@ class WebFlutterDriver extends FlutterDriver {
|
|||
class FlutterWebConnection {
|
||||
/// Creates a FlutterWebConnection with WebDriver
|
||||
/// and whether the WebDriver supports timeline action.
|
||||
FlutterWebConnection(this._driver, this.supportsTimelineAction) {
|
||||
_driver.logs.get(async_io.LogType.browser).listen((async_io.LogEntry entry) {
|
||||
print('[${entry.level}]: ${entry.message}');
|
||||
});
|
||||
}
|
||||
FlutterWebConnection(this._driver, this.supportsTimelineAction);
|
||||
|
||||
final async_io.WebDriver _driver;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ void tryToDelete(Directory directory) {
|
|||
try {
|
||||
directory.deleteSync(recursive: true);
|
||||
} on FileSystemException catch (error) {
|
||||
print('Failed to delete ${directory.path}: $error');
|
||||
driverLog('test', 'Failed to delete ${directory.path}: $error');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -385,9 +385,7 @@ class FlutterSkippingFileComparator extends FlutterGoldenFileComparator {
|
|||
|
||||
@override
|
||||
Future<bool> compare(Uint8List imageBytes, Uri golden) async {
|
||||
print(
|
||||
'Skipping "$golden" test : $reason'
|
||||
);
|
||||
markTestSkipped('Skipping "$golden" test: $reason');
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -502,8 +500,9 @@ class FlutterLocalFileComparator extends FlutterGoldenFileComparator with LocalC
|
|||
testExpectation = await skiaClient.getExpectationForTest(testName);
|
||||
|
||||
if (testExpectation == null || testExpectation.isEmpty) {
|
||||
// There is no baseline for this test
|
||||
print('No expectations provided by Skia Gold for test: $golden. '
|
||||
// There is no baseline for this test.
|
||||
markTestSkipped(
|
||||
'No expectations provided by Skia Gold for test: $golden. '
|
||||
'This may be a new test. If this is an unexpected result, check '
|
||||
'https://flutter-gold.skia.org.\n'
|
||||
'Validate image output found at $basedir'
|
||||
|
|
|
@ -8,18 +8,19 @@
|
|||
// Fails with "flutter test --test-randomize-ordering-seed=123"
|
||||
@Tags(<String>['no-shuffle'])
|
||||
|
||||
// See also dev/automated_tests/flutter_test/flutter_gold_test.dart
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:core';
|
||||
import 'dart:io' hide Directory;
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui' show hashValues, hashList;
|
||||
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_goldens/flutter_goldens.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
|
@ -41,17 +42,6 @@ const List<int> _kFailPngBytes =
|
|||
120, 1, 99, 249, 207, 240, 255, 63, 0, 7, 18, 3, 2, 164, 147, 160, 197, 0,
|
||||
0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130];
|
||||
|
||||
Future<void> testWithOutput(String name, Future<void> Function() body, String expectedOutput) async {
|
||||
test(name, () async {
|
||||
final StringBuffer output = StringBuffer();
|
||||
void _recordPrint(Zone self, ZoneDelegate parent, Zone zone, String line) {
|
||||
output.write(line);
|
||||
}
|
||||
await runZoned<Future<void>>(body, zoneSpecification: ZoneSpecification(print: _recordPrint));
|
||||
expect(output.toString(), expectedOutput);
|
||||
});
|
||||
}
|
||||
|
||||
void main() {
|
||||
late MemoryFileSystem fs;
|
||||
late FakePlatform platform;
|
||||
|
@ -569,7 +559,6 @@ void main() {
|
|||
|
||||
const String hash = '55109a4bed52acc780530f7a9aeff6c0';
|
||||
fakeSkiaClient.expectationForTestValues['flutter.golden_test.1'] = hash;
|
||||
fakeSkiaClient.expectationForTestValues['flutter.new_golden_test.1'] = '';
|
||||
fakeSkiaClient.imageBytesValues[hash] =_kTestPngBytes;
|
||||
fakeSkiaClient.cleanTestNameValues['library.flutter.golden_test.1.png'] = 'flutter.golden_test.1';
|
||||
});
|
||||
|
@ -584,32 +573,6 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
testWithOutput('passes non-existent baseline for new test, null expectation', () async {
|
||||
expect(
|
||||
await comparator.compare(
|
||||
Uint8List.fromList(_kFailPngBytes),
|
||||
Uri.parse('flutter.new_golden_test.1'),
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
}, 'No expectations provided by Skia Gold for test: library.flutter.new_golden_test.1. '
|
||||
'This may be a new test. If this is an unexpected result, check https://flutter-gold.skia.org.\n'
|
||||
'Validate image output found at flutter/test/library/'
|
||||
);
|
||||
|
||||
testWithOutput('passes non-existent baseline for new test, empty expectation', () async {
|
||||
expect(
|
||||
await comparator.compare(
|
||||
Uint8List.fromList(_kFailPngBytes),
|
||||
Uri.parse('flutter.new_golden_test.2'),
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
}, 'No expectations provided by Skia Gold for test: library.flutter.new_golden_test.2. '
|
||||
'This may be a new test. If this is an unexpected result, check https://flutter-gold.skia.org.\n'
|
||||
'Validate image output found at flutter/test/library/'
|
||||
);
|
||||
|
||||
test('compare properly awaits validation & output before failing.', () async {
|
||||
final Completer<bool> completer = Completer<bool>();
|
||||
final Future<bool> result = comparator.compare(
|
||||
|
@ -713,14 +676,14 @@ class FakeProcessManager extends Fake implements ProcessManager {
|
|||
workingDirectories.add(workingDirectory);
|
||||
final ProcessResult? result = processResults[RunInvocation(command.cast<String>(), workingDirectory)];
|
||||
if (result == null && fallbackProcessResult == null) {
|
||||
// Throwing here might gobble up the exception message if a test fails.
|
||||
print('ProcessManager.run was called with $command ($workingDirectory) unexpectedly - $processResults.');
|
||||
printOnFailure('ProcessManager.run was called with $command ($workingDirectory) unexpectedly - $processResults.');
|
||||
fail('See above.');
|
||||
}
|
||||
return result ?? fallbackProcessResult!;
|
||||
}
|
||||
}
|
||||
|
||||
// See also dev/automated_tests/flutter_test/flutter_gold_test.dart
|
||||
class FakeSkiaGoldClient extends Fake implements SkiaGoldClient {
|
||||
Map<String, String> expectationForTestValues = <String, String>{};
|
||||
Object? getExpectationForTestThrowable;
|
||||
|
|
|
@ -183,9 +183,10 @@ class SkiaGoldClient {
|
|||
if (result.exitCode != 0) {
|
||||
// We do not want to throw for non-zero exit codes here, as an intentional
|
||||
// change or new golden file test expect non-zero exit codes. Logging here
|
||||
// is meant to inform when an unexpected result occurs.
|
||||
print('goldctl imgtest add stdout: ${result.stdout}');
|
||||
print('goldctl imgtest add stderr: ${result.stderr}');
|
||||
// is meant to help debugging in CI when an unexpected result occurs.
|
||||
// See also: https://github.com/flutter/flutter/issues/91285
|
||||
print('goldctl imgtest add stdout: ${result.stdout}'); // ignore: avoid_print
|
||||
print('goldctl imgtest add stderr: ${result.stderr}'); // ignore: avoid_print
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -301,7 +302,10 @@ class SkiaGoldClient {
|
|||
throw const FormatException('Skia gold expectations do not match expected format.');
|
||||
expectation = jsonResponse['digest'] as String?;
|
||||
} on FormatException catch (error) {
|
||||
print(
|
||||
// Ideally we'd use something like package:test's printOnError, but best reliabilty
|
||||
// in getting logs on CI for now we're just using print.
|
||||
// See also: https://github.com/flutter/flutter/issues/91285
|
||||
print( // ignore: avoid_print
|
||||
'Formatting error detected requesting expectations from Flutter Gold.\n'
|
||||
'error: $error\n'
|
||||
'url: $requestForExpectations\n'
|
||||
|
|
|
@ -6,6 +6,8 @@ import 'dart:typed_data';
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test_api/test_api.dart'; // ignore: deprecated_member_use
|
||||
|
||||
import '_goldens_io.dart' if (dart.library.html) '_goldens_web.dart' as _goldens;
|
||||
|
||||
/// Compares image pixels against a golden image file.
|
||||
|
@ -268,7 +270,7 @@ class TrivialComparator implements GoldenFileComparator {
|
|||
|
||||
@override
|
||||
Future<bool> compare(Uint8List imageBytes, Uri golden) {
|
||||
print('Golden file comparison requested for "$golden"; skipping...');
|
||||
markTestSkipped('Golden file comparison requested for "$golden"; skipping...');
|
||||
return Future<bool>.value(true);
|
||||
}
|
||||
|
||||
|
@ -288,7 +290,7 @@ class _TrivialWebGoldenComparator implements WebGoldenComparator {
|
|||
|
||||
@override
|
||||
Future<bool> compare(double width, double height, Uri golden) {
|
||||
print('Golden comparison requested for "$golden"; skipping...');
|
||||
markTestSkipped('Golden comparison requested for "$golden"; skipping...');
|
||||
return Future<bool>.value(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ Future<void> _runLiveTest(Suite suiteConfig, LiveTest liveTest, _Reporter report
|
|||
Future<void> _runSkippedTest(Suite suiteConfig, Test test, List<Group> parents, _Reporter reporter) async {
|
||||
final LocalTest skipped = LocalTest(test.name, test.metadata, () { }, trace: test.trace);
|
||||
if (skipped.metadata.skipReason != null) {
|
||||
print('Skip: ${skipped.metadata.skipReason}');
|
||||
reporter.log('Skip: ${skipped.metadata.skipReason}');
|
||||
}
|
||||
final LiveTest liveTest = skipped.load(suiteConfig);
|
||||
reporter._onTestStarted(liveTest);
|
||||
|
@ -334,7 +334,7 @@ class _Reporter {
|
|||
if (message.type == MessageType.skip) {
|
||||
text = ' $_yellow$text$_noColor';
|
||||
}
|
||||
print(text);
|
||||
log(text);
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -351,8 +351,8 @@ class _Reporter {
|
|||
return;
|
||||
}
|
||||
_progressLine(_description(liveTest), suffix: ' $_bold$_red[E]$_noColor');
|
||||
print(_indent(error.toString()));
|
||||
print(_indent('$stackTrace'));
|
||||
log(_indent(error.toString()));
|
||||
log(_indent('$stackTrace'));
|
||||
}
|
||||
|
||||
/// A callback called when the engine is finished running tests.
|
||||
|
@ -421,7 +421,7 @@ class _Reporter {
|
|||
buffer.write(message);
|
||||
buffer.write(_noColor);
|
||||
|
||||
print(buffer.toString());
|
||||
log(buffer.toString());
|
||||
}
|
||||
|
||||
/// Returns a representation of [duration] as `MM:SS`.
|
||||
|
@ -442,6 +442,13 @@ class _Reporter {
|
|||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// Print the message to the console.
|
||||
void log(String message) {
|
||||
// We centralize all the prints in this file through this one method so that
|
||||
// in principle we can reroute the output easily should we need to.
|
||||
print(message); // ignore: avoid_print
|
||||
}
|
||||
}
|
||||
|
||||
String _indent(String string, { int? size, String? first }) {
|
||||
|
|
|
@ -416,7 +416,7 @@ Future<void> benchmarkWidgets(
|
|||
assert(() {
|
||||
if (mayRunWithAsserts)
|
||||
return true;
|
||||
print(kDebugWarning);
|
||||
debugPrint(kDebugWarning);
|
||||
return true;
|
||||
}());
|
||||
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
# Use the analysis options settings from the top level of the repo (not
|
||||
# the ones from above, which include the `public_member_api_docs` rule).
|
||||
|
||||
include: ../../analysis_options.yaml
|
||||
include: ../analysis_options.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
avoid_catches_without_on_clauses: true
|
||||
curly_braces_in_flow_control_structures: true
|
||||
library_private_types_in_public_api: false # Tool does not have any public API
|
||||
library_private_types_in_public_api: false # Tool does not have any public API.
|
||||
no_runtimeType_toString: false # We use runtimeType for debugging in the tool.
|
||||
prefer_relative_imports: true
|
||||
public_member_api_docs: false # Tool does not have any public API.
|
||||
unawaited_futures: true
|
||||
|
|
5
packages/flutter_tools/bin/analysis_options.yaml
Normal file
5
packages/flutter_tools/bin/analysis_options.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
include: ../analysis_options.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
avoid_print: false # These are CLI tools which print as a matter of course.
|
|
@ -25,6 +25,12 @@
|
|||
/// about any additional exports that you add to this file, as doing so will
|
||||
/// increase the API surface that we have to test in Flutter tools, and the APIs
|
||||
/// in `dart:io` can sometimes be hard to use in tests.
|
||||
|
||||
// We allow `print()` in this file as a fallback for writing to the terminal via
|
||||
// regular stdout/stderr/stdio paths. Everything else in the flutter_tools
|
||||
// library should route terminal I/O through the [Stdio] class defined below.
|
||||
// ignore_for_file: avoid_print
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io' as io
|
||||
show
|
||||
|
|
|
@ -247,6 +247,7 @@ class Cache {
|
|||
}
|
||||
} on Exception catch (error) {
|
||||
// There is currently no logger attached since this is computed at startup.
|
||||
// ignore: avoid_print
|
||||
print(userMessages.runnerNoRoot('$error'));
|
||||
}
|
||||
return normalize('.');
|
||||
|
|
|
@ -307,6 +307,7 @@ class DaemonDomain extends Domain {
|
|||
if (message.level == 'status') {
|
||||
// We use `print()` here instead of `stdout.writeln()` in order to
|
||||
// capture the print output for testing.
|
||||
// ignore: avoid_print
|
||||
print(message.message);
|
||||
} else if (message.level == 'error') {
|
||||
globals.stdio.stderrWrite('${message.message}\n');
|
||||
|
|
|
@ -96,7 +96,7 @@ class MacOSDevice extends DesktopDevice {
|
|||
'open', package.applicationBundle(buildMode),
|
||||
]).then((ProcessResult result) {
|
||||
if (result.exitCode != 0) {
|
||||
print('Failed to foreground app; open returned ${result.exitCode}');
|
||||
_logger.printError('Failed to foreground app; open returned ${result.exitCode}');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2668,10 +2668,9 @@ Future<void> _ensureFlutterToolsSnapshot() async {
|
|||
'../../bin/cache/dart-sdk/bin/dart',
|
||||
snapshotArgs,
|
||||
);
|
||||
if (snapshotResult.exitCode != 0) {
|
||||
print(snapshotResult.stdout);
|
||||
print(snapshotResult.stderr);
|
||||
}
|
||||
printOnFailure('Results of generating snapshot:');
|
||||
printOnFailure(snapshotResult.stdout.toString());
|
||||
printOnFailure(snapshotResult.stderr.toString());
|
||||
expect(snapshotResult.exitCode, 0);
|
||||
}
|
||||
|
||||
|
@ -2713,10 +2712,9 @@ Future<void> _analyzeProject(String workingDir, { List<String> expectedFailures
|
|||
workingDirectory: workingDir,
|
||||
);
|
||||
if (expectedFailures.isEmpty) {
|
||||
if (exec.exitCode != 0) {
|
||||
print(exec.stdout);
|
||||
print(exec.stderr);
|
||||
}
|
||||
printOnFailure('Results of running analyzer:');
|
||||
printOnFailure(exec.stdout.toString());
|
||||
printOnFailure(exec.stderr.toString());
|
||||
expect(exec.exitCode, 0);
|
||||
return;
|
||||
}
|
||||
|
@ -2770,10 +2768,9 @@ Future<void> _runFlutterTest(Directory workingDir, { String target }) async {
|
|||
args,
|
||||
workingDirectory: workingDir.path,
|
||||
);
|
||||
if (exec.exitCode != 0) {
|
||||
print(exec.stdout);
|
||||
print(exec.stderr);
|
||||
}
|
||||
printOnFailure('Output of running flutter test:');
|
||||
printOnFailure(exec.stdout.toString());
|
||||
printOnFailure(exec.stderr.toString());
|
||||
expect(exec.exitCode, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,6 @@ void main() {
|
|||
expect(logContents, contains('String: an exception % --'));
|
||||
expect(logContents, contains('CrashingFlutterCommand.runCommand'));
|
||||
expect(logContents, contains('[✓] Flutter'));
|
||||
print(globals.crashReporter.runtimeType);
|
||||
|
||||
final CrashDetails sentDetails = (globals.crashReporter as WaitingCrashReporter)._details;
|
||||
expect(sentDetails.command, 'flutter crash');
|
||||
|
|
|
@ -28,8 +28,9 @@ void main() {
|
|||
'--no-color',
|
||||
...arguments,
|
||||
], workingDirectory: projectPath);
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
printOnFailure('Output of flutter ${arguments.join(" ")}');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
expect(result.exitCode, exitCode, reason: 'Expected to exit with non-zero exit code.');
|
||||
assertContains(result.stdout.toString(), statusTextContains);
|
||||
assertContains(result.stdout.toString(), errorTextContains);
|
||||
|
|
|
@ -31,8 +31,9 @@ void main() {
|
|||
'--target-platform=android-arm64'
|
||||
], workingDirectory: workingDirectory);
|
||||
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
printOnFailure('Output of flutter build apk:');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
expect(result.stdout.toString(), contains('app-release.apk (total compressed)'));
|
||||
|
||||
final String line = result.stdout.toString()
|
||||
|
@ -67,8 +68,9 @@ void main() {
|
|||
'--no-codesign',
|
||||
], workingDirectory: workingDirectory);
|
||||
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
printOnFailure('Output of flutter build ios:');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
expect(result.stdout.toString(), contains('Dart AOT symbols accounted decompressed size'));
|
||||
|
||||
final String line = result.stdout.toString()
|
||||
|
@ -102,8 +104,9 @@ void main() {
|
|||
'--enable-macos-desktop',
|
||||
], workingDirectory: workingDirectory);
|
||||
|
||||
print(configResult.stdout);
|
||||
print(configResult.stderr);
|
||||
printOnFailure('Output of flutter config:');
|
||||
printOnFailure(configResult.stdout.toString());
|
||||
printOnFailure(configResult.stderr.toString());
|
||||
|
||||
final ProcessResult result = await processManager.run(<String>[
|
||||
flutterBin,
|
||||
|
@ -113,8 +116,9 @@ void main() {
|
|||
'--code-size-directory=${codeSizeDir.path}',
|
||||
], workingDirectory: workingDirectory);
|
||||
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
printOnFailure('Output of flutter build macos:');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
expect(result.stdout.toString(), contains('Dart AOT symbols accounted decompressed size'));
|
||||
|
||||
final String line = result.stdout.toString()
|
||||
|
@ -147,8 +151,9 @@ void main() {
|
|||
'--debug',
|
||||
], workingDirectory: fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world'));
|
||||
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
printOnFailure('Output of flutter build apk:');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
expect(result.stderr.toString(), contains('"--analyze-size" can only be used on release builds'));
|
||||
|
||||
expect(result.exitCode, 1);
|
||||
|
|
|
@ -34,7 +34,7 @@ void main() {
|
|||
final Completer<void> sawBackgroundMessage = Completer<void>.sync();
|
||||
final Completer<void> sawNewBackgroundMessage = Completer<void>.sync();
|
||||
final StreamSubscription<String> subscription = flutter.stdout.listen((String line) {
|
||||
print('[LOG]:"$line"');
|
||||
printOnFailure('[LOG]:"$line"');
|
||||
if (line.contains('Main thread') && !sawForegroundMessage.isCompleted) {
|
||||
sawForegroundMessage.complete();
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ void main() {
|
|||
final Completer<void> sawBackgroundMessage = Completer<void>.sync();
|
||||
final Completer<void> sawNewBackgroundMessage = Completer<void>.sync();
|
||||
final StreamSubscription<String> subscription = flutter.stdout.listen((String line) {
|
||||
print('[LOG]:"$line"');
|
||||
printOnFailure('[LOG]:"$line"');
|
||||
if (line.contains('Isolate thread') && !sawBackgroundMessage.isCompleted) {
|
||||
sawBackgroundMessage.complete();
|
||||
}
|
||||
|
|
|
@ -33,8 +33,9 @@ void main() {
|
|||
'--no-codesign',
|
||||
], workingDirectory: workingDirectory);
|
||||
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
printOnFailure('Output of flutter build ios:');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
|
||||
expect(result.exitCode, 0);
|
||||
|
||||
|
|
|
@ -64,11 +64,7 @@ Future<void> main(List<String> args) async {
|
|||
await cache.lock();
|
||||
process.kill(io.ProcessSignal.sigkill);
|
||||
} finally {
|
||||
try {
|
||||
tempDir.deleteSync(recursive: true);
|
||||
} on FileSystemException {
|
||||
// Ignore filesystem exceptions when trying to delete tempdir.
|
||||
}
|
||||
tryToDelete(tempDir);
|
||||
Cache.flutterRoot = oldRoot;
|
||||
}
|
||||
expect(logger.statusText, isEmpty);
|
||||
|
|
|
@ -26,8 +26,10 @@ void main() {
|
|||
'--target-platform', 'android-arm',
|
||||
'--verbose',
|
||||
], workingDirectory: woringDirectory);
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
|
||||
printOnFailure('Output of flutter build apk:');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
|
||||
expect(result.exitCode, 0);
|
||||
|
||||
|
|
|
@ -38,11 +38,7 @@ void main() {
|
|||
});
|
||||
|
||||
tearDown(() {
|
||||
try {
|
||||
parentDirectory.deleteSync(recursive: true);
|
||||
} on FileSystemException {
|
||||
print('Failed to delete test directory');
|
||||
}
|
||||
tryToDelete(parentDirectory);
|
||||
});
|
||||
|
||||
testWithoutContext('Can upgrade and downgrade a Flutter checkout', () async {
|
||||
|
@ -56,7 +52,7 @@ void main() {
|
|||
'git', 'config', '--system', 'core.longpaths', 'true',
|
||||
]);
|
||||
|
||||
print('Step 1 - clone the $_kBranch of flutter into the test directory');
|
||||
printOnFailure('Step 1 - clone the $_kBranch of flutter into the test directory');
|
||||
exitCode = await processUtils.stream(<String>[
|
||||
'git',
|
||||
'clone',
|
||||
|
@ -64,7 +60,7 @@ void main() {
|
|||
], workingDirectory: parentDirectory.path, trace: true);
|
||||
expect(exitCode, 0);
|
||||
|
||||
print('Step 2 - switch to the $_kBranch');
|
||||
printOnFailure('Step 2 - switch to the $_kBranch');
|
||||
exitCode = await processUtils.stream(<String>[
|
||||
'git',
|
||||
'checkout',
|
||||
|
@ -75,7 +71,7 @@ void main() {
|
|||
], workingDirectory: testDirectory.path, trace: true);
|
||||
expect(exitCode, 0);
|
||||
|
||||
print('Step 3 - revert back to $_kInitialVersion');
|
||||
printOnFailure('Step 3 - revert back to $_kInitialVersion');
|
||||
exitCode = await processUtils.stream(<String>[
|
||||
'git',
|
||||
'reset',
|
||||
|
@ -84,7 +80,7 @@ void main() {
|
|||
], workingDirectory: testDirectory.path, trace: true);
|
||||
expect(exitCode, 0);
|
||||
|
||||
print('Step 4 - upgrade to the newest $_kBranch');
|
||||
printOnFailure('Step 4 - upgrade to the newest $_kBranch');
|
||||
// This should update the persistent tool state with the sha for HEAD
|
||||
exitCode = await processUtils.stream(<String>[
|
||||
flutterBin,
|
||||
|
@ -94,7 +90,7 @@ void main() {
|
|||
], workingDirectory: testDirectory.path, trace: true);
|
||||
expect(exitCode, 0);
|
||||
|
||||
print('Step 5 - verify that the version is different');
|
||||
printOnFailure('Step 5 - verify that the version is different');
|
||||
final RunResult versionResult = await processUtils.run(<String>[
|
||||
'git',
|
||||
'describe',
|
||||
|
@ -104,10 +100,9 @@ void main() {
|
|||
'--tags',
|
||||
], workingDirectory: testDirectory.path);
|
||||
expect(versionResult.stdout, isNot(contains(_kInitialVersion)));
|
||||
print('current version is ${versionResult.stdout.trim()}\ninitial was $_kInitialVersion');
|
||||
printOnFailure('current version is ${versionResult.stdout.trim()}\ninitial was $_kInitialVersion');
|
||||
|
||||
print('Step 6 - downgrade back to the initial version');
|
||||
// Step 6. Downgrade back to initial version.
|
||||
printOnFailure('Step 6 - downgrade back to the initial version');
|
||||
exitCode = await processUtils.stream(<String>[
|
||||
flutterBin,
|
||||
'downgrade',
|
||||
|
@ -116,8 +111,7 @@ void main() {
|
|||
], workingDirectory: testDirectory.path, trace: true);
|
||||
expect(exitCode, 0);
|
||||
|
||||
print('Step 7 - verify downgraded version matches original version');
|
||||
// Step 7. Verify downgraded version matches original version.
|
||||
printOnFailure('Step 7 - verify downgraded version matches original version');
|
||||
final RunResult oldVersionResult = await processUtils.run(<String>[
|
||||
'git',
|
||||
'describe',
|
||||
|
@ -127,6 +121,6 @@ void main() {
|
|||
'--tags',
|
||||
], workingDirectory: testDirectory.path);
|
||||
expect(oldVersionResult.stdout, contains(_kInitialVersion));
|
||||
print('current version is ${oldVersionResult.stdout.trim()}\ninitial was $_kInitialVersion');
|
||||
printOnFailure('current version is ${oldVersionResult.stdout.trim()}\ninitial was $_kInitialVersion');
|
||||
});
|
||||
}
|
||||
|
|
|
@ -36,8 +36,9 @@ void main() {
|
|||
fileSystem.path.join(tempDir.path, 'main.dart'),
|
||||
]);
|
||||
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
printOnFailure('Output of dart main.dart:');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
expect(result.exitCode, 0);
|
||||
});
|
||||
|
||||
|
@ -55,8 +56,9 @@ void main() {
|
|||
fileSystem.path.join(tempDir.path, 'main.dart'),
|
||||
]);
|
||||
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
printOnFailure('Output of dart main.dart:');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
expect(result.exitCode, 1);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ String unsafeString = null;
|
|||
|
||||
for (final String targetPlatform in targetPlatforms) {
|
||||
testWithoutContext('flutter build $targetPlatform --no-sound-null-safety', () {
|
||||
print(tempDir);
|
||||
final ProcessResult result = processManager.runSync(<String>[
|
||||
flutterBin,
|
||||
...getLocalEngineArguments(),
|
||||
|
|
|
@ -138,10 +138,9 @@ Future<void> _ensureFlutterToolsSnapshot() async {
|
|||
'../../bin/cache/dart-sdk/bin/dart',
|
||||
snapshotArgs,
|
||||
);
|
||||
if (snapshotResult.exitCode != 0) {
|
||||
print(snapshotResult.stdout);
|
||||
print(snapshotResult.stderr);
|
||||
}
|
||||
printOnFailure('Output of dart ${snapshotArgs.join(" ")}:');
|
||||
printOnFailure(snapshotResult.stdout.toString());
|
||||
printOnFailure(snapshotResult.stderr.toString());
|
||||
expect(snapshotResult.exitCode, 0);
|
||||
}
|
||||
|
||||
|
@ -237,9 +236,8 @@ Future<void> _analyzeProject(Directory workingDir) async {
|
|||
args,
|
||||
workingDirectory: workingDir.path,
|
||||
);
|
||||
if (exec.exitCode != 0) {
|
||||
print(exec.stdout);
|
||||
print(exec.stderr);
|
||||
}
|
||||
printOnFailure('Output of flutter analyze:');
|
||||
printOnFailure(exec.stdout.toString());
|
||||
printOnFailure(exec.stderr.toString());
|
||||
expect(exec.exitCode, 0);
|
||||
}
|
||||
|
|
|
@ -108,8 +108,14 @@ void main() {
|
|||
await flutter.resume(); // we start paused so we can set up our TICK 1 listener before the app starts
|
||||
unawaited(sawTick1.future.timeout(
|
||||
const Duration(seconds: 5),
|
||||
onTimeout: () { print('The test app is taking longer than expected to print its synchronization line...'); },
|
||||
onTimeout: () {
|
||||
// This print is useful for people debugging this test. Normally we would avoid printing in
|
||||
// a test but this is an exception because it's useful ambient information.
|
||||
// ignore: avoid_print
|
||||
print('The test app is taking longer than expected to print its synchronization line...');
|
||||
},
|
||||
));
|
||||
printOnFailure('waiting for synchronization line...');
|
||||
await sawTick1.future; // after this, app is in steady state
|
||||
await flutter.addBreakpoint(
|
||||
project.scheduledBreakpointUri,
|
||||
|
@ -126,19 +132,19 @@ void main() {
|
|||
);
|
||||
bool reloaded = false;
|
||||
final Future<void> reloadFuture = flutter.hotReload().then((void value) { reloaded = true; });
|
||||
print('waiting for pause...');
|
||||
printOnFailure('waiting for pause...');
|
||||
isolate = await flutter.waitForPause();
|
||||
expect(isolate.pauseEvent.kind, equals(EventKind.kPauseBreakpoint));
|
||||
print('waiting for debugger message...');
|
||||
printOnFailure('waiting for debugger message...');
|
||||
await sawDebuggerPausedMessage.future;
|
||||
expect(reloaded, isFalse);
|
||||
print('waiting for resume...');
|
||||
printOnFailure('waiting for resume...');
|
||||
await flutter.resume();
|
||||
print('waiting for reload future...');
|
||||
printOnFailure('waiting for reload future...');
|
||||
await reloadFuture;
|
||||
expect(reloaded, isTrue);
|
||||
reloaded = false;
|
||||
print('subscription cancel...');
|
||||
printOnFailure('subscription cancel...');
|
||||
await subscription.cancel();
|
||||
});
|
||||
|
||||
|
@ -148,7 +154,7 @@ void main() {
|
|||
final Completer<void> sawDebuggerPausedMessage2 = Completer<void>();
|
||||
final StreamSubscription<String> subscription = flutter.stdout.listen(
|
||||
(String line) {
|
||||
print('[LOG]:"$line"');
|
||||
printOnFailure('[LOG]:"$line"');
|
||||
if (line.contains('(((TICK 1)))')) {
|
||||
expect(sawTick1.isCompleted, isFalse);
|
||||
sawTick1.complete();
|
||||
|
|
|
@ -47,7 +47,7 @@ void main() {
|
|||
onSecondLoad.complete();
|
||||
}
|
||||
});
|
||||
flutter.stdout.listen(print);
|
||||
flutter.stdout.listen(printOnFailure);
|
||||
await flutter.run();
|
||||
await onFirstLoad.future;
|
||||
|
||||
|
@ -74,7 +74,7 @@ void main() {
|
|||
onSecondLoad.complete();
|
||||
}
|
||||
});
|
||||
flutter.stdout.listen(print);
|
||||
flutter.stdout.listen(printOnFailure);
|
||||
await flutter.run();
|
||||
await onFirstLoad.future;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ void main() {
|
|||
'flutter',
|
||||
);
|
||||
|
||||
final ProcessResult createResult = processManager.runSync(<String>[
|
||||
processManager.runSync(<String>[
|
||||
flutterBin,
|
||||
...getLocalEngineArguments(),
|
||||
'create',
|
||||
|
@ -39,7 +39,6 @@ void main() {
|
|||
'objc',
|
||||
'hello',
|
||||
], workingDirectory: tempDir.path);
|
||||
print(createResult.stdout);
|
||||
|
||||
projectRoot = tempDir.childDirectory('hello').path;
|
||||
});
|
||||
|
@ -59,7 +58,7 @@ void main() {
|
|||
File outputAppFrameworkBinary;
|
||||
|
||||
setUpAll(() {
|
||||
final ProcessResult buildResult = processManager.runSync(<String>[
|
||||
processManager.runSync(<String>[
|
||||
flutterBin,
|
||||
...getLocalEngineArguments(),
|
||||
'build',
|
||||
|
@ -70,7 +69,6 @@ void main() {
|
|||
'--obfuscate',
|
||||
'--split-debug-info=foo debug info/',
|
||||
], workingDirectory: projectRoot);
|
||||
print(buildResult.stdout);
|
||||
|
||||
buildPath = fileSystem.directory(fileSystem.path.join(
|
||||
projectRoot,
|
||||
|
@ -125,7 +123,6 @@ void main() {
|
|||
infoPlistPath,
|
||||
],
|
||||
);
|
||||
print(bonjourServices.stdout);
|
||||
final bool bonjourServicesFound = (bonjourServices.stdout as String).contains('_dartobservatory._tcp');
|
||||
expect(bonjourServicesFound, buildMode == BuildMode.debug);
|
||||
|
||||
|
@ -140,7 +137,6 @@ void main() {
|
|||
infoPlistPath,
|
||||
],
|
||||
);
|
||||
print(localNetworkUsage.stdout);
|
||||
final bool localNetworkUsageFound = localNetworkUsage.exitCode == 0;
|
||||
expect(localNetworkUsageFound, buildMode == BuildMode.debug);
|
||||
});
|
||||
|
@ -155,7 +151,6 @@ void main() {
|
|||
'arm64',
|
||||
],
|
||||
);
|
||||
print(symbols.stdout);
|
||||
final bool aotSymbolsFound = (symbols.stdout as String).contains('_kDartVmSnapshot');
|
||||
expect(aotSymbolsFound, buildMode != BuildMode.debug);
|
||||
});
|
||||
|
@ -197,7 +192,9 @@ void main() {
|
|||
// Skip bitcode stripping since we just checked that above.
|
||||
},
|
||||
);
|
||||
print(xcodeBackendResult.stdout);
|
||||
printOnFailure('Output of xcode_backend.sh:');
|
||||
printOnFailure(xcodeBackendResult.stdout.toString());
|
||||
printOnFailure(xcodeBackendResult.stderr.toString());
|
||||
|
||||
expect(xcodeBackendResult.exitCode, 0);
|
||||
expect(outputFlutterFrameworkBinary.existsSync(), isTrue);
|
||||
|
@ -211,7 +208,6 @@ void main() {
|
|||
'hello',
|
||||
outputAppFrameworkBinary.path,
|
||||
]);
|
||||
print(grepResult.stdout);
|
||||
expect(grepResult.stdout, isNot(contains('matches')));
|
||||
});
|
||||
});
|
||||
|
@ -233,7 +229,6 @@ void main() {
|
|||
'FLUTTER_XCODE_ONLY_ACTIVE_ARCH': 'NO',
|
||||
},
|
||||
);
|
||||
print(buildSimulator.stdout);
|
||||
// This test case would fail if arm64 or x86_64 simulators could not build.
|
||||
expect(buildSimulator.exitCode, 0);
|
||||
|
||||
|
@ -251,7 +246,6 @@ void main() {
|
|||
final ProcessResult archs = processManager.runSync(
|
||||
<String>['file', simulatorAppFrameworkBinary.path],
|
||||
);
|
||||
print(archs.stdout);
|
||||
expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library x86_64'));
|
||||
expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library arm64'));
|
||||
});
|
||||
|
|
|
@ -53,8 +53,9 @@ void main() {
|
|||
];
|
||||
final ProcessResult result = processManager.runSync(buildCommand, workingDirectory: workingDirectory);
|
||||
|
||||
print(result.stdout);
|
||||
print(result.stderr);
|
||||
printOnFailure('Output of flutter build macos:');
|
||||
printOnFailure(result.stdout.toString());
|
||||
printOnFailure(result.stderr.toString());
|
||||
expect(result.exitCode, 0);
|
||||
|
||||
expect(result.stdout, contains('Running pod install'));
|
||||
|
@ -134,8 +135,9 @@ void main() {
|
|||
// Build again without cleaning.
|
||||
final ProcessResult secondBuild = processManager.runSync(buildCommand, workingDirectory: workingDirectory);
|
||||
|
||||
print(secondBuild.stdout);
|
||||
print(secondBuild.stderr);
|
||||
printOnFailure('Output of second build:');
|
||||
printOnFailure(secondBuild.stdout.toString());
|
||||
printOnFailure(secondBuild.stderr.toString());
|
||||
expect(secondBuild.exitCode, 0);
|
||||
|
||||
expect(secondBuild.stdout, isNot(contains('Running pod install')));
|
||||
|
|
|
@ -27,7 +27,7 @@ Future<void> waitForObservatoryMessage(Process process, int port) async {
|
|||
process.stdout
|
||||
.transform(utf8.decoder)
|
||||
.listen((String line) {
|
||||
print(line);
|
||||
printOnFailure(line);
|
||||
if (line.contains('An Observatory debugger and profiler on Flutter test device is available at')) {
|
||||
if (line.contains('http://127.0.0.1:$port')) {
|
||||
completer.complete();
|
||||
|
@ -38,7 +38,7 @@ Future<void> waitForObservatoryMessage(Process process, int port) async {
|
|||
});
|
||||
process.stderr
|
||||
.transform(utf8.decoder)
|
||||
.listen(print);
|
||||
.listen(printOnFailure);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,13 @@ const ProcessManager processManager = LocalProcessManager();
|
|||
final String flutterRoot = getFlutterRoot();
|
||||
final String flutterBin = fileSystem.path.join(flutterRoot, 'bin', 'flutter');
|
||||
|
||||
void debugPrint(String message) {
|
||||
// This is called to intentionally print debugging output when a test is
|
||||
// either taking too long or has failed.
|
||||
// ignore: avoid_print
|
||||
print(message);
|
||||
}
|
||||
|
||||
typedef LineHandler = String/*?*/ Function(String line);
|
||||
|
||||
abstract class Transition {
|
||||
|
@ -136,7 +143,7 @@ class LogLine {
|
|||
String toString() => '$stamp $channel: $message';
|
||||
|
||||
void printClearly() {
|
||||
print('$stamp $channel: ${clarify(message)}');
|
||||
debugPrint('$stamp $channel: ${clarify(message)}');
|
||||
}
|
||||
|
||||
static String clarify(String line) {
|
||||
|
@ -197,9 +204,9 @@ Future<ProcessTestResult> runFlutter(
|
|||
int nextTransition = 0;
|
||||
void describeStatus() {
|
||||
if (transitions.isNotEmpty) {
|
||||
print('Expected state transitions:');
|
||||
debugPrint('Expected state transitions:');
|
||||
for (int index = 0; index < transitions.length; index += 1) {
|
||||
print(
|
||||
debugPrint(
|
||||
'${index.toString().padLeft(5)} '
|
||||
'${index < nextTransition ? 'ALREADY MATCHED ' :
|
||||
index == nextTransition ? 'NOW WAITING FOR>' :
|
||||
|
@ -207,9 +214,9 @@ Future<ProcessTestResult> runFlutter(
|
|||
}
|
||||
}
|
||||
if (logs.isEmpty) {
|
||||
print('So far nothing has been logged${ debug ? "" : "; use debug:true to print all output" }.');
|
||||
debugPrint('So far nothing has been logged${ debug ? "" : "; use debug:true to print all output" }.');
|
||||
} else {
|
||||
print('Log${ debug ? "" : " (only contains logged lines; use debug:true to print all output)" }:');
|
||||
debugPrint('Log${ debug ? "" : " (only contains logged lines; use debug:true to print all output)" }:');
|
||||
for (final LogLine log in logs) {
|
||||
log.printClearly();
|
||||
}
|
||||
|
@ -221,12 +228,12 @@ Future<ProcessTestResult> runFlutter(
|
|||
if (!streamingLogs) {
|
||||
streamingLogs = true;
|
||||
if (!debug) {
|
||||
print('Test is taking a long time (${clock.elapsed.inSeconds} seconds so far).');
|
||||
debugPrint('Test is taking a long time (${clock.elapsed.inSeconds} seconds so far).');
|
||||
}
|
||||
describeStatus();
|
||||
print('(streaming all logs from this point on...)');
|
||||
debugPrint('(streaming all logs from this point on...)');
|
||||
} else {
|
||||
print('(taking a long time...)');
|
||||
debugPrint('(taking a long time...)');
|
||||
}
|
||||
}
|
||||
String stamp() => '[${(clock.elapsed.inMilliseconds / 1000.0).toStringAsFixed(1).padLeft(5, " ")}s]';
|
||||
|
@ -240,7 +247,7 @@ Future<ProcessTestResult> runFlutter(
|
|||
}
|
||||
if (nextTransition < transitions.length && transitions[nextTransition].matches(line)) {
|
||||
if (streamingLogs) {
|
||||
print('(matched ${transitions[nextTransition]})');
|
||||
debugPrint('(matched ${transitions[nextTransition]})');
|
||||
}
|
||||
if (transitions[nextTransition].logging != null) {
|
||||
if (!logging && transitions[nextTransition].logging/*!*/) {
|
||||
|
@ -249,9 +256,9 @@ Future<ProcessTestResult> runFlutter(
|
|||
logging = transitions[nextTransition].logging/*!*/;
|
||||
if (streamingLogs) {
|
||||
if (logging) {
|
||||
print('(enabled logging)');
|
||||
debugPrint('(enabled logging)');
|
||||
} else {
|
||||
print('(disabled logging)');
|
||||
debugPrint('(disabled logging)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -286,8 +293,8 @@ Future<ProcessTestResult> runFlutter(
|
|||
process.stdout.transform<String>(utf8.decoder).transform<String>(const LineSplitter()).listen(processStdout);
|
||||
process.stderr.transform<String>(utf8.decoder).transform<String>(const LineSplitter()).listen(processStderr);
|
||||
unawaited(process.exitCode.timeout(expectedMaxDuration, onTimeout: () { // This is a failure timeout, must not be short.
|
||||
print('${stamp()} (process is not quitting, trying to send a "q" just in case that helps)');
|
||||
print('(a functional test should never reach this point)');
|
||||
debugPrint('${stamp()} (process is not quitting, trying to send a "q" just in case that helps)');
|
||||
debugPrint('(a functional test should never reach this point)');
|
||||
final LogLine inLog = LogLine('stdin', stamp(), 'q');
|
||||
logs.add(inLog);
|
||||
if (streamingLogs) {
|
||||
|
@ -298,24 +305,24 @@ Future<ProcessTestResult> runFlutter(
|
|||
}).catchError((Object error) { /* ignore errors here, they will be reported on the next line */ }));
|
||||
final int exitCode = await process.exitCode;
|
||||
if (streamingLogs) {
|
||||
print('${stamp()} (process terminated with exit code $exitCode)');
|
||||
debugPrint('${stamp()} (process terminated with exit code $exitCode)');
|
||||
}
|
||||
timeout?.cancel();
|
||||
if (nextTransition < transitions.length) {
|
||||
print('The subprocess terminated before all the expected transitions had been matched.');
|
||||
debugPrint('The subprocess terminated before all the expected transitions had been matched.');
|
||||
if (logs.any((LogLine line) => line.couldBeCrash)) {
|
||||
print('The subprocess may in fact have crashed. Check the stderr logs below.');
|
||||
debugPrint('The subprocess may in fact have crashed. Check the stderr logs below.');
|
||||
}
|
||||
print('The transition that we were hoping to see next but that we never saw was:');
|
||||
print('${nextTransition.toString().padLeft(5)} NOW WAITING FOR> ${transitions[nextTransition]}');
|
||||
debugPrint('The transition that we were hoping to see next but that we never saw was:');
|
||||
debugPrint('${nextTransition.toString().padLeft(5)} NOW WAITING FOR> ${transitions[nextTransition]}');
|
||||
if (!streamingLogs) {
|
||||
describeStatus();
|
||||
print('(process terminated with exit code $exitCode)');
|
||||
debugPrint('(process terminated with exit code $exitCode)');
|
||||
}
|
||||
throw TestFailure('Missed some expected transitions.');
|
||||
}
|
||||
if (streamingLogs) {
|
||||
print('${stamp()} (completed execution successfully!)');
|
||||
debugPrint('${stamp()} (completed execution successfully!)');
|
||||
}
|
||||
return ProcessTestResult(exitCode, logs);
|
||||
}
|
||||
|
|
|
@ -79,6 +79,10 @@ abstract class FlutterTestDriver {
|
|||
lastTime = time;
|
||||
}
|
||||
if (_printDebugOutputToStdOut) {
|
||||
// This is the one place in this file that can call print. It is gated by
|
||||
// _printDebugOutputToStdOut which should not be set to true in CI; it is
|
||||
// intended only for use in local debugging.
|
||||
// ignore: avoid_print
|
||||
print('$time$_logPrefix$line');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,6 +215,10 @@ void main() {
|
|||
}
|
||||
expect(result.exitCode, 0);
|
||||
});
|
||||
|
||||
testWithoutContext('flutter gold skips tests where the expectations are missing', () async {
|
||||
return _testFile('flutter_gold', automatedTestsDirectory, flutterTestDirectory, exitCode: isZero);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _testFile(
|
||||
|
|
|
@ -40,6 +40,8 @@ void main() {
|
|||
// Regression test for https://github.com/flutter/flutter/issues/79498
|
||||
testWithoutContext('Can connect to the timeline without getting ANR from the application', () async {
|
||||
final Timer timer = Timer(const Duration(minutes: 5), () {
|
||||
// This message is intended to show up in CI logs.
|
||||
// ignore: avoid_print
|
||||
print(
|
||||
'Warning: test isolate is still active after 5 minutes. This is likely an '
|
||||
'app-not-responding error and not a flake. See https://github.com/flutter/flutter/issues/79498 '
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
|
||||
// Not a test file, invoked by `variable_expansion_windows_test.dart`.
|
||||
void main(List<String> args) {
|
||||
print('args: $args');
|
||||
// This print is used for communicating with the test host.
|
||||
print('args: $args'); // ignore: avoid_print
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@ void tryToDelete(Directory directory) {
|
|||
directory.deleteSync(recursive: true);
|
||||
}
|
||||
} on FileSystemException catch (error) {
|
||||
// We print this so that it's visible in the logs, to get an idea of how
|
||||
// common this problem is, and if any patterns are ever noticed by anyone.
|
||||
// ignore: avoid_print
|
||||
print('Failed to delete ${directory.path}: $error');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ void testUsingContext(
|
|||
},
|
||||
body: () {
|
||||
final String flutterRoot = getFlutterRoot();
|
||||
return runZoned<Future<dynamic>>(() {
|
||||
return runZonedGuarded<Future<dynamic>>(() {
|
||||
try {
|
||||
return context.run<dynamic>(
|
||||
// Apply the overrides to the test context in the zone since their
|
||||
|
@ -148,9 +148,10 @@ void testUsingContext(
|
|||
_printBufferedErrors(context);
|
||||
rethrow;
|
||||
}
|
||||
}, onError: (Object error, StackTrace stackTrace) { // ignore: deprecated_member_use
|
||||
print(error);
|
||||
print(stackTrace);
|
||||
}, (Object error, StackTrace stackTrace) {
|
||||
// When things fail, it's ok to print to the console!
|
||||
print(error); // ignore: avoid_print
|
||||
print(stackTrace); // ignore: avoid_print
|
||||
_printBufferedErrors(context);
|
||||
throw error;
|
||||
});
|
||||
|
@ -176,7 +177,9 @@ void _printBufferedErrors(AppContext testContext) {
|
|||
if (testContext.get<Logger>() is BufferLogger) {
|
||||
final BufferLogger bufferLogger = testContext.get<Logger>() as BufferLogger;
|
||||
if (bufferLogger.errorText.isNotEmpty) {
|
||||
print(bufferLogger.errorText);
|
||||
// This is where the logger outputting errors is implemented, so it has
|
||||
// to use `print`.
|
||||
print(bufferLogger.errorText); // ignore: avoid_print
|
||||
}
|
||||
bufferLogger.clear();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ void main() {
|
|||
testWithoutContext('newly added code executes during hot restart', () async {
|
||||
final Completer<void> completer = Completer<void>();
|
||||
final StreamSubscription<String> subscription = flutter.stdout.listen((String line) {
|
||||
print(line);
|
||||
if (line.contains('(((((RELOAD WORKED)))))')) {
|
||||
completer.complete();
|
||||
}
|
||||
|
@ -56,7 +55,6 @@ void main() {
|
|||
testWithoutContext('newly added code executes during hot restart - canvaskit', () async {
|
||||
final Completer<void> completer = Completer<void>();
|
||||
final StreamSubscription<String> subscription = flutter.stdout.listen((String line) {
|
||||
print(line);
|
||||
if (line.contains('(((((RELOAD WORKED)))))')) {
|
||||
completer.complete();
|
||||
}
|
||||
|
|
5
packages/flutter_tools/tool/analysis_options.yaml
Normal file
5
packages/flutter_tools/tool/analysis_options.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
include: ../analysis_options.yaml
|
||||
|
||||
linter:
|
||||
rules:
|
||||
avoid_print: false # These are CLI tools which print as a matter of course.
|
|
@ -51,6 +51,7 @@ typedef LoggingFunction = void Function(LogMessage log);
|
|||
///
|
||||
/// Exits with status code 1 if the `log` is [LoggingLevel.severe].
|
||||
void defaultLoggingFunction(LogMessage log) {
|
||||
// ignore: avoid_print
|
||||
print('[${log.levelName}]::${log.tag}--${log.time}: ${log.message}');
|
||||
if (log.level == LoggingLevel.severe) {
|
||||
exit(1);
|
||||
|
|
|
@ -64,7 +64,7 @@ class IntegrationTestWidgetsFlutterBinding extends LiveTestWidgetsFlutterBinding
|
|||
},
|
||||
);
|
||||
} on MissingPluginException {
|
||||
print(r'''
|
||||
debugPrint(r'''
|
||||
Warning: integration_test plugin was not detected.
|
||||
|
||||
If you're running the tests with `flutter drive`, please make sure your tests
|
||||
|
@ -391,7 +391,7 @@ https://flutter.dev/docs/testing/integration-tests#testing-on-firebase-test-lab
|
|||
count++;
|
||||
await Future<void>.delayed(const Duration(seconds: 2));
|
||||
if (count > 20) {
|
||||
print('delayForFrameTimings is taking longer than expected...');
|
||||
debugPrint('delayForFrameTimings is taking longer than expected...');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// This is a CLI library; we use prints as part of the interface.
|
||||
// ignore_for_file: avoid_print
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// This is a CLI library; we use prints as part of the interface.
|
||||
// ignore_for_file: avoid_print
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
|
|
|
@ -104,7 +104,6 @@ Future<void> main() async {
|
|||
testWidgets('Test traceAction', (WidgetTester tester) async {
|
||||
await integrationBinding.enableTimeline(vmService: fakeVM);
|
||||
await integrationBinding.traceAction(() async {});
|
||||
print(integrationBinding.reportData);
|
||||
expect(integrationBinding.reportData, isNotNull);
|
||||
expect(integrationBinding.reportData!.containsKey('timeline'), true);
|
||||
expect(
|
||||
|
|
|
@ -10,6 +10,8 @@ import 'package:integration_test/integration_test.dart';
|
|||
Future<void> main() async {
|
||||
final IntegrationTestWidgetsFlutterBinding binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized() as IntegrationTestWidgetsFlutterBinding;
|
||||
binding.allTestsPassed.future.then((_) {
|
||||
// We use this print to communicate with ../binding_fail_test.dart
|
||||
// ignore: avoid_print
|
||||
print('IntegrationTestWidgetsFlutterBinding test results: ${jsonEncode(binding.results)}');
|
||||
});
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import 'package:integration_test/integration_test.dart';
|
|||
Future<void> main() async {
|
||||
final IntegrationTestWidgetsFlutterBinding binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized() as IntegrationTestWidgetsFlutterBinding;
|
||||
binding.allTestsPassed.future.then((_) {
|
||||
// We use this print to communicate with ../binding_fail_test.dart
|
||||
// ignore: avoid_print
|
||||
print('IntegrationTestWidgetsFlutterBinding test results: ${jsonEncode(binding.results)}');
|
||||
});
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import 'package:integration_test/integration_test.dart';
|
|||
Future<void> main() async {
|
||||
final IntegrationTestWidgetsFlutterBinding binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized() as IntegrationTestWidgetsFlutterBinding;
|
||||
binding.allTestsPassed.future.then((_) {
|
||||
// We use this print to communicate with ../binding_fail_test.dart
|
||||
// ignore: avoid_print
|
||||
print('IntegrationTestWidgetsFlutterBinding test results: ${jsonEncode(binding.results)}');
|
||||
});
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import 'package:integration_test/integration_test.dart';
|
|||
Future<void> main() async {
|
||||
final IntegrationTestWidgetsFlutterBinding binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized() as IntegrationTestWidgetsFlutterBinding;
|
||||
binding.allTestsPassed.future.then((_) {
|
||||
// We use this print to communicate with ../binding_fail_test.dart
|
||||
// ignore: avoid_print
|
||||
print('IntegrationTestWidgetsFlutterBinding test results: ${jsonEncode(binding.results)}');
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue