blob: 3be96c46093d249dfada8c77cb10eb595add35c2 [file] [log] [blame]
// Copyright 2013 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/widgets.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter_test/flutter_test.dart';
import 'utils.dart';
void main() => defineTests();
void defineTests() {
group(
'structure',
() {
testWidgets(
'footnote is detected and handle correctly',
(WidgetTester tester) async {
const String data = 'Foo[^a]\n[^a]: Bar';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(
data: data,
),
),
);
final Iterable<Widget> widgets = tester.allWidgets;
expectTextStrings(widgets, <String>[
'Foo1',
'1.',
'Bar ↩',
]);
},
);
testWidgets(
'footnote is detected and handle correctly for selectable markdown',
(WidgetTester tester) async {
const String data = 'Foo[^a]\n[^a]: Bar';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(
data: data,
selectable: true,
),
),
);
final Iterable<Widget> widgets = tester.allWidgets;
expectTextStrings(widgets, <String>[
'Foo1',
'1.',
'Bar ↩',
]);
},
);
testWidgets(
'ignore footnotes without description',
(WidgetTester tester) async {
const String data = 'Foo[^1] Bar[^2]\n[^1]: Bar';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(
data: data,
),
),
);
final Iterable<Widget> widgets = tester.allWidgets;
expectTextStrings(widgets, <String>[
'Foo1 Bar[^2]',
'1.',
'Bar ↩',
]);
},
);
testWidgets(
'ignore superscripts and footnotes order',
(WidgetTester tester) async {
const String data = '[^2]: Bar \n [^1]: Foo \n Foo[^f] Bar[^b]';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(
data: data,
),
),
);
final Iterable<Widget> widgets = tester.allWidgets;
expectTextStrings(widgets, <String>[
'Foo1 Bar2',
'1.',
'Foo ↩',
'2.',
'Bar ↩',
]);
},
);
testWidgets(
'handle two digits superscript',
(WidgetTester tester) async {
const String data = '''
1[^1] 2[^2] 3[^3] 4[^4] 5[^5] 6[^6] 7[^7] 8[^8] 9[^9] 10[^10]
[^1]:1
[^2]:2
[^3]:3
[^4]:4
[^5]:5
[^6]:6
[^7]:7
[^8]:8
[^9]:9
[^10]:10
''';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(
data: data,
),
),
);
final Iterable<Widget> widgets = tester.allWidgets;
expectTextStrings(widgets, <String>[
'11 22 33 44 55 66 77 88 99 1010',
'1.',
'1 ↩',
'2.',
'2 ↩',
'3.',
'3 ↩',
'4.',
'4 ↩',
'5.',
'5 ↩',
'6.',
'6 ↩',
'7.',
'7 ↩',
'8.',
'8 ↩',
'9.',
'9 ↩',
'10.',
'10 ↩',
]);
},
);
},
);
group(
'superscript textstyle replacing',
() {
testWidgets(
'superscript has correct default fontfeature',
(WidgetTester tester) async {
const String data = 'Foo[^a]\n[^a]: Bar';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(
data: data,
),
),
);
final Iterable<Widget> widgets = tester.allWidgets;
final Text text =
widgets.firstWhere((Widget widget) => widget is Text) as Text;
final TextSpan span = text.textSpan! as TextSpan;
final List<InlineSpan>? children = span.children;
expect(children, isNotNull);
expect(children!.length, 2);
expect(children[1].style, isNotNull);
expect(children[1].style!.fontFeatures?.length, 1);
expect(children[1].style!.fontFeatures?.first.feature, 'sups');
},
);
testWidgets(
'superscript has correct custom fontfeature',
(WidgetTester tester) async {
const String data = 'Foo[^a]\n[^a]: Bar';
await tester.pumpWidget(
boilerplate(
MarkdownBody(
data: data,
styleSheet:
MarkdownStyleSheet(superscriptFontFeatureTag: 'numr'),
),
),
);
final Iterable<Widget> widgets = tester.allWidgets;
final Text text =
widgets.firstWhere((Widget widget) => widget is Text) as Text;
final TextSpan span = text.textSpan! as TextSpan;
final List<InlineSpan>? children = span.children;
expect(children, isNotNull);
expect(children!.length, 2);
expect(children[1].style, isNotNull);
expect(children[1].style!.fontFeatures?.length, 2);
expect(children[1].style!.fontFeatures?[1].feature, 'numr');
},
);
testWidgets(
'superscript index has the same font style like text',
(WidgetTester tester) async {
const String data = '# Foo[^a]\n[^a]: Bar';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(
data: data,
),
),
);
final Iterable<Widget> widgets = tester.allWidgets;
final Text text =
widgets.firstWhere((Widget widget) => widget is Text) as Text;
final TextSpan span = text.textSpan! as TextSpan;
final List<InlineSpan>? children = span.children;
expect(children![0].style, isNotNull);
expect(children[1].style!.fontSize, children[0].style!.fontSize);
expect(children[1].style!.fontFamily, children[0].style!.fontFamily);
expect(children[1].style!.fontStyle, children[0].style!.fontStyle);
expect(children[1].style!.fontSize, children[0].style!.fontSize);
},
);
testWidgets(
'link is correctly copied to new superscript index',
(WidgetTester tester) async {
final List<MarkdownLink> linkTapResults = <MarkdownLink>[];
const String data = 'Foo[^a]\n[^a]: Bar';
await tester.pumpWidget(
boilerplate(
MarkdownBody(
data: data,
onTapLink: (String text, String? href, String title) =>
linkTapResults.add(MarkdownLink(text, href, title)),
),
),
);
final Iterable<Widget> widgets = tester.allWidgets;
final Text text =
widgets.firstWhere((Widget widget) => widget is Text) as Text;
final TextSpan span = text.textSpan! as TextSpan;
final List<Type> gestureRecognizerTypes = <Type>[];
span.visitChildren((InlineSpan inlineSpan) {
if (inlineSpan is TextSpan) {
final TapGestureRecognizer? recognizer =
inlineSpan.recognizer as TapGestureRecognizer?;
gestureRecognizerTypes.add(recognizer?.runtimeType ?? Null);
if (recognizer != null) {
recognizer.onTap!();
}
}
return true;
});
expect(span.children!.length, 2);
expect(
gestureRecognizerTypes,
orderedEquals(<Type>[Null, TapGestureRecognizer]),
);
expectLinkTap(linkTapResults[0], const MarkdownLink('1', '#fn-a'));
},
);
},
);
}