259 lines
7.9 KiB
Dart
259 lines
7.9 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/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
final Matcher _matchesCommit = isMethodCall('TextInput.finishAutofillContext', arguments: true);
|
|
final Matcher _matchesCancel = isMethodCall('TextInput.finishAutofillContext', arguments: false);
|
|
|
|
void main() {
|
|
testWidgets('AutofillGroup has the right clients', (WidgetTester tester) async {
|
|
const outerKey = Key('outer');
|
|
const innerKey = Key('inner');
|
|
|
|
const client1 = TextField(autofillHints: <String>['1']);
|
|
const client2 = TextField(autofillHints: <String>['2']);
|
|
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: Scaffold(
|
|
body: AutofillGroup(
|
|
key: outerKey,
|
|
child: Column(
|
|
children: <Widget>[
|
|
client1,
|
|
AutofillGroup(
|
|
key: innerKey,
|
|
child: Column(children: <Widget>[client2, TextField(autofillHints: null)]),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final AutofillGroupState innerState = tester.state<AutofillGroupState>(find.byKey(innerKey));
|
|
final AutofillGroupState outerState = tester.state<AutofillGroupState>(find.byKey(outerKey));
|
|
|
|
final State<TextField> clientState1 = tester.state<State<TextField>>(find.byWidget(client1));
|
|
final State<TextField> clientState2 = tester.state<State<TextField>>(find.byWidget(client2));
|
|
|
|
expect(outerState.autofillClients.toList(), <State<TextField>>[clientState1]);
|
|
// The second TextField in the AutofillGroup doesn't have autofill enabled.
|
|
expect(innerState.autofillClients.toList(), <State<TextField>>[clientState2]);
|
|
});
|
|
|
|
testWidgets('new clients can be added & removed to a scope', (WidgetTester tester) async {
|
|
const scopeKey = Key('scope');
|
|
|
|
const client1 = TextField(autofillHints: <String>['1']);
|
|
var client2 = const TextField(autofillHints: null);
|
|
|
|
late StateSetter setState;
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: AutofillGroup(
|
|
key: scopeKey,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setter) {
|
|
setState = setter;
|
|
return Column(children: <Widget>[client1, client2]);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final AutofillGroupState scopeState = tester.state<AutofillGroupState>(find.byKey(scopeKey));
|
|
|
|
final State<TextField> clientState1 = tester.state<State<TextField>>(find.byWidget(client1));
|
|
final State<TextField> clientState2 = tester.state<State<TextField>>(find.byWidget(client2));
|
|
|
|
expect(scopeState.autofillClients.toList(), <State<TextField>>[clientState1]);
|
|
|
|
// Add to scope.
|
|
setState(() {
|
|
client2 = const TextField(autofillHints: <String>['2']);
|
|
});
|
|
|
|
await tester.pump();
|
|
|
|
expect(scopeState.autofillClients, contains(clientState1));
|
|
expect(scopeState.autofillClients, contains(clientState2));
|
|
expect(scopeState.autofillClients.length, 2);
|
|
|
|
// Remove from scope again.
|
|
setState(() {
|
|
client2 = const TextField(autofillHints: null);
|
|
});
|
|
|
|
await tester.pump();
|
|
|
|
expect(scopeState.autofillClients, <State<TextField>>[clientState1]);
|
|
});
|
|
|
|
testWidgets('AutofillGroup has the right clients after reparenting', (WidgetTester tester) async {
|
|
const outerKey = Key('outer');
|
|
const innerKey = Key('inner');
|
|
final GlobalKey keyClient3 = GlobalKey();
|
|
|
|
const client1 = TextField(autofillHints: <String>['1']);
|
|
const client2 = TextField(autofillHints: <String>['2']);
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: AutofillGroup(
|
|
key: outerKey,
|
|
child: Column(
|
|
children: <Widget>[
|
|
client1,
|
|
AutofillGroup(
|
|
key: innerKey,
|
|
child: Column(
|
|
children: <Widget>[
|
|
client2,
|
|
TextField(key: keyClient3, autofillHints: const <String>['3']),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final AutofillGroupState innerState = tester.state<AutofillGroupState>(find.byKey(innerKey));
|
|
final AutofillGroupState outerState = tester.state<AutofillGroupState>(find.byKey(outerKey));
|
|
|
|
final State<TextField> clientState1 = tester.state<State<TextField>>(find.byWidget(client1));
|
|
final State<TextField> clientState2 = tester.state<State<TextField>>(find.byWidget(client2));
|
|
final State<TextField> clientState3 = tester.state<State<TextField>>(find.byKey(keyClient3));
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: AutofillGroup(
|
|
key: outerKey,
|
|
child: Column(
|
|
children: <Widget>[
|
|
client1,
|
|
TextField(key: keyClient3, autofillHints: const <String>['3']),
|
|
const AutofillGroup(
|
|
key: innerKey,
|
|
child: Column(children: <Widget>[client2]),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(outerState.autofillClients.length, 2);
|
|
expect(outerState.autofillClients, contains(clientState1));
|
|
expect(outerState.autofillClients, contains(clientState3));
|
|
expect(innerState.autofillClients, <State<TextField>>[clientState2]);
|
|
});
|
|
|
|
testWidgets('disposing AutofillGroups', (WidgetTester tester) async {
|
|
late StateSetter setState;
|
|
const group1 = Key('group1');
|
|
const group2 = Key('group2');
|
|
const group3 = Key('group3');
|
|
const placeholder = TextField(autofillHints: <String>[AutofillHints.name]);
|
|
|
|
var children = const <Widget>[
|
|
AutofillGroup(
|
|
key: group1,
|
|
child: AutofillGroup(child: placeholder),
|
|
),
|
|
AutofillGroup(key: group2, onDisposeAction: AutofillContextAction.cancel, child: placeholder),
|
|
AutofillGroup(
|
|
key: group3,
|
|
child: AutofillGroup(child: placeholder),
|
|
),
|
|
];
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setter) {
|
|
setState = setter;
|
|
return Column(children: children);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(tester.testTextInput.log, isNot(contains(_matchesCommit)));
|
|
|
|
tester.testTextInput.log.clear();
|
|
|
|
// Remove the first topmost group group1. Should commit.
|
|
setState(() {
|
|
children = const <Widget>[
|
|
AutofillGroup(
|
|
key: group2,
|
|
onDisposeAction: AutofillContextAction.cancel,
|
|
child: placeholder,
|
|
),
|
|
AutofillGroup(
|
|
key: group3,
|
|
child: AutofillGroup(child: placeholder),
|
|
),
|
|
];
|
|
});
|
|
|
|
await tester.pump();
|
|
|
|
expect(tester.testTextInput.log.single, _matchesCommit);
|
|
|
|
tester.testTextInput.log.clear();
|
|
|
|
// Remove the topmost group group2. Should cancel.
|
|
setState(() {
|
|
children = const <Widget>[
|
|
AutofillGroup(
|
|
key: group3,
|
|
child: AutofillGroup(child: placeholder),
|
|
),
|
|
];
|
|
});
|
|
|
|
await tester.pump();
|
|
|
|
expect(tester.testTextInput.log.single, _matchesCancel);
|
|
|
|
tester.testTextInput.log.clear();
|
|
|
|
// Remove the inner group within group3. No action.
|
|
setState(() {
|
|
children = const <Widget>[AutofillGroup(key: group3, child: placeholder)];
|
|
});
|
|
|
|
await tester.pump();
|
|
|
|
expect(tester.testTextInput.log, isNot(contains('TextInput.finishAutofillContext')));
|
|
|
|
tester.testTextInput.log.clear();
|
|
|
|
// Remove the topmosts group group3. Should commit.
|
|
setState(() {
|
|
children = const <Widget>[];
|
|
});
|
|
|
|
await tester.pump();
|
|
|
|
expect(tester.testTextInput.log.single, _matchesCommit);
|
|
});
|
|
}
|