mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Analyze code snippets in flutter_test docs (#132246)
Fixes https://github.com/flutter/flutter/issues/132274.
This commit is contained in:
parent
e11cc35076
commit
64a0683b41
@ -70,7 +70,8 @@ import 'package:path/path.dart' as path;
|
||||
import 'package:watcher/watcher.dart';
|
||||
|
||||
final String _flutterRoot = path.dirname(path.dirname(path.dirname(path.fromUri(Platform.script))));
|
||||
final String _defaultFlutterPackage = path.join(_flutterRoot, 'packages', 'flutter', 'lib');
|
||||
final String _packageFlutter = path.join(_flutterRoot, 'packages', 'flutter', 'lib');
|
||||
final String _packageFlutterTest = path.join(_flutterRoot, 'packages', 'flutter_test', 'lib');
|
||||
final String _defaultDartUiLocation = path.join(_flutterRoot, 'bin', 'cache', 'pkg', 'sky_engine', 'lib', 'ui');
|
||||
final String _flutter = path.join(_flutterRoot, 'bin', Platform.isWindows ? 'flutter.bat' : 'flutter');
|
||||
|
||||
@ -142,12 +143,16 @@ Future<void> main(List<String> arguments) async {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
Directory flutterPackage;
|
||||
List<Directory> flutterPackages;
|
||||
if (parsedArguments.rest.length == 1) {
|
||||
// Used for testing.
|
||||
flutterPackage = Directory(parsedArguments.rest.single);
|
||||
flutterPackages = <Directory>[Directory(parsedArguments.rest.single)];
|
||||
} else {
|
||||
flutterPackage = Directory(_defaultFlutterPackage);
|
||||
flutterPackages = <Directory>[
|
||||
Directory(_packageFlutter),
|
||||
Directory(_packageFlutterTest),
|
||||
// TODO(goderbauer): Add all other packages.
|
||||
];
|
||||
}
|
||||
|
||||
final bool includeDartUi = parsedArguments.wasParsed('dart-ui-location') || parsedArguments['include-dart-ui'] as bool;
|
||||
@ -165,14 +170,14 @@ Future<void> main(List<String> arguments) async {
|
||||
|
||||
if (parsedArguments['interactive'] != null) {
|
||||
await _runInteractive(
|
||||
flutterPackage: flutterPackage,
|
||||
flutterPackages: flutterPackages,
|
||||
tempDirectory: parsedArguments['temp'] as String?,
|
||||
filePath: parsedArguments['interactive'] as String,
|
||||
dartUiLocation: includeDartUi ? dartUiLocation : null,
|
||||
);
|
||||
} else {
|
||||
if (await _SnippetChecker(
|
||||
flutterPackage,
|
||||
flutterPackages,
|
||||
tempDirectory: parsedArguments['temp'] as String?,
|
||||
verbose: parsedArguments['verbose'] as bool,
|
||||
dartUiLocation: includeDartUi ? dartUiLocation : null,
|
||||
@ -360,7 +365,7 @@ class _SnippetChecker {
|
||||
/// supplied, the default location of the `dart:ui` code in the Flutter
|
||||
/// repository is used (i.e. "<flutter repo>/bin/cache/pkg/sky_engine/lib/ui").
|
||||
_SnippetChecker(
|
||||
this._flutterPackage, {
|
||||
this._flutterPackages, {
|
||||
String? tempDirectory,
|
||||
this.verbose = false,
|
||||
Directory? dartUiLocation,
|
||||
@ -438,8 +443,8 @@ class _SnippetChecker {
|
||||
/// automatically if there are no errors unless _keepTmp is true.
|
||||
final Directory _tempDirectory;
|
||||
|
||||
/// The package directory for the flutter package within the flutter root dir.
|
||||
final Directory _flutterPackage;
|
||||
/// The package directories within the flutter root dir that will be checked.
|
||||
final List<Directory> _flutterPackages;
|
||||
|
||||
/// The directory for the dart:ui code to be analyzed with the flutter code.
|
||||
///
|
||||
@ -481,7 +486,7 @@ class _SnippetChecker {
|
||||
"import 'dart:typed_data';",
|
||||
"import 'dart:ui' as ui;",
|
||||
"import 'package:flutter_test/flutter_test.dart';",
|
||||
for (final File file in _listDartFiles(Directory(_defaultFlutterPackage)))
|
||||
for (final File file in _listDartFiles(Directory(_packageFlutter)))
|
||||
"import 'package:flutter/${path.basename(file.path)}';",
|
||||
].map<_Line>((String code) => _Line.generated(code: code)).toList();
|
||||
}
|
||||
@ -495,7 +500,8 @@ class _SnippetChecker {
|
||||
stderr.writeln('Unable to analyze engine dart snippets at ${_dartUiLocation!.path}.');
|
||||
}
|
||||
final List<File> filesToAnalyze = <File>[
|
||||
..._listDartFiles(_flutterPackage, recursive: true),
|
||||
for (final Directory flutterPackage in _flutterPackages)
|
||||
..._listDartFiles(flutterPackage, recursive: true),
|
||||
if (_dartUiLocation != null && _dartUiLocation!.existsSync())
|
||||
..._listDartFiles(_dartUiLocation!, recursive: true),
|
||||
];
|
||||
@ -1084,7 +1090,7 @@ class _SnippetFile {
|
||||
|
||||
Future<void> _runInteractive({
|
||||
required String? tempDirectory,
|
||||
required Directory flutterPackage,
|
||||
required List<Directory> flutterPackages,
|
||||
required String filePath,
|
||||
required Directory? dartUiLocation,
|
||||
}) async {
|
||||
@ -1106,7 +1112,7 @@ Future<void> _runInteractive({
|
||||
print('Starting up in interactive mode on ${path.relative(filePath, from: _flutterRoot)} ...');
|
||||
print('Type "q" to quit, or "r" to force a reload.');
|
||||
|
||||
final _SnippetChecker checker = _SnippetChecker(flutterPackage, tempDirectory: tempDirectory)
|
||||
final _SnippetChecker checker = _SnippetChecker(flutterPackages, tempDirectory: tempDirectory)
|
||||
.._createConfigurationFiles();
|
||||
|
||||
ProcessSignal.sigint.watch().listen((_) {
|
||||
|
@ -27,7 +27,7 @@
|
||||
/// with the following signature:
|
||||
///
|
||||
/// ```dart
|
||||
/// Future<void> testExecutable(FutureOr<void> Function() testMain);
|
||||
/// Future<void> testExecutable(FutureOr<void> Function() testMain) async { }
|
||||
/// ```
|
||||
///
|
||||
/// The test framework will execute that method and pass it the `main()` method
|
||||
|
@ -57,6 +57,9 @@ class Evaluation {
|
||||
}
|
||||
}
|
||||
|
||||
// Examples can assume:
|
||||
// typedef HomePage = Placeholder;
|
||||
|
||||
/// An accessibility guideline describes a recommendation an application should
|
||||
/// meet to be considered accessible.
|
||||
///
|
||||
|
@ -55,14 +55,14 @@ import 'package:flutter/widgets.dart';
|
||||
/// // Start recording (`recording` is true)
|
||||
/// await tester.pumpFrames(animationSheet.record(
|
||||
/// target,
|
||||
/// recording: true,
|
||||
/// recording: true, // ignore: avoid_redundant_argument_values
|
||||
/// ), const Duration(seconds: 1));
|
||||
///
|
||||
/// await gesture.up();
|
||||
///
|
||||
/// await tester.pumpFrames(animationSheet.record(
|
||||
/// target,
|
||||
/// recording: true,
|
||||
/// recording: true, // ignore: avoid_redundant_argument_values
|
||||
/// ), const Duration(seconds: 1));
|
||||
///
|
||||
/// // Compare against golden file
|
||||
|
@ -143,6 +143,10 @@ class CapturedAccessibilityAnnouncement {
|
||||
final Assertiveness assertiveness;
|
||||
}
|
||||
|
||||
// Examples can assume:
|
||||
// late TestWidgetsFlutterBinding binding;
|
||||
// late Size someSize;
|
||||
|
||||
/// Base class for bindings used by widgets library tests.
|
||||
///
|
||||
/// The [ensureInitialized] method creates (if necessary) and returns an
|
||||
@ -1548,7 +1552,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
|
||||
/// ```dart
|
||||
/// TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
|
||||
/// if (binding is LiveTestWidgetsFlutterBinding) {
|
||||
/// binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.[thePolicy];
|
||||
/// binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.onlyPumps;
|
||||
/// }
|
||||
/// ```
|
||||
/// {@endtemplate}
|
||||
|
@ -1,74 +0,0 @@
|
||||
// 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.
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:matcher/expect.dart' show Description;
|
||||
import 'package:matcher/src/expect/async_matcher.dart'; // ignore: implementation_imports
|
||||
import 'package:test_api/hooks.dart' show TestFailure;
|
||||
|
||||
import 'goldens.dart';
|
||||
|
||||
/// Matcher created by [bufferMatchesGoldenFile].
|
||||
class _BufferGoldenMatcher extends AsyncMatcher {
|
||||
/// Creates an instance of [BufferGoldenMatcher]. Called by [bufferMatchesGoldenFile].
|
||||
const _BufferGoldenMatcher(this.key, this.version);
|
||||
|
||||
/// The [key] to the golden image.
|
||||
final Uri key;
|
||||
|
||||
/// The [version] of the golden image.
|
||||
final int? version;
|
||||
|
||||
@override
|
||||
Future<String?> matchAsync(dynamic item) async {
|
||||
Uint8List buffer;
|
||||
if (item is List<int>) {
|
||||
buffer = Uint8List.fromList(item);
|
||||
} else if (item is Future<List<int>>) {
|
||||
buffer = Uint8List.fromList(await item);
|
||||
} else {
|
||||
throw AssertionError('Expected `List<int>` or `Future<List<int>>`, instead found: ${item.runtimeType}');
|
||||
}
|
||||
final Uri testNameUri = goldenFileComparator.getTestUri(key, version);
|
||||
if (autoUpdateGoldenFiles) {
|
||||
await goldenFileComparator.update(testNameUri, buffer);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final bool success = await goldenFileComparator.compare(buffer, testNameUri);
|
||||
return success ? null : 'does not match';
|
||||
} on TestFailure catch (ex) {
|
||||
return ex.message;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Description describe(Description description) {
|
||||
final Uri testNameUri = goldenFileComparator.getTestUri(key, version);
|
||||
return description.add('Byte buffer matches golden image "$testNameUri"');
|
||||
}
|
||||
}
|
||||
|
||||
/// Asserts that a [Future<List<int>>], or [List<int] matches the
|
||||
/// golden image file identified by [key], with an optional [version] number.
|
||||
///
|
||||
/// The [key] is the [String] representation of a URL.
|
||||
///
|
||||
/// The [version] is a number that can be used to differentiate historical
|
||||
/// golden files. This parameter is optional.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// Sample invocations of [bufferMatchesGoldenFile].
|
||||
///
|
||||
/// ```dart
|
||||
/// await expectLater(
|
||||
/// const <int>[ /* bytes... */ ],
|
||||
/// bufferMatchesGoldenFile('sample.png'),
|
||||
/// );
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
AsyncMatcher bufferMatchesGoldenFile(String key, {int? version}) {
|
||||
return _BufferGoldenMatcher(Uri.parse(key), version);
|
||||
}
|
@ -24,6 +24,9 @@ const double kDragSlopDefault = 20.0;
|
||||
|
||||
const String _defaultPlatform = kIsWeb ? 'web' : 'android';
|
||||
|
||||
// Examples can assume:
|
||||
// typedef MyWidget = Placeholder;
|
||||
|
||||
/// Class that programmatically interacts with the [Semantics] tree.
|
||||
///
|
||||
/// Allows for testing of the [Semantics] tree, which is used by assistive
|
||||
@ -123,13 +126,13 @@ class SemanticsController {
|
||||
///
|
||||
/// ## Sample Code
|
||||
///
|
||||
/// ```
|
||||
/// ```dart
|
||||
/// testWidgets('MyWidget', (WidgetTester tester) async {
|
||||
/// await tester.pumpWidget(MyWidget());
|
||||
/// await tester.pumpWidget(const MyWidget());
|
||||
///
|
||||
/// expect(
|
||||
/// tester.semantics.simulatedAccessibilityTraversal(),
|
||||
/// containsAllInOrder([
|
||||
/// containsAllInOrder(<Matcher>[
|
||||
/// containsSemantics(label: 'My Widget'),
|
||||
/// containsSemantics(label: 'is awesome!', isChecked: true),
|
||||
/// ]),
|
||||
|
@ -17,6 +17,12 @@ typedef ElementPredicate = bool Function(Element element);
|
||||
/// Some frequently used widget [Finder]s.
|
||||
const CommonFinders find = CommonFinders._();
|
||||
|
||||
// Examples can assume:
|
||||
// typedef Button = Placeholder;
|
||||
// late WidgetTester tester;
|
||||
// late String filePath;
|
||||
// late Key backKey;
|
||||
|
||||
/// Provides lightweight syntax for getting frequently used widget [Finder]s.
|
||||
///
|
||||
/// This class is instantiated once, as [find].
|
||||
@ -116,9 +122,9 @@ class CommonFinders {
|
||||
///
|
||||
/// ```dart
|
||||
/// // Suppose you have a button with text 'Update' in it:
|
||||
/// Button(
|
||||
/// const Button(
|
||||
/// child: Text('Update')
|
||||
/// )
|
||||
/// );
|
||||
///
|
||||
/// // You can find and tap on it like this:
|
||||
/// tester.tap(find.widgetWithText(Button, 'Update'));
|
||||
@ -217,9 +223,9 @@ class CommonFinders {
|
||||
///
|
||||
/// ```dart
|
||||
/// // Suppose you have a button with icon 'arrow_forward' in it:
|
||||
/// Button(
|
||||
/// const Button(
|
||||
/// child: Icon(Icons.arrow_forward)
|
||||
/// )
|
||||
/// );
|
||||
///
|
||||
/// // You can find and tap on it like this:
|
||||
/// tester.tap(find.widgetWithIcon(Button, Icons.arrow_forward));
|
||||
@ -242,11 +248,11 @@ class CommonFinders {
|
||||
/// ```dart
|
||||
/// // Suppose you have a button with image in it:
|
||||
/// Button(
|
||||
/// child: Image.file(filePath)
|
||||
/// )
|
||||
/// child: Image.file(File(filePath))
|
||||
/// );
|
||||
///
|
||||
/// // You can find and tap on it like this:
|
||||
/// tester.tap(find.widgetWithImage(Button, FileImage(filePath)));
|
||||
/// tester.tap(find.widgetWithImage(Button, FileImage(File(filePath))));
|
||||
/// ```
|
||||
///
|
||||
/// If the `skipOffstage` argument is true (the default), then this skips
|
||||
@ -283,7 +289,7 @@ class CommonFinders {
|
||||
///
|
||||
/// ```dart
|
||||
/// // Suppose you have a button created like this:
|
||||
/// Widget myButton = Button(
|
||||
/// Widget myButton = const Button(
|
||||
/// child: Text('Update')
|
||||
/// );
|
||||
///
|
||||
@ -396,7 +402,7 @@ class CommonFinders {
|
||||
/// tester.widget<Opacity>(
|
||||
/// find.ancestor(
|
||||
/// of: find.text('faded'),
|
||||
/// matching: find.byType('Opacity'),
|
||||
/// matching: find.byType(Opacity),
|
||||
/// )
|
||||
/// ).opacity,
|
||||
/// 0.5
|
||||
|
@ -331,6 +331,13 @@ Matcher isMethodCall(String name, { required dynamic arguments }) {
|
||||
Matcher coversSameAreaAs(Path expectedPath, { required Rect areaToCompare, int sampleSize = 20 })
|
||||
=> _CoversSameAreaAs(expectedPath, areaToCompare: areaToCompare, sampleSize: sampleSize);
|
||||
|
||||
// Examples can assume:
|
||||
// late Image image;
|
||||
// late Future<Image> imageFuture;
|
||||
// typedef MyWidget = Placeholder;
|
||||
// late Future<ByteData> someFont;
|
||||
// late WidgetTester tester;
|
||||
|
||||
/// Asserts that a [Finder], [Future<ui.Image>], or [ui.Image] matches the
|
||||
/// golden image file identified by [key], with an optional [version] number.
|
||||
///
|
||||
@ -404,18 +411,18 @@ Matcher coversSameAreaAs(Path expectedPath, { required Rect areaToCompare, int s
|
||||
/// {@tool snippet}
|
||||
/// How to load a custom font for golden images.
|
||||
/// ```dart
|
||||
/// testWidgets('Creating a golden image with a custom font', (tester) async {
|
||||
/// testWidgets('Creating a golden image with a custom font', (WidgetTester tester) async {
|
||||
/// // Assuming the 'Roboto.ttf' file is declared in the pubspec.yaml file
|
||||
/// final font = rootBundle.load('path/to/font-file/Roboto.ttf');
|
||||
/// final Future<ByteData> font = rootBundle.load('path/to/font-file/Roboto.ttf');
|
||||
///
|
||||
/// final fontLoader = FontLoader('Roboto')..addFont(font);
|
||||
/// final FontLoader fontLoader = FontLoader('Roboto')..addFont(font);
|
||||
/// await fontLoader.load();
|
||||
///
|
||||
/// await tester.pumpWidget(const SomeWidget());
|
||||
/// await tester.pumpWidget(const MyWidget());
|
||||
///
|
||||
/// await expectLater(
|
||||
/// find.byType(SomeWidget),
|
||||
/// matchesGoldenFile('someWidget.png'),
|
||||
/// find.byType(MyWidget),
|
||||
/// matchesGoldenFile('myWidget.png'),
|
||||
/// );
|
||||
/// });
|
||||
/// ```
|
||||
@ -431,7 +438,7 @@ Matcher coversSameAreaAs(Path expectedPath, { required Rect areaToCompare, int s
|
||||
/// ```dart
|
||||
/// Future<void> testExecutable(FutureOr<void> Function() testMain) async {
|
||||
/// setUpAll(() async {
|
||||
/// final fontLoader = FontLoader('SomeFont')..addFont(someFont);
|
||||
/// final FontLoader fontLoader = FontLoader('SomeFont')..addFont(someFont);
|
||||
/// await fontLoader.load();
|
||||
/// });
|
||||
///
|
||||
@ -473,18 +480,20 @@ AsyncMatcher matchesGoldenFile(Object key, {int? version}) {
|
||||
/// ## Sample code
|
||||
///
|
||||
/// ```dart
|
||||
/// final ui.Paint paint = ui.Paint()
|
||||
/// ..style = ui.PaintingStyle.stroke
|
||||
/// ..strokeWidth = 1.0;
|
||||
/// final ui.PictureRecorder recorder = ui.PictureRecorder();
|
||||
/// final ui.Canvas pictureCanvas = ui.Canvas(recorder);
|
||||
/// pictureCanvas.drawCircle(Offset.zero, 20.0, paint);
|
||||
/// final ui.Picture picture = recorder.endRecording();
|
||||
/// ui.Image referenceImage = picture.toImage(50, 50);
|
||||
/// testWidgets('matchesReferenceImage', (WidgetTester tester) async {
|
||||
/// final ui.Paint paint = ui.Paint()
|
||||
/// ..style = ui.PaintingStyle.stroke
|
||||
/// ..strokeWidth = 1.0;
|
||||
/// final ui.PictureRecorder recorder = ui.PictureRecorder();
|
||||
/// final ui.Canvas pictureCanvas = ui.Canvas(recorder);
|
||||
/// pictureCanvas.drawCircle(Offset.zero, 20.0, paint);
|
||||
/// final ui.Picture picture = recorder.endRecording();
|
||||
/// ui.Image referenceImage = await picture.toImage(50, 50);
|
||||
///
|
||||
/// await expectLater(find.text('Save'), matchesReferenceImage(referenceImage));
|
||||
/// await expectLater(image, matchesReferenceImage(referenceImage);
|
||||
/// await expectLater(imageFuture, matchesReferenceImage(referenceImage));
|
||||
/// await expectLater(find.text('Save'), matchesReferenceImage(referenceImage));
|
||||
/// await expectLater(image, matchesReferenceImage(referenceImage));
|
||||
/// await expectLater(imageFuture, matchesReferenceImage(referenceImage));
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// See also:
|
||||
@ -508,9 +517,12 @@ AsyncMatcher matchesReferenceImage(ui.Image image) {
|
||||
/// ## Sample code
|
||||
///
|
||||
/// ```dart
|
||||
/// final SemanticsHandle handle = tester.ensureSemantics();
|
||||
/// expect(tester.getSemantics(find.text('hello')), matchesSemantics(label: 'hello'));
|
||||
/// handle.dispose();
|
||||
/// testWidgets('matchesSemantics', (WidgetTester tester) async {
|
||||
/// final SemanticsHandle handle = tester.ensureSemantics();
|
||||
/// // ...
|
||||
/// expect(tester.getSemantics(find.text('hello')), matchesSemantics(label: 'hello'));
|
||||
/// handle.dispose();
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// See also:
|
||||
@ -685,9 +697,12 @@ Matcher matchesSemantics({
|
||||
/// ## Sample code
|
||||
///
|
||||
/// ```dart
|
||||
/// final SemanticsHandle handle = tester.ensureSemantics();
|
||||
/// expect(tester.getSemantics(find.text('hello')), hasSemantics(label: 'hello'));
|
||||
/// handle.dispose();
|
||||
/// testWidgets('containsSemantics', (WidgetTester tester) async {
|
||||
/// final SemanticsHandle handle = tester.ensureSemantics();
|
||||
/// // ...
|
||||
/// expect(tester.getSemantics(find.text('hello')), containsSemantics(label: 'hello'));
|
||||
/// handle.dispose();
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// See also:
|
||||
@ -859,9 +874,12 @@ Matcher containsSemantics({
|
||||
/// ## Sample code
|
||||
///
|
||||
/// ```dart
|
||||
/// final SemanticsHandle handle = tester.ensureSemantics();
|
||||
/// await expectLater(tester, meetsGuideline(textContrastGuideline));
|
||||
/// handle.dispose();
|
||||
/// testWidgets('containsSemantics', (WidgetTester tester) async {
|
||||
/// final SemanticsHandle handle = tester.ensureSemantics();
|
||||
/// // ...
|
||||
/// await expectLater(tester, meetsGuideline(textContrastGuideline));
|
||||
/// handle.dispose();
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// Supported accessibility guidelines:
|
||||
|
@ -12,6 +12,10 @@ import 'finders.dart';
|
||||
import 'recording_canvas.dart';
|
||||
import 'test_async_utils.dart';
|
||||
|
||||
// Examples can assume:
|
||||
// late RenderObject myRenderObject;
|
||||
// late Symbol methodName;
|
||||
|
||||
/// Matches objects or functions that paint a display list that matches the
|
||||
/// canvas calls described by the pattern.
|
||||
///
|
||||
@ -20,8 +24,8 @@ import 'test_async_utils.dart';
|
||||
/// following signatures:
|
||||
///
|
||||
/// ```dart
|
||||
/// void function(PaintingContext context, Offset offset);
|
||||
/// void function(Canvas canvas);
|
||||
/// void exampleOne(PaintingContext context, Offset offset) { }
|
||||
/// void exampleTwo(Canvas canvas) { }
|
||||
/// ```
|
||||
///
|
||||
/// In the case of functions that take a [PaintingContext] and an [Offset], the
|
||||
@ -65,7 +69,9 @@ Matcher paintsExactlyCountTimes(Symbol methodName, int count) {
|
||||
/// literal syntax, for example:
|
||||
///
|
||||
/// ```dart
|
||||
/// if (methodName == #drawCircle) { ... }
|
||||
/// if (methodName == #drawCircle) {
|
||||
/// // ...
|
||||
/// }
|
||||
/// ```
|
||||
typedef PaintPatternPredicate = bool Function(Symbol methodName, List<dynamic> arguments);
|
||||
|
||||
|
@ -8,15 +8,15 @@
|
||||
/// ```dart
|
||||
/// class A {
|
||||
/// const A(this.i);
|
||||
/// int i;
|
||||
/// final int? i;
|
||||
/// }
|
||||
///
|
||||
/// main () {
|
||||
/// void main () {
|
||||
/// // prevent prefer_const_constructors lint
|
||||
/// A(nonconst(null));
|
||||
///
|
||||
/// // prevent prefer_const_declarations lint
|
||||
/// final int $null = nonconst(null);
|
||||
/// final int? $null = nonconst(null);
|
||||
/// final A a = nonconst(const A(null));
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -35,6 +35,9 @@ class RecordedInvocation {
|
||||
}
|
||||
}
|
||||
|
||||
// Examples can assume:
|
||||
// late WidgetTester tester;
|
||||
|
||||
/// A [Canvas] for tests that records its method calls.
|
||||
///
|
||||
/// This class can be used in conjunction with [TestRecordingPaintingContext]
|
||||
|
@ -12,6 +12,9 @@ class _AsyncScope {
|
||||
final Zone zone;
|
||||
}
|
||||
|
||||
// Examples can assume:
|
||||
// late WidgetTester tester;
|
||||
|
||||
/// Utility class for all the async APIs in the `flutter_test` library.
|
||||
///
|
||||
/// This class provides checking for asynchronous APIs, allowing the library to
|
||||
|
@ -81,6 +81,9 @@ E? _lastWhereOrNull<E>(Iterable<E> list, bool Function(E) test) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Examples can assume:
|
||||
// typedef MyWidget = Placeholder;
|
||||
|
||||
/// Runs the [callback] inside the Flutter test environment.
|
||||
///
|
||||
/// Use this function for testing custom [StatelessWidget]s and
|
||||
@ -117,7 +120,7 @@ E? _lastWhereOrNull<E>(Iterable<E> list, bool Function(E) test) {
|
||||
///
|
||||
/// ```dart
|
||||
/// testWidgets('MyWidget', (WidgetTester tester) async {
|
||||
/// await tester.pumpWidget(MyWidget());
|
||||
/// await tester.pumpWidget(const MyWidget());
|
||||
/// await tester.tap(find.text('Save'));
|
||||
/// expect(find.text('Success'), findsOneWidget);
|
||||
/// });
|
||||
@ -319,12 +322,13 @@ class TargetPlatformVariant extends TestVariant<TargetPlatform> {
|
||||
/// }
|
||||
///
|
||||
/// final ValueVariant<TestScenario> variants = ValueVariant<TestScenario>(
|
||||
/// <TestScenario>{value1, value2},
|
||||
/// <TestScenario>{TestScenario.value1, TestScenario.value2},
|
||||
/// );
|
||||
///
|
||||
/// testWidgets('Test handling of TestScenario', (WidgetTester tester) {
|
||||
/// expect(variants.currentValue, equals(value1));
|
||||
/// }, variant: variants);
|
||||
/// void main() {
|
||||
/// testWidgets('Test handling of TestScenario', (WidgetTester tester) async {
|
||||
/// expect(variants.currentValue, equals(TestScenario.value1));
|
||||
/// }, variant: variants);
|
||||
/// }
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
class ValueVariant<T> extends TestVariant<T> {
|
||||
@ -507,7 +511,7 @@ Future<void> expectLater(
|
||||
///
|
||||
/// ```dart
|
||||
/// testWidgets('MyWidget', (WidgetTester tester) async {
|
||||
/// await tester.pumpWidget(MyWidget());
|
||||
/// await tester.pumpWidget(const MyWidget());
|
||||
/// await tester.tap(find.text('Save'));
|
||||
/// await tester.pump(); // allow the application to handle
|
||||
/// await tester.pump(const Duration(seconds: 1)); // skip past the animation
|
||||
@ -555,7 +559,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
|
||||
/// {@tool snippet}
|
||||
/// ```dart
|
||||
/// testWidgets('MyWidget asserts invalid bounds', (WidgetTester tester) async {
|
||||
/// await tester.pumpWidget(MyWidget(-1));
|
||||
/// await tester.pumpWidget(const MyWidget());
|
||||
/// expect(tester.takeException(), isAssertionError); // or isNull, as appropriate.
|
||||
/// });
|
||||
/// ```
|
||||
|
@ -1173,7 +1173,7 @@ class _UnsupportedDisplay implements TestDisplay {
|
||||
/// // Fake the desired properties of the TestWindow. All code running
|
||||
/// // within this test will perceive the following fake text scale
|
||||
/// // factor as the real text scale factor of the window.
|
||||
/// testBinding.window.textScaleFactorFakeValue = 2.5;
|
||||
/// testBinding.window.textScaleFactorTestValue = 2.5; // ignore: deprecated_member_use
|
||||
///
|
||||
/// // Test code that depends on text scale factor here.
|
||||
/// });
|
||||
|
Loading…
Reference in New Issue
Block a user