mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This auto-formats all *.dart files in the repository outside of the `engine` subdirectory and enforces that these files stay formatted with a presubmit check. **Reviewers:** Please carefully review all the commits except for the one titled "formatted". The "formatted" commit was auto-generated by running `dev/tools/format.sh -a -f`. The other commits were hand-crafted to prepare the repo for the formatting change. I recommend reviewing the commits one-by-one via the "Commits" tab and avoiding Github's "Files changed" tab as it will likely slow down your browser because of the size of this PR. --------- Co-authored-by: Kate Lovett <katelovett@google.com> Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
142 lines
4.4 KiB
Dart
142 lines
4.4 KiB
Dart
// 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 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
/// On web, the context menu (aka toolbar) is provided by the browser.
|
|
const bool isContextMenuProvidedByPlatform = isBrowser;
|
|
|
|
// Returns the RenderEditable at the given index, or the first if not given.
|
|
RenderEditable findRenderEditable(WidgetTester tester, {int index = 0}) {
|
|
final RenderObject root = tester.renderObject(find.byType(EditableText).at(index));
|
|
expect(root, isNotNull);
|
|
|
|
late RenderEditable renderEditable;
|
|
void recursiveFinder(RenderObject child) {
|
|
if (child is RenderEditable) {
|
|
renderEditable = child;
|
|
return;
|
|
}
|
|
child.visitChildren(recursiveFinder);
|
|
}
|
|
|
|
root.visitChildren(recursiveFinder);
|
|
expect(renderEditable, isNotNull);
|
|
return renderEditable;
|
|
}
|
|
|
|
List<TextSelectionPoint> globalize(Iterable<TextSelectionPoint> points, RenderBox box) {
|
|
return points.map<TextSelectionPoint>((TextSelectionPoint point) {
|
|
return TextSelectionPoint(box.localToGlobal(point.point), point.direction);
|
|
}).toList();
|
|
}
|
|
|
|
Offset textOffsetToPosition(WidgetTester tester, int offset, {int index = 0}) {
|
|
final RenderEditable renderEditable = findRenderEditable(tester, index: index);
|
|
final List<TextSelectionPoint> endpoints = globalize(
|
|
renderEditable.getEndpointsForSelection(TextSelection.collapsed(offset: offset)),
|
|
renderEditable,
|
|
);
|
|
expect(endpoints.length, 1);
|
|
return endpoints[0].point + const Offset(kIsWeb ? 1.0 : 0.0, -2.0);
|
|
}
|
|
|
|
/// Mimic key press events by sending key down and key up events via the [tester].
|
|
Future<void> sendKeys(
|
|
WidgetTester tester,
|
|
List<LogicalKeyboardKey> keys, {
|
|
bool shift = false,
|
|
bool wordModifier = false,
|
|
bool lineModifier = false,
|
|
bool shortcutModifier = false,
|
|
required TargetPlatform targetPlatform,
|
|
}) async {
|
|
final String targetPlatformString = targetPlatform.toString();
|
|
final String platform =
|
|
targetPlatformString.substring(targetPlatformString.indexOf('.') + 1).toLowerCase();
|
|
if (shift) {
|
|
await tester.sendKeyDownEvent(LogicalKeyboardKey.shiftLeft, platform: platform);
|
|
}
|
|
if (shortcutModifier) {
|
|
await tester.sendKeyDownEvent(
|
|
platform == 'macos' || platform == 'ios'
|
|
? LogicalKeyboardKey.metaLeft
|
|
: LogicalKeyboardKey.controlLeft,
|
|
platform: platform,
|
|
);
|
|
}
|
|
if (wordModifier) {
|
|
await tester.sendKeyDownEvent(
|
|
platform == 'macos' || platform == 'ios'
|
|
? LogicalKeyboardKey.altLeft
|
|
: LogicalKeyboardKey.controlLeft,
|
|
platform: platform,
|
|
);
|
|
}
|
|
if (lineModifier) {
|
|
await tester.sendKeyDownEvent(
|
|
platform == 'macos' || platform == 'ios'
|
|
? LogicalKeyboardKey.metaLeft
|
|
: LogicalKeyboardKey.altLeft,
|
|
platform: platform,
|
|
);
|
|
}
|
|
for (final LogicalKeyboardKey key in keys) {
|
|
await tester.sendKeyEvent(key, platform: platform);
|
|
await tester.pump();
|
|
}
|
|
if (lineModifier) {
|
|
await tester.sendKeyUpEvent(
|
|
platform == 'macos' || platform == 'ios'
|
|
? LogicalKeyboardKey.metaLeft
|
|
: LogicalKeyboardKey.altLeft,
|
|
platform: platform,
|
|
);
|
|
}
|
|
if (wordModifier) {
|
|
await tester.sendKeyUpEvent(
|
|
platform == 'macos' || platform == 'ios'
|
|
? LogicalKeyboardKey.altLeft
|
|
: LogicalKeyboardKey.controlLeft,
|
|
platform: platform,
|
|
);
|
|
}
|
|
if (shortcutModifier) {
|
|
await tester.sendKeyUpEvent(
|
|
platform == 'macos' || platform == 'ios'
|
|
? LogicalKeyboardKey.metaLeft
|
|
: LogicalKeyboardKey.controlLeft,
|
|
platform: platform,
|
|
);
|
|
}
|
|
if (shift) {
|
|
await tester.sendKeyUpEvent(LogicalKeyboardKey.shiftLeft, platform: platform);
|
|
}
|
|
if (shift || wordModifier || lineModifier) {
|
|
await tester.pump();
|
|
}
|
|
}
|
|
|
|
// Simple controller that builds a WidgetSpan with 100 height.
|
|
class OverflowWidgetTextEditingController extends TextEditingController {
|
|
@override
|
|
TextSpan buildTextSpan({
|
|
required BuildContext context,
|
|
TextStyle? style,
|
|
required bool withComposing,
|
|
}) {
|
|
return TextSpan(
|
|
style: style,
|
|
children: <InlineSpan>[
|
|
const TextSpan(text: 'Hi'),
|
|
WidgetSpan(child: Container(color: Colors.redAccent, height: 100.0)),
|
|
],
|
|
);
|
|
}
|
|
}
|