blob: 9002873820788c1fc6a346b0154dbe123742659b [file] [log] [blame]
// 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/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('RichText with recognizers without handlers does not throw', (
WidgetTester tester,
) async {
final TapGestureRecognizer recognizer1 = TapGestureRecognizer();
addTearDown(recognizer1.dispose);
final LongPressGestureRecognizer recognizer2 = LongPressGestureRecognizer();
addTearDown(recognizer2.dispose);
final DoubleTapGestureRecognizer recognizer3 = DoubleTapGestureRecognizer();
addTearDown(recognizer3.dispose);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: RichText(
text: TextSpan(
text: 'root',
children: <InlineSpan>[
TextSpan(text: 'one', recognizer: recognizer1),
TextSpan(text: 'two', recognizer: recognizer2),
TextSpan(text: 'three', recognizer: recognizer3),
],
),
),
),
);
expect(
tester.getSemantics(find.byType(RichText)),
matchesSemantics(
children: <Matcher>[
matchesSemantics(label: 'root'),
matchesSemantics(label: 'one'),
matchesSemantics(label: 'two'),
matchesSemantics(label: 'three'),
],
),
);
});
testWidgets('TextSpan Locale works', (WidgetTester tester) async {
final TapGestureRecognizer recognizer1 = TapGestureRecognizer();
addTearDown(recognizer1.dispose);
final DoubleTapGestureRecognizer recognizer2 = DoubleTapGestureRecognizer();
addTearDown(recognizer2.dispose);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: RichText(
text: TextSpan(
text: 'root',
locale: const Locale('es', 'MX'),
children: <InlineSpan>[
TextSpan(text: 'one', recognizer: recognizer1),
const WidgetSpan(child: SizedBox()),
TextSpan(text: 'three', recognizer: recognizer2),
],
),
),
),
);
expect(
tester.getSemantics(find.byType(RichText)),
matchesSemantics(
children: <Matcher>[
matchesSemantics(
attributedLabel: AttributedString(
'root',
attributes: <StringAttribute>[
LocaleStringAttribute(
range: const TextRange(start: 0, end: 4),
locale: const Locale('es', 'MX'),
),
],
),
),
matchesSemantics(
attributedLabel: AttributedString(
'one',
attributes: <StringAttribute>[
LocaleStringAttribute(
range: const TextRange(start: 0, end: 3),
locale: const Locale('es', 'MX'),
),
],
),
),
matchesSemantics(
attributedLabel: AttributedString(
'three',
attributes: <StringAttribute>[
LocaleStringAttribute(
range: const TextRange(start: 0, end: 5),
locale: const Locale('es', 'MX'),
),
],
),
),
],
),
);
});
testWidgets('TextSpan spellOut works', (WidgetTester tester) async {
final TapGestureRecognizer recognizer1 = TapGestureRecognizer();
addTearDown(recognizer1.dispose);
final DoubleTapGestureRecognizer recognizer2 = DoubleTapGestureRecognizer();
addTearDown(recognizer2.dispose);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: RichText(
text: TextSpan(
text: 'root',
spellOut: true,
children: <InlineSpan>[
TextSpan(text: 'one', recognizer: recognizer1),
const WidgetSpan(child: SizedBox()),
TextSpan(text: 'three', recognizer: recognizer2),
],
),
),
),
);
expect(
tester.getSemantics(find.byType(RichText)),
matchesSemantics(
children: <Matcher>[
matchesSemantics(
attributedLabel: AttributedString(
'root',
attributes: <StringAttribute>[
SpellOutStringAttribute(range: const TextRange(start: 0, end: 4)),
],
),
),
matchesSemantics(
attributedLabel: AttributedString(
'one',
attributes: <StringAttribute>[
SpellOutStringAttribute(range: const TextRange(start: 0, end: 3)),
],
),
),
matchesSemantics(
attributedLabel: AttributedString(
'three',
attributes: <StringAttribute>[
SpellOutStringAttribute(range: const TextRange(start: 0, end: 5)),
],
),
),
],
),
);
});
testWidgets('WidgetSpan calculate correct intrinsic heights', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: ColoredBox(
color: Colors.green,
child: IntrinsicHeight(
child: RichText(
text: const TextSpan(
children: <InlineSpan>[
TextSpan(text: 'Start\n', style: TextStyle(height: 1.0, fontSize: 16)),
WidgetSpan(child: Row(children: <Widget>[SizedBox(height: 16, width: 16)])),
TextSpan(text: 'End', style: TextStyle(height: 1.0, fontSize: 16)),
],
),
),
),
),
),
),
);
expect(tester.getSize(find.byType(IntrinsicHeight)).height, 3 * 16);
});
testWidgets('RichText implements debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
RichText(
text: const TextSpan(text: 'rich text'),
textAlign: TextAlign.center,
textDirection: TextDirection.rtl,
softWrap: false,
overflow: TextOverflow.ellipsis,
textScaleFactor: 1.3,
maxLines: 1,
locale: const Locale('zh', 'HK'),
strutStyle: const StrutStyle(fontSize: 16),
textWidthBasis: TextWidthBasis.longestLine,
textHeightBehavior: const TextHeightBehavior(applyHeightToFirstAscent: false),
).debugFillProperties(builder);
final List<String> description =
builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(
description,
unorderedMatches(<Matcher>[
contains('textAlign: center'),
contains('textDirection: rtl'),
contains('softWrap: no wrapping except at line break characters'),
contains('overflow: ellipsis'),
contains('textScaler: linear (1.3x)'),
contains('maxLines: 1'),
contains('textWidthBasis: longestLine'),
contains('text: "rich text"'),
contains('locale: zh_HK'),
allOf(startsWith('strutStyle: StrutStyle('), contains('size: 16.0')),
allOf(
startsWith('textHeightBehavior: TextHeightBehavior('),
contains('applyHeightToFirstAscent: false'),
contains('applyHeightToLastDescent: true'),
),
]),
);
});
}