From 7de98ad61bf647bdd135dd0da56444078af04e0e Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Thu, 17 Jun 2021 12:38:32 -0700 Subject: [PATCH 01/20] Integration testing --- integration_test/app_test.dart | 51 +++-- ios/Podfile.lock | 12 +- ios/Runner.xcodeproj/project.pbxproj | 24 +-- .../contents.xcworkspacedata | 2 +- lib/main.dart | 6 +- pubspec.lock | 196 ++++++++++++------ pubspec.yaml | 9 +- test_driver/integration_test.dart | 3 + 8 files changed, 191 insertions(+), 112 deletions(-) create mode 100644 test_driver/integration_test.dart diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 1b51b34..5dec203 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -11,26 +11,43 @@ import 'package:integration_test/integration_test.dart'; import 'package:flutter_sample/main.dart' as app; -void main() => run(_testMain); +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); -void _testMain() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - app.main(); + testWidgets('Finds child instances of Flutter Sample app', (WidgetTester tester) async { + Widget myApp = app.MyApp(); + await tester.pumpWidget(myApp); - // Trigger a frame. - await tester.pumpAndSettle(); + //expect(find.text('Storage permission required.'), findsOneWidget); - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); + final materialAppFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(MaterialApp)); + expect(materialAppFinder, findsOneWidget); - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); + final scaffoldFinder = find.descendant(of: materialAppFinder, matching: find.byType(Scaffold)); + expect(scaffoldFinder, findsOneWidget); - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); + final appBarFinder = find.descendant(of: scaffoldFinder, matching: find.byType(AppBar)); + expect(appBarFinder, findsOneWidget); + + final textFinder = find.descendant(of: appBarFinder, matching: find.byType(Text)); + expect(textFinder, findsOneWidget); + }); + /* + testWidgets('Finds child instances when state initialized and permission granted', (WidgetTester tester) async { + }); + + testWidgets('Finds child instances when state not initialized or permission denied', (WidgetTester tester) async { + const textWidget = Text('Storage permission required.'); + // Provide the textWidget to Align. + await tester.pumpWidget(Align(alignment: Alignment.center, child: textWidget)); + // Search for the textWidget in the tree and verify it exists. + expect(find.byWidget(textWidget), findsOneWidget); + + const alignWidget = Align(alignment: Alignment.center, child: Text('Storage permission required.')); + // Provide the alignWidget to the Container. + await tester.pumpWidget(Container(child: alignWidget)); + // Search for the alignWidget in the tree and verify it exists. + expect(find.byWidget(alignWidget), findsOneWidget); }); -} + */ +} \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 4a6af23..e911450 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2,11 +2,11 @@ PODS: - Flutter (1.0.0) - integration_test (0.0.1): - Flutter - - PDFNet (8.1.0.76833) + - PDFNet (9.0.1.77780) - pdftron_flutter (0.0.1): - Flutter - PDFNet - - permission_handler (3.0.1): + - "permission_handler (5.1.0+2)": - Flutter DEPENDENCIES: @@ -31,10 +31,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c integration_test: 6eb66a19f7104200dcfdd62bc0077e1b09686e4f - PDFNet: 248e57518524fdbb47970216c2db3522e4f51028 + PDFNet: b9e7a7831af4020a4835e19ecf6abf9b81ce29a4 pdftron_flutter: 32bd96e9bc9254c1861f17725e40dd611a7056cd - permission_handler: 6e56ded745f5a0b9dcc0327c65c4acd6a33b776b + permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 -PODFILE CHECKSUM: c3dd2ce4973c59b1eed0b8fefd9e24700fcd3376 +PODFILE CHECKSUM: 1256ed743e0e6641e71d5339a76d03b9e411be9b -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.1 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 82b64c0..8d4fc38 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -228,13 +228,12 @@ buildActionMask = 2147483647; files = ( ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", - "${PODS_ROOT}/PDFNet/Tools-Localization", + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Tools-Localization", + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -282,19 +281,12 @@ buildActionMask = 2147483647; files = ( ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/PDFNet/PDFNet.framework", - "${PODS_ROOT}/PDFNet/Tools.framework", - "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", - "${BUILT_PRODUCTS_DIR}/pdftron_flutter/pdftron_flutter.framework", + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PDFNet.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Tools.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/pdftron_flutter.framework", + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a1..919434a 100644 --- a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/lib/main.dart b/lib/main.dart index 3d5fcbc..465571f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -53,9 +53,9 @@ class _MyAppState extends State { } Future askForPermission() async { - Map permissions = - await PermissionHandler().requestPermissions([PermissionGroup.storage]); - if (granted(permissions[PermissionGroup.storage]) && mounted) { + var permission = + await Permission.storage.request(); + if (permission.isGranted && mounted) { setState(() { _storagePermitted = true; }); diff --git a/pubspec.lock b/pubspec.lock index 41932b8..64f8355 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,126 +7,126 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "12.0.0" + version: "22.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.40.6" + version: "1.7.1" archive: dependency: transitive description: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.13" + version: "3.1.2" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.6.0" + version: "2.1.1" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.3" + version: "2.6.1" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.5" + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" cli_util: dependency: transitive description: name: cli_util url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.3.0" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.5" + version: "1.15.0" convert: dependency: transitive description: name: convert url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "3.0.0" coverage: dependency: transitive description: name: coverage url: "https://pub.dartlang.org" source: hosted - version: "0.14.2" + version: "1.0.3" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.5" + version: "3.0.1" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.3" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.0.0-nullsafety.4" + version: "6.1.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" flutter_driver: - dependency: transitive + dependency: "direct dev" description: flutter source: sdk version: "0.0.0" @@ -146,133 +146,182 @@ packages: name: glob url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "2.0.1" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" integration_test: dependency: "direct dev" description: flutter source: sdk - version: "0.9.2+2" + version: "0.0.0" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" + version: "1.0.0" js: dependency: transitive description: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3-nullsafety.3" - json_rpc_2: - dependency: transitive - description: - name: json_rpc_2 - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" + version: "0.6.3" logging: dependency: transitive description: name: logging url: "https://pub.dartlang.org" source: hosted - version: "0.11.4" + version: "1.0.1" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.3" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.6" - node_interop: + version: "1.3.0" + mime: dependency: transitive description: - name: node_interop + name: mime url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" - node_io: + version: "1.0.0" + node_preamble: dependency: transitive description: - name: node_io + name: node_preamble url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "2.0.1" package_config: dependency: transitive description: name: package_config url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "2.0.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.8.0" pdftron_flutter: dependency: "direct main" description: path: "." ref: HEAD - resolved-ref: "0513833f3c555a0806992cff025ce86c509551d1" + resolved-ref: "1fe2a34ede93cc1111bd84d8b34575acb376afe0" url: "git://github.com/PDFTron/pdftron-flutter.git" source: git - version: "0.0.9" + version: "0.0.57" pedantic: dependency: transitive description: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.3" + version: "1.11.1" permission_handler: dependency: "direct main" description: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "8.1.1" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.0" platform: dependency: transitive description: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.0-nullsafety.4" + version: "3.0.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" pool: dependency: transitive description: name: pool url: "https://pub.dartlang.org" source: hosted - version: "1.5.0-nullsafety.3" + version: "1.5.0" process: dependency: transitive description: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.0.0-nullsafety.4" + version: "4.2.1" pub_semver: dependency: transitive description: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.4.4" + version: "2.0.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.4" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + shelf_static: + dependency: transitive + description: + name: shelf_static + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" sky_engine: dependency: transitive description: flutter @@ -284,118 +333,133 @@ packages: name: source_map_stack_trace url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.4" + version: "2.1.0" source_maps: dependency: transitive description: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.10-nullsafety.3" + version: "0.10.10" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.4" + version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.6" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" sync_http: dependency: transitive description: name: sync_http url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.3.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" + test: + dependency: "direct dev" + description: + name: test + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.8" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.6" + version: "0.3.0" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.3.12-nullsafety.9" + version: "0.3.19" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.5" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.5" + version: "2.1.0" vm_service: dependency: transitive description: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "5.5.0" + version: "6.2.0" watcher: dependency: transitive description: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+15" + version: "1.0.0" web_socket_channel: dependency: transitive description: name: web_socket_channel url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "2.1.0" webdriver: dependency: transitive description: name: webdriver url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "3.0.0" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" yaml: dependency: transitive description: name: yaml url: "https://pub.dartlang.org" source: hosted - version: "2.2.1" + version: "3.1.0" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=1.22.0" diff --git a/pubspec.yaml b/pubspec.yaml index ee52404..f12dfee 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: @@ -28,17 +28,20 @@ dependencies: git: url: git://github.com/PDFTron/pdftron-flutter.git - permission_handler: '3.0.1' + permission_handler: ^8.1.1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.2 + cupertino_icons: ^1.0.3 dev_dependencies: flutter_test: sdk: flutter integration_test: sdk: flutter + flutter_driver: + sdk: flutter + test: any # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/test_driver/integration_test.dart b/test_driver/integration_test.dart new file mode 100644 index 0000000..b38629c --- /dev/null +++ b/test_driver/integration_test.dart @@ -0,0 +1,3 @@ +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); From 360fb0f5a6af3f6925051a62beae0b8d0994d8cd Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Thu, 17 Jun 2021 13:38:39 -0700 Subject: [PATCH 02/20] Integration testing --- integration_test/app_test.dart | 44 +++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 5dec203..b46e343 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -8,6 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:flutter_sample/thumbnail.dart'; import 'package:flutter_sample/main.dart' as app; @@ -18,7 +19,7 @@ void main() { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); - //expect(find.text('Storage permission required.'), findsOneWidget); + expect(find.text('PDFTron Flutter Sample'), findsOneWidget); final materialAppFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(MaterialApp)); expect(materialAppFinder, findsOneWidget); @@ -34,20 +35,47 @@ void main() { }); /* testWidgets('Finds child instances when state initialized and permission granted', (WidgetTester tester) async { + var orientationBuilderWidget = OrientationBuilder(builder: (context, orientation) { + + } + ); + await tester.pumpWidget(InkWell(child: orientationBuilderWidget)); + expect(find.byWidget(orientationBuilderWidget), findsOneWidget); }); + + testWidgets('Finds child container instance of InkWell', (WidgetTester tester) async { + // underscored fields/classes/methods are only available in the .dart file where they are defined + int index = 0; + Thumbnail thumbnail = thumbnailList[index]; + var inkWellContainerWidget = Container( + margin: EdgeInsets.all(app.MARGIN), + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage(thumbnail.assetPath), + fit: BoxFit.fitWidth, + ), + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + spreadRadius: 1, + blurRadius: 3, + offset: Offset(2, 2), // changes position of shadow + ), + ]), + ); + await tester.pumpWidget(InkWell(child: inkWellContainerWidget)); + expect(find.byWidget(inkWellContainerWidget), findsOneWidget); + });*/ testWidgets('Finds child instances when state not initialized or permission denied', (WidgetTester tester) async { - const textWidget = Text('Storage permission required.'); - // Provide the textWidget to Align. + const textWidget = Text('Storage permission required.', textDirection: TextDirection.ltr); await tester.pumpWidget(Align(alignment: Alignment.center, child: textWidget)); - // Search for the textWidget in the tree and verify it exists. expect(find.byWidget(textWidget), findsOneWidget); - const alignWidget = Align(alignment: Alignment.center, child: Text('Storage permission required.')); - // Provide the alignWidget to the Container. + const alignWidget = Align(alignment: Alignment.center, child: textWidget); await tester.pumpWidget(Container(child: alignWidget)); - // Search for the alignWidget in the tree and verify it exists. expect(find.byWidget(alignWidget), findsOneWidget); }); - */ + } \ No newline at end of file From a658d67d25fa77b7d5cbdd19c7fb75f276aec120 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Thu, 17 Jun 2021 14:55:53 -0700 Subject: [PATCH 03/20] Integration testing --- integration_test/app_test.dart | 67 ++++++++++++++++------------------ 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index b46e343..1c04cce 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -21,52 +21,47 @@ void main() { expect(find.text('PDFTron Flutter Sample'), findsOneWidget); - final materialAppFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(MaterialApp)); + final materialAppFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(MaterialApp)).first; expect(materialAppFinder, findsOneWidget); - final scaffoldFinder = find.descendant(of: materialAppFinder, matching: find.byType(Scaffold)); + final scaffoldFinder = find.descendant(of: materialAppFinder, matching: find.byType(Scaffold)).first; expect(scaffoldFinder, findsOneWidget); - final appBarFinder = find.descendant(of: scaffoldFinder, matching: find.byType(AppBar)); + final appBarFinder = find.descendant(of: scaffoldFinder, matching: find.byType(AppBar)).first; expect(appBarFinder, findsOneWidget); - final textFinder = find.descendant(of: appBarFinder, matching: find.byType(Text)); + final textFinder = find.descendant(of: appBarFinder, matching: find.byType(Text)).first; expect(textFinder, findsOneWidget); - }); - /* - testWidgets('Finds child instances when state initialized and permission granted', (WidgetTester tester) async { - var orientationBuilderWidget = OrientationBuilder(builder: (context, orientation) { + + var bodyFinder; + try { + bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(SafeArea)).first; + expect(bodyFinder, findsOneWidget); + } catch (e) { + bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(Container)).first; + } + expect(bodyFinder, findsOneWidget); + + if (bodyFinder.first is SafeArea) { + debugPrint(bodyFinder.evaluate().toString()); + + final outContainerFinder = find.descendant(of: bodyFinder, matching: find.byType(Container)).first; + expect(outContainerFinder, findsOneWidget); + + final orientationBuilderFinder = find.descendant(of: bodyFinder, matching: find.byType(OrientationBuilder)).first; + expect(orientationBuilderFinder, findsOneWidget); + //final orientationBuilderFinder = find.descendant(of: bodyFinder, matching: find.byType(OrientationBuilder)).first; + //expect(orientationBuilderFinder, findsOneWidget); + + } else if (bodyFinder.first is Container) { + final alignFinder = find.descendant(of: bodyFinder, matching: find.byType(Align)).first; + expect(alignFinder, findsOneWidget); + + final alignTextFinder = find.descendant(of: alignFinder, matching: find.byType(Text)).first; + expect(alignTextFinder, findsOneWidget); } - ); - await tester.pumpWidget(InkWell(child: orientationBuilderWidget)); - expect(find.byWidget(orientationBuilderWidget), findsOneWidget); }); - - testWidgets('Finds child container instance of InkWell', (WidgetTester tester) async { - // underscored fields/classes/methods are only available in the .dart file where they are defined - int index = 0; - Thumbnail thumbnail = thumbnailList[index]; - var inkWellContainerWidget = Container( - margin: EdgeInsets.all(app.MARGIN), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage(thumbnail.assetPath), - fit: BoxFit.fitWidth, - ), - color: Colors.white, - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.2), - spreadRadius: 1, - blurRadius: 3, - offset: Offset(2, 2), // changes position of shadow - ), - ]), - ); - await tester.pumpWidget(InkWell(child: inkWellContainerWidget)); - expect(find.byWidget(inkWellContainerWidget), findsOneWidget); - });*/ testWidgets('Finds child instances when state not initialized or permission denied', (WidgetTester tester) async { const textWidget = Text('Storage permission required.', textDirection: TextDirection.ltr); From 9f4e3bd4f73f964114ed1b7b8072919947cd670c Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Thu, 17 Jun 2021 15:33:38 -0700 Subject: [PATCH 04/20] Integration testing --- integration_test/app_test.dart | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 1c04cce..fd0906f 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -8,7 +8,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:flutter_sample/thumbnail.dart'; import 'package:flutter_sample/main.dart' as app; @@ -19,7 +18,7 @@ void main() { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); - expect(find.text('PDFTron Flutter Sample'), findsOneWidget); + expect(find.text('PDFTron Flutter Sample'), findsOneWidget); final materialAppFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(MaterialApp)).first; expect(materialAppFinder, findsOneWidget); @@ -51,8 +50,15 @@ void main() { final orientationBuilderFinder = find.descendant(of: bodyFinder, matching: find.byType(OrientationBuilder)).first; expect(orientationBuilderFinder, findsOneWidget); - //final orientationBuilderFinder = find.descendant(of: bodyFinder, matching: find.byType(OrientationBuilder)).first; - //expect(orientationBuilderFinder, findsOneWidget); + // Check if orientationBuilder returns GridView + final inkWellBuilder = find.descendant(of: orientationBuilderFinder, matching: find.byType(InkWell)).first; + expect(inkWellBuilder, findsOneWidget); + + final containerBuilder = find.descendant(of: inkWellBuilder, matching: find.byType(Container)).first; + expect(containerBuilder, findsOneWidget); + + final imageBuilder = find.descendant(of: containerBuilder, matching: find.byType(Image)).first; + expect(imageBuilder, findsOneWidget); } else if (bodyFinder.first is Container) { final alignFinder = find.descendant(of: bodyFinder, matching: find.byType(Align)).first; @@ -61,6 +67,8 @@ void main() { final alignTextFinder = find.descendant(of: alignFinder, matching: find.byType(Text)).first; expect(alignTextFinder, findsOneWidget); } + + debugPrint("Test completing: Finds child instances of Flutter Sample app"); }); testWidgets('Finds child instances when state not initialized or permission denied', (WidgetTester tester) async { @@ -71,6 +79,8 @@ void main() { const alignWidget = Align(alignment: Alignment.center, child: textWidget); await tester.pumpWidget(Container(child: alignWidget)); expect(find.byWidget(alignWidget), findsOneWidget); + + debugPrint("Test completing: Finds child instances when state not initialized or permission denied"); }); } \ No newline at end of file From 6ba19dc9d3c2ba2326e3e4b69752b7fb4d796207 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Thu, 17 Jun 2021 16:29:56 -0700 Subject: [PATCH 05/20] Integration testing --- integration_test/app_test.dart | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index fd0906f..1c1e17d 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -14,7 +14,8 @@ import 'package:flutter_sample/main.dart' as app; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('Finds child instances of Flutter Sample app', (WidgetTester tester) async { + testWidgets('Find child instances in app widget hierarchy', (WidgetTester tester) async { + debugPrint(" RUNNING TEST: 'Find child instances in app widget hierarchy'"); Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); @@ -32,25 +33,15 @@ void main() { final textFinder = find.descendant(of: appBarFinder, matching: find.byType(Text)).first; expect(textFinder, findsOneWidget); - var bodyFinder; - try { - bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(SafeArea)).first; - expect(bodyFinder, findsOneWidget); - } catch (e) { - bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(Container)).first; - } - expect(bodyFinder, findsOneWidget); + var bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(SafeArea)).first; - if (bodyFinder.first is SafeArea) { - debugPrint(bodyFinder.evaluate().toString()); - + if (bodyFinder.evaluate().isNotEmpty) { final outContainerFinder = find.descendant(of: bodyFinder, matching: find.byType(Container)).first; expect(outContainerFinder, findsOneWidget); final orientationBuilderFinder = find.descendant(of: bodyFinder, matching: find.byType(OrientationBuilder)).first; expect(orientationBuilderFinder, findsOneWidget); - // Check if orientationBuilder returns GridView final inkWellBuilder = find.descendant(of: orientationBuilderFinder, matching: find.byType(InkWell)).first; expect(inkWellBuilder, findsOneWidget); @@ -60,7 +51,10 @@ void main() { final imageBuilder = find.descendant(of: containerBuilder, matching: find.byType(Image)).first; expect(imageBuilder, findsOneWidget); - } else if (bodyFinder.first is Container) { + } else { + bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(Container)).first; + expect(bodyFinder, findsOneWidget); + final alignFinder = find.descendant(of: bodyFinder, matching: find.byType(Align)).first; expect(alignFinder, findsOneWidget); @@ -68,10 +62,11 @@ void main() { expect(alignTextFinder, findsOneWidget); } - debugPrint("Test completing: Finds child instances of Flutter Sample app"); + debugPrint(" DONE TEST"); }); testWidgets('Finds child instances when state not initialized or permission denied', (WidgetTester tester) async { + debugPrint(" RUNNING TEST: 'Finds child instances when state not initialized or permission denied'"); const textWidget = Text('Storage permission required.', textDirection: TextDirection.ltr); await tester.pumpWidget(Align(alignment: Alignment.center, child: textWidget)); expect(find.byWidget(textWidget), findsOneWidget); @@ -80,7 +75,7 @@ void main() { await tester.pumpWidget(Container(child: alignWidget)); expect(find.byWidget(alignWidget), findsOneWidget); - debugPrint("Test completing: Finds child instances when state not initialized or permission denied"); + debugPrint(" DONE TEST: Finds child instances when state not initialized or permission denied"); }); } \ No newline at end of file From e3ddc608b06c8e9cdb2c244da108642a23e8dc73 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Thu, 17 Jun 2021 16:48:25 -0700 Subject: [PATCH 06/20] Correct wording --- integration_test/app_test.dart | 16 +++++---- ios/Runner.xcodeproj/project.pbxproj | 54 ++++++++++++++-------------- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 1c1e17d..9098616 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -35,6 +35,8 @@ void main() { var bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(SafeArea)).first; + // Body widget is SafeArea type. + // Occurs when app is initialized and storage is permitted. if (bodyFinder.evaluate().isNotEmpty) { final outContainerFinder = find.descendant(of: bodyFinder, matching: find.byType(Container)).first; expect(outContainerFinder, findsOneWidget); @@ -42,16 +44,18 @@ void main() { final orientationBuilderFinder = find.descendant(of: bodyFinder, matching: find.byType(OrientationBuilder)).first; expect(orientationBuilderFinder, findsOneWidget); - final inkWellBuilder = find.descendant(of: orientationBuilderFinder, matching: find.byType(InkWell)).first; - expect(inkWellBuilder, findsOneWidget); + final inkWellFinder = find.descendant(of: orientationBuilderFinder, matching: find.byType(InkWell)).first; + expect(inkWellFinder, findsOneWidget); - final containerBuilder = find.descendant(of: inkWellBuilder, matching: find.byType(Container)).first; - expect(containerBuilder, findsOneWidget); + final containerFinder = find.descendant(of: inkWellFinder, matching: find.byType(Container)).first; + expect(containerFinder, findsOneWidget); - final imageBuilder = find.descendant(of: containerBuilder, matching: find.byType(Image)).first; - expect(imageBuilder, findsOneWidget); + final imageFinder = find.descendant(of: containerFinder, matching: find.byType(Image)).first; + expect(imageFinder, findsOneWidget); } else { + // Body widget is Container type. + // Occurs when app is not initialized or storage is not permitted. bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(Container)).first; expect(bodyFinder, findsOneWidget); diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 8d4fc38..e9b7555 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -9,7 +9,7 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 7D9D4596AFE603889D0C4AF9 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 156D97EE3B349FF3B0506A4B /* Pods_Runner.framework */; }; + 943B166731AF29A54E1E56A7 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 204000B1A7320C6A866AAD69 /* Pods_Runner.framework */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; @@ -33,22 +33,22 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 156D97EE3B349FF3B0506A4B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 26A290795C8B345E7B54F3D8 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 204000B1A7320C6A866AAD69 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2BE6492F675995FD34402DF3 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3BDFDD4EE7D4A48E6F1023CD /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 8C7015EC7AC266049F570AC8 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 978AC9E7D689FE7A1CC725C4 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A318E888EA367D38A42C1330 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -56,21 +56,32 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7D9D4596AFE603889D0C4AF9 /* Pods_Runner.framework in Frameworks */, + 943B166731AF29A54E1E56A7 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 526543B57B076E700259821D /* Frameworks */ = { + 144481D43B8FD6BABC279BD2 /* Frameworks */ = { isa = PBXGroup; children = ( - 156D97EE3B349FF3B0506A4B /* Pods_Runner.framework */, + 204000B1A7320C6A866AAD69 /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; }; + 68FFF092814E7FD8BDE5D113 /* Pods */ = { + isa = PBXGroup; + children = ( + 2BE6492F675995FD34402DF3 /* Pods-Runner.debug.xcconfig */, + 8C7015EC7AC266049F570AC8 /* Pods-Runner.release.xcconfig */, + A318E888EA367D38A42C1330 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -88,8 +99,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, - B73FC6430D1564515ACDA0A8 /* Pods */, - 526543B57B076E700259821D /* Frameworks */, + 68FFF092814E7FD8BDE5D113 /* Pods */, + 144481D43B8FD6BABC279BD2 /* Frameworks */, ); sourceTree = ""; }; @@ -125,17 +136,6 @@ name = "Supporting Files"; sourceTree = ""; }; - B73FC6430D1564515ACDA0A8 /* Pods */ = { - isa = PBXGroup; - children = ( - 978AC9E7D689FE7A1CC725C4 /* Pods-Runner.debug.xcconfig */, - 3BDFDD4EE7D4A48E6F1023CD /* Pods-Runner.release.xcconfig */, - 26A290795C8B345E7B54F3D8 /* Pods-Runner.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -143,15 +143,15 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 828B385D0F4ED6C1571E5C5F /* [CP] Check Pods Manifest.lock */, + 428ABE4C58A2A019489A3B39 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 9F87D447099B0ED1C64C936E /* [CP] Embed Pods Frameworks */, - 69F2FFE7873B2C24CBEDA23A /* [CP] Copy Pods Resources */, + FB76715B0EFF3C89AFE1FCBA /* [CP] Embed Pods Frameworks */, + 4243294FAA000FD34AB76E5C /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -223,7 +223,7 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 69F2FFE7873B2C24CBEDA23A /* [CP] Copy Pods Resources */ = { + 4243294FAA000FD34AB76E5C /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -240,7 +240,7 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 828B385D0F4ED6C1571E5C5F /* [CP] Check Pods Manifest.lock */ = { + 428ABE4C58A2A019489A3B39 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -276,7 +276,7 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - 9F87D447099B0ED1C64C936E /* [CP] Embed Pods Frameworks */ = { + FB76715B0EFF3C89AFE1FCBA /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( From 52650580efb57595e99fdd298b38d5ff247496bc Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Thu, 17 Jun 2021 16:56:45 -0700 Subject: [PATCH 07/20] Remove print statements --- integration_test/app_test.dart | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 9098616..b21f841 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -14,8 +14,7 @@ import 'package:flutter_sample/main.dart' as app; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('Find child instances in app widget hierarchy', (WidgetTester tester) async { - debugPrint(" RUNNING TEST: 'Find child instances in app widget hierarchy'"); + testWidgets('Find instances in app widget hierarchy', (WidgetTester tester) async { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); @@ -65,12 +64,9 @@ void main() { final alignTextFinder = find.descendant(of: alignFinder, matching: find.byType(Text)).first; expect(alignTextFinder, findsOneWidget); } - - debugPrint(" DONE TEST"); }); testWidgets('Finds child instances when state not initialized or permission denied', (WidgetTester tester) async { - debugPrint(" RUNNING TEST: 'Finds child instances when state not initialized or permission denied'"); const textWidget = Text('Storage permission required.', textDirection: TextDirection.ltr); await tester.pumpWidget(Align(alignment: Alignment.center, child: textWidget)); expect(find.byWidget(textWidget), findsOneWidget); @@ -78,8 +74,6 @@ void main() { const alignWidget = Align(alignment: Alignment.center, child: textWidget); await tester.pumpWidget(Container(child: alignWidget)); expect(find.byWidget(alignWidget), findsOneWidget); - - debugPrint(" DONE TEST: Finds child instances when state not initialized or permission denied"); }); } \ No newline at end of file From 1b06d3cfd32a45b76c6b34aad131708fefd195ba Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Thu, 17 Jun 2021 17:08:19 -0700 Subject: [PATCH 08/20] Split test and remove unneeded test --- integration_test/app_test.dart | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index b21f841..4865ac8 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -14,7 +14,7 @@ import 'package:flutter_sample/main.dart' as app; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('Find instances in app widget hierarchy', (WidgetTester tester) async { + testWidgets('Check widget hierarchy of app excl. body', (WidgetTester tester) async { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); @@ -31,8 +31,13 @@ void main() { final textFinder = find.descendant(of: appBarFinder, matching: find.byType(Text)).first; expect(textFinder, findsOneWidget); - - var bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(SafeArea)).first; + }); + + testWidgets('Check widget hierarchy of app body', (WidgetTester tester) async { + Widget myApp = app.MyApp(); + await tester.pumpWidget(myApp); + + var bodyFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(SafeArea)).first; // Body widget is SafeArea type. // Occurs when app is initialized and storage is permitted. @@ -55,7 +60,7 @@ void main() { } else { // Body widget is Container type. // Occurs when app is not initialized or storage is not permitted. - bodyFinder = find.descendant(of: scaffoldFinder, matching: find.byType(Container)).first; + bodyFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(Container)).first; expect(bodyFinder, findsOneWidget); final alignFinder = find.descendant(of: bodyFinder, matching: find.byType(Align)).first; @@ -64,16 +69,5 @@ void main() { final alignTextFinder = find.descendant(of: alignFinder, matching: find.byType(Text)).first; expect(alignTextFinder, findsOneWidget); } - }); - - testWidgets('Finds child instances when state not initialized or permission denied', (WidgetTester tester) async { - const textWidget = Text('Storage permission required.', textDirection: TextDirection.ltr); - await tester.pumpWidget(Align(alignment: Alignment.center, child: textWidget)); - expect(find.byWidget(textWidget), findsOneWidget); - - const alignWidget = Align(alignment: Alignment.center, child: textWidget); - await tester.pumpWidget(Container(child: alignWidget)); - expect(find.byWidget(alignWidget), findsOneWidget); - }); - + }); } \ No newline at end of file From 43347f385561ff1a1c9f6bceb79cc8a3dfcb9b2f Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Fri, 18 Jun 2021 15:16:28 -0700 Subject: [PATCH 09/20] Integration testing --- integration_test/app_test.dart | 61 +++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 4865ac8..be52504 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -14,59 +14,66 @@ import 'package:flutter_sample/main.dart' as app; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('Check widget hierarchy of app excl. body', (WidgetTester tester) async { + testWidgets('Check widget hierarchy of app excl. Scaffold body', (WidgetTester tester) async { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); - expect(find.text('PDFTron Flutter Sample'), findsOneWidget); + final materialAppFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(MaterialApp)); + expect(materialAppFinder, findsWidgets); - final materialAppFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(MaterialApp)).first; - expect(materialAppFinder, findsOneWidget); - - final scaffoldFinder = find.descendant(of: materialAppFinder, matching: find.byType(Scaffold)).first; + final scaffoldFinder = find.byWidgetPredicate((widget) => widget is Scaffold + && (widget.body is SafeArea || widget.body is Container)); expect(scaffoldFinder, findsOneWidget); - final appBarFinder = find.descendant(of: scaffoldFinder, matching: find.byType(AppBar)).first; + final appBarFinder = find.byWidget(tester.firstWidget(scaffoldFinder).appBar!); expect(appBarFinder, findsOneWidget); - final textFinder = find.descendant(of: appBarFinder, matching: find.byType(Text)).first; + final textFinder = find.byWidget(tester.firstWidget(appBarFinder).title!); expect(textFinder, findsOneWidget); + + Text text = tester.firstWidget(textFinder); + expect(text.data, 'PDFTron Flutter Sample'); }); - testWidgets('Check widget hierarchy of app body', (WidgetTester tester) async { + testWidgets('Check widget hierarchy of Scaffold body', (WidgetTester tester) async { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); - var bodyFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(SafeArea)).first; + final scaffoldFinder = find.byWidgetPredicate((widget) => widget is Scaffold + && (widget.body is SafeArea || widget.body is Container)); + expect(scaffoldFinder, findsOneWidget); + + var scaffold = tester.firstWidget(scaffoldFinder); + var body = scaffold.body; + + var bodyFinder = find.byWidget(scaffold.body!); + expect(bodyFinder, findsOneWidget); - // Body widget is SafeArea type. - // Occurs when app is initialized and storage is permitted. - if (bodyFinder.evaluate().isNotEmpty) { - final outContainerFinder = find.descendant(of: bodyFinder, matching: find.byType(Container)).first; - expect(outContainerFinder, findsOneWidget); + // Body widget is SafeArea type if app is initialized and storage is permitted. + if (body is SafeArea) { + final safeAreaContainerFinder = find.descendant(of: bodyFinder, matching: find.byType(Container)); + expect(safeAreaContainerFinder, findsWidgets); - final orientationBuilderFinder = find.descendant(of: bodyFinder, matching: find.byType(OrientationBuilder)).first; - expect(orientationBuilderFinder, findsOneWidget); + final orientationBuilderFinder = find.descendant(of: safeAreaContainerFinder.first, matching: find.byType(OrientationBuilder)); + expect(orientationBuilderFinder, findsWidgets); - final inkWellFinder = find.descendant(of: orientationBuilderFinder, matching: find.byType(InkWell)).first; - expect(inkWellFinder, findsOneWidget); + final inkWellFinder = find.descendant(of: orientationBuilderFinder.first, matching: find.byType(InkWell)); + expect(inkWellFinder, findsWidgets); - final containerFinder = find.descendant(of: inkWellFinder, matching: find.byType(Container)).first; + final containerFinder = find.descendant(of: inkWellFinder.first, matching: find.byType(Container)); expect(containerFinder, findsOneWidget); - final imageFinder = find.descendant(of: containerFinder, matching: find.byType(Image)).first; + final imageFinder = find.descendant(of: containerFinder.first, matching: find.byType(Image)); expect(imageFinder, findsOneWidget); } else { - // Body widget is Container type. - // Occurs when app is not initialized or storage is not permitted. - bodyFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(Container)).first; - expect(bodyFinder, findsOneWidget); + // Body widget is Container type if app is not initialized or storage is not permitted. + expect(body.runtimeType, Container); - final alignFinder = find.descendant(of: bodyFinder, matching: find.byType(Align)).first; + final alignFinder = find.descendant(of: bodyFinder, matching: find.byType(Align)); expect(alignFinder, findsOneWidget); - final alignTextFinder = find.descendant(of: alignFinder, matching: find.byType(Text)).first; + final alignTextFinder = find.descendant(of: alignFinder, matching: find.byType(Text)); expect(alignTextFinder, findsOneWidget); } }); From 19dff66bb331a2389e0a940f9bbba6f4e7359f73 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Fri, 18 Jun 2021 15:23:40 -0700 Subject: [PATCH 10/20] Combine tests --- integration_test/app_test.dart | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index be52504..a8188f1 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -14,12 +14,12 @@ import 'package:flutter_sample/main.dart' as app; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('Check widget hierarchy of app excl. Scaffold body', (WidgetTester tester) async { + testWidgets('Check widget hierarchy of app', (WidgetTester tester) async { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); final materialAppFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(MaterialApp)); - expect(materialAppFinder, findsWidgets); + expect(materialAppFinder, findsOneWidget); final scaffoldFinder = find.byWidgetPredicate((widget) => widget is Scaffold && (widget.body is SafeArea || widget.body is Container)); @@ -33,15 +33,6 @@ void main() { Text text = tester.firstWidget(textFinder); expect(text.data, 'PDFTron Flutter Sample'); - }); - - testWidgets('Check widget hierarchy of Scaffold body', (WidgetTester tester) async { - Widget myApp = app.MyApp(); - await tester.pumpWidget(myApp); - - final scaffoldFinder = find.byWidgetPredicate((widget) => widget is Scaffold - && (widget.body is SafeArea || widget.body is Container)); - expect(scaffoldFinder, findsOneWidget); var scaffold = tester.firstWidget(scaffoldFinder); var body = scaffold.body; @@ -55,9 +46,9 @@ void main() { expect(safeAreaContainerFinder, findsWidgets); final orientationBuilderFinder = find.descendant(of: safeAreaContainerFinder.first, matching: find.byType(OrientationBuilder)); - expect(orientationBuilderFinder, findsWidgets); + expect(orientationBuilderFinder, findsOneWidget); - final inkWellFinder = find.descendant(of: orientationBuilderFinder.first, matching: find.byType(InkWell)); + final inkWellFinder = find.descendant(of: orientationBuilderFinder, matching: find.byType(InkWell)); expect(inkWellFinder, findsWidgets); final containerFinder = find.descendant(of: inkWellFinder.first, matching: find.byType(Container)); From cea7202fe9fbe9f272227f57566a40d2f463edd8 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Fri, 18 Jun 2021 16:17:08 -0700 Subject: [PATCH 11/20] Use keys to find widgets --- integration_test/app_test.dart | 45 +++++++++------------------------- lib/main.dart | 3 ++- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index a8188f1..43a2068 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -18,43 +18,19 @@ void main() { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); - final materialAppFinder = find.descendant(of: find.byWidget(myApp), matching: find.byType(MaterialApp)); - expect(materialAppFinder, findsOneWidget); - - final scaffoldFinder = find.byWidgetPredicate((widget) => widget is Scaffold - && (widget.body is SafeArea || widget.body is Container)); - expect(scaffoldFinder, findsOneWidget); - - final appBarFinder = find.byWidget(tester.firstWidget(scaffoldFinder).appBar!); - expect(appBarFinder, findsOneWidget); - - final textFinder = find.byWidget(tester.firstWidget(appBarFinder).title!); - expect(textFinder, findsOneWidget); - - Text text = tester.firstWidget(textFinder); - expect(text.data, 'PDFTron Flutter Sample'); - - var scaffold = tester.firstWidget(scaffoldFinder); - var body = scaffold.body; - - var bodyFinder = find.byWidget(scaffold.body!); + final titleFinder = find.text('PDFTron Flutter Sample'); + expect(titleFinder, findsOneWidget); + + var bodyFinder = find.byKey(Key('body')); expect(bodyFinder, findsOneWidget); + var body = tester.firstWidget(bodyFinder); // Body widget is SafeArea type if app is initialized and storage is permitted. if (body is SafeArea) { - final safeAreaContainerFinder = find.descendant(of: bodyFinder, matching: find.byType(Container)); - expect(safeAreaContainerFinder, findsWidgets); - - final orientationBuilderFinder = find.descendant(of: safeAreaContainerFinder.first, matching: find.byType(OrientationBuilder)); - expect(orientationBuilderFinder, findsOneWidget); - - final inkWellFinder = find.descendant(of: orientationBuilderFinder, matching: find.byType(InkWell)); + final inkWellFinder = find.descendant(of: bodyFinder, matching: find.byType(InkWell)); expect(inkWellFinder, findsWidgets); - final containerFinder = find.descendant(of: inkWellFinder.first, matching: find.byType(Container)); - expect(containerFinder, findsOneWidget); - - final imageFinder = find.descendant(of: containerFinder.first, matching: find.byType(Image)); + final imageFinder = find.descendant(of: inkWellFinder.first, matching: find.byType(Image)); expect(imageFinder, findsOneWidget); } else { @@ -64,8 +40,11 @@ void main() { final alignFinder = find.descendant(of: bodyFinder, matching: find.byType(Align)); expect(alignFinder, findsOneWidget); - final alignTextFinder = find.descendant(of: alignFinder, matching: find.byType(Text)); - expect(alignTextFinder, findsOneWidget); + final textFinder = find.descendant(of: alignFinder, matching: find.byType(Text)); + expect(textFinder, findsOneWidget); + + Text text = tester.firstWidget(textFinder); + assert(text.data == 'Storage permission required.' || text.data == 'PDFTron SDK not initialized.'); } }); } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 465571f..5942968 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -74,7 +74,7 @@ class _MyAppState extends State { Widget getBody() { if (_initialized && _storagePermitted) { - return SafeArea(child: Container( + return SafeArea(key: Key('body'), child: Container( child: OrientationBuilder(builder: (context, orientation) { return GridView.builder( itemCount: thumbnailList.length, @@ -116,6 +116,7 @@ class _MyAppState extends State { )); } else { return Container( + key: Key('body'), child: Align( alignment: Alignment .center, // Align however you like (i.e .centerRight, centerLeft) From a14e7b70f4292db673232b6daba734e614f542e1 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Fri, 18 Jun 2021 16:41:06 -0700 Subject: [PATCH 12/20] Use final instead of var --- integration_test/app_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 43a2068..c2088ac 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -21,11 +21,11 @@ void main() { final titleFinder = find.text('PDFTron Flutter Sample'); expect(titleFinder, findsOneWidget); - var bodyFinder = find.byKey(Key('body')); + final bodyFinder = find.byKey(Key('body')); expect(bodyFinder, findsOneWidget); - var body = tester.firstWidget(bodyFinder); // Body widget is SafeArea type if app is initialized and storage is permitted. + final body = tester.firstWidget(bodyFinder); if (body is SafeArea) { final inkWellFinder = find.descendant(of: bodyFinder, matching: find.byType(InkWell)); expect(inkWellFinder, findsWidgets); From 42f2484d794454765de4ce31473648caea18338f Mon Sep 17 00:00:00 2001 From: Dominic Cupidon Date: Fri, 18 Jun 2021 17:12:37 -0700 Subject: [PATCH 13/20] Created tests for app and updated README.md --- README.md | 10 +- integration_test/app_test.dart | 88 +++++-- integration_test/driver.dart | 8 - ios/Podfile.lock | 12 +- ios/Runner.xcodeproj/project.pbxproj | 24 +- .../contents.xcworkspacedata | 2 +- lib/main.dart | 28 +-- pubspec.lock | 236 ++++-------------- pubspec.yaml | 10 +- test/widget_test.dart | 30 --- test_driver/integration_test.dart | 3 + 11 files changed, 152 insertions(+), 299 deletions(-) delete mode 100644 integration_test/driver.dart delete mode 100644 test/widget_test.dart create mode 100644 test_driver/integration_test.dart diff --git a/README.md b/README.md index d1392d0..7dec66d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # PDFTron Flutter Sample -Flutter sample project that integrates a document viewer using [PDFTron Flutter](https://github.com/PDFTron/pdftron-flutter). Check out the [integration guides](https://www.pdftron.com/documentation/android/flutter) to learn how to add PDFTron to your Flutter App. +Flutter sample project that integrates a document viewer using [PDFTron Flutter](https://github.com/PDFTron/pdftron-flutter). + +Check out the [integration guides](https://www.pdftron.com/documentation/guides/flutter) to learn how to add PDFTron to your Flutter App. ## Preview @@ -7,15 +9,17 @@ Flutter sample project that integrates a document viewer using [PDFTron Flutter] :--:|:--: demo-android | demo-android -## Step +## Installation +### Android 1. Create a `local.properties` file inside the android folder with your Android SDK location, for example: ``` sdk.dir=/Users//Library/Android/sdk ``` -2. For iOS, run: +### iOS +1. For iOS, run: ``` cd ios pod install diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 1b51b34..20b8da0 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -1,36 +1,76 @@ -// This is a basic Flutter integration test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. +import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_sample/thumbnail.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; - import 'package:flutter_sample/main.dart' as app; +import 'package:pdftron_flutter/pdftron_flutter.dart'; +import 'package:permission_handler/permission_handler.dart'; + +// Test for the sample app +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + List calls = []; -void main() => run(_testMain); + setUpAll(() async { + // Used to track method calls + MethodChannel('pdftron_flutter').setMockMethodCallHandler( (MethodCall call) async { + calls.add(call.method); + }); + }); -void _testMain() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - app.main(); + tearDown(() { + // Clears list after each test + calls.clear(); + }); - // Trigger a frame. - await tester.pumpAndSettle(); + // Destroys the method call tracker after all tests have ran + tearDownAll(() async { + MethodChannel('pdftron_flutter').setMockMethodCallHandler(null); + }); - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); + testWidgets("Loading App", (WidgetTester tester) async { + await tester.runAsync(() async { + // Loads sample app + await tester.pumpWidget(app.MyApp()); - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); + // Tests to ensure the proper UI loads when the PDFTron SDK has not been initialised + expect(find.byType(Text), findsNWidgets(2)); + expect(find.text("PDFTron Flutter Sample"), findsOneWidget); - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); + // Rebuilds widget + await tester.pump(); + + // Tests to ensure the proper UI loads once the PDFTron SDK has been initialised + expect(find.byType(InkWell), findsWidgets); + }); + }, variant: TargetPlatformVariant({TargetPlatform.android, TargetPlatform.iOS})); + + testWidgets("Opening Thumbnail", (WidgetTester tester) async { + await tester.runAsync(() async { + await tester.pumpWidget(app.MyApp()); + await tester.pump(); + expect(find.byType(InkWell), findsWidgets); + + // Chooses a random thumbnail to select + Random rng = Random(); + + // 6 is used instead of thumbnailList.length as that is the number of + // thumbnails visible upon loading. + int index = rng.nextInt(6); + Finder thumbnail = find.byKey(ValueKey(thumbnailList[index].documentUrl)); + + // Opens the selected thumbnail + await tester.tap(thumbnail); + await tester.pump(); + + // Tests to ensure that the PdftronFlutter method were called + await Future.delayed(Duration(seconds: 2), () async { + expect(calls.contains(Functions.openDocument), true); + }); + }); + }, variant: TargetPlatformVariant({TargetPlatform.android, TargetPlatform.iOS})); } + diff --git a/integration_test/driver.dart b/integration_test/driver.dart deleted file mode 100644 index a03bca0..0000000 --- a/integration_test/driver.dart +++ /dev/null @@ -1,8 +0,0 @@ -// This file is provided as a convenience for running integration tests via the -// flutter drive command. -// -// flutter drive --driver integration_test/driver.dart --target integration_test/app_test.dart - -import 'package:integration_test/integration_test_driver.dart'; - -Future main() => integrationDriver(); diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 4a6af23..e911450 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2,11 +2,11 @@ PODS: - Flutter (1.0.0) - integration_test (0.0.1): - Flutter - - PDFNet (8.1.0.76833) + - PDFNet (9.0.1.77780) - pdftron_flutter (0.0.1): - Flutter - PDFNet - - permission_handler (3.0.1): + - "permission_handler (5.1.0+2)": - Flutter DEPENDENCIES: @@ -31,10 +31,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c integration_test: 6eb66a19f7104200dcfdd62bc0077e1b09686e4f - PDFNet: 248e57518524fdbb47970216c2db3522e4f51028 + PDFNet: b9e7a7831af4020a4835e19ecf6abf9b81ce29a4 pdftron_flutter: 32bd96e9bc9254c1861f17725e40dd611a7056cd - permission_handler: 6e56ded745f5a0b9dcc0327c65c4acd6a33b776b + permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 -PODFILE CHECKSUM: c3dd2ce4973c59b1eed0b8fefd9e24700fcd3376 +PODFILE CHECKSUM: 1256ed743e0e6641e71d5339a76d03b9e411be9b -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.1 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 82b64c0..8d4fc38 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -228,13 +228,12 @@ buildActionMask = 2147483647; files = ( ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh", - "${PODS_ROOT}/PDFNet/Tools-Localization", + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Tools-Localization", + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -282,19 +281,12 @@ buildActionMask = 2147483647; files = ( ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/PDFNet/PDFNet.framework", - "${PODS_ROOT}/PDFNet/Tools.framework", - "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework", - "${BUILT_PRODUCTS_DIR}/pdftron_flutter/pdftron_flutter.framework", + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PDFNet.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Tools.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/pdftron_flutter.framework", + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a1..919434a 100644 --- a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/lib/main.dart b/lib/main.dart index 3d5fcbc..fdfbe6a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,8 +15,8 @@ const MARGIN = 5.0; const PORTRAIT_NUM_COLUMNS = 2; const LANDSCAPE_NUM_COLUMNS = 3; -final navigationColor = Platform.isIOS ? Color(0xffffffff) : Color(0xff48a1e0); -final titleColor = Platform.isIOS ? Color(0xff007aff) : Color(0xffffffff); +final navigationColor = (BuildContext context) => Theme.of(context).platform == TargetPlatform.iOS ? Color(0xffffffff) : Color(0xff48a1e0); +final titleColor = (BuildContext context) => Theme.of(context).platform == TargetPlatform.iOS ? Color(0xff007aff) : Color(0xffffffff); class MyApp extends StatefulWidget { @override @@ -24,7 +24,7 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - bool _storagePermitted = Platform.isIOS; + late bool _storagePermitted; bool _initialized = false; @override @@ -32,7 +32,11 @@ class _MyAppState extends State { super.initState(); initPlatformState(); - if (Platform.isAndroid) { + setState(() { + _storagePermitted = Theme.of(context).platform == TargetPlatform.iOS; + }); + + if (Theme.of(context).platform == TargetPlatform.android) { askForPermission(); } } @@ -53,20 +57,15 @@ class _MyAppState extends State { } Future askForPermission() async { - Map permissions = - await PermissionHandler().requestPermissions([PermissionGroup.storage]); - if (granted(permissions[PermissionGroup.storage]) && mounted) { + PermissionStatus permission = await Permission.storage.request(); + if (permission.isGranted && mounted) { setState(() { _storagePermitted = true; }); } } - bool granted(PermissionStatus status) { - return status == PermissionStatus.granted; - } - - void openDocument(String document) { + void openDocument(String document) async { // configure the viewer by setting the config fields Config config = new Config(); PdftronFlutter.openDocument(document, config: config); @@ -88,6 +87,7 @@ class _MyAppState extends State { itemBuilder: (BuildContext context, int index) { Thumbnail thumbnail = thumbnailList[index]; return InkWell( + key: ValueKey(thumbnail.documentUrl), child: Container( margin: EdgeInsets.all(MARGIN), decoration: BoxDecoration( @@ -134,9 +134,9 @@ class _MyAppState extends State { centerTitle: true, title: Text( 'PDFTron Flutter Sample', - style: TextStyle(color: titleColor), + style: TextStyle(color: titleColor(context)), ), - backgroundColor: navigationColor, + backgroundColor: navigationColor(context), ), body: getBody()), ); diff --git a/pubspec.lock b/pubspec.lock index 41932b8..3776aa7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,132 +1,90 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "12.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "0.40.6" archive: dependency: transitive description: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" + version: "3.1.2" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.3" + version: "2.6.1" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.5" + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" - cli_util: - dependency: transitive - description: - name: cli_util - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" + version: "1.2.0" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.5" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - coverage: - dependency: transitive - description: - name: coverage - url: "https://pub.dartlang.org" - source: hosted - version: "0.14.2" + version: "1.15.0" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.5" + version: "3.0.1" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.3" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.0.0-nullsafety.4" + version: "6.1.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" flutter_driver: - dependency: transitive + dependency: "direct dev" description: flutter source: sdk version: "0.0.0" @@ -140,262 +98,156 @@ packages: description: flutter source: sdk version: "0.0.0" - glob: - dependency: transitive - description: - name: glob - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" integration_test: dependency: "direct dev" description: flutter source: sdk - version: "0.9.2+2" - io: - dependency: transitive - description: - name: io - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.4" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.3-nullsafety.3" - json_rpc_2: - dependency: transitive - description: - name: json_rpc_2 - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" - logging: - dependency: transitive - description: - name: logging - url: "https://pub.dartlang.org" - source: hosted - version: "0.11.4" + version: "0.0.0" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.3" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.6" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - package_config: - dependency: transitive - description: - name: package_config - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" + version: "1.3.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.8.0" pdftron_flutter: dependency: "direct main" description: - path: "." - ref: HEAD - resolved-ref: "0513833f3c555a0806992cff025ce86c509551d1" - url: "git://github.com/PDFTron/pdftron-flutter.git" - source: git - version: "0.0.9" - pedantic: - dependency: transitive - description: - name: pedantic + name: pdftron_flutter url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.3" + version: "1.0.0-beta.2" permission_handler: dependency: "direct main" description: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" - platform: + version: "8.0.0+2" + permission_handler_platform_interface: dependency: transitive description: - name: platform + name: permission_handler_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.0.0-nullsafety.4" - pool: + version: "3.6.0" + platform: dependency: transitive description: - name: pool + name: platform url: "https://pub.dartlang.org" source: hosted - version: "1.5.0-nullsafety.3" - process: + version: "3.0.0" + plugin_platform_interface: dependency: transitive description: - name: process + name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.0.0-nullsafety.4" - pub_semver: + version: "2.0.0" + process: dependency: transitive description: - name: pub_semver + name: process url: "https://pub.dartlang.org" source: hosted - version: "1.4.4" + version: "4.2.1" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.4" - source_maps: - dependency: transitive - description: - name: source_maps - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.10-nullsafety.3" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.4" + version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.6" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" sync_http: dependency: transitive description: name: sync_http url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.3.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.6" - test_core: - dependency: transitive - description: - name: test_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.12-nullsafety.9" + version: "0.3.0" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.5" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.5" + version: "2.1.0" vm_service: dependency: transitive description: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "5.5.0" - watcher: - dependency: transitive - description: - name: watcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.7+15" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "6.2.0" webdriver: dependency: transitive description: name: webdriver url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" - yaml: - dependency: transitive - description: - name: yaml - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" + version: "3.0.0" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=1.22.0" diff --git a/pubspec.yaml b/pubspec.yaml index ee52404..cae2443 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,17 +18,15 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: sdk: flutter - pdftron_flutter: - git: - url: git://github.com/PDFTron/pdftron-flutter.git + pdftron_flutter: '1.0.0-beta.2' - permission_handler: '3.0.1' + permission_handler: '8.0.0+2' # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. @@ -37,6 +35,8 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + flutter_driver: + sdk: flutter integration_test: sdk: flutter diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index ae07987..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flutter_sample/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/test_driver/integration_test.dart b/test_driver/integration_test.dart new file mode 100644 index 0000000..b38629c --- /dev/null +++ b/test_driver/integration_test.dart @@ -0,0 +1,3 @@ +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); From c1b311cd30082d29884cae04da20485c03883a54 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Fri, 18 Jun 2021 18:40:17 -0700 Subject: [PATCH 14/20] Combine tests --- integration_test/app_test.dart | 26 +--- pubspec.lock | 212 ++++++++++++++++++++++++++++++++- pubspec.yaml | 4 +- 3 files changed, 217 insertions(+), 25 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 8c77794..d937770 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -7,7 +7,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:flutter_sample/main.dart' as app; import 'package:pdftron_flutter/pdftron_flutter.dart'; -import 'package:permission_handler/permission_handler.dart'; // Test for the sample app void main() { @@ -18,8 +17,7 @@ void main() { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); - final titleFinder = find.text('PDFTron Flutter Sample'); - expect(titleFinder, findsOneWidget); + expect(find.text("PDFTron Flutter Sample"), findsOneWidget); final bodyFinder = find.byKey(Key('body')); expect(bodyFinder, findsOneWidget); @@ -45,8 +43,10 @@ void main() { Text text = tester.firstWidget(textFinder); assert(text.data == 'Storage permission required.' || text.data == 'PDFTron SDK not initialized.'); + + expect(find.byType(Text), findsNWidgets(2)); } - }); + }); setUpAll(() async { // Used to track method calls @@ -65,23 +65,7 @@ void main() { MethodChannel('pdftron_flutter').setMockMethodCallHandler(null); }); - testWidgets("Loading App", (WidgetTester tester) async { - await tester.runAsync(() async { - // Loads sample app - await tester.pumpWidget(app.MyApp()); - - // Tests to ensure the proper UI loads when the PDFTron SDK has not been initialised - expect(find.byType(Text), findsNWidgets(2)); - expect(find.text("PDFTron Flutter Sample"), findsOneWidget); - - // Rebuilds widget - await tester.pump(); - - // Tests to ensure the proper UI loads once the PDFTron SDK has been initialised - expect(find.byType(InkWell), findsWidgets); - }); - }, variant: TargetPlatformVariant({TargetPlatform.android, TargetPlatform.iOS})); - + // Incomplete; can't yet control if app is initialized and permission given testWidgets("Opening Thumbnail", (WidgetTester tester) async { await tester.runAsync(() async { await tester.pumpWidget(app.MyApp()); diff --git a/pubspec.lock b/pubspec.lock index 3776aa7..d18187a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,20 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "22.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.1" archive: dependency: transitive description: @@ -8,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.2" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" async: dependency: transitive description: @@ -36,6 +57,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" clock: dependency: transitive description: @@ -50,6 +78,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + coverage: + dependency: transitive + description: + name: coverage + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" crypto: dependency: transitive description: @@ -98,11 +140,53 @@ packages: description: flutter source: sdk version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" integration_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" matcher: dependency: transitive description: @@ -117,6 +201,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" path: dependency: transitive description: @@ -131,13 +236,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0-beta.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" permission_handler: dependency: "direct main" description: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "8.0.0+2" + version: "8.1.1" permission_handler_platform_interface: dependency: transitive description: @@ -159,6 +271,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" process: dependency: transitive description: @@ -166,11 +285,60 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.1" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.4" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + shelf_static: + dependency: transitive + description: + name: shelf_static + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + source_maps: + dependency: transitive + description: + name: source_maps + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.10" source_span: dependency: transitive description: @@ -213,6 +381,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + test: + dependency: "direct dev" + description: + name: test + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.8" test_api: dependency: transitive description: @@ -220,6 +395,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.0" + test_core: + dependency: transitive + description: + name: test_core + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.19" typed_data: dependency: transitive description: @@ -241,6 +423,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.2.0" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" webdriver: dependency: transitive description: @@ -248,6 +444,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.0" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" sdks: dart: ">=2.12.0 <3.0.0" flutter: ">=1.22.0" diff --git a/pubspec.yaml b/pubspec.yaml index f12dfee..83f0652 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,9 +24,7 @@ dependencies: flutter: sdk: flutter - pdftron_flutter: - git: - url: git://github.com/PDFTron/pdftron-flutter.git + pdftron_flutter: '1.0.0-beta.2' permission_handler: ^8.1.1 From 37c6147302009c5b77c21901ee2f376fde5c4a20 Mon Sep 17 00:00:00 2001 From: Dominic Cupidon Date: Mon, 21 Jun 2021 11:16:02 -0700 Subject: [PATCH 15/20] Updates: * Removed a test that Adrienne had covered more thoroughly * Allowed for tests to gain storage permissions on Android * Added command to run tests in README.md * Added comments to files --- README.md | 8 +++++++ integration_test/app_test.dart | 38 ++++++++----------------------- test_driver/integration_test.dart | 19 +++++++++++++++- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 7dec66d..c16a8b0 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,18 @@ pod install ## Run +### Sample App + ``` flutter run ``` +### Test + +``` +flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart +``` + ## Upgrade For updating flutter projects, please check out [here](https://flutter.dev/docs/development/tools/sdk/upgrading). diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 20b8da0..31a6b3b 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -1,5 +1,4 @@ import 'dart:math'; - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_sample/thumbnail.dart'; @@ -7,66 +6,47 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:flutter_sample/main.dart' as app; import 'package:pdftron_flutter/pdftron_flutter.dart'; -import 'package:permission_handler/permission_handler.dart'; -// Test for the sample app -void main() { +// Test for the sample app. +void main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); List calls = []; setUpAll(() async { - // Used to track method calls + // Used to track method calls. MethodChannel('pdftron_flutter').setMockMethodCallHandler( (MethodCall call) async { calls.add(call.method); }); }); tearDown(() { - // Clears list after each test + // Clears list after each test. calls.clear(); }); - // Destroys the method call tracker after all tests have ran + // Destroys the method call tracker after all tests have ran. tearDownAll(() async { MethodChannel('pdftron_flutter').setMockMethodCallHandler(null); }); - testWidgets("Loading App", (WidgetTester tester) async { - await tester.runAsync(() async { - // Loads sample app - await tester.pumpWidget(app.MyApp()); - - // Tests to ensure the proper UI loads when the PDFTron SDK has not been initialised - expect(find.byType(Text), findsNWidgets(2)); - expect(find.text("PDFTron Flutter Sample"), findsOneWidget); - - // Rebuilds widget - await tester.pump(); - - // Tests to ensure the proper UI loads once the PDFTron SDK has been initialised - expect(find.byType(InkWell), findsWidgets); - }); - }, variant: TargetPlatformVariant({TargetPlatform.android, TargetPlatform.iOS})); - testWidgets("Opening Thumbnail", (WidgetTester tester) async { await tester.runAsync(() async { await tester.pumpWidget(app.MyApp()); await tester.pump(); expect(find.byType(InkWell), findsWidgets); - // Chooses a random thumbnail to select + // Chooses a random thumbnail to select. Random rng = Random(); - // 6 is used instead of thumbnailList.length as that is the number of - // thumbnails visible upon loading. + // 6 is used instead of thumbnailList.length as that is the number of thumbnails visible upon loading. int index = rng.nextInt(6); Finder thumbnail = find.byKey(ValueKey(thumbnailList[index].documentUrl)); - // Opens the selected thumbnail + // Opens the selected thumbnail. await tester.tap(thumbnail); await tester.pump(); - // Tests to ensure that the PdftronFlutter method were called + // Tests to ensure that the PdftronFlutter method were called. await Future.delayed(Duration(seconds: 2), () async { expect(calls.contains(Functions.openDocument), true); }); diff --git a/test_driver/integration_test.dart b/test_driver/integration_test.dart index b38629c..ad98ece 100644 --- a/test_driver/integration_test.dart +++ b/test_driver/integration_test.dart @@ -1,3 +1,20 @@ +import 'dart:io' show Platform, Process; import 'package:integration_test/integration_test_driver.dart'; +import 'package:path/path.dart'; -Future main() => integrationDriver(); +// Driver for the integration test. +Future main() async { + // Obtains storage permission on Android. + Map vars = Platform.environment; + String path = join(vars['ANDROID_SDK_ROOT'] ?? vars['ANDROID_HOME'] as String, "platform-tools", Platform.isWindows ? "adb.exe" : "adb"); + await Process.run(path, [ + 'shell', + 'pm', + 'grant', + 'com.example.fluttersample', + 'android.permission.WRITE_EXTERNAL_STORAGE' + ]); + + // Starts the driver. + await integrationDriver(); +} From 712753f4e2ad75d62e8bb81fa48e9f1ab10342d6 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Mon, 21 Jun 2021 11:21:32 -0700 Subject: [PATCH 16/20] Add details in README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c16a8b0..8bcd2c6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # PDFTron Flutter Sample -Flutter sample project that integrates a document viewer using [PDFTron Flutter](https://github.com/PDFTron/pdftron-flutter). +Flutter sample project that integrates a document viewer using PDFTron Flutter. -Check out the [integration guides](https://www.pdftron.com/documentation/guides/flutter) to learn how to add PDFTron to your Flutter App. +PDFTron's Flutter PDF library now supports sound null safety and is available on [GitHub](https://github.com/PDFTron/pdftron-flutter) and [pub.dev](https://pub.dev/packages/pdftron_flutter). To learn how to add PDFTron to your Flutter App, check out the [integration guides](https://www.pdftron.com/documentation/guides/flutter). ## Preview @@ -41,7 +41,7 @@ flutter drive --driver=test_driver/integration_test.dart --target=integration_te ## Upgrade -For updating flutter projects, please check out [here](https://flutter.dev/docs/development/tools/sdk/upgrading). +For updating flutter projects, please check out [Upgrading Flutter](https://flutter.dev/docs/development/tools/sdk/upgrading). ## License See [License](./LICENSE) From 8fa133cab32a5ffa8a0b48a0b4dd03566efc8517 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Mon, 21 Jun 2021 11:25:32 -0700 Subject: [PATCH 17/20] Update wording --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bcd2c6..3d5acc3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # PDFTron Flutter Sample -Flutter sample project that integrates a document viewer using PDFTron Flutter. +A Flutter sample project that integrates a document viewer using PDFTron Flutter. PDFTron's Flutter PDF library now supports sound null safety and is available on [GitHub](https://github.com/PDFTron/pdftron-flutter) and [pub.dev](https://pub.dev/packages/pdftron_flutter). To learn how to add PDFTron to your Flutter App, check out the [integration guides](https://www.pdftron.com/documentation/guides/flutter). From e6bd281cf0a7f914f32d7d88892cc3386d687c77 Mon Sep 17 00:00:00 2001 From: Dominic Cupidon Date: Mon, 21 Jun 2021 11:32:07 -0700 Subject: [PATCH 18/20] Changed the order of tests --- integration_test/app_test.dart | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 14f52ee..726af47 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -12,6 +12,23 @@ void main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); List calls = []; + setUpAll(() async { + // Used to track method calls. + MethodChannel('pdftron_flutter').setMockMethodCallHandler( (MethodCall call) async { + calls.add(call.method); + }); + }); + + tearDown(() { + // Clears list after each test. + calls.clear(); + }); + + // Destroys the method call tracker after all tests have ran. + tearDownAll(() async { + MethodChannel('pdftron_flutter').setMockMethodCallHandler(null); + }); + testWidgets('Check widget hierarchy of app', (WidgetTester tester) async { Widget myApp = app.MyApp(); await tester.pumpWidget(myApp); @@ -47,23 +64,6 @@ void main() async { } }); - setUpAll(() async { - // Used to track method calls. - MethodChannel('pdftron_flutter').setMockMethodCallHandler( (MethodCall call) async { - calls.add(call.method); - }); - }); - - tearDown(() { - // Clears list after each test. - calls.clear(); - }); - - // Destroys the method call tracker after all tests have ran. - tearDownAll(() async { - MethodChannel('pdftron_flutter').setMockMethodCallHandler(null); - }); - testWidgets("Opening Thumbnail", (WidgetTester tester) async { await tester.runAsync(() async { await tester.pumpWidget(app.MyApp()); From 58a76b9db928d95aa879cd582598c1aaaa5b24dc Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Tue, 22 Jun 2021 11:12:51 -0700 Subject: [PATCH 19/20] Remove permission_handler package --- lib/main.dart | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 4c495d8..da2b6f9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_sample/thumbnail.dart'; import 'package:pdftron_flutter/pdftron_flutter.dart'; -import 'package:permission_handler/permission_handler.dart'; void main() => runApp(MyApp()); @@ -24,21 +23,12 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - late bool _storagePermitted; bool _initialized = false; @override void initState() { super.initState(); initPlatformState(); - - setState(() { - _storagePermitted = Theme.of(context).platform == TargetPlatform.iOS; - }); - - if (Theme.of(context).platform == TargetPlatform.android) { - askForPermission(); - } } // Platform messages are asynchronous, so we initialize in an async method. @@ -56,16 +46,6 @@ class _MyAppState extends State { } } - Future askForPermission() async { - var permission = - await Permission.storage.request(); - if (permission.isGranted && mounted) { - setState(() { - _storagePermitted = true; - }); - } - } - void openDocument(String document) async { // configure the viewer by setting the config fields Config config = new Config(); @@ -73,7 +53,7 @@ class _MyAppState extends State { } Widget getBody() { - if (_initialized && _storagePermitted) { + if (_initialized) { return SafeArea(key: Key('body'), child: Container( child: OrientationBuilder(builder: (context, orientation) { return GridView.builder( @@ -121,9 +101,7 @@ class _MyAppState extends State { child: Align( alignment: Alignment .center, // Align however you like (i.e .centerRight, centerLeft) - child: Text(_initialized - ? 'Storage permission required.' - : 'PDFTron SDK not initialized.'), + child: Text('PDFTron SDK not initialized.'), )); } } From 67904acec3ca7eddd2ae07f571852b01c0eec160 Mon Sep 17 00:00:00 2001 From: akwanpdf Date: Tue, 22 Jun 2021 13:59:39 -0700 Subject: [PATCH 20/20] Remove permission_handler package --- pubspec.lock | 23 +---------------------- pubspec.yaml | 2 -- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index d18187a..490f2ca 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -243,20 +243,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.11.1" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - url: "https://pub.dartlang.org" - source: hosted - version: "8.1.1" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "3.6.0" platform: dependency: transitive description: @@ -264,13 +250,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" pool: dependency: transitive description: @@ -460,4 +439,4 @@ packages: version: "3.1.0" sdks: dart: ">=2.12.0 <3.0.0" - flutter: ">=1.22.0" + flutter: ">=1.12.0" diff --git a/pubspec.yaml b/pubspec.yaml index 83f0652..922beb4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,8 +26,6 @@ dependencies: pdftron_flutter: '1.0.0-beta.2' - permission_handler: ^8.1.1 - # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.3