Files
eatvio_app/test/common/widgets/markdown_editor_test.dart

627 lines
18 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.
import 'package:eatvio_app/common/widgets/markdown_editor.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('MarkdownEditor', () {
testWidgets('отображается как виджет', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(),
),
),
);
expect(find.byType(MarkdownEditor), findsOneWidget);
});
testWidgets('инициализируется с initialText', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(initialText: 'Initial text'),
),
),
);
expect(find.byType(MarkdownEditor), findsOneWidget);
});
testWidgets('отображает hintText', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(hintText: 'Enter text here'),
),
),
);
expect(find.byType(MarkdownEditor), findsOneWidget);
});
testWidgets('вызывает onChanged при изменении текста', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
onChanged: (value) => changedValue = value,
),
),
),
);
final textField = find.byType(TextField);
expect(textField, findsOneWidget);
await tester.enterText(textField, 'Test');
await tester.pump();
// onChanged должен быть вызван
expect(changedValue, isNotNull);
});
testWidgets('отображает toolbar когда showInlineToolbar = true', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(showInlineToolbar: true),
),
),
);
await tester.pump();
// Toolbar должен быть виден
expect(find.byIcon(Icons.format_bold), findsOneWidget);
});
testWidgets('скрывает toolbar когда showInlineToolbar = false', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(showInlineToolbar: false),
),
),
);
await tester.pump();
// Toolbar не должен быть виден
expect(find.byIcon(Icons.format_bold), findsNothing);
});
testWidgets('применяет форматирование жирным', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
onChanged: (value) => changedValue = value,
showInlineToolbar: true,
),
),
),
);
await tester.pump();
final textField = find.byType(TextField);
await tester.enterText(textField, 'Test');
await tester.pump();
// Нажимаем кнопку жирного
await tester.tap(find.byIcon(Icons.format_bold));
await tester.pump();
expect(changedValue, isNotNull);
});
testWidgets('применяет форматирование курсивом', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
onChanged: (value) => changedValue = value,
showInlineToolbar: true,
),
),
),
);
await tester.pump();
final textField = find.byType(TextField);
await tester.enterText(textField, 'Test');
await tester.pump();
await tester.tap(find.byIcon(Icons.format_italic));
await tester.pump();
expect(changedValue, isNotNull);
});
testWidgets('применяет заголовок', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
onChanged: (value) => changedValue = value,
showInlineToolbar: true,
),
),
),
);
await tester.pump();
final textField = find.byType(TextField);
await tester.enterText(textField, 'Test');
await tester.pump();
// Находим кнопку заголовка (текст 'H')
final headingButton = find.text('H');
await tester.tap(headingButton);
await tester.pump();
expect(changedValue, isNotNull);
});
testWidgets('применяет нумерованный список', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
onChanged: (value) => changedValue = value,
showInlineToolbar: true,
),
),
),
);
await tester.pump();
final textField = find.byType(TextField);
await tester.enterText(textField, 'Test');
await tester.pump();
await tester.tap(find.byIcon(Icons.format_list_numbered));
await tester.pump();
expect(changedValue, isNotNull);
});
testWidgets('применяет маркированный список', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
onChanged: (value) => changedValue = value,
showInlineToolbar: true,
),
),
),
);
await tester.pump();
final textField = find.byType(TextField);
await tester.enterText(textField, 'Test');
await tester.pump();
await tester.tap(find.byIcon(Icons.format_list_bulleted));
await tester.pump();
expect(changedValue, isNotNull);
});
testWidgets('применяет ссылку', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
onChanged: (value) => changedValue = value,
showInlineToolbar: true,
),
),
),
);
await tester.pump();
final textField = find.byType(TextField);
await tester.enterText(textField, 'Test');
await tester.pump();
await tester.tap(find.byIcon(Icons.link));
await tester.pump();
expect(changedValue, isNotNull);
});
testWidgets('применяет горизонтальную линию', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
onChanged: (value) => changedValue = value,
showInlineToolbar: true,
),
),
),
);
await tester.pump();
final textField = find.byType(TextField);
await tester.enterText(textField, 'Test');
await tester.pump();
await tester.tap(textField);
await tester.pump();
await tester.tap(find.byIcon(Icons.horizontal_rule));
await tester.pump();
expect(changedValue, contains('---'));
});
testWidgets('переключает режим preview', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: '# Test',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
// Изначально должен быть режим редактирования
expect(find.byType(TextField), findsOneWidget);
// Нажимаем кнопку preview
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
// Должен быть режим preview
expect(find.byType(TextField), findsNothing);
// Нажимаем кнопку редактирования
await tester.tap(find.byIcon(Icons.edit));
await tester.pumpAndSettle();
// Должен вернуться режим редактирования
expect(find.byType(TextField), findsOneWidget);
});
testWidgets('вызывает onToolbarVisibilityChanged при изменении видимости', (WidgetTester tester) async {
bool? toolbarVisible;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
showInlineToolbar: true,
onToolbarVisibilityChanged: (visible) => toolbarVisible = visible,
),
),
),
);
await tester.pumpAndSettle();
expect(toolbarVisible, isNotNull);
});
testWidgets('удаляет форматирование жирным если уже применено', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: '**Test**',
onChanged: (value) => changedValue = value,
showInlineToolbar: true,
),
),
),
);
await tester.pump();
final textField = find.byType(TextField);
await tester.tap(textField);
await tester.pump();
await tester.tap(find.byIcon(Icons.format_bold));
await tester.pump();
expect(changedValue, isNotNull);
});
testWidgets('обрабатывает ссылку в формате markdown', (WidgetTester tester) async {
String? changedValue;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: '[Link](url)',
onChanged: (value) => changedValue = value,
showInlineToolbar: true,
),
),
),
);
await tester.pump();
final textField = find.byType(TextField);
await tester.tap(textField);
await tester.pump();
await tester.tap(find.byIcon(Icons.link));
await tester.pump();
expect(changedValue, isNotNull);
});
testWidgets('отображает preview с заголовком', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: '# Heading',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
// Заголовок рендерится через Text виджет
expect(find.textContaining('Heading'), findsWidgets);
});
testWidgets('отображает preview с маркированным списком', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: '- Item 1\n- Item 2',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
// Проверяем, что preview отображается (RichText виджеты должны быть)
expect(find.byType(RichText), findsWidgets);
// Проверяем наличие текста через RichText
final richTexts = find.byType(RichText);
expect(richTexts, findsWidgets);
});
testWidgets('отображает preview с нумерованным списком', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: '1. First\n2. Second',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
// Проверяем, что preview отображается (RichText виджеты должны быть)
expect(find.byType(RichText), findsWidgets);
});
testWidgets('отображает preview с горизонтальной линией', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: '---',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
expect(find.byType(Divider), findsOneWidget);
});
testWidgets('обрабатывает hasError параметр', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
hasError: true,
),
),
),
);
expect(find.byType(MarkdownEditor), findsOneWidget);
});
testWidgets('обрабатывает minLines и maxLines', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
minLines: 2,
maxLines: 5,
),
),
),
);
expect(find.byType(MarkdownEditor), findsOneWidget);
});
testWidgets('обрабатывает heightPreview', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
heightPreview: 200,
initialText: 'Test',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
expect(find.byType(MarkdownEditor), findsOneWidget);
});
testWidgets('обрабатывает пустой текст в preview', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
hintText: 'Enter text',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
expect(find.text('Enter text'), findsOneWidget);
});
testWidgets('обрабатывает многострочный текст с форматированием', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: '# Title\n\n**Bold** text\n\n- List item',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
// Проверяем, что preview отображается (должны быть Text и RichText виджеты)
expect(find.byType(Text), findsWidgets);
expect(find.byType(RichText), findsWidgets);
});
testWidgets('обрабатывает встроенное форматирование в тексте', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: 'This is **bold** and this is *italic*',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
// Проверяем, что preview отображается (RichText должен быть)
expect(find.byType(RichText), findsWidgets);
});
testWidgets('обрабатывает ссылки в тексте', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: 'Check [this link](https://example.com)',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
// Проверяем, что preview отображается (RichText должен быть)
expect(find.byType(RichText), findsWidgets);
});
testWidgets('обрабатывает заголовки разных уровней', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: '# H1\n## H2\n### H3',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
expect(find.text('H1'), findsOneWidget);
expect(find.text('H2'), findsOneWidget);
expect(find.text('H3'), findsOneWidget);
});
testWidgets('обрабатывает пустые строки в preview', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
body: MarkdownEditor(
initialText: 'Line 1\n\nLine 2',
showInlineToolbar: true,
),
),
),
);
await tester.pump();
await tester.tap(find.byIcon(Icons.visibility));
await tester.pumpAndSettle();
// Проверяем, что preview отображается (RichText должен быть)
expect(find.byType(RichText), findsWidgets);
});
});
}