From 599453c82e6fbb47d95b84e6dc1f05ed7298d161 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 10 Feb 2022 18:31:35 +0600 Subject: [PATCH] cleared junks --- packages/fl_query/example/pubspec.lock | 21 - packages/fl_query/pubspec.yaml | 11 - .../test/anonymous_operations_test.dart | 171 ---- packages/fl_query/test/cache/cache_data.dart | 362 ------- .../test/cache/graphql_cache_test.dart | 313 ------ packages/fl_query/test/cache/store_test.dart | 79 -- packages/fl_query/test/coverage.dart | 20 - packages/fl_query/test/fetch_policy_test.dart | 122 --- .../fl_query/test/graphql_client_test.dart | 888 ------------------ packages/fl_query/test/helpers.dart | 34 - .../test/mock_server/ws_echo_server.dart | 26 - .../fl_query/test/query_options_test.dart | 51 - packages/fl_query/test/sample_upload.jpg | Bin 256 -> 0 bytes packages/fl_query/test/sample_upload.mov | Bin 271 -> 0 bytes packages/fl_query/test/test_helpers.dart | 70 -- packages/fl_query/test/websocket_test.dart | 431 --------- 16 files changed, 2599 deletions(-) delete mode 100644 packages/fl_query/test/anonymous_operations_test.dart delete mode 100644 packages/fl_query/test/cache/cache_data.dart delete mode 100644 packages/fl_query/test/cache/graphql_cache_test.dart delete mode 100644 packages/fl_query/test/cache/store_test.dart delete mode 100644 packages/fl_query/test/coverage.dart delete mode 100644 packages/fl_query/test/fetch_policy_test.dart delete mode 100644 packages/fl_query/test/graphql_client_test.dart delete mode 100644 packages/fl_query/test/helpers.dart delete mode 100644 packages/fl_query/test/mock_server/ws_echo_server.dart delete mode 100644 packages/fl_query/test/query_options_test.dart delete mode 100644 packages/fl_query/test/sample_upload.jpg delete mode 100644 packages/fl_query/test/sample_upload.mov delete mode 100644 packages/fl_query/test/test_helpers.dart delete mode 100644 packages/fl_query/test/websocket_test.dart diff --git a/packages/fl_query/example/pubspec.lock b/packages/fl_query/example/pubspec.lock index 64151ee..43f064c 100644 --- a/packages/fl_query/example/pubspec.lock +++ b/packages/fl_query/example/pubspec.lock @@ -97,13 +97,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.1" - rxdart: - dependency: transitive - description: - name: rxdart - url: "https://pub.dartlang.org" - source: hosted - version: "0.27.3" sky_engine: dependency: transitive description: flutter @@ -116,13 +109,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" string_scanner: dependency: transitive description: @@ -158,13 +144,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" sdks: dart: ">=2.15.1 <3.0.0" flutter: ">=1.17.0" diff --git a/packages/fl_query/pubspec.yaml b/packages/fl_query/pubspec.yaml index dff106e..c614393 100644 --- a/packages/fl_query/pubspec.yaml +++ b/packages/fl_query/pubspec.yaml @@ -12,20 +12,9 @@ dependencies: sdk: flutter meta: ^1.3.0 path: ^1.8.0 - # gql: ^0.13.0 - # gql_exec: 0.3.0 - # gql_link: 0.4.0 - # gql_http_link: 0.4.0 - # gql_transform_link: ^0.2.0 - # gql_error_link: ^0.2.0 - # gql_dedupe_link: ^2.0.0 - # normalize: ^0.6.0 hive: ^2.0.0 http: ^0.13.0 collection: ^1.15.0 - web_socket_channel: ^2.0.0 - stream_channel: ^2.1.0 - rxdart: ^0.27.1 uuid: ^3.0.1 internet_connection_checker: ^0.0.1+3 diff --git a/packages/fl_query/test/anonymous_operations_test.dart b/packages/fl_query/test/anonymous_operations_test.dart deleted file mode 100644 index 918008c..0000000 --- a/packages/fl_query/test/anonymous_operations_test.dart +++ /dev/null @@ -1,171 +0,0 @@ -import 'package:gql/language.dart'; -import 'package:test/test.dart'; -import 'package:mockito/mockito.dart'; - -import 'package:fl_query/fl_query.dart'; - -import './helpers.dart'; - -void main() { - const String readRepositories = r'''{ - viewer { - repositories(last: 42) { - nodes { - __typename - id - name - viewerHasStarred - } - } - } - } -'''; - - const String addStar = r'''mutation { - action: addStar(input: {starrableId: "some_repo"}) { - starrable { - viewerHasStarred - } - } - } -'''; - - late MockLink link; - late GraphQLClient graphQLClientClient; - - group('simple json', () { - setUp(() { - link = MockLink(); - - graphQLClientClient = GraphQLClient( - cache: getTestCache(), - link: link, - ); - }); - - group('query', () { - test('successful query', () async { - final WatchQueryOptions _options = WatchQueryOptions( - document: parseString(readRepositories), - variables: {}, - ); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable( - [ - Response( - data: { - 'viewer': { - 'repositories': { - 'nodes': [ - { - '__typename': 'Repository', - 'id': 'MDEwOlJlcG9zaXRvcnkyNDgzOTQ3NA==', - 'name': 'pq', - 'viewerHasStarred': false, - }, - { - '__typename': 'Repository', - 'id': 'MDEwOlJlcG9zaXRvcnkzMjkyNDQ0Mw==', - 'name': 'go-evercookie', - 'viewerHasStarred': false, - }, - { - '__typename': 'Repository', - 'id': 'MDEwOlJlcG9zaXRvcnkzNTA0NjgyNA==', - 'name': 'watchbot', - 'viewerHasStarred': false, - }, - ], - }, - }, - }, - ), - ], - ), - ); - - final QueryResult r = await graphQLClientClient.query(_options); - - verify( - link.request( - Request( - operation: Operation( - document: parseString(readRepositories), - operationName: null, - ), - variables: {}, - context: Context(), - ), - ), - ); - - expect(r.exception, isNull); - expect(r.data, isNotNull); - final List> nodes = - (r.data!['viewer']['repositories']['nodes'] as List) - .cast>(); - expect(nodes, hasLength(3)); - expect(nodes[0]['id'], 'MDEwOlJlcG9zaXRvcnkyNDgzOTQ3NA=='); - expect(nodes[1]['name'], 'go-evercookie'); - expect(nodes[2]['viewerHasStarred'], false); - return; - }); -// test('failed query because of network', {}); -// test('failed query because of because of error response', {}); -// test('failed query because of because of invalid response', () { -// String responseBody = -// '{\"message\":\"Bad credentials\",\"documentation_url\":\"https://developer.github.com/v4\"}'; -// int responseCode = 401; -// }); -// test('partially success query with some errors', {}); - }); - group('mutation', () { - test('successful mutation', () async { - final MutationOptions _options = MutationOptions( - document: parseString(addStar), - ); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable( - [ - Response( - data: { - 'action': { - 'starrable': { - 'viewerHasStarred': true, - }, - }, - }, - ), - ], - ), - ); - - final QueryResult response = await graphQLClientClient.mutate(_options); - - verify( - link.request( - Request( - operation: Operation( - document: parseString(addStar), - ), - variables: {}, - context: Context(), - ), - ), - ); - - expect(response.exception, isNull); - expect(response.data, isNotNull); - final bool? viewerHasStarred = - response.data!['action']['starrable']['viewerHasStarred'] as bool?; - expect(viewerHasStarred, true); - }); - }); - }); -} diff --git a/packages/fl_query/test/cache/cache_data.dart b/packages/fl_query/test/cache/cache_data.dart deleted file mode 100644 index 4c86a27..0000000 --- a/packages/fl_query/test/cache/cache_data.dart +++ /dev/null @@ -1,362 +0,0 @@ -import 'package:gql_exec/gql_exec.dart'; -import 'package:gql/language.dart'; -import 'package:fl_query/fl_query.dart' show Fragment; -import 'package:fl_query/src/utilities/helpers.dart'; -import 'package:http/http.dart' as http; -import 'package:http_parser/http_parser.dart'; - -const String rawOperationKey = 'rawOperationKey'; - -class TestCase { - TestCase({ - required this.data, - required String operation, - Map variables = const {}, - this.normalizedEntities, - }) : request = Request( - operation: Operation(document: parseString(operation)), - variables: variables, - context: Context(), - ); - - Request request; - - /// data to write to cache - Map data; - - /// entities to inspect the store for, if any - List>? normalizedEntities; -} - -final basicTest = TestCase( - operation: r'''{ - a { - __typename - id - # union - list { - __typename - value - ... on Item { id } - } - b { - __typename - id - c { - __typename - id, - cField - } - bField { field } - }, - d { - id, - dField {field} - } - aField { field } - } - }''', - data: { - 'a': { - '__typename': 'A', - 'id': 1, - 'list': [ - {'__typename': 'Num', 'value': 1}, - {'__typename': 'Num', 'value': 2}, - {'__typename': 'Num', 'value': 3}, - {'__typename': 'Item', 'id': 4, 'value': 4} - ], - 'b': { - '__typename': 'B', - 'id': 5, - 'c': { - '__typename': 'C', - 'id': 6, - 'cField': 'value', - }, - 'bField': {'field': true} - }, - 'd': { - 'id': 9, - 'dField': {'field': true} - }, - 'aField': {'field': false} - }, - }, -); - -/// https://github.com/gql-dart/gql/blob/master/links/gql_http_link/test/multipart_upload_test.dart -final fileVarsTest = TestCase( - data: { - "multipleUpload": [ - { - "id": "r1odc4PAz", - "filename": "sample_upload.jpg", - "mimetype": "image/jpeg", - "path": "./uploads/r1odc4PAz-sample_upload.jpg" - }, - { - "id": "5Ea18qlMur", - "filename": "sample_upload.txt", - "mimetype": "text/plain", - "path": "./uploads/5Ea18qlMur-sample_upload.txt" - } - ], - }, - operation: r""" - mutation($files: [Upload!]!) { - multipleUpload(files: $files) { - id - filename - mimetype - path - } - } - """, - variables: { - 'files': [ - http.MultipartFile.fromBytes( - "", - [0, 1, 254, 255], - filename: "sample_upload.jpg", - contentType: MediaType("image", "jpeg"), - ), - http.MultipartFile.fromString( - "", - "just plain text", - filename: "sample_upload.txt", - contentType: MediaType("text", "plain"), - ), - ], - }, -); - -final originalCValue = { - '__typename': 'C', - 'id': 6, - 'cField': 'value', -}; -final originalCFragment = Fragment( - document: parseString( - r''' - fragment partialC on C { - __typename - id - cField - } - ''', - ), -); - -final updatedCFragment = Fragment( - document: parseString( - r''' - fragment partialC on C { - __typename - id - new - cField - } - ''', - ), -); - -final updatedCValue = { - '__typename': 'C', - 'id': 6, - 'new': 'field', - 'cField': 'changed value', -}; - -final Map? updatedCBasicTestData = deeplyMergeLeft([ - basicTest.data, - { - 'a': { - 'b': { - 'c': { - '__typename': 'C', - 'id': 6, - 'cField': 'changed value', - }, - }, - }, - }, -]); - -final basicTestSubsetAValue = TestCase( - operation: r'''{ - a { - __typename - id - list { - __typename - value - ... on Item { id } - } - d { id } - } - }''', - data: { - 'a': { - '__typename': 'A', - 'id': 1, - 'list': [ - {'__typename': 'Num', 'value': 5}, - {'__typename': 'Num', 'value': 6}, - {'__typename': 'Num', 'value': 7}, - { - '__typename': 'Item', - 'id': 8, - 'value': 8, - } - ], - 'd': { - 'id': 10, - }, - }, - }, -); - -getUpdatedSubsetOperationData({withUpdatedC = false}) => { - 'a': { - '__typename': 'A', - 'id': 1, - 'list': basicTestSubsetAValue.data['a']['list'], - 'b': { - '__typename': 'B', - 'id': 5, - 'c': { - '__typename': 'C', - 'id': 6, - 'cField': '${withUpdatedC ? "changed " : ""}value', - }, - 'bField': {'field': true} - }, - 'd': { - 'id': 10, - 'dField': {'field': true} - }, - 'aField': {'field': false} - }, - }; - -final cyclicalTest = TestCase(operation: r'''{ - a { - __typename - id - b { - __typename - id - as { - __typename - id - } - } - } - }''', data: { - 'a': { - '__typename': 'A', - 'id': 1, - 'b': { - '__typename': 'B', - 'id': 5, - 'as': [ - { - '__typename': 'A', - 'id': 1, - }, - ] - }, - }, -}, normalizedEntities: [ - { - '__typename': 'A', - 'id': 1, - 'b': {r"$ref": 'B:5'} - }, - { - '__typename': 'B', - 'id': 5, - 'as': [ - {r"$ref": 'A:1'} - ], - }, -]); - -Map get cyclicalObjOperationData { - Map a; - Map b; - a = { - '__typename': 'A', - 'id': 1, - }; - b = { - '__typename': 'B', - 'id': 5, - 'as': [a] - }; - a['b'] = b; - return {'a': a}; -} - -final typelessTest = TestCase( - operation: r'''{ - a { - # union - list { - #__typename - value - #... on Item { id } - } - b { - id - c { - id, - cField - } - bField { field } - }, - d { - id, - dField {field} - } - aField { field } - } - }''', - data: { - 'a': { - 'list': [ - { - //'__typename': 'Num', - 'value': 1, - }, - { - //'__typename': 'Num', - 'value': 2, - }, - { - //'__typename': 'Num', - 'value': 3, - }, - { - //'__typename': 'Item', - //'id': 4, - 'value': 4, - } - ], - 'b': { - 'id': 5, - 'c': { - 'id': 6, - 'cField': 'value', - }, - 'bField': {'field': true} - }, - 'd': { - 'id': 9, - 'dField': {'field': true} - }, - 'aField': {'field': false} - }, - }, -); diff --git a/packages/fl_query/test/cache/graphql_cache_test.dart b/packages/fl_query/test/cache/graphql_cache_test.dart deleted file mode 100644 index 580ded1..0000000 --- a/packages/fl_query/test/cache/graphql_cache_test.dart +++ /dev/null @@ -1,313 +0,0 @@ -import 'package:fl_query/src/cache/_normalizing_data_proxy.dart'; -import 'package:normalize/normalize.dart' show PartialDataException; -import 'package:test/test.dart'; - -import 'package:fl_query/src/cache/cache.dart'; - -import '../helpers.dart'; -import './cache_data.dart'; - -typedef CacheTransaction = JSONDataProxy Function(JSONDataProxy proxy); - -void main() { - if (debuggingUnexpectedTestFailures) { - print( - 'DEBUGGING UNEXPECTED TEST FAILURES: $debuggingUnexpectedTestFailures.\n' - 'RUNNING TESTS WITH returnPartialData SET TO TRUE.\n', - ); - } - - group('Normalizes writes', () { - late QueryCache cache; - setUp(() { - cache = getTestCache(); - }); - test('.writeQuery .readQuery round trip', () { - cache.writeQuery(basicTest.request, data: basicTest.data); - expect( - cache.readQuery(basicTest.request), - equals(basicTest.data), - ); - }); - - test('typeless .writeQuery .readQuery round trip', () { - cache.writeQuery(typelessTest.request, data: typelessTest.data); - expect( - cache.readQuery(typelessTest.request), - equals(typelessTest.data), - ); - }); - - test('typeless custom dataIdFromObject', () { - cache.writeQuery(typelessTest.request, data: typelessTest.data); - expect( - cache.readQuery(typelessTest.request), - equals(typelessTest.data), - ); - }); - - test('.writeQuery should fail on missing fields', () { - expect( - () => cache.writeQuery(basicTest.request, data: { - ...basicTest.data, - 'a': { - ...basicTest.data['a'], - 'b': { - 'id': 5, - } - }, - }), - throwsA(isA().having( - (e) => e.path, - 'An accurate path to the first missing subfield', - ['a', 'b', '__typename'], - )), - ); - }); - - test('updating nested normalized fragment changes top level operation', () { - cache.writeQuery(basicTest.request, data: basicTest.data); - final idFields = { - '__typename': updatedCValue['__typename'], - 'id': updatedCValue['id'], - }; - cache.writeFragment( - updatedCFragment.asRequest( - idFields: idFields, - ), - data: updatedCValue, - ); - - expect( - cache.readQuery(basicTest.request), - equals(updatedCBasicTestData), - ); - - expect( - cache.readFragment( - updatedCFragment.asRequest( - idFields: idFields, - ), - ), - updatedCValue, - ); - }); - - test('updating subset query only partially overrides superset query', () { - cache.writeQuery(basicTest.request, data: basicTest.data); - - cache.writeQuery( - basicTestSubsetAValue.request, - data: basicTestSubsetAValue.data, - ); - expect( - cache.readQuery(basicTest.request), - equals(getUpdatedSubsetOperationData()), - ); - }); - }); - - group('Handles cyclical references', () { - final QueryCache cache = getTestCache(); - test('lazily reads cyclical references', () { - cache.writeQuery(cyclicalTest.request, data: cyclicalTest.data); - for (final normalized in cyclicalTest.normalizedEntities!) { - final dataId = "${normalized['__typename']}:${normalized['id']}"; - expect(cache.readNormalized(dataId), equals(normalized)); - } - }); - }); - - group('Handles Object/pointer self-references/cycles', () { - final QueryCache cache = getTestCache(); - test('correctly reads cyclical references', () { - cyclicalTest.data = cyclicalObjOperationData; - cache.writeQuery(cyclicalTest.request, data: cyclicalTest.data); - for (final normalized in cyclicalTest.normalizedEntities!) { - final dataId = "${normalized['__typename']}:${normalized['id']}"; - expect(cache.readNormalized(dataId), equals(normalized)); - } - }); - }); - - group( - '.recordOptimisticTransaction', - () { - late QueryCache cache; - - setUp(() { - cache = getTestCache(); - }); - - test( - 'OptimisticCache.readQuery and .readFragment pass through', - () { - cache.writeQuery(basicTest.request, data: basicTest.data); - cache.broadcastRequested = false; - cache.recordOptimisticTransaction( - (proxy) { - expect( - proxy.readQuery(basicTest.request), - equals(basicTest.data), - ); - - final idFields = { - '__typename': originalCValue['__typename'], - 'id': originalCValue['id'], - }; - - expect( - proxy.readFragment(originalCFragment.asRequest( - idFields: idFields, - )), - originalCValue, - ); - - expect( - (proxy as NormalizingDataProxy).broadcastRequested, - isFalse, - ); - - return proxy; - }, - '1', - ); - - // no edits - expect(cache.broadcastRequested, isFalse); - expect(cache.optimisticPatches.first.id, equals('1')); - expect(cache.optimisticPatches.first.data, equals({})); - }, - ); - - test( - '.writeQuery, .readQuery(optimistic: true) round trip', - () { - cache.recordOptimisticTransaction( - (proxy) => proxy - ..writeQuery( - basicTest.request, - data: basicTest.data, - ), - '1', - ); - expect( - cache.readQuery(basicTest.request, optimistic: true), - equals(basicTest.data), - ); - }, - ); - - recordCFragmentUpdate(QueryCache cache) => - cache.recordOptimisticTransaction( - (proxy) => proxy - ..writeFragment( - updatedCFragment.asRequest(idFields: { - '__typename': updatedCValue['__typename'], - 'id': updatedCValue['id'], - }), - data: updatedCValue, - ), - '2', - ); - - test( - 'updating nested normalized fragment changes top level operation', - () { - cache.writeQuery(basicTest.request, data: basicTest.data); - recordCFragmentUpdate(cache); - expect( - cache.readQuery(basicTest.request), - equals(updatedCBasicTestData), - ); - }, - ); - - recordBasicSubsetData(QueryCache cache) => - cache.recordOptimisticTransaction( - (proxy) => proxy - ..writeQuery( - basicTestSubsetAValue.request, - data: basicTestSubsetAValue.data, - ), - '3', - ); - test( - 'updating subset query partially overrides superset query', - () { - cache.writeQuery(basicTest.request, data: basicTest.data); - recordCFragmentUpdate(cache); - recordBasicSubsetData(cache); - expect( - cache.readQuery(basicTest.request, optimistic: true), - equals(getUpdatedSubsetOperationData(withUpdatedC: true)), - ); - }, - ); - - test( - '.removeOptimisticPatch results in data from lower layers on readQuery', - () { - cache.writeQuery(basicTest.request, data: basicTest.data); - recordCFragmentUpdate(cache); - recordBasicSubsetData(cache); - cache.removeOptimisticPatch('2'); - cache.removeOptimisticPatch('3'); - expect( - cache.readQuery(basicTest.request, optimistic: true), - equals(basicTest.data), - ); - }, - ); - }, - ); - - group('Handles MultipartFile variables', () { - late QueryCache cache; - setUp(() { - cache = getTestCache(); - }); - test('.writeQuery .readQuery round trip', () { - cache.writeQuery(fileVarsTest.request, data: fileVarsTest.data); - expect( - cache.readQuery(fileVarsTest.request), - equals(fileVarsTest.data), - ); - }); - }); - - group('custom dataIdFromObject', () { - /// Uses a `/` instead of the default `:` - String? customDataIdFromObject(Object object) { - if (object is Map && - object.containsKey('__typename') && - object.containsKey('id')) - return "${object['__typename']}/${object['id']}"; - return null; - } - - late QueryCache cache; - setUp(() { - cache = QueryCache( - dataIdFromObject: customDataIdFromObject, - partialDataPolicy: PartialDataCachePolicy.reject, - ); - }); - - test('.writeQuery .readQuery round trip', () { - cache.writeQuery(basicTest.request, data: basicTest.data); - expect( - cache.readQuery(basicTest.request), - equals(basicTest.data), - ); - }); - - test('typeless .writeQuery .readQuery round trip', () { - cache.writeQuery(typelessTest.request, data: typelessTest.data); - expect( - cache.readQuery(typelessTest.request), - equals(typelessTest.data), - ); - }); - }); -} diff --git a/packages/fl_query/test/cache/store_test.dart b/packages/fl_query/test/cache/store_test.dart deleted file mode 100644 index 30223d7..0000000 --- a/packages/fl_query/test/cache/store_test.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'dart:io'; - -import 'package:fl_query/fl_query.dart'; -import 'package:fl_query/src/utilities/helpers.dart'; -import 'package:test/test.dart'; - -void main() { - group('InMemoryStore', () { - final data = { - 'id': {'key': 'value'}, - 'id2': {'otherKey': false} - }; - test('basic methods', () { - final store = InMemoryStore(); - store.put('id', data['id']); - expect(store.get('id'), equals(data['id'])); - - store.delete('id'); - expect(store.data, equals({})); - }); - test('bulk methods', () { - final store = InMemoryStore(); - - store.putAll(data); - - expect(store.data, equals(data)); - expect(store.toMap(), equals(data)); - - store.reset(); - - expect(data['id'], notNull); // no mutations - }); - }); - - group('HiveStore', () { - final data = { - 'id': {'key': 'value'}, - 'id2': {'otherKey': false} - }; - final path = './test/cache/test_hive_boxes/'; - test('basic methods', () async { - final store = - await HiveStore.open(boxName: 'basic', path: path + 'basic'); - store.put('id', data['id']); - expect(store.get('id'), equals(data['id'])); - - store.delete('id'); - expect(store.toMap(), equals({})); - - await store.box.deleteFromDisk(); - }); - test('bulk methods', () async { - final store = await HiveStore.open(boxName: 'bulk', path: path + 'bulk'); - - store.putAll(data); - expect(store.toMap(), equals(data)); - - await store.reset(); - expect(store.toMap(), equals({})); - - expect(data['id'], notNull); // no mutations - - await store.box.deleteFromDisk(); - }); - - test('box rereferencing', () async { - final store = await HiveStore.open(path: path); - store.putAll(data); - - expect(HiveStore().toMap(), equals(data)); - - await store.box.deleteFromDisk(); - }); - - tearDownAll(() async { - await Directory(path).delete(recursive: true); - }); - }); -} diff --git a/packages/fl_query/test/coverage.dart b/packages/fl_query/test/coverage.dart deleted file mode 100644 index 9c0d47b..0000000 --- a/packages/fl_query/test/coverage.dart +++ /dev/null @@ -1,20 +0,0 @@ -// initially auto-generated by test_coverage, -// but that project is unmaintained https://github.com/pulyaevskiy/test-coverage/issues/40 - -import 'anonymous_operations_test.dart' as anonymous_operations_test; -import 'cache/graphql_cache_test.dart' as cache_graphql_cache_test; -import 'cache/store_test.dart' as cache_store_test; -import 'fetch_policy_test.dart' as fetch_policy_test; -import 'graphql_client_test.dart' as graphql_client_test; -import 'query_options_test.dart' as query_options_test; -import 'websocket_test.dart' as websocket_test; - -void main() { - query_options_test.main(); - cache_store_test.main(); - cache_graphql_cache_test.main(); - fetch_policy_test.main(); - anonymous_operations_test.main(); - websocket_test.main(); - graphql_client_test.main(); -} diff --git a/packages/fl_query/test/fetch_policy_test.dart b/packages/fl_query/test/fetch_policy_test.dart deleted file mode 100644 index 6f73c55..0000000 --- a/packages/fl_query/test/fetch_policy_test.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'package:test/test.dart'; -import 'package:mockito/mockito.dart'; - -import 'package:fl_query/fl_query.dart'; -import 'package:gql/language.dart'; - -import './helpers.dart'; - -void main() { - const String readRepositories = r''' - query ReadRepositories($nRepositories: Int!) { - viewer { - repositories(last: $nRepositories) { - nodes { - __typename - id - name - viewerHasStarred - } - } - } - } - '''; - readRepositoryData({withTypenames = true, withIds = true}) { - return { - 'viewer': { - 'repositories': { - 'nodes': [ - { - if (withIds) 'id': 'MDEwOlJlcG9zaXRvcnkyNDgzOTQ3NA==', - 'name': 'pq', - 'viewerHasStarred': false - }, - { - if (withIds) 'id': 'MDEwOlJlcG9zaXRvcnkzMjkyNDQ0Mw==', - 'name': 'go-evercookie', - 'viewerHasStarred': false - }, - { - if (withIds) 'id': 'MDEwOlJlcG9zaXRvcnkzNTA0NjgyNA==', - 'name': 'watchbot', - 'viewerHasStarred': false - }, - ] - .map((map) => - withTypenames ? {'__typename': 'Repository', ...map} : map) - .toList(), - }, - }, - }; - } - - late MockLink link; - late GraphQLClient client; - - group('FetchPolicy', () { - setUp(() { - link = MockLink(); - - client = GraphQLClient( - cache: getTestCache(), - link: link, - ); - }); - - group('query', () { - // TODO cacheFirst code path: Return result from cache. Only fetch from network if cached result is not available. - // TODO cacheAndNetwork code path: Return result from cache first (if it exists), then return network result once it's available. - // TODO cacheOnly code path: Return result from cache if available, fail otherwise. - // TODO noCache code path: Return result from network, fail if network call doesn't succeed, don't save to cache. - // TODO networkOnly code path: Return result from network, fail if network call doesn't succeed, save to cache. - test('switch to cacheOnly returns cached data', () async { - final _options = QueryOptions( - fetchPolicy: FetchPolicy.cacheAndNetwork, - document: parseString(readRepositories), - variables: { - 'nRepositories': 42, - }, - ); - final repoData = readRepositoryData(withTypenames: true); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable([ - Response(data: repoData), - ]), - ); - - final QueryResult r = await client.query(_options); - - verify( - link.request( - Request( - operation: Operation( - document: parseString(readRepositories), - //operationName: 'ReadRepositories', - ), - variables: { - 'nRepositories': 42, - }, - context: Context(), - ), - ), - ); - - expect(r.exception, isNull); - expect(r.data, equals(repoData)); - - final QueryResult cacheResult = await client.query(QueryOptions( - fetchPolicy: FetchPolicy.cacheOnly, - document: parseString(readRepositories), - variables: { - 'nRepositories': 42, - }, - )); - expect(cacheResult.exception, isNull); - expect(cacheResult.data, equals(repoData)); - }); - }); - }); -} diff --git a/packages/fl_query/test/graphql_client_test.dart b/packages/fl_query/test/graphql_client_test.dart deleted file mode 100644 index 8fb154f..0000000 --- a/packages/fl_query/test/graphql_client_test.dart +++ /dev/null @@ -1,888 +0,0 @@ -import 'package:fl_query/src/core/result_parser.dart'; -import 'package:test/test.dart'; -import 'package:mockito/mockito.dart'; - -import 'package:fl_query/fl_query.dart'; -import 'package:gql/language.dart'; - -import './helpers.dart'; - -void main() { - const String readSingle = r''' - query ReadSingle($id: ID!) { - single(id: $id) { - id, - __typename, - name - } - } - '''; - - const String writeSingle = r''' - mutation WriteSingle($id: ID!, $name: String!) { - updateSingle(id: $id, name: $name) { - id, - __typename, - name - } - } - '''; - - const String readRepositories = r''' - query ReadRepositories($nRepositories: Int!) { - viewer { - repositories(last: $nRepositories) { - nodes { - __typename - id - name - viewerHasStarred - } - } - } - } - '''; - Map readRepositoryData({ - bool withTypenames = true, - bool withIds = true, - bool viewerHasStarred = false, - }) { - return { - 'viewer': { - 'repositories': { - 'nodes': [ - { - if (withIds) 'id': 'MDEwOlJlcG9zaXRvcnkyNDgzOTQ3NA==', - 'name': 'pq', - 'viewerHasStarred': viewerHasStarred - }, - { - if (withIds) 'id': 'MDEwOlJlcG9zaXRvcnkzMjkyNDQ0Mw==', - 'name': 'go-evercookie', - 'viewerHasStarred': viewerHasStarred - }, - { - if (withIds) 'id': 'MDEwOlJlcG9zaXRvcnkzNTA0NjgyNA==', - 'name': 'watchbot', - 'viewerHasStarred': viewerHasStarred - }, - ] - .map((map) => - withTypenames ? {'__typename': 'Repository', ...map} : map) - .toList(), - }, - }, - }; - } - - const String addStar = r''' - mutation AddStar($starrableId: ID!) { - action: addStar(input: {starrableId: $starrableId}) { - starrable { - viewerHasStarred - } - } - } - '''; - - late MockLink link; - late GraphQLClient client; - - group('simple json', () { - setUp(() { - link = MockLink(); - - client = GraphQLClient( - cache: getTestCache(), - link: link, - ); - }); - - group('query', () { - test('successful response', () async { - final _options = QueryOptions( - document: parseString(readRepositories), - variables: { - 'nRepositories': 42, - }, - ); - final repoData = readRepositoryData(withTypenames: true); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable([ - Response( - data: repoData, - context: Context().withEntry( - HttpLinkResponseContext( - statusCode: 200, - headers: {'foo': 'bar'}, - ), - ), - ), - ]), - ); - - final QueryResult r = await client.query(_options); - - verify( - link.request( - Request( - operation: Operation( - document: parseString(readRepositories), - //operationName: 'ReadRepositories', - ), - variables: { - 'nRepositories': 42, - }, - context: Context(), - ), - ), - ); - - expect(r.exception, isNull); - expect(r.data, equals(repoData)); - - expect( - r.context.entry()!.statusCode, - equals(200), - ); - expect( - r.context.entry()!.headers['foo'], - equals('bar'), - ); - }); - test('successful response with parser', () async { - final ResultParserFn> parserFn = (data) { - return data['viewer']['repositories']['nodes'] - .map((node) => node['name'] as String) - .toList(); - }; - final _options = QueryOptions( - document: parseString(readRepositories), - variables: { - 'nRepositories': 42, - }, - parserFn: parserFn, - ); - final repoData = readRepositoryData(withTypenames: true); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable([ - Response( - data: repoData, - context: Context().withEntry( - HttpLinkResponseContext( - statusCode: 200, - headers: {'foo': 'bar'}, - ), - ), - ), - ]), - ); - - final QueryResult> r = await client.query(_options); - - verify( - link.request( - Request( - operation: Operation( - document: parseString(readRepositories), - //operationName: 'ReadRepositories', - ), - variables: { - 'nRepositories': 42, - }, - context: Context(), - ), - ), - ); - - expect(r.exception, isNull); - expect(r.data, equals(repoData)); - - List? parsedData = r.parsedData; - expect( - parsedData, - equals([ - 'pq', - 'go-evercookie', - 'watchbot', - ])); - - expect( - r.context.entry()!.statusCode, - equals(200), - ); - expect( - r.context.entry()!.headers['foo'], - equals('bar'), - ); - }); - - test('successful response without normalization', () async { - final readUnidentifiedRepositories = parseString(r''' - query ReadRepositories($nRepositories: Int!) { - viewer { - repositories(last: $nRepositories) { - nodes { - name - viewerHasStarred - } - } - } - } - '''); - final repoData = readRepositoryData( - withTypenames: false, - withIds: false, - ); - - final _options = QueryOptions( - document: readUnidentifiedRepositories, - variables: {'nRepositories': 42}, - ); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable([ - Response(data: repoData), - ]), - ); - - final QueryResult r = await client.query(_options); - - verify(link.request(_options.asRequest)); - expect(r.data, equals(repoData)); - }); - test('correct consecutive responses', () async { - final _options = QueryOptions( - fetchPolicy: FetchPolicy.networkOnly, - document: parseString(readRepositories), - variables: { - 'nRepositories': 42, - }, - ); - final firstData = - readRepositoryData(withTypenames: true, viewerHasStarred: false); - final secondData = - readRepositoryData(withTypenames: true, viewerHasStarred: true); - - final resp = (d) => Stream.fromIterable([ - Response( - data: d, - context: Context().withEntry( - HttpLinkResponseContext( - statusCode: 200, - headers: {'foo': 'bar'}, - ), - ), - ) - ]); - - when(link.request(any)).thenAnswer((_) => resp(firstData)); - QueryResult r = await client.query(_options); - expect(r.exception, isNull); - expect(r.data, equals(firstData)); - - when(link.request(any)).thenAnswer((_) => resp(secondData)); - r = await client.query(_options); - expect(r.exception, isNull); - expect(r.data, equals(secondData)); - }); - - test('malformed server response', () async { - final _options = QueryOptions( - document: parseString(readRepositories), - variables: {'nRepositories': 42}, - ); - final malformedRepoData = { - 'viewer': { - // maybe the server doesn't validate response structures properly, - // or a user generates a response on the client, etc - 'repos': readRepositoryData()['viewer']!['repositories'] - }, - }; - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable([ - Response(data: malformedRepoData), - ]), - ); - - final QueryResult r = await client.query(_options); - - expect(r.data, equals(malformedRepoData), - reason: 'Malformed data should be passed along with errors'); - - throwsA(isA().having( - (e) => e.path, - 'An accurate path to the first missing subfield', - ['a', 'b', '__typename'], - )); - }); - - test('failed query because of an exception with null string', () async { - final e = Exception(); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromFuture(Future.error(e)), - ); - - final QueryResult r = await client.query( - WatchQueryOptions( - document: parseString(readRepositories), - ), - ); - - expect( - r.exception!.exception!.originalException, - e, - ); - }); - - test('failed query because of an exception with empty string', () async { - final e = Exception(''); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromFuture(Future.error(e)), - ); - - final QueryResult r = await client.query( - WatchQueryOptions( - document: parseString(readRepositories), - ), - ); - - expect( - r.exception!.exception!.originalException, - e, - ); - }); -// test('failed query because of because of error response', {}); -// test('failed query because of because of invalid response', () { -// String responseBody = -// '{\"message\":\"Bad credentials\",\"documentation_url\":\"https://developer.github.com/v4\"}'; -// int responseCode = 401; -// }); -// test('partially success query with some errors', {}); - }); - group('mutation', () { - test('query stream notified', () async { - final initialQueryResponse = Response( - data: { - 'single': { - 'id': '1', - '__typename': 'Single', - 'name': 'initialQueryName', - }, - }, - ); - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable( - [initialQueryResponse], - ), - ); - - final ObservableQuery observable = client.watchQuery( - WatchQueryOptions( - document: parseString(readSingle), - eagerlyFetchResults: true, - variables: {'id': '1'}, - ), - ); - - expect( - observable.stream, - emitsInOrder( - [ - // we have no optimistic result - isA().having( - (result) => result.isLoading, - 'loading result', - true, - ), - isA().having( - (result) => result.data!['single']['name'], - 'initial query result', - 'initialQueryName', - ), - isA().having( - (result) => result.data!['single']['name'], - 'result caused by mutation', - 'newNameFromMutation', - ) - ], - ), - ); - - final mutationResponseWithNewName = Response( - data: { - 'updateSingle': { - 'id': '1', - '__typename': 'Single', - 'name': 'newNameFromMutation', - }, - }, - ); - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable( - [mutationResponseWithNewName], - ), - ); - - final variables = {'id': '1', 'name': 'newNameFromMutation'}; - - final QueryResult response = await client.mutate(MutationOptions( - document: parseString(writeSingle), variables: variables)); - - expect(response.data!['updateSingle']['name'], variables['name']); - }); - - test('successful mutation', () async { - final MutationOptions _options = MutationOptions( - document: parseString(addStar), - ); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable( - [ - Response( - data: { - 'action': { - 'starrable': { - 'viewerHasStarred': true, - }, - }, - }, - ), - ], - ), - ); - - final QueryResult response = await client.mutate(_options); - - verify( - link.request( - Request( - operation: Operation( - document: parseString(addStar), - //operationName: 'AddStar', - ), - variables: {}, - context: Context(), - ), - ), - ); - - expect(response.exception, isNull); - expect(response.data, isNotNull); - final bool? viewerHasStarred = - response.data!['action']['starrable']['viewerHasStarred'] as bool?; - expect(viewerHasStarred, true); - }); - test('successful mutation with parser', () async { - final ResultParserFn resultParser = - (data) => data['action']['starrable']['viewerHasStarred'] as bool; - final MutationOptions _options = MutationOptions( - document: parseString(addStar), - parserFn: resultParser, - ); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable( - [ - Response( - data: { - 'action': { - 'starrable': { - 'viewerHasStarred': true, - }, - }, - }, - ), - ], - ), - ); - - final QueryResult response = await client.mutate(_options); - - verify( - link.request( - Request( - operation: Operation( - document: parseString(addStar), - //operationName: 'AddStar', - ), - variables: {}, - context: Context(), - ), - ), - ); - final bool parsedResult = response.parsedData; - expect(parsedResult, isTrue); - expect(response.exception, isNull); - expect(response.data, isNotNull); - final bool? viewerHasStarred = - response.data!['action']['starrable']['viewerHasStarred'] as bool?; - expect(viewerHasStarred, true); - }); - - test('successful mutation through watchQuery', () async { - final _options = MutationOptions( - document: parseString(addStar), - variables: {}, - ); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable( - [ - Response( - data: { - 'action': { - 'starrable': { - 'viewerHasStarred': true, - }, - }, - }, - ), - ], - ), - ); - - final observableQuery = client.watchQuery(WatchQueryOptions( - document: _options.document, - variables: _options.variables, - fetchResults: false, - )); - - final result = await observableQuery.fetchResults().networkResult!; - - verify( - link.request( - Request( - operation: Operation( - document: parseString(addStar), - //operationName: 'AddStar', - ), - variables: {}, - context: Context(), - ), - ), - ); - - expect(result.hasException, isFalse); - expect(result.data, isNotNull); - final bool? viewerHasStarred = - result.data!['action']['starrable']['viewerHasStarred'] as bool?; - expect(viewerHasStarred, true); - }); - }); - - group('subscription', () { - test('results', () async { - final responses = [ - { - 'id': '1', - 'name': 'first', - }, - { - 'id': '2', - 'name': 'second', - }, - ].map((item) => Response( - data: { - 'item': { - '__typename': 'Item', - ...item, - }, - }, - )); - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable(responses), - ); - - final stream = client.subscribe( - SubscriptionOptions( - document: parseString( - r''' - subscription { - item { - id - name - } - } - ''', - ), - ), - ); - - expect( - stream, - emitsInOrder( - [ - isA().having( - (result) => result.data!['item']['name'], - 'first subscription item', - 'first', - ), - isA().having( - (result) => result.data!['item']['name'], - 'second subscription item', - 'second', - ) - ], - ), - ); - }); - test('parses results', () async { - final responses = [ - { - 'id': '1', - 'name': 'first', - }, - { - 'id': '2', - 'name': 'second', - }, - ].map((item) => Response( - data: { - 'item': { - '__typename': 'Item', - ...item, - }, - }, - )); - when( - link.request(any), - ).thenAnswer( - (_) => Stream.fromIterable(responses), - ); - - final ResultParserFn parserFn = - (data) => data['item']['name'] as String; - ; - - final stream = client.subscribe( - SubscriptionOptions( - parserFn: parserFn, - document: parseString( - r''' - subscription { - item { - id - name - } - } - ''', - ), - ), - ); - - expect( - stream, - emitsInOrder(['first', 'second'] - .map((e) => isA>().having((result) { - final String? parsed = result.parsedData; - return parsed; - }, "Parsed item", e))), - ); - }); - - test('wraps stream exceptions', () async { - final ex = ServerException( - parsedResponse: null, - originalException: Error(), - ); - - when( - link.request(any), - ).thenAnswer( - (_) => Stream.error(ex), - ); - - final stream = client.subscribe( - SubscriptionOptions( - document: parseString( - r''' - subscription { - item { - id - name - } - } - ''', - ), - ), - ); - - expect( - stream, - emitsInOrder( - [ - isA().having( - (result) => result.exception!.exception, - 'wrapped exception', - ex, - ), - ], - ), - ); - }); - test('wraps all exceptions from outside of stream', () async { - final err = Error(); - - when( - link.request(any), - ).thenThrow(err); - - final stream = client.subscribe( - SubscriptionOptions( - document: parseString( - r''' - subscription { - item { - id - name - } - } - ''', - ), - ), - ); - - expect( - stream, - emitsInOrder( - [ - isA().having( - (result) => result.exception!.exception!.originalException, - 'wrapped exception', - err, - ), - ], - ), - ); - }); - }); - }); - - group('direct cache access', () { - setUp(() { - link = MockLink(); - - client = GraphQLClient( - cache: getTestCache(), - link: link, - ); - }); - - test('all methods with exposition', () { - /// entity identifiers for normalization - final idFields = {'__typename': 'MyType', 'id': 1}; - - /// The direct cache API uses `gql_link` Requests directly - /// These can also be obtained via `options.asRequest` from any `Options` object, - /// or via `Operation(document: gql(...)).asRequest()` - final queryRequest = Request( - operation: Operation( - document: gql( - r'''{ - someField { - id, - myField - } - }''', - ), - ), - ); - - final queryData = { - '__typename': 'Query', - 'someField': { - ...idFields, - 'myField': 'originalValue', - }, - }; - - /// `broadcast: true` (the default) would rebroadcast cache updates to all safe instances of `ObservableQuery` - /// **NOTE**: only `GraphQLClient` can immediately call for a query rebroadcast. if you request a rebroadcast directly - /// from the cache, it still has to wait for the client to check in on it - client.writeQuery(queryRequest, data: queryData, broadcast: false); - - /// `optimistic: true` (the default) integrates optimistic data - /// written to the cache into your read. - expect( - client.readQuery(queryRequest, optimistic: false), equals(queryData)); - - /// While fragments are never executed themselves, we provide a `gql_link`-like API for consistency. - /// These can also be obtained via `Fragment(document: gql(...)).asRequest()`. - final fragmentRequest = FragmentRequest( - fragment: Fragment( - document: gql( - r''' - fragment mySmallSubset on MyType { - myField, - someNewField - } - ''', - ), - ), - idFields: idFields, - ); - - /// We've specified `idFields` and are only editing a subset of the data - final fragmentData = { - 'myField': 'updatedValue', - 'someNewField': [ - {'newData': false} - ], - }; - - /// We didn't disable `broadcast`, so all instances of `ObservableQuery` will be notified of any changes - client.writeFragment(fragmentRequest, data: fragmentData); - - /// __typename is automatically included in all reads - expect( - client.readFragment(fragmentRequest), - equals({ - '__typename': 'MyType', - ...fragmentData, - }), - ); - - final updatedQueryData = { - '__typename': 'Query', - 'someField': { - ...idFields, - 'myField': 'updatedValue', - }, - }; - - /// `myField` is updated, but we don't have `someNewField`, as expected. - expect(client.readQuery(queryRequest), equals(updatedQueryData)); - }); - }); -} diff --git a/packages/fl_query/test/helpers.dart b/packages/fl_query/test/helpers.dart deleted file mode 100644 index 6eb7e5c..0000000 --- a/packages/fl_query/test/helpers.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'dart:async'; - -import 'package:fl_query/fl_query.dart'; - -import 'package:mockito/mockito.dart'; - -class MockLink extends Mock implements Link { - @override - Stream request(Request? request, [NextLink? forward]) => - super.noSuchMethod( - Invocation.method(#request, [request, forward]), - returnValue: Stream.fromIterable( - [], - ), - ) as Stream; -} - -const debuggingUnexpectedTestFailures = false; - -overridePrint(testFn(List log)) => () { - final log = []; - final spec = ZoneSpecification(print: (_, __, ___, String msg) { - log.add(msg); - }); - return Zone.current.fork(specification: spec).run(() => testFn(log)); - }; - -class TestCache extends QueryCache { - bool get returnPartialData => debuggingUnexpectedTestFailures; - - get partialDataPolicy => PartialDataCachePolicy.reject; -} - -QueryCache getTestCache() => TestCache(); diff --git a/packages/fl_query/test/mock_server/ws_echo_server.dart b/packages/fl_query/test/mock_server/ws_echo_server.dart deleted file mode 100644 index 45c5360..0000000 --- a/packages/fl_query/test/mock_server/ws_echo_server.dart +++ /dev/null @@ -1,26 +0,0 @@ -/// Web Socket echo server -/// to run the test and cover the web socket test -/// -/// author: https://github.com/vincenzopalazzo -import 'dart:io'; - -const String forceDisconnectCommand = '___force_disconnect___'; - -/// Main function to create and run the echo server over the web socket. -Future runWebSocketServer( - {String host = "127.0.0.1", int port = 5600}) async { - HttpServer server = await HttpServer.bind(host, port); - server.transform(WebSocketTransformer()).listen(onWebSocketData); - return "ws://$host:$port"; -} - -/// Handle event received on server. -void onWebSocketData(WebSocket client) { - client.listen((data) async { - if (data != null && data.toString().contains(forceDisconnectCommand)) { - client.close(WebSocketStatus.normalClosure, 'shutting down'); - } else { - client.add(data); - } - }); -} diff --git a/packages/fl_query/test/query_options_test.dart b/packages/fl_query/test/query_options_test.dart deleted file mode 100644 index 90e1dcd..0000000 --- a/packages/fl_query/test/query_options_test.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:gql/ast.dart'; -import 'package:gql/language.dart'; -import 'package:fl_query/fl_query.dart'; -import 'package:test/test.dart'; - -void main() { - group('query options', () { - group('type getters', () { - test('on QueryOptions', () { - final options = QueryOptions( - document: parseString('query { bar }'), - ); - expect(options.type, equals(OperationType.query)); - expect(options.isQuery, equals(true)); - }); - test('on MutationOptions', () { - final options = MutationOptions( - document: parseString('mutation { bar }'), - ); - expect(options.type, equals(OperationType.mutation)); - expect(options.isMutation, equals(true)); - }); - test('on SubscriptionOptions', () { - final options = SubscriptionOptions( - document: parseString('subscription { bar }'), - ); - expect(options.type, equals(OperationType.subscription)); - expect(options.isSubscription, equals(true)); - }); - }); - group('gql integration', () { - test('Options.asRequest', () { - final options = QueryOptions( - document: parseString('query { bar }'), - variables: { - 'foo': { - 'biz': 'bar', - 'bam': [1] - } - }, - context: Context.fromList([ - HttpLinkHeaders(headers: {'my': 'header'}) - ])); - final req = options.asRequest; - expect(options.document, equals(req.operation.document)); - expect(options.variables, equals(req.variables)); - expect(options.context, equals(req.context)); - }); - }); - }); -} diff --git a/packages/fl_query/test/sample_upload.jpg b/packages/fl_query/test/sample_upload.jpg deleted file mode 100644 index 7ee0f5ccc58507b68e5d7e321499bc6105b914ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmV+b0ssC10s{mE1_uZU3JVMk4i69!5)%{^78e*98XFuP9v>hfA|oUvCMPHs;jK6uCK7Mva__cwzs&sy1Tr+zQ4f1!o$SH#>dFX z%FE2n&d<=%($mz{*4NnC+S}aS-rwNi;^XAy=I7|?>g(+7?(gvN^7Hid_V@Vt`uqI- G{{H|ig@1tn diff --git a/packages/fl_query/test/sample_upload.mov b/packages/fl_query/test/sample_upload.mov deleted file mode 100644 index 4012485fda480e528eb700063f67ea1e1d801a39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271 zcmV+q0r39*{rvm-`S|zt_4M=d@$m2N?dFDR?<>cey;o#ri-Q3&S+1S_C)zs6{ z(a_J%&CJWn$;ijX#l*wH!N9-1y}Y}+xwyBswY0Ocv9PbMt*oo6si>!>rKF>xp`f3h zot&GRnV6TBm6Vf`k&us$jf{(miHL`Wg@l8Gfq;L0eSCX*d3bkrb#!xbad2;LZES05 zX=rC=Wn^PwVPIcgU0hpQSy)$ARa8?_QBY4#O-xHlNk~UVMMOhFK|nt~Jv=))IXE{q zH8e9aF)%MKEi5Z4DJUlX9|O7g$V!v diff --git a/packages/fl_query/test/test_helpers.dart b/packages/fl_query/test/test_helpers.dart deleted file mode 100644 index da19da0..0000000 --- a/packages/fl_query/test/test_helpers.dart +++ /dev/null @@ -1,70 +0,0 @@ -import 'dart:collection'; - -import 'package:test/test.dart'; - -import 'package:fl_query/src/utilities/helpers.dart'; - -void main() { - group('deeplyMergeLeft', () { - test('shallow', () { - expect( - deeplyMergeLeft([ - {'keyA': 'a1'}, - {'keyA': 'a2', 'keyB': 'b2'}, - {'keyB': 'b3'} - ]), - equals({'keyA': 'a2', 'keyB': 'b3'}), - ); - }); - - test('deep', () { - expect( - deeplyMergeLeft([ - { - 'keyA': 'a1', - 'keyB': { - 'keyC': {'keyD': 'd1'} - } - }, - { - 'keyA': 'a2', - 'keyB': { - 'keyC': {'keyD': 'd2'} - } - }, - ]), - equals({ - 'keyA': 'a2', - 'keyB': { - 'keyC': {'keyD': 'd2'} - } - }), - ); - }); - - test('deep hashmaps are merged', () { - expect( - deeplyMergeLeft([ - HashMap.from({ - 'keyA': 'a1', - 'keyB': { - 'keyC': HashMap.from({'keyD': 'd1'}) - } - }), - { - 'keyA': 'a2', - 'keyB': { - 'keyC': HashMap.from({'keyD': 'd2'}) - } - }, - ]), - equals({ - 'keyA': 'a2', - 'keyB': { - 'keyC': {'keyD': 'd2'} - } - }), - ); - }); - }); -} diff --git a/packages/fl_query/test/websocket_test.dart b/packages/fl_query/test/websocket_test.dart deleted file mode 100644 index 21f22e9..0000000 --- a/packages/fl_query/test/websocket_test.dart +++ /dev/null @@ -1,431 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:test/test.dart'; -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:gql/language.dart'; -import 'package:fl_query/fl_query.dart'; - -import './helpers.dart'; -import './mock_server/ws_echo_server.dart'; -import 'mock_server/ws_echo_server.dart'; - -SocketClient getTestClient( - {required String wsUrl, - StreamController? controller, - bool autoReconnect = true, - Map? customHeaders, - Duration delayBetweenReconnectionAttempts = - const Duration(milliseconds: 1)}) => - SocketClient( - wsUrl, - config: SocketClientConfig( - autoReconnect: autoReconnect, - headers: customHeaders, - delayBetweenReconnectionAttempts: delayBetweenReconnectionAttempts, - ), - randomBytesForUuid: Uint8List.fromList( - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], - ), - ); - -Future main() async { - String wsUrl = await runWebSocketServer(); - group('InitOperation', () { - test('null payload', () { - // ignore: deprecated_member_use_from_same_package - final operation = InitOperation(null); - expect(operation.toJson(), {'type': 'connection_init'}); - }); - test('simple payload', () { - // ignore: deprecated_member_use_from_same_package - final operation = InitOperation(42); - expect(operation.toJson(), {'type': 'connection_init', 'payload': 42}); - }); - test('complex payload', () { - // ignore: deprecated_member_use_from_same_package - final operation = InitOperation({ - 'value': 42, - 'nested': { - 'number': [3, 7], - 'string': ['foo', 'bar'] - } - }); - expect(operation.toJson(), { - 'type': 'connection_init', - 'payload': { - 'value': 42, - 'nested': { - 'number': [3, 7], - 'string': ['foo', 'bar'] - } - } - }); - }); - }); - - group('SocketClient without payload', () { - late SocketClient socketClient; - StreamController controller; - final expectedMessage = r'{' - r'"type":"start","id":"01020304-0506-4708-890a-0b0c0d0e0f10",' - r'"payload":{"operationName":null,"variables":{},"query":"subscription {\n \n}"}' - r'}'; - setUp(overridePrint((log) { - controller = StreamController(sync: true); - socketClient = getTestClient(controller: controller, wsUrl: wsUrl); - })); - tearDown(overridePrint( - (log) => socketClient.dispose(), - )); - test('connection', () async { - await expectLater( - socketClient.connectionState.asBroadcastStream(), - emitsInOrder( - [ - SocketConnectionState.connecting, - SocketConnectionState.connected, - ], - ), - ); - }); - test('disconnect via dispose', () async { - // First wait for connection to complete - await expectLater( - socketClient.connectionState.asBroadcastStream(), - emitsInOrder( - [ - SocketConnectionState.connecting, - SocketConnectionState.connected, - ], - ), - ); - - // We need to begin waiting on the connectionState - // before we issue the command to disconnect; otherwise - // it can reconnect so fast that it will be reconnected - // by the time that the expectLater check is initiated. - await overridePrint((_) async { - Timer(const Duration(milliseconds: 20), () async { - await socketClient.dispose(); - }); - })(); - // The connectionState BehaviorController emits the current state - // to any new listener, so we expect it to start in the connected - // state and transition to notConnected because of dispose. - await expectLater( - socketClient.connectionState, - emitsInOrder([ - SocketConnectionState.connected, - SocketConnectionState.notConnected, - ]), - ); - - // Have to wait for socket close to be fully processed after we reach - // the notConnected state, including updating channel with close code. - await Future.delayed(const Duration(milliseconds: 20)); - - // The websocket should be in a fully closed state at this point, - // we should have a confirmed close code in the channel. - expect(socketClient.socketChannel, isNotNull); - expect(socketClient.socketChannel!.closeCode, isNotNull); - }); - test('subscription data', () async { - final payload = Request( - operation: Operation(document: parseString('subscription {}')), - ); - final waitForConnection = true; - final subscriptionDataStream = - socketClient.subscribe(payload, waitForConnection); - await socketClient.connectionState - .where((state) => state == SocketConnectionState.connected) - .first; - - // ignore: unawaited_futures - socketClient.socketChannel!.stream - .where((message) => message == expectedMessage) - .first - .then((_) { - socketClient.socketChannel!.sink.add(jsonEncode({ - 'type': 'data', - 'id': '01020304-0506-4708-890a-0b0c0d0e0f10', - 'payload': { - 'data': {'foo': 'bar'}, - 'errors': [ - {'message': 'error and data can coexist'} - ] - } - })); - }); - - await expectLater( - subscriptionDataStream, - emits( - // todo should ids be included in response context? probably '01020304-0506-4708-890a-0b0c0d0e0f10' - Response( - data: {'foo': 'bar'}, - errors: [ - GraphQLError(message: 'error and data can coexist'), - ], - context: Context().withEntry(ResponseExtensions(null)), - ), - ), - ); - }); - test('resubscribe', () async { - final payload = Request( - operation: Operation(document: gql('subscription {}')), - ); - final waitForConnection = true; - final subscriptionDataStream = - socketClient.subscribe(payload, waitForConnection); - - await expectLater( - socketClient.connectionState, - emitsInOrder([ - SocketConnectionState.connecting, - SocketConnectionState.connected, - ]), - ); - - await overridePrint((_) async { - socketClient.onConnectionLost(); - })(); - - await expectLater( - socketClient.connectionState, - emitsInOrder([ - SocketConnectionState.notConnected, - SocketConnectionState.connecting, - SocketConnectionState.connected, - ]), - ); - - // ignore: unawaited_futures - socketClient.socketChannel!.stream - .where((message) => message == expectedMessage) - .first - .then((_) { - socketClient.socketChannel!.sink.add(jsonEncode({ - 'type': 'data', - 'id': '01020304-0506-4708-890a-0b0c0d0e0f10', - 'payload': { - 'data': {'foo': 'bar'}, - 'errors': [ - {'message': 'error and data can coexist'} - ] - } - })); - }); - - await expectLater( - subscriptionDataStream, - emits( - // todo should ids be included in response context? probably '01020304-0506-4708-890a-0b0c0d0e0f10' - Response( - data: {'foo': 'bar'}, - errors: [ - GraphQLError(message: 'error and data can coexist'), - ], - context: Context().withEntry(ResponseExtensions(null)), - ), - ), - ); - }); - test('resubscribe after server disconnect', () async { - final payload = Request( - operation: Operation(document: gql('subscription {}')), - ); - final waitForConnection = true; - final subscriptionDataStream = - socketClient.subscribe(payload, waitForConnection); - - await expectLater( - socketClient.connectionState, - emitsInOrder([ - SocketConnectionState.connecting, - SocketConnectionState.connected, - ]), - ); - - // We need to begin waiting on the connectionState - // before we issue the command to disconnect; otherwise - // it can reconnect so fast that it will be reconnected - // by the time that the expectLater check is initiated. - Timer(const Duration(milliseconds: 20), () async { - socketClient.socketChannel!.sink.add(forceDisconnectCommand); - }); - // The connectionState BehaviorController emits the current state - // to any new listener, so we expect it to start in the connected - // state, transition to notConnected, and then reconnect after that. - await expectLater( - socketClient.connectionState, - emitsInOrder([ - SocketConnectionState.connected, - SocketConnectionState.notConnected, - SocketConnectionState.connecting, - SocketConnectionState.connected, - ]), - ); - - // ignore: unawaited_futures - socketClient.socketChannel!.stream - .where((message) => message == expectedMessage) - .first - .then((_) { - socketClient.socketChannel!.sink.add(jsonEncode({ - 'type': 'data', - 'id': '01020304-0506-4708-890a-0b0c0d0e0f10', - 'payload': { - 'data': {'foo': 'bar'}, - 'errors': [ - {'message': 'error and data can coexist'} - ] - } - })); - }); - - await expectLater( - subscriptionDataStream, - emits( - // todo should ids be included in response context? probably '01020304-0506-4708-890a-0b0c0d0e0f10' - Response( - data: {'foo': 'bar'}, - errors: [ - GraphQLError(message: 'error and data can coexist'), - ], - context: Context().withEntry(ResponseExtensions(null)), - ), - ), - ); - }); - }, tags: "integration"); - - group('SocketClient without autoReconnect', () { - late SocketClient socketClient; - StreamController controller; - setUp(overridePrint((log) { - controller = StreamController(sync: true); - socketClient = getTestClient( - controller: controller, wsUrl: wsUrl, autoReconnect: false); - })); - tearDown(overridePrint( - (log) => socketClient.dispose(), - )); - test('server disconnect', () async { - final payload = Request( - operation: Operation(document: gql('subscription {}')), - ); - final waitForConnection = true; - socketClient.subscribe(payload, waitForConnection); - - await expectLater( - socketClient.connectionState, - emitsInOrder([ - SocketConnectionState.connecting, - SocketConnectionState.connected, - ]), - ); - - Timer(const Duration(milliseconds: 20), () async { - socketClient.socketChannel!.sink.add(forceDisconnectCommand); - }); - // Same strategy as elsewhere, start expecting the state on the - // stream before the disconnect actually happens... - await expectLater( - socketClient.connectionState, - emitsInOrder([ - SocketConnectionState.connected, - SocketConnectionState.notConnected, - ]), - ); - - expect( - socketClient.socketChannel!.closeCode, WebSocketStatus.normalClosure); - }); - }, tags: "integration"); - - group('SocketClient with const payload', () { - late SocketClient socketClient; - const initPayload = {'token': 'mytoken'}; - - setUp(overridePrint((log) { - socketClient = SocketClient( - wsUrl, - config: SocketClientConfig(initialPayload: () => initPayload), - ); - })); - - tearDown(overridePrint( - (log) => expectLater( - socketClient.dispose().timeout(Duration(seconds: 1)), - completion(null), - ), - )); - - test('connection', () async { - await socketClient.connectionState - .where((state) => state == SocketConnectionState.connected) - .first; - - await expectLater( - socketClient.socketChannel!.stream.map((s) { - return jsonDecode(s)['payload']; - }), - emits(initPayload)); - }); - }); - - group('SocketClient with future payload', () { - late SocketClient socketClient; - const initPayload = {'token': 'mytoken'}; - - setUp(overridePrint((log) { - socketClient = SocketClient( - wsUrl, - config: SocketClientConfig( - initialPayload: () async { - await Future.delayed(Duration(seconds: 3)); - return initPayload; - }, - ), - ); - })); - - tearDown(overridePrint((log) async { - await socketClient.dispose(); - })); - - test('connection', () async { - await socketClient.connectionState - .where((state) => state == SocketConnectionState.connected) - .first; - - await expectLater( - socketClient.socketChannel!.stream.map((s) { - return jsonDecode(s)['payload']; - }), - emits(initPayload), - ); - }); - - /* - FIXME: Testing the correct header in the request - group('SocketClient with custom headers with const payload', () { - const customHeaders = {'myHeader': 'myHeader'}; - - setUp(overridePrint((log) { - socketClient = getTestClient(wsUrl: wsUrl, customHeaders: customHeaders); - })); - - test('check header', () async { - await socketClient.connectionState - .where((state) => state == SocketConnectionState.notConnected) - .first; - }); - }); - */ - }); -}