twonly-app-dependencies/flutter_markdown_plus/test/emphasis_test.dart
2026-04-22 17:15:35 +02:00

4287 lines
145 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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_plus/flutter_markdown_plus.dart';
import 'package:flutter_test/flutter_test.dart';
import 'utils.dart';
// The emphasis and strong emphasis section of the GitHub Flavored Markdown
// specification (https://github.github.com/gfm/#emphasis-and-strong-emphasis)
// is extensive covering over 130 example cases. The tests in this file cover
// all of the GFM tests; example 360 through 490.
void main() => defineTests();
void defineTests() {
group(
'Emphasis',
() {
group(
'Rule 1',
() {
// Rule 1 tests check the single '*' can open emphasis.
testWidgets(
// Example 360 from GFM.
'italic text using asterisk tags',
(WidgetTester tester) async {
const String data = '*foo bar*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 361 from GFM.
'invalid left-flanking delimiter run because * is followed by whitespace',
(WidgetTester tester) async {
const String data = 'a * foo bar*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 362 from GFM.
'invalid left-flanking delimiter run because * preceded by alphanumeric followed by punctuation',
(WidgetTester tester) async {
const String data = 'a*"foo bar"*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
// NOTE: Example 363 is not included. The test is "Unicode nonbreaking
// spaces count as whitespace, too: '* a *' The Markdown parse sees
// this as a unordered list item." https://github.github.com/gfm/#example-363
testWidgets(
// Example 364 from GFM.
'intraword emphasis with * is permitted alpha characters',
(WidgetTester tester) async {
const String data = 'foo*bar*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
expect(textWidget, isNotNull);
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foobar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with no emphasis.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 365 from GFM.
'intraword emphasis with * is permitted numeric characters',
(WidgetTester tester) async {
const String data = '5*6*78';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
expect(textWidget, isNotNull);
final String text = textWidget.textSpan!.toPlainText();
expect(text, '5678');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span is normal text with no emphasis.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Third text span is normal text with no emphasis.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
},
);
group('Rule 2', () {
testWidgets(
// Example 366 from GFM.
'italic text using underscore tags',
(WidgetTester tester) async {
const String data = '_foo bar_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 367 from GFM.
'invalid left-flanking delimiter run because _ is followed by whitespace',
(WidgetTester tester) async {
const String data = '_ foo bar_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 368 from GFM.
'invalid left-flanking delimiter run because _ preceded by alphanumeric followed by punctuation',
(WidgetTester tester) async {
const String data = 'a_"foo bar"_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 369 from GFM.
'emphasis with _ is not allowed inside words alpha characters',
(WidgetTester tester) async {
const String data = 'foo_bar_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 370 from GFM.
'emphasis with _ is not allowed inside words numeric characters',
(WidgetTester tester) async {
const String data = '5_6_78';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 371 from GFM.
'emphasis with _ is not allowed inside words unicode characters',
(WidgetTester tester) async {
const String data = 'пристаням_стремятся_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 372 from GFM.
'invalid first delimiter right-flanking followed by second delimiter left-flanking',
(WidgetTester tester) async {
const String data = 'aa_"bb"_cc';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 373 from GFM.
'valid open delimiter left- and right-flanking preceded by punctuation',
(WidgetTester tester) async {
const String data = 'foo-_(bar)_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo-(bar)');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with no emphasis.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
});
group('Rule 3', () {
testWidgets(
// Example 374 from GFM.
'invalid emphasis - closing delimiter does not match opening delimiter',
(WidgetTester tester) async {
const String data = '_foo*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 375 from GFM.
'invalid emphasis - closing * is preceded by whitespace',
(WidgetTester tester) async {
const String data = '*foo bar *';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 376 from GFM.
'invalid emphasis - closing * is preceded by newline',
(WidgetTester tester) async {
const String data = '*foo bar\n*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '*foo bar *');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 377 from GFM.
'invalid emphasis - second * is preceded by punctuation followed by alphanumeric',
(WidgetTester tester) async {
const String data = '*(*foo)';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 378 from GFM.
'nested * emphasis',
(WidgetTester tester) async {
const String data = '*(*foo*)*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '(foo)');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 379 from GFM.
'intraword emphasis with * is allowed',
(WidgetTester tester) async {
const String data = '*foo*bar';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foobar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span is normal text with no emphasis.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
});
group('Rule 4', () {
testWidgets(
// Example 380 from GFM.
'invalid emphasis because closing _ is preceded by whitespace',
(WidgetTester tester) async {
const String data = '_foo bar _';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 381 from GFM.
'invalid emphasis because second _ is preceded by punctuation and followed by an alphanumeric',
(WidgetTester tester) async {
const String data = '_(_foo)';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 382 from GFM.
'nested _ emphasis',
(WidgetTester tester) async {
const String data = '_(_foo_)_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '(foo)');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 383 from GFM.
'intraword emphasis with _ is disallowed - alpha characters',
(WidgetTester tester) async {
const String data = '_foo_bar';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 384 from GFM.
'intraword emphasis with _ is disallowed - unicode characters',
(WidgetTester tester) async {
const String data = '_пристаням_стремятся';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 385 from GFM.
'intraword emphasis with _ is disallowed - nested emphasis tags',
(WidgetTester tester) async {
const String data = '_foo_bar_baz_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo_bar_baz');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 386 from GFM.
'valid emphasis closing delimiter is both left- and right-flanking followed by punctuation',
(WidgetTester tester) async {
const String data = '_(bar)_.';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '(bar).');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span is normal text with no emphasis.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
});
group('Rule 5', () {
testWidgets(
// Example 387 from GFM.
'strong emphasis using ** emphasis tags',
(WidgetTester tester) async {
const String data = '**foo bar**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 388 from GFM.
'invalid strong emphasis - opening delimiter followed by whitespace',
(WidgetTester tester) async {
const String data = '** foo bar**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 389 from GFM.
'invalid strong emphasis - opening ** is preceded by an alphanumeric and followed by punctuation',
(WidgetTester tester) async {
const String data = 'a**"foo"**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 390 from GFM.
'intraword strong emphasis with ** is permitted',
(WidgetTester tester) async {
const String data = 'foo**bar**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foobar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with no emphasis.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
});
group('Rule 6', () {
testWidgets(
// Example 391 from GFM.
'strong emphasis using __ emphasis tags',
(WidgetTester tester) async {
const String data = '__foo bar__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 392 from GFM.
'invalid strong emphasis - opening delimiter followed by whitespace',
(WidgetTester tester) async {
const String data = '__ foo bar__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 393 from GFM.
'invalid strong emphasis - opening delimiter followed by newline',
(WidgetTester tester) async {
const String data = '__\nfoo bar__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '__ foo bar__');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 394 from GFM.
'invalid strong emphasis - opening __ is preceded by an alphanumeric and followed by punctuation',
(WidgetTester tester) async {
const String data = 'a__"foo"__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 395 from GFM.
'intraword strong emphasis is forbidden with __ - alpha characters',
(WidgetTester tester) async {
const String data = 'foo__bar__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 396 from GFM.
'intraword strong emphasis is forbidden with __ - numeric characters',
(WidgetTester tester) async {
const String data = '5__6__78';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 397 from GFM.
'intraword strong emphasis is forbidden with __ - unicode characters',
(WidgetTester tester) async {
const String data = 'пристаням__стремятся__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 398 from GFM.
'intraword strong emphasis is forbidden with __ - nested strong emphasis',
(WidgetTester tester) async {
const String data = '__foo, __bar__, baz__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo, bar, baz');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 399 from GFM.
'valid strong emphasis because opening delimiter is both left- and right-flanking preceded by punctuation',
(WidgetTester tester) async {
const String data = 'foo-__(bar)__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo-(bar)');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with no emphasis.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
});
group('Rule 7', () {
testWidgets(
// Example 400 from GFM.
'invalid strong emphasis - closing delimiter is preceded by whitespace',
(WidgetTester tester) async {
const String data = '**foo bar **';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 401 from GFM.
'invalid strong emphasis - second ** is preceded by punctuation and followed by an alphanumeric',
(WidgetTester tester) async {
const String data = '**(**foo)';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 402 from GFM.
'emphasis with nested strong emphasis',
(WidgetTester tester) async {
const String data = '*(**foo**)*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '(foo)');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has italic style with normal weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 403 from GFM.
'strong emphasis with multiple nested emphasis',
(WidgetTester tester) async {
const String data = '**Gomphocarpus (*Gomphocarpus physocarpus*, syn. *Asclepias physocarpa*)**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'Gomphocarpus (Gomphocarpus physocarpus, syn. Asclepias physocarpa)');
// There should be five spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 5, isTrue);
// First text span has bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span has both italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has bold weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
null,
FontWeight.bold,
);
// Fourth text span has both italic style with bold weight.
final InlineSpan fourthSpan = textSpan.children![3];
expectTextSpanStyle(
fourthSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Fifth text span has bold weight.
final InlineSpan fifthSpan = textSpan.children![4];
expectTextSpanStyle(
fifthSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 404 from GFM.
'strong emphasis with nested emphasis',
(WidgetTester tester) async {
const String data = '**foo "*bar*" foo**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo "bar" foo');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span has bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span has both italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has bold weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 405 from GFM.
'intraword strong emphasis',
(WidgetTester tester) async {
const String data = '**foo**bar';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foobar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with strong emphasis.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span is normal text with no emphasis.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
});
group('Rule 8', () {
testWidgets(
// Example 406 from GFM.
'invalid strong emphasis - closing delimiter is preceded by whitespace',
(WidgetTester tester) async {
const String data = '__foo bar __';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 407 from GFM.
'invalid strong emphasis - second __ is preceded by punctuation followed by alphanumeric',
(WidgetTester tester) async {
const String data = '__(__foo)';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 408 from GFM.
'strong emphasis nested in emphasis',
(WidgetTester tester) async {
const String data = '_(__foo__)_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '(foo)');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has italic style with normal weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 409 from GFM.
'intraword strong emphasis is forbidden with __ - alpha characters',
(WidgetTester tester) async {
const String data = '__foo__bar';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 410 from GFM.
'intraword strong emphasis is forbidden with __ - unicode characters',
(WidgetTester tester) async {
const String data = '__пристаням__стремятся';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 411 from GFM.
'intraword nested strong emphasis is forbidden with __',
(WidgetTester tester) async {
const String data = '__foo__bar__baz__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo__bar__baz');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 412 from GFM.
'strong emphasis because closing delimiter is both left- and right-flanking is followed by punctuation',
(WidgetTester tester) async {
const String data = '__(bar)__.';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '(bar).');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with strong emphasis.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
});
group('Rule 9', () {
testWidgets(
// Example 413 from GFM.
'nonempty sequence emphasis span - text followed by link',
(WidgetTester tester) async {
const String data = '*foo [bar](/url)*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is plain text and has italic style with normal weight.
final TextSpan firstSpan = textSpan.children![0] as TextSpan;
expect(firstSpan.recognizer, isNull);
expectTextSpanStyle(
firstSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final TextSpan secondSpan = textSpan.children![1] as TextSpan;
expect(secondSpan.recognizer, isNotNull);
expect(secondSpan.recognizer is GestureRecognizer, isTrue);
expectTextSpanStyle(
secondSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 414 from GFM.
'nonempty sequence emphasis span - two lines of text',
(WidgetTester tester) async {
const String data = '*foo\nbar*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 415 from GFM.
'strong emphasis nested inside emphasis - _ delimiter',
(WidgetTester tester) async {
const String data = '_foo __bar__ baz_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar baz');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has italic style with normal weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 416 from GFM.
'emphasis nested inside emphasis',
(WidgetTester tester) async {
const String data = '_foo _bar_ baz_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar baz');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 417 from GFM.
'intraword emphasis nested inside emphasis - _ delimiter',
(WidgetTester tester) async {
const String data = '__foo_ bar_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 418 from GFM.
'intraword emphasis nested inside emphasis - * delimiter',
(WidgetTester tester) async {
const String data = '*foo *bar**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 419 from GFM.
'strong emphasis nested inside emphasis - * delimiter',
(WidgetTester tester) async {
const String data = '*foo **bar** baz*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar baz');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has italic style with normal weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 418 from GFM.
'intraword strong emphasis nested inside emphasis - * delimiter',
(WidgetTester tester) async {
const String data = '*foo**bar**baz*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foobarbaz');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has italic style with normal weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 421 from GFM.
'consecutive emphasis sections are not allowed',
(WidgetTester tester) async {
const String data = '*foo**bar*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo**bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 422 from GFM.
'strong emphasis nested inside emphasis - space after first word',
(WidgetTester tester) async {
const String data = '***foo** bar*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 423 from GFM.
'strong emphasis nested inside emphasis - space before second word',
(WidgetTester tester) async {
const String data = '*foo **bar***';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
},
);
testWidgets(
// Example 424 from GFM.
'intraword strong emphasis nested inside emphasis',
(WidgetTester tester) async {
const String data = '*foo**bar***';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foobar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
},
);
testWidgets(
// Example 425 from GFM.
'intraword emphasis and strong emphasis',
(WidgetTester tester) async {
const String data = 'foo***bar***baz';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foobarbaz');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span is plain text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span is plain text with normal weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 426 from GFM.
'intraword emphasis and strong emphasis - multiples of 3',
(WidgetTester tester) async {
const String data = 'foo******bar*********baz';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foobar***baz');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span is plain text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span is plain text with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
// Third text span is plain text with normal weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 427 from GFM.
'infinite levels of nesting are possible within emphasis',
(WidgetTester tester) async {
const String data = '*foo **bar *baz*\nbim** bop*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar baz bim bop');
// There should be five spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length, 3);
// First text span has italic style and normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has both italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has bold weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 428 from GFM.
'infinite levels of nesting are possible within emphasis - text and a link',
(WidgetTester tester) async {
const String data = '*foo [*bar*](/url)*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style and normal weight.
final TextSpan firstSpan = textSpan.children![0] as TextSpan;
expect(firstSpan.recognizer, isNull);
expectTextSpanStyle(
firstSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final TextSpan secondSpan = textSpan.children![1] as TextSpan;
expect(secondSpan.recognizer, isNotNull);
expect(secondSpan.recognizer is GestureRecognizer, isTrue);
expectTextSpanStyle(
secondSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 429 from GFM.
'there can be no empty emphasis * delimiter',
(WidgetTester tester) async {
const String data = '** is not an empty emphasis';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 430 from GFM.
'there can be no empty strong emphasis * delimiter',
(WidgetTester tester) async {
const String data = '**** is not an empty strong emphasis';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
});
group('Rule 10', () {
testWidgets(
// Example 431 from GFM.
'nonempty sequence of inline elements with strong emphasis - text and a link',
(WidgetTester tester) async {
const String data = '**foo [bar](/url)**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with bold weight.
final TextSpan firstSpan = textSpan.children![0] as TextSpan;
expect(firstSpan.recognizer, isNull);
expectTextSpanStyle(
firstSpan,
null,
FontWeight.bold,
);
// Second span is a link with bold weight.
final TextSpan secondSpan = textSpan.children![1] as TextSpan;
expect(secondSpan.recognizer, isNotNull);
expect(secondSpan.recognizer is GestureRecognizer, isTrue);
expectTextSpanStyle(
secondSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 432 from GFM.
'nonempty sequence of inline elements with strong emphasis - two lines of texts',
(WidgetTester tester) async {
const String data = '**foo\nbar**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 433 from GFM.
'emphasis and strong emphasis nested inside strong emphasis - nested emphasis',
(WidgetTester tester) async {
const String data = '__foo _bar_ baz__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar baz');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span is plain text with bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span is plain text with bold weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 434 from GFM.
'emphasis and strong emphasis nested inside strong emphasis - nested strong emphasis',
(WidgetTester tester) async {
const String data = '__foo __bar__ baz__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar baz');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 435 from GFM.
'emphasis and strong emphasis nested inside strong emphasis - nested strong emphasis',
(WidgetTester tester) async {
const String data = '____foo__ bar__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 436 from GFM.
'emphasis and strong emphasis nested inside strong emphasis - nested strong emphasis',
(WidgetTester tester) async {
const String data = '**foo **bar****';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 437 from GFM.
'emphasis and strong emphasis nested inside strong emphasis - nested emphasis',
(WidgetTester tester) async {
const String data = '**foo *bar* baz**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar baz');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span is plain text with bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span is plain text with bold weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 438 from GFM.
'emphasis and strong emphasis nested inside strong emphasis - intraword nested emphasis',
(WidgetTester tester) async {
const String data = '**foo*bar*baz**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foobarbaz');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span is plain text with bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span is plain text with bold weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 439 from GFM.
'emphasis and strong emphasis nested inside strong emphasis - nested emphasis on first word',
(WidgetTester tester) async {
const String data = '***foo* bar**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Second span is plain text with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 440 from GFM.
'emphasis and strong emphasis nested inside strong emphasis - nested emphasis on second word',
(WidgetTester tester) async {
const String data = '**foo *bar***';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is plain text with bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
},
);
testWidgets(
// Example 441 from GFM.
'infinite levels of nesting are possible within strong emphasis',
(WidgetTester tester) async {
const String data = '**foo *bar **baz**\nbim* bop**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar baz bim bop');
// There should be five spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length, 3);
// First text span is plain text with bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span has both italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has both italic style with bold weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 442 from GFM.
'infinite levels of nesting are possible within strong emphasis - text and a link',
(WidgetTester tester) async {
const String data = '**foo [*bar*](/url)**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is plain text and bold weight.
final TextSpan firstSpan = textSpan.children![0] as TextSpan;
expect(firstSpan.recognizer, isNull);
expectTextSpanStyle(
firstSpan,
null,
FontWeight.bold,
);
// Second span has both italic style with normal weight.
final TextSpan secondSpan = textSpan.children![1] as TextSpan;
expect(secondSpan.recognizer, isNotNull);
expect(secondSpan.recognizer is GestureRecognizer, isTrue);
expectTextSpanStyle(
secondSpan,
FontStyle.italic,
FontWeight.bold,
);
},
);
testWidgets(
// Example 443 from GFM.
'there can be no empty emphasis _ delimiter',
(WidgetTester tester) async {
const String data = '__ is not an empty emphasis';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 444 from GFM.
'there can be no empty strong emphasis _ delimiter',
(WidgetTester tester) async {
const String data = '____ is not an empty strong emphasis';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
});
group('Rule 11', () {
testWidgets(
// Example 445 from GFM.
'an * cannot occur at the beginning or end of * delimited emphasis',
(WidgetTester tester) async {
const String data = 'foo ***';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 446 from GFM.
'an escaped * can occur inside * delimited emphasis',
(WidgetTester tester) async {
const String data = r'foo *\**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo *');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 446 from GFM.
'an _ can occur inside * delimited emphasis',
(WidgetTester tester) async {
const String data = 'foo *_*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo _');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 448 from GFM.
'an * cannot occur at the beginning or end of ** delimited strong emphasis',
(WidgetTester tester) async {
const String data = 'foo *****';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 449 from GFM.
'an escaped * can occur inside ** delimited strong emphasis',
(WidgetTester tester) async {
const String data = r'foo **\***';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo *');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span is normal text with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 450 from GFM.
'an _ can occur inside ** delimited strong emphasis',
(WidgetTester tester) async {
const String data = 'foo **_**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo _');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span is normal text with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 451 from GFM.
'unmatched emphasis delimiters excess * at beginning',
(WidgetTester tester) async {
const String data = '**foo*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '*foo');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 452 from GFM.
'unmatched emphasis delimiters excess * at end',
(WidgetTester tester) async {
const String data = '*foo**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo*');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span is normal text with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 453 from GFM.
'unmatched strong emphasis delimiters excess * at beginning',
(WidgetTester tester) async {
const String data = '***foo**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '*foo');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span is normal text with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 454 from GFM.
'unmatched strong emphasis delimiters excess * at beginning',
(WidgetTester tester) async {
const String data = '****foo*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '***foo');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 455 from GFM.
'unmatched strong emphasis delimiters excess * at end',
(WidgetTester tester) async {
const String data = '**foo***';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo*');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span is plain text with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 456 from GFM.
'unmatched strong emphasis delimiters excess * at end',
(WidgetTester tester) async {
const String data = '*foo****';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo***');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span is plain text with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
});
group('Rule 12', () {
testWidgets(
// Example 457 from GFM.
'an _ cannot occur at the beginning or end of _ delimited emphasis',
(WidgetTester tester) async {
const String data = 'foo ___';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 458 from GFM.
'an escaped _ can occur inside _ delimited emphasis',
(WidgetTester tester) async {
const String data = r'foo _\__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo _');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 459 from GFM.
'an * can occur inside _ delimited emphasis',
(WidgetTester tester) async {
const String data = 'foo _*_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo *');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 460 from GFM.
'an _ cannot occur at the beginning or end of __ delimited strong emphasis',
(WidgetTester tester) async {
const String data = 'foo _____';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, data);
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 461 from GFM.
'an escaped _ can occur inside __ delimited strong emphasis',
(WidgetTester tester) async {
const String data = r'foo __\___';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo _');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span is normal text with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 462 from GFM.
'an * can occur inside __ delimited strong emphasis',
(WidgetTester tester) async {
const String data = 'foo __*__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo *');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span is normal text with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 463 from GFM.
'unmatched emphasis delimiters excess _ at beginning',
(WidgetTester tester) async {
const String data = '__foo_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '_foo');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 464 from GFM.
'unmatched emphasis delimiters excess _ at end',
(WidgetTester tester) async {
const String data = '_foo__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo_');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span is normal text with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 465 from GFM.
'unmatched strong emphasis delimiters excess _ at beginning',
(WidgetTester tester) async {
const String data = '___foo__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '_foo');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span is normal text with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 466 from GFM.
'unmatched strong emphasis delimiters excess _ at beginning',
(WidgetTester tester) async {
const String data = '____foo_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '___foo');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 467 from GFM.
'unmatched strong emphasis delimiters excess _ at end',
(WidgetTester tester) async {
const String data = '__foo___';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo_');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is normal text with bold weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.bold,
);
// Second span is plain text with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 468 from GFM.
'unmatched strong emphasis delimiters excess _ at end',
(WidgetTester tester) async {
const String data = '_foo____';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
// Expect text to be unchanged from original data string.
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo___');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span is plain text with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
});
group('Rule 13', () {
testWidgets(
// Example 469 from GFM.
'nested delimiters must be different - nested * is strong emphasis',
(WidgetTester tester) async {
const String data = '**foo**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 470 from GFM.
'nested delimiters must be different - nest _ in * emphasis',
(WidgetTester tester) async {
const String data = '*_foo_*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 471 from GFM.
'nested delimiters must be different - nested _ is strong emphasis',
(WidgetTester tester) async {
const String data = '__foo__';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 472 from GFM.
'nested delimiters must be different - nest * in _ emphasis',
(WidgetTester tester) async {
const String data = '_*foo*_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
testWidgets(
// Example 473 from GFM.
'nested delimiters must be different - nested * strong emphasis',
(WidgetTester tester) async {
const String data = '****foo****';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 474 from GFM.
'nested delimiters must be different - nested _ strong emphasis',
(WidgetTester tester) async {
const String data = '____foo____';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 475 from GFM.
'nested delimiters must be different - long sequence of * delimiters',
(WidgetTester tester) async {
const String data = '******foo******';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
null,
FontWeight.bold,
);
},
);
});
// Rule 14 doesn't make any difference to flutter_markdown_plus but tests for
// rule 14 are included here for completeness.
group('Rule 14', () {
testWidgets(
// Example 476 from GFM.
'font style and weight order * delimiter',
(WidgetTester tester) async {
const String data = '***foo***';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
},
);
testWidgets(
// Example 476 from GFM.
'font style and weight order _ delimiter',
(WidgetTester tester) async {
const String data = '_____foo_____';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo');
expectTextSpanStyle(
textWidget.textSpan! as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
},
);
});
group('Rule 15', () {
testWidgets(
// Example 478 from GFM.
'overlapping * and _ emphasis delimiters',
(WidgetTester tester) async {
const String data = '*foo _bar* baz_';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo _bar baz_');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span is plain text with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.normal,
);
},
);
testWidgets(
// Example 479 from GFM.
'overlapping * and __ emphasis delimiters',
(WidgetTester tester) async {
const String data = '*foo __bar *baz bim__ bam*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, 'foo bar *baz bim bam');
// There should be three spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 3, isTrue);
// First text span has italic style with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
// Second span has italic style with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.bold,
);
// Third text span has italic style with normal weight.
final InlineSpan thirdSpan = textSpan.children![2];
expectTextSpanStyle(
thirdSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
});
group('Rule 16', () {
testWidgets(
// Example 480 from GFM.
'overlapping ** strong emphasis delimiters',
(WidgetTester tester) async {
const String data = '**foo **bar baz**';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '**foo bar baz');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is plain text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span is plain text with bold weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
null,
FontWeight.bold,
);
},
);
testWidgets(
// Example 479 from GFM.
'overlapping * emphasis delimiters',
(WidgetTester tester) async {
const String data = '*foo *bar baz*';
await tester.pumpWidget(
boilerplate(
const MarkdownBody(data: data),
),
);
final Finder textFinder = find.byType(Text);
expect(textFinder, findsOneWidget);
final Text textWidget = textFinder.evaluate().first.widget as Text;
final String text = textWidget.textSpan!.toPlainText();
expect(text, '*foo bar baz');
// There should be two spans of text.
final TextSpan textSpan = textWidget.textSpan! as TextSpan;
expect(textSpan, isNotNull);
expect(textSpan.children!.length == 2, isTrue);
// First text span is plain text with normal weight.
final InlineSpan firstSpan = textSpan.children![0];
expectTextSpanStyle(
firstSpan as TextSpan,
null,
FontWeight.normal,
);
// Second span has italic style with normal weight.
final InlineSpan secondSpan = textSpan.children![1];
expectTextSpanStyle(
secondSpan as TextSpan,
FontStyle.italic,
FontWeight.normal,
);
},
);
});
group('Rule 17', () {
// The markdown package does not follow rule 17. Sam Rawlins made the
// following comment on issue #280 on March 7, 2020:
//
// In terms of the spec, we are not following Rule 17 of "Emphasis and
// strong emphasis." Inline code spans, links, images, and HTML tags
// group more tightly than emphasis. Currently the Dart package respects
// the broader rule that any time we can close a tag, we do, attempting
// in the order of most recent openings first. I don't think this is
// terribly hard to correct.
// https://github.com/dart-lang/markdown/issues/280
//
// Test for rule 17 are not included since markdown package is not
// following the rule.
}, skip: 'No Rule 17 tests implemented');
},
);
}