Add tests for shared_app_data.#.dart API examples. (#147830)

This PR contributes to https://github.com/flutter/flutter/issues/130459

### Description
- Updates `examples/api/lib/widgets/shared_app_data/shared_app_data.0.dart` to meet latest API examples structure
- Updates `examples/api/lib/widgets/shared_app_data/shared_app_data.1.dart` to meet latest API examples structure
- Adds tests for `examples/api/lib/widgets/shared_app_data/shared_app_data.0.dart`
- Adds tests for `examples/api/lib/widgets/shared_app_data/shared_app_data.1.dart`
This commit is contained in:
Kostia Sokolovskyi 2024-05-20 19:49:04 +02:00 committed by GitHub
parent 6cb9119148
commit d9cf066191
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 242 additions and 45 deletions

View File

@ -384,8 +384,6 @@ final Set<String> _knownMissingTests = <String>{
'examples/api/test/widgets/inherited_theme/inherited_theme.0_test.dart', 'examples/api/test/widgets/inherited_theme/inherited_theme.0_test.dart',
'examples/api/test/widgets/sliver/decorated_sliver.0_test.dart', 'examples/api/test/widgets/sliver/decorated_sliver.0_test.dart',
'examples/api/test/widgets/autofill/autofill_group.0_test.dart', 'examples/api/test/widgets/autofill/autofill_group.0_test.dart',
'examples/api/test/widgets/shared_app_data/shared_app_data.1_test.dart',
'examples/api/test/widgets/shared_app_data/shared_app_data.0_test.dart',
'examples/api/test/widgets/nested_scroll_view/nested_scroll_view_state.0_test.dart', 'examples/api/test/widgets/nested_scroll_view/nested_scroll_view_state.0_test.dart',
'examples/api/test/widgets/nested_scroll_view/nested_scroll_view.2_test.dart', 'examples/api/test/widgets/nested_scroll_view/nested_scroll_view.2_test.dart',
'examples/api/test/widgets/nested_scroll_view/nested_scroll_view.1_test.dart', 'examples/api/test/widgets/nested_scroll_view/nested_scroll_view.1_test.dart',

View File

@ -6,38 +6,41 @@ import 'package:flutter/material.dart';
/// Flutter code sample for [SharedAppData]. /// Flutter code sample for [SharedAppData].
class ShowSharedValue extends StatelessWidget { void main() {
const ShowSharedValue({super.key, required this.appDataKey}); runApp(const SharedAppDataExampleApp());
}
final String appDataKey; class SharedAppDataExampleApp extends StatelessWidget {
const SharedAppDataExampleApp({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// The SharedAppData.getValue() call causes this widget to depend on the return const MaterialApp(
// value of the SharedAppData's 'foo' key. If it's changed, with home: SharedAppDataExample(),
// SharedAppData.setValue(), then this widget will be rebuilt. );
final String value = SharedAppData.getValue<String, String>(context, appDataKey, () => 'initial');
return Text('$appDataKey: $value');
} }
} }
// Demonstrates that changes to the SharedAppData _only_ cause the dependent // Demonstrates that changes to the SharedAppData _only_ cause the dependent
// widgets to be rebuilt. In this case that's the ShowSharedValue widget that's // widgets to be rebuilt. In this case that's the ShowSharedValue widget that's
// displaying the value of a key whose value has been updated. // displaying the value of a key whose value has been updated.
class Home extends StatefulWidget { class SharedAppDataExample extends StatefulWidget {
const Home({super.key}); const SharedAppDataExample({super.key});
@override @override
State<Home> createState() => _HomeState(); State<SharedAppDataExample> createState() => _SharedAppDataExampleState();
} }
class _HomeState extends State<Home> { class _SharedAppDataExampleState extends State<SharedAppDataExample> {
int _fooVersion = 0; int _fooVersion = 0;
int _barVersion = 0; int _barVersion = 0;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar(
title: const Text('SharedAppData Sample'),
),
body: Center( body: Center(
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -50,10 +53,13 @@ class _HomeState extends State<Home> {
child: const Text('change foo'), child: const Text('change foo'),
onPressed: () { onPressed: () {
_fooVersion += 1; _fooVersion += 1;
// Changing the SharedAppData's value for 'foo' causes the // Changing the SharedAppData's value for 'foo' key causes the
// widgets that depend on 'foo' to be rebuilt. // widgets that depend on 'foo' key to be rebuilt.
SharedAppData.setValue<String, String?>( SharedAppData.setValue<String, String?>(
context, 'foo', 'FOO $_fooVersion'); // no need to call setState() context,
'foo',
'FOO $_fooVersion',
); // No need to call setState().
}, },
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
@ -61,8 +67,13 @@ class _HomeState extends State<Home> {
child: const Text('change bar'), child: const Text('change bar'),
onPressed: () { onPressed: () {
_barVersion += 1; _barVersion += 1;
// Changing the SharedAppData's value for 'bar' key causes the
// widgets that depend on 'bar' key to be rebuilt.
SharedAppData.setValue<String, String?>( SharedAppData.setValue<String, String?>(
context, 'bar', 'BAR $_barVersion'); // no need to call setState() context,
'bar',
'BAR $_barVersion',
); // No need to call setState().
}, },
), ),
], ],
@ -72,6 +83,22 @@ class _HomeState extends State<Home> {
} }
} }
void main() { class ShowSharedValue extends StatelessWidget {
runApp(const MaterialApp(home: Home())); const ShowSharedValue({super.key, required this.appDataKey});
final String appDataKey;
@override
Widget build(BuildContext context) {
// The SharedAppData.getValue() call causes this widget to depend on the
// value of the SharedAppData's key. If it's changed, with
// SharedAppData.setValue(), then this widget will be rebuilt.
final String value = SharedAppData.getValue<String, String>(
context,
appDataKey,
() => 'initial',
);
return Text('$appDataKey: $value');
}
} }

View File

@ -7,27 +7,34 @@ import 'package:flutter/material.dart';
/// Flutter code sample for [SharedAppData]. /// Flutter code sample for [SharedAppData].
// A single lazily-constructed object that's shared with the entire application void main() {
// via `SharedObject.of(context)`. The value of the object can be changed with runApp(const SharedAppDataExampleApp());
// `SharedObject.reset(context)`. Resetting the value will cause all of the }
// widgets that depend on it to be rebuilt.
class SharedObject {
SharedObject._();
static final Object _sharedObjectKey = Object(); class SharedAppDataExampleApp extends StatelessWidget {
const SharedAppDataExampleApp({super.key});
@override @override
String toString() => describeIdentity(this); Widget build(BuildContext context) {
return const MaterialApp(
static void reset(BuildContext context) { home: SharedAppDataExample(),
// Calling SharedAppData.setValue() causes dependent widgets to be rebuilt. );
SharedAppData.setValue<Object, SharedObject>(context, _sharedObjectKey, SharedObject._());
} }
}
static SharedObject of(BuildContext context) { class SharedAppDataExample extends StatelessWidget {
// If a value for _sharedObjectKey has never been set then the third const SharedAppDataExample({super.key});
// callback parameter is used to generate an initial value.
return SharedAppData.getValue<Object, SharedObject>(context, _sharedObjectKey, () => SharedObject._()); @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('SharedAppData Sample'),
),
body: const Center(
child: CustomWidget(),
),
);
} }
} }
@ -48,17 +55,34 @@ class CustomWidget extends StatelessWidget {
} }
} }
class Home extends StatelessWidget { // A single lazily-constructed object that's shared with the entire application
const Home({super.key}); // via `SharedObject.of(context)`. The value of the object can be changed with
// `SharedObject.reset(context)`. Resetting the value will cause all of the
// widgets that depend on it to be rebuilt.
class SharedObject {
SharedObject._();
static final Object _sharedObjectKey = Object();
@override @override
Widget build(BuildContext context) { String toString() => describeIdentity(this);
return const Scaffold(
body: Center(child: CustomWidget()), static void reset(BuildContext context) {
// Calling SharedAppData.setValue() causes dependent widgets to be rebuilt.
SharedAppData.setValue<Object, SharedObject>(
context,
_sharedObjectKey,
SharedObject._(),
);
}
static SharedObject of(BuildContext context) {
// If a value for _sharedObjectKey has never been set then the third
// callback parameter is used to generate an initial value.
return SharedAppData.getValue<Object, SharedObject>(
context,
_sharedObjectKey,
() => SharedObject._(),
); );
} }
} }
void main() {
runApp(const MaterialApp(home: Home()));
}

View File

@ -0,0 +1,100 @@
// 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_api_samples/widgets/shared_app_data/shared_app_data.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Verify correct labels are displayed', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SharedAppDataExampleApp(),
);
expect(find.text('SharedAppData Sample'), findsOneWidget);
expect(find.text('foo: initial'), findsOneWidget);
expect(find.text('bar: initial'), findsOneWidget);
expect(find.text('change foo'), findsOneWidget);
expect(find.text('change bar'), findsOneWidget);
});
testWidgets('foo value can be updated', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SharedAppDataExampleApp(),
);
int counter = 0;
while (counter < 10) {
counter++;
await tester.tap(find.ancestor(
of: find.text('change foo'),
matching: find.byType(ElevatedButton),
));
await tester.pump();
expect(find.text('foo: FOO $counter'), findsOneWidget);
}
});
testWidgets('bar value can be updated', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SharedAppDataExampleApp(),
);
int counter = 0;
while (counter < 10) {
counter++;
await tester.tap(find.ancestor(
of: find.text('change bar'),
matching: find.byType(ElevatedButton),
));
await tester.pump();
expect(find.text('bar: BAR $counter'), findsOneWidget);
}
});
testWidgets('foo and bar values update independently of one another', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SharedAppDataExampleApp(),
);
int fooCounter = 0;
int barCounter = 0;
for (int i = 0; i < 20; i++) {
if (i.isEven) {
fooCounter++;
} else {
barCounter++;
}
await tester.tap(
find.ancestor(
of: i.isEven ? find.text('change foo') : find.text('change bar'),
matching: find.byType(ElevatedButton),
),
);
await tester.pump();
expect(
find.text(
'foo: ${fooCounter == 0 ? 'initial' : 'FOO $fooCounter'}',
),
findsOneWidget,
);
expect(
find.text(
'bar: ${barCounter == 0 ? 'initial' : 'BAR $barCounter'}',
),
findsOneWidget,
);
}
});
}

View File

@ -0,0 +1,48 @@
// 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_api_samples/widgets/shared_app_data/shared_app_data.1.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
example.SharedObject getSharedObject(WidgetTester tester) {
final BuildContext context = tester.element(
find.byType(example.CustomWidget),
);
return example.SharedObject.of(context);
}
testWidgets('Verify correct labels are displayed', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SharedAppDataExampleApp(),
);
final example.SharedObject sharedObject = getSharedObject(tester);
expect(find.text('SharedAppData Sample'), findsOneWidget);
expect(find.text('Replace $sharedObject'), findsOneWidget);
});
testWidgets('Button tap resets SharedObject', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SharedAppDataExampleApp(),
);
for (int i = 0; i < 10; i++) {
final example.SharedObject sharedObject = getSharedObject(tester);
final Finder buttonFinder = find.ancestor(
of: find.text('Replace $sharedObject'),
matching: find.byType(ElevatedButton),
);
expect(buttonFinder, findsOneWidget);
await tester.tap(buttonFinder);
await tester.pump();
}
});
}