306 lines
11 KiB
Dart
306 lines
11 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/rendering.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import '../widgets/semantics_tester.dart';
|
|
|
|
void main() {
|
|
testWidgets('SemanticsNodes overlapping in z', (WidgetTester tester) async {
|
|
// Cards are semantic boundaries that always own their own SemanticNode,
|
|
// PhysicalModels merge their semantics information into parent.
|
|
//
|
|
// Side view of the widget tree:
|
|
//
|
|
// Card('abs. elevation: 30') ---------------
|
|
// | 8 ----------- Card('abs. elevation 25')
|
|
// Card('abs. elevation: 22') --------------- |
|
|
// | 7 |
|
|
// PhysicalModel('abs. elevation: 15') --------------- | 15
|
|
// | 5 |
|
|
// --------------------------------------- Card('abs. elevation: 10')
|
|
// | 10
|
|
// |
|
|
// --------------------------------------- 'ground'
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
await tester.pumpWidget(MaterialApp(
|
|
home: Column(
|
|
children: <Widget>[
|
|
const Text('ground'),
|
|
Card(
|
|
elevation: 10.0,
|
|
child: Column(
|
|
children: <Widget>[
|
|
const Text('absolute elevation: 10'),
|
|
PhysicalModel(
|
|
elevation: 5.0,
|
|
color: Colors.black,
|
|
child: Column(
|
|
children: <Widget>[
|
|
const Text('absolute elevation: 15'),
|
|
Card(
|
|
elevation: 7.0,
|
|
child: Column(
|
|
children: const <Widget>[
|
|
Text('absolute elevation: 22'),
|
|
Card(
|
|
elevation: 8.0,
|
|
child: Text('absolute elevation: 30'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const Card(
|
|
elevation: 15.0,
|
|
child: Text('absolute elevation: 25'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
final SemanticsNode ground = tester.getSemantics(find.text('ground'));
|
|
expect(ground.thickness, 0.0);
|
|
expect(ground.elevation, 0.0);
|
|
expect(ground.label, 'ground');
|
|
|
|
final SemanticsNode elevation10 = tester.getSemantics(find.text('absolute elevation: 10'));
|
|
final SemanticsNode elevation15 = tester.getSemantics(find.text('absolute elevation: 15'));
|
|
expect(elevation10, same(elevation15)); // configs got merged into each other.
|
|
expect(elevation10.thickness, 15.0);
|
|
expect(elevation10.elevation, 0.0);
|
|
expect(elevation10.label, 'absolute elevation: 10\nabsolute elevation: 15');
|
|
|
|
final SemanticsNode elevation22 = tester.getSemantics(find.text('absolute elevation: 22'));
|
|
expect(elevation22.thickness, 7.0);
|
|
expect(elevation22.elevation, 15.0);
|
|
expect(elevation22.label, 'absolute elevation: 22');
|
|
|
|
final SemanticsNode elevation25 = tester.getSemantics(find.text('absolute elevation: 25'));
|
|
expect(elevation25.thickness, 15.0);
|
|
expect(elevation25.elevation, 10.0);
|
|
expect(elevation22.label, 'absolute elevation: 22');
|
|
|
|
final SemanticsNode elevation30 = tester.getSemantics(find.text('absolute elevation: 30'));
|
|
expect(elevation30.thickness, 8.0);
|
|
expect(elevation30.elevation, 7.0);
|
|
expect(elevation30.label, 'absolute elevation: 30');
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
testWidgets('SemanticsNodes overlapping in z with switched children', (WidgetTester tester) async {
|
|
// Same as 'SemanticsNodes overlapping in z', but the order of children
|
|
// is reversed
|
|
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
await tester.pumpWidget(MaterialApp(
|
|
home: Column(
|
|
children: <Widget>[
|
|
const Text('ground'),
|
|
Card(
|
|
elevation: 10.0,
|
|
child: Column(
|
|
children: <Widget>[
|
|
const Card(
|
|
elevation: 15.0,
|
|
child: Text('absolute elevation: 25'),
|
|
),
|
|
PhysicalModel(
|
|
elevation: 5.0,
|
|
color: Colors.black,
|
|
child: Column(
|
|
children: <Widget>[
|
|
const Text('absolute elevation: 15'),
|
|
Card(
|
|
elevation: 7.0,
|
|
child: Column(
|
|
children: const <Widget>[
|
|
Text('absolute elevation: 22'),
|
|
Card(
|
|
elevation: 8.0,
|
|
child: Text('absolute elevation: 30'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const Text('absolute elevation: 10'),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
final SemanticsNode ground = tester.getSemantics(find.text('ground'));
|
|
expect(ground.thickness, 0.0);
|
|
expect(ground.elevation, 0.0);
|
|
expect(ground.label, 'ground');
|
|
|
|
final SemanticsNode elevation10 = tester.getSemantics(find.text('absolute elevation: 10'));
|
|
final SemanticsNode elevation15 = tester.getSemantics(find.text('absolute elevation: 15'));
|
|
expect(elevation10, same(elevation15)); // configs got merged into each other.
|
|
expect(elevation10.thickness, 15.0);
|
|
expect(elevation10.elevation, 0.0);
|
|
expect(elevation10.label, 'absolute elevation: 15\nabsolute elevation: 10');
|
|
|
|
final SemanticsNode elevation22 = tester.getSemantics(find.text('absolute elevation: 22'));
|
|
expect(elevation22.thickness, 7.0);
|
|
expect(elevation22.elevation, 15.0);
|
|
expect(elevation22.label, 'absolute elevation: 22');
|
|
|
|
final SemanticsNode elevation25 = tester.getSemantics(find.text('absolute elevation: 25'));
|
|
expect(elevation25.thickness, 15.0);
|
|
expect(elevation25.elevation, 10.0);
|
|
expect(elevation22.label, 'absolute elevation: 22');
|
|
|
|
final SemanticsNode elevation30 = tester.getSemantics(find.text('absolute elevation: 30'));
|
|
expect(elevation30.thickness, 8.0);
|
|
expect(elevation30.elevation, 7.0);
|
|
expect(elevation30.label, 'absolute elevation: 30');
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
testWidgets('single node thickness', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(const MaterialApp(
|
|
home: Center(
|
|
child: Material(
|
|
elevation: 24.0,
|
|
child: Text('Hello'),
|
|
),
|
|
),
|
|
));
|
|
|
|
final SemanticsNode node = tester.getSemantics(find.text('Hello'));
|
|
expect(node.thickness, 0.0);
|
|
expect(node.elevation, 24.0);
|
|
expect(node.label, 'Hello');
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
testWidgets('force-merge', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(MaterialApp(
|
|
home: Card(
|
|
elevation: 10.0,
|
|
child: Column(
|
|
children: <Widget>[
|
|
const Text('abs. elevation: 10.0'),
|
|
MergeSemantics(
|
|
child: Semantics(
|
|
explicitChildNodes: true, // just to be sure that it's going to be an explicit merge
|
|
child: Column(
|
|
children: const <Widget>[
|
|
Card(
|
|
elevation: 15.0,
|
|
child: Text('abs. elevation 25.0'),
|
|
),
|
|
Card(
|
|
elevation: 5.0,
|
|
child: Text('abs. elevation 15.0'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
));
|
|
|
|
|
|
final SemanticsNode elevation10 = tester.getSemantics(find.text('abs. elevation: 10.0'));
|
|
expect(elevation10.thickness, 10.0);
|
|
expect(elevation10.elevation, 0.0);
|
|
expect(elevation10.label, 'abs. elevation: 10.0');
|
|
expect(elevation10.childrenCount, 1);
|
|
|
|
// TODO(goderbauer): remove awkward workaround when accessing force-merged
|
|
// SemanticsData becomes easier, https://github.com/flutter/flutter/issues/25669
|
|
SemanticsData? mergedChildData;
|
|
elevation10.visitChildren((SemanticsNode child) {
|
|
expect(mergedChildData, isNull);
|
|
mergedChildData = child.getSemanticsData();
|
|
return true;
|
|
});
|
|
|
|
expect(mergedChildData!.thickness, 15.0);
|
|
expect(mergedChildData!.elevation, 10.0);
|
|
expect(mergedChildData!.label, 'abs. elevation 25.0\nabs. elevation 15.0');
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
testWidgets('force-merge with inversed children', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(MaterialApp(
|
|
home: Card(
|
|
elevation: 10.0,
|
|
child: Column(
|
|
children: <Widget>[
|
|
const Text('abs. elevation: 10.0'),
|
|
MergeSemantics(
|
|
child: Semantics(
|
|
explicitChildNodes: true, // just to be sure that it's going to be an explicit merge
|
|
child: Column(
|
|
children: const <Widget>[
|
|
Card(
|
|
elevation: 5.0,
|
|
child: Text('abs. elevation 15.0'),
|
|
),
|
|
Card(
|
|
elevation: 15.0,
|
|
child: Text('abs. elevation 25.0'),
|
|
),
|
|
],
|
|
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
));
|
|
|
|
|
|
final SemanticsNode elevation10 = tester.getSemantics(find.text('abs. elevation: 10.0'));
|
|
expect(elevation10.thickness, 10.0);
|
|
expect(elevation10.elevation, 0.0);
|
|
expect(elevation10.label, 'abs. elevation: 10.0');
|
|
expect(elevation10.childrenCount, 1);
|
|
|
|
// TODO(goderbauer): remove awkward workaround when accessing force-merged
|
|
// SemanticsData becomes easier, https://github.com/flutter/flutter/issues/25669
|
|
SemanticsData? mergedChildData;
|
|
elevation10.visitChildren((SemanticsNode child) {
|
|
expect(mergedChildData, isNull);
|
|
mergedChildData = child.getSemanticsData();
|
|
return true;
|
|
});
|
|
|
|
expect(mergedChildData!.thickness, 15.0);
|
|
expect(mergedChildData!.elevation, 10.0);
|
|
expect(mergedChildData!.label, 'abs. elevation 15.0\nabs. elevation 25.0');
|
|
|
|
semantics.dispose();
|
|
});
|
|
}
|