From 9878de42211433abb7fd799baff2dacdba63a623 Mon Sep 17 00:00:00 2001 From: Jatin Date: Fri, 31 Oct 2025 22:29:54 +0530 Subject: [PATCH] test: add widget tests for SavedPagesScreen functionality --- pubspec.lock | 130 +++- pubspec.yaml | 9 +- test/ui/screens/saved_pages_test.dart | 448 ++++++++++++ test/ui/screens/saved_pages_test.mocks.dart | 738 ++++++++++++++++++++ 4 files changed, 1320 insertions(+), 5 deletions(-) create mode 100644 test/ui/screens/saved_pages_test.dart create mode 100644 test/ui/screens/saved_pages_test.mocks.dart diff --git a/pubspec.lock b/pubspec.lock index 02d75ecc..18bfc3a0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -58,7 +58,7 @@ packages: source: hosted version: "9.0.0" bloc_test: - dependency: "direct main" + dependency: "direct dev" description: name: bloc_test sha256: "1dd549e58be35148bc22a9135962106aa29334bc1e3f285994946a1057b29d7b" @@ -73,6 +73,70 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + build: + dependency: transitive + description: + name: build + sha256: ce76b1d48875e3233fde17717c23d1f60a91cc631597e49a400c89b475395b1d + url: "https://pub.dev" + source: hosted + version: "3.1.0" + build_config: + dependency: transitive + description: + name: build_config + sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "409002f1adeea601018715d613115cfaf0e31f512cb80ae4534c79867ae2363d" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: d1d57f7807debd7349b4726a19fd32ec8bc177c71ad0febf91a20f84cd2d4b46 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: b24597fceb695969d47025c958f3837f9f0122e237c6a22cb082a5ac66c3ca30 + url: "https://pub.dev" + source: hosted + version: "2.7.1" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: "066dda7f73d8eb48ba630a55acb50c4a84a2e6b453b1cb4567f581729e794f7b" + url: "https://pub.dev" + source: hosted + version: "9.3.1" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: a30f0a0e38671e89a492c44d005b5545b830a961575bbd8336d42869ff71066d + url: "https://pub.dev" + source: hosted + version: "8.12.0" characters: dependency: transitive description: @@ -113,6 +177,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243" + url: "https://pub.dev" + source: hosted + version: "4.11.0" collection: dependency: transitive description: @@ -169,6 +241,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb" + url: "https://pub.dev" + source: hosted + version: "3.1.1" device_info_plus: dependency: transitive description: @@ -352,6 +432,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.3.1" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.dev" + source: hosted + version: "2.3.2" html: dependency: transitive description: @@ -568,6 +656,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + mockito: + dependency: "direct dev" + description: + name: mockito + sha256: "2314cbe9165bcd16106513df9cf3c3224713087f09723b128928dc11a4379f99" + url: "https://pub.dev" + source: hosted + version: "5.5.0" mocktail: dependency: transitive description: @@ -720,6 +816,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + url: "https://pub.dev" + source: hosted + version: "1.5.0" shared_preferences: dependency: "direct main" description: @@ -813,6 +917,14 @@ packages: description: flutter source: sdk version: "0.0.0" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "7b19d6ba131c6eb98bfcbf8d56c1a7002eba438af2e7ae6f8398b2b0f4f381e3" + url: "https://pub.dev" + source: hosted + version: "3.1.0" source_map_stack_trace: dependency: transitive description: @@ -861,6 +973,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://pub.dev" + source: hosted + version: "2.1.1" string_scanner: dependency: transitive description: @@ -917,6 +1037,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.8" + timing: + dependency: transitive + description: + name: timing + sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" + url: "https://pub.dev" + source: hosted + version: "1.0.2" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ccfbc8fd..430f1c4a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: texterra description: "This project provides an interactive user interface to control font properties such as font size, font family, font color, and font style. Built using Flutter and Bloc for state management, it ensures a modern, responsive, and smooth user experience." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -42,11 +42,13 @@ dependencies: image_picker: ^1.2.0 path_provider: ^2.1.5 path: ^1.9.1 - bloc_test: ^10.0.0 dev_dependencies: flutter_test: sdk: flutter + mockito: ^5.5.0 + bloc_test: ^10.0.0 + build_runner: ^2.7.1 # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is @@ -61,7 +63,6 @@ dev_dependencies: # The following section is specific to Flutter packages. flutter: - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. @@ -111,6 +112,6 @@ flutter_native_splash: fullscreen: true image: assets/icons/whitebg.png - android_12: + android_12: color: "#ffffff" image: assets/icons/whitebg.png diff --git a/test/ui/screens/saved_pages_test.dart b/test/ui/screens/saved_pages_test.dart new file mode 100644 index 00000000..33a14a5c --- /dev/null +++ b/test/ui/screens/saved_pages_test.dart @@ -0,0 +1,448 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:mockito/mockito.dart'; +import 'package:mockito/annotations.dart'; + +// Import your actual files - adjust paths as needed +import 'package:texterra/cubit/canvas_cubit.dart'; +import 'package:texterra/cubit/canvas_state.dart'; +import 'package:texterra/constants/color_constants.dart'; +import 'package:texterra/ui/screens/saved_pages.dart'; + +// Generate mocks +@GenerateMocks([CanvasCubit]) +import 'saved_pages_test.mocks.dart'; + +void main() { + late MockCanvasCubit mockCanvasCubit; + + setUp(() { + mockCanvasCubit = MockCanvasCubit(); + + // Setup default state + when(mockCanvasCubit.state).thenReturn(CanvasState.initial()); + when(mockCanvasCubit.stream) + .thenAnswer((_) => Stream.value(CanvasState.initial())); + }); + + Widget createTestWidget() { + return MaterialApp( + home: BlocProvider.value( + value: mockCanvasCubit, + child: const SavedPagesScreen(), + ), + ); + } + + group('SavedPagesScreen Widget Tests', () { + testWidgets('displays empty state when no pages saved', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => []); + when(mockCanvasCubit.getPagePreview(any)).thenAnswer((_) async => null); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.byIcon(Icons.description_outlined), findsOneWidget); + expect(find.text('No saved pages yet'), findsOneWidget); + expect(find.text('Create and save your first page!'), findsOneWidget); + }); + + testWidgets('displays list of saved pages', (WidgetTester tester) async { + // Arrange + final mockPages = ['Page 1', 'Page 2', 'Page 3']; + when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => mockPages); + + for (var pageName in mockPages) { + when(mockCanvasCubit.getPagePreview(pageName)).thenAnswer((_) async => { + 'name': pageName, + 'textCount': 5, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + } + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.text('Page 1'), findsOneWidget); + expect(find.text('Page 2'), findsOneWidget); + expect(find.text('Page 3'), findsOneWidget); + expect(find.byType(Card), findsNWidgets(3)); + }); + + testWidgets('displays correct text count for pages', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['Test Page']); + when(mockCanvasCubit.getPagePreview('Test Page')) + .thenAnswer((_) async => { + 'name': 'Test Page', + 'textCount': 3, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.text('3 text items'), findsOneWidget); + }); + + testWidgets('displays singular text item correctly', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['Single Item']); + when(mockCanvasCubit.getPagePreview('Single Item')) + .thenAnswer((_) async => { + 'name': 'Single Item', + 'textCount': 1, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.text('1 text item'), findsOneWidget); + }); + + testWidgets('has app bar with correct title', (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => []); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.text('Saved Pages'), findsOneWidget); + expect(find.byType(AppBar), findsOneWidget); + }); + + testWidgets('has back button in app bar', (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => []); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.byIcon(Icons.arrow_back), findsOneWidget); + }); + + testWidgets('has refresh button in app bar', (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => []); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.byIcon(Icons.refresh), findsOneWidget); + }); + + testWidgets('displays page label when available', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['Labeled Page']); + when(mockCanvasCubit.getPagePreview('Labeled Page')) + .thenAnswer((_) async => { + 'name': 'Labeled Page', + 'textCount': 2, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': 'AB', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.text('AB'), findsOneWidget); + }); + + testWidgets('displays description icon when no label', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['No Label']); + when(mockCanvasCubit.getPagePreview('No Label')).thenAnswer((_) async => { + 'name': 'No Label', + 'textCount': 2, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.byIcon(Icons.description), findsOneWidget); + }); + + testWidgets('shows open and delete buttons for each page', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['Test Page']); + when(mockCanvasCubit.getPagePreview('Test Page')) + .thenAnswer((_) async => { + 'name': 'Test Page', + 'textCount': 2, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.byIcon(Icons.open_in_new), findsOneWidget); + expect(find.byIcon(Icons.delete_outline), findsOneWidget); + }); + + testWidgets('tapping page card calls loadPage', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['Clickable Page']); + when(mockCanvasCubit.getPagePreview('Clickable Page')) + .thenAnswer((_) async => { + 'name': 'Clickable Page', + 'textCount': 2, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + when(mockCanvasCubit.loadPage('Clickable Page')).thenAnswer((_) async {}); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + await tester.tap(find.byType(InkWell).first); + await tester.pumpAndSettle(); + + // Assert + verify(mockCanvasCubit.loadPage('Clickable Page')).called(1); + }); + + testWidgets('tapping delete button shows confirmation dialog', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['Delete Me']); + when(mockCanvasCubit.getPagePreview('Delete Me')) + .thenAnswer((_) async => { + 'name': 'Delete Me', + 'textCount': 2, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + await tester.tap(find.byIcon(Icons.delete_outline)); + await tester.pumpAndSettle(); + + // Assert + expect(find.text('Delete Page'), findsOneWidget); + expect(find.text('Cancel'), findsOneWidget); + expect(find.text('Delete'), findsWidgets); + }); + + testWidgets('confirming delete calls deletePage', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['Delete Me']); + when(mockCanvasCubit.getPagePreview('Delete Me')) + .thenAnswer((_) async => { + 'name': 'Delete Me', + 'textCount': 2, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + when(mockCanvasCubit.deletePage('Delete Me')).thenAnswer((_) async {}); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + await tester.tap(find.byIcon(Icons.delete_outline)); + await tester.pumpAndSettle(); + + await tester.tap(find.widgetWithText(ElevatedButton, 'Delete')); + await tester.pumpAndSettle(); + + // Assert + verify(mockCanvasCubit.deletePage('Delete Me')).called(1); + }); + + testWidgets('canceling delete closes dialog without deleting', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['Keep Me']); + when(mockCanvasCubit.getPagePreview('Keep Me')).thenAnswer((_) async => { + 'name': 'Keep Me', + 'textCount': 2, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + await tester.tap(find.byIcon(Icons.delete_outline)); + await tester.pumpAndSettle(); + + await tester.tap(find.text('Cancel')); + await tester.pumpAndSettle(); + + // Assert + verifyNever(mockCanvasCubit.deletePage('Keep Me')); + expect(find.text('Delete Page'), findsNothing); + }); + + testWidgets('refresh button reloads pages', (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => []); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + await tester.tap(find.byIcon(Icons.refresh)); + await tester.pumpAndSettle(); + + // Assert + verify(mockCanvasCubit.getSavedPages()).called(greaterThan(1)); + }); + }); + + group('SavedPagesScreen Time Formatting Tests', () { + testWidgets('displays "Just now" for recent pages', + (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => ['Recent']); + when(mockCanvasCubit.getPagePreview('Recent')).thenAnswer((_) async => { + 'name': 'Recent', + 'textCount': 1, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + 'lastModified': DateTime.now(), + 'label': '', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.textContaining('Just now'), findsOneWidget); + }); + + testWidgets('displays hours ago for pages modified hours ago', + (WidgetTester tester) async { + // Arrange + final twoHoursAgo = DateTime.now().subtract(const Duration(hours: 2)); + when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => ['Old']); + when(mockCanvasCubit.getPagePreview('Old')).thenAnswer((_) async => { + 'name': 'Old', + 'textCount': 1, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': twoHoursAgo.millisecondsSinceEpoch, + 'lastModified': twoHoursAgo, + 'label': '', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.textContaining('2 hours ago'), findsOneWidget); + }); + + testWidgets('displays days ago for pages modified days ago', + (WidgetTester tester) async { + // Arrange + final threeDaysAgo = DateTime.now().subtract(const Duration(days: 3)); + when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => ['Older']); + when(mockCanvasCubit.getPagePreview('Older')).thenAnswer((_) async => { + 'name': 'Older', + 'textCount': 1, + 'backgroundColor': ColorConstants.dialogTextBlack, + 'timestamp': threeDaysAgo.millisecondsSinceEpoch, + 'lastModified': threeDaysAgo, + 'label': '', + }); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert + expect(find.textContaining('3 days ago'), findsOneWidget); + }); + }); + + group('SavedPagesScreen Error Handling Tests', () { + testWidgets('handles null preview gracefully', (WidgetTester tester) async { + // Arrange + when(mockCanvasCubit.getSavedPages()) + .thenAnswer((_) async => ['Bad Page']); + when(mockCanvasCubit.getPagePreview('Bad Page')) + .thenAnswer((_) async => null); + + // Act + await tester.pumpWidget(createTestWidget()); + await tester.pumpAndSettle(); + + // Assert - Should still display the page with default values + expect(find.text('Bad Page'), findsOneWidget); + expect(find.text('0 text items'), findsOneWidget); + }); + }); +} diff --git a/test/ui/screens/saved_pages_test.mocks.dart b/test/ui/screens/saved_pages_test.mocks.dart new file mode 100644 index 00000000..5ed94574 --- /dev/null +++ b/test/ui/screens/saved_pages_test.mocks.dart @@ -0,0 +1,738 @@ +// Mocks generated by Mockito 5.4.6 from annotations +// in texterra/test/ui/screens/saved_pages_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:ui' as _i5; + +import 'package:flutter/material.dart' as _i6; +import 'package:flutter_bloc/flutter_bloc.dart' as _i8; +import 'package:mockito/mockito.dart' as _i1; +import 'package:texterra/cubit/canvas_cubit.dart' as _i3; +import 'package:texterra/cubit/canvas_state.dart' as _i2; +import 'package:texterra/models/draw_model.dart' as _i7; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: must_be_immutable +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeCanvasState_0 extends _i1.SmartFake implements _i2.CanvasState { + _FakeCanvasState_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [CanvasCubit]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCanvasCubit extends _i1.Mock implements _i3.CanvasCubit { + MockCanvasCubit() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.CanvasState get state => (super.noSuchMethod( + Invocation.getter(#state), + returnValue: _FakeCanvasState_0( + this, + Invocation.getter(#state), + ), + ) as _i2.CanvasState); + + @override + _i4.Stream<_i2.CanvasState> get stream => (super.noSuchMethod( + Invocation.getter(#stream), + returnValue: _i4.Stream<_i2.CanvasState>.empty(), + ) as _i4.Stream<_i2.CanvasState>); + + @override + bool get isClosed => (super.noSuchMethod( + Invocation.getter(#isClosed), + returnValue: false, + ) as bool); + + @override + void toggleTray() => super.noSuchMethod( + Invocation.method( + #toggleTray, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void selectText(int? index) => super.noSuchMethod( + Invocation.method( + #selectText, + [index], + ), + returnValueForMissingStub: null, + ); + + @override + void toggleTextShadow(int? index) => super.noSuchMethod( + Invocation.method( + #toggleTextShadow, + [index], + ), + returnValueForMissingStub: null, + ); + + @override + void changeShadowColor( + int? index, + _i5.Color? color, + ) => + super.noSuchMethod( + Invocation.method( + #changeShadowColor, + [ + index, + color, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void changeShadowBlur( + int? index, + double? blurRadius, + ) => + super.noSuchMethod( + Invocation.method( + #changeShadowBlur, + [ + index, + blurRadius, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void changeShadowOffset( + int? index, + _i5.Offset? offset, + ) => + super.noSuchMethod( + Invocation.method( + #changeShadowOffset, + [ + index, + offset, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void applyShadowPreset( + int? index, + _i3.ShadowPreset? preset, + ) => + super.noSuchMethod( + Invocation.method( + #applyShadowPreset, + [ + index, + preset, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void fillCanvas(_i5.Color? fillColor) => super.noSuchMethod( + Invocation.method( + #fillCanvas, + [fillColor], + ), + returnValueForMissingStub: null, + ); + + @override + void deselectText() => super.noSuchMethod( + Invocation.method( + #deselectText, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void addText(String? text) => super.noSuchMethod( + Invocation.method( + #addText, + [text], + ), + returnValueForMissingStub: null, + ); + + @override + void toggleTextHighlight( + int? index, { + _i5.Color? highlightColor, + }) => + super.noSuchMethod( + Invocation.method( + #toggleTextHighlight, + [index], + {#highlightColor: highlightColor}, + ), + returnValueForMissingStub: null, + ); + + @override + void changeHighlightColor( + int? index, + _i5.Color? color, + ) => + super.noSuchMethod( + Invocation.method( + #changeHighlightColor, + [ + index, + color, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void resetFormatting(int? index) => super.noSuchMethod( + Invocation.method( + #resetFormatting, + [index], + ), + returnValueForMissingStub: null, + ); + + @override + void changeTextColor( + int? index, + _i5.Color? color, + ) => + super.noSuchMethod( + Invocation.method( + #changeTextColor, + [ + index, + color, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void changeBackgroundColor(_i5.Color? color) => super.noSuchMethod( + Invocation.method( + #changeBackgroundColor, + [color], + ), + returnValueForMissingStub: null, + ); + + @override + _i4.Future uploadBackgroundImage() => (super.noSuchMethod( + Invocation.method( + #uploadBackgroundImage, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future takePhotoForBackground() => (super.noSuchMethod( + Invocation.method( + #takePhotoForBackground, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + void removeBackgroundImage() => super.noSuchMethod( + Invocation.method( + #removeBackgroundImage, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void editText( + int? index, + String? newText, + ) => + super.noSuchMethod( + Invocation.method( + #editText, + [ + index, + newText, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void moveText( + int? index, + double? x, + double? y, + ) => + super.noSuchMethod( + Invocation.method( + #moveText, + [ + index, + x, + y, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void moveTextWithHistory( + int? index, + double? x, + double? y, + ) => + super.noSuchMethod( + Invocation.method( + #moveTextWithHistory, + [ + index, + x, + y, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void rotateText( + int? index, + double? rotation, + ) => + super.noSuchMethod( + Invocation.method( + #rotateText, + [ + index, + rotation, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void rotateTextWithHistory( + int? index, + double? rotation, + ) => + super.noSuchMethod( + Invocation.method( + #rotateTextWithHistory, + [ + index, + rotation, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void changeFontSize( + int? index, + double? fontSize, + ) => + super.noSuchMethod( + Invocation.method( + #changeFontSize, + [ + index, + fontSize, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void changeFontFamily( + int? index, + String? fontFamily, + ) => + super.noSuchMethod( + Invocation.method( + #changeFontFamily, + [ + index, + fontFamily, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void changeFontStyle( + int? index, + _i5.FontStyle? fontStyle, + ) => + super.noSuchMethod( + Invocation.method( + #changeFontStyle, + [ + index, + fontStyle, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void changeTextUnderline( + int? index, + bool? isUnderlined, + ) => + super.noSuchMethod( + Invocation.method( + #changeTextUnderline, + [ + index, + isUnderlined, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void changeFontWeight( + int? index, + _i5.FontWeight? fontWeight, + ) => + super.noSuchMethod( + Invocation.method( + #changeFontWeight, + [ + index, + fontWeight, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void changeTextAlignment( + int? index, + _i5.TextAlign? align, + ) => + super.noSuchMethod( + Invocation.method( + #changeTextAlignment, + [ + index, + align, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void undo() => super.noSuchMethod( + Invocation.method( + #undo, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void redo() => super.noSuchMethod( + Invocation.method( + #redo, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void clearCanvas() => super.noSuchMethod( + Invocation.method( + #clearCanvas, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void deleteText(int? index) => super.noSuchMethod( + Invocation.method( + #deleteText, + [index], + ), + returnValueForMissingStub: null, + ); + + @override + _i4.Future savePage( + String? pageName, { + String? label, + int? color, + }) => + (super.noSuchMethod( + Invocation.method( + #savePage, + [pageName], + { + #label: label, + #color: color, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future handleSaveAction() => (super.noSuchMethod( + Invocation.method( + #handleSaveAction, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future loadPage(String? pageName) => (super.noSuchMethod( + Invocation.method( + #loadPage, + [pageName], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + void createNewPage() => super.noSuchMethod( + Invocation.method( + #createNewPage, + [], + ), + returnValueForMissingStub: null, + ); + + @override + _i4.Future> getSavedPages() => (super.noSuchMethod( + Invocation.method( + #getSavedPages, + [], + ), + returnValue: _i4.Future>.value([]), + ) as _i4.Future>); + + @override + _i4.Future deletePage(String? pageName) => (super.noSuchMethod( + Invocation.method( + #deletePage, + [pageName], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future?> getPagePreview(String? pageName) => + (super.noSuchMethod( + Invocation.method( + #getPagePreview, + [pageName], + ), + returnValue: _i4.Future?>.value(), + ) as _i4.Future?>); + + @override + _i4.Future clearAllSavedData() => (super.noSuchMethod( + Invocation.method( + #clearAllSavedData, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + void copyText( + int? index, + _i6.BuildContext? context, + ) => + super.noSuchMethod( + Invocation.method( + #copyText, + [ + index, + context, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void toggleDrawingMode() => super.noSuchMethod( + Invocation.method( + #toggleDrawingMode, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void setDrawingMode(bool? isDrawing) => super.noSuchMethod( + Invocation.method( + #setDrawingMode, + [isDrawing], + ), + returnValueForMissingStub: null, + ); + + @override + void setDrawColor(_i5.Color? color) => super.noSuchMethod( + Invocation.method( + #setDrawColor, + [color], + ), + returnValueForMissingStub: null, + ); + + @override + void setStrokeWidth(double? width) => super.noSuchMethod( + Invocation.method( + #setStrokeWidth, + [width], + ), + returnValueForMissingStub: null, + ); + + @override + void setBrushType(_i7.BrushType? brushType) => super.noSuchMethod( + Invocation.method( + #setBrushType, + [brushType], + ), + returnValueForMissingStub: null, + ); + + @override + void startNewDrawPath(_i5.Offset? point) => super.noSuchMethod( + Invocation.method( + #startNewDrawPath, + [point], + ), + returnValueForMissingStub: null, + ); + + @override + void updateDrawPath(_i5.Offset? point) => super.noSuchMethod( + Invocation.method( + #updateDrawPath, + [point], + ), + returnValueForMissingStub: null, + ); + + @override + void clearDrawings() => super.noSuchMethod( + Invocation.method( + #clearDrawings, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void undoLastDrawing() => super.noSuchMethod( + Invocation.method( + #undoLastDrawing, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void emit(_i2.CanvasState? state) => super.noSuchMethod( + Invocation.method( + #emit, + [state], + ), + returnValueForMissingStub: null, + ); + + @override + void onChange(_i8.Change<_i2.CanvasState>? change) => super.noSuchMethod( + Invocation.method( + #onChange, + [change], + ), + returnValueForMissingStub: null, + ); + + @override + void addError( + Object? error, [ + StackTrace? stackTrace, + ]) => + super.noSuchMethod( + Invocation.method( + #addError, + [ + error, + stackTrace, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void onError( + Object? error, + StackTrace? stackTrace, + ) => + super.noSuchMethod( + Invocation.method( + #onError, + [ + error, + stackTrace, + ], + ), + returnValueForMissingStub: null, + ); + + @override + _i4.Future close() => (super.noSuchMethod( + Invocation.method( + #close, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); +}