Skip to content

Commit a6ca33c

Browse files
Jordan-NelsonDillon Nysdnys1
authored
feat(datastore): add observeQuery API (#892)
* feat: dart only implementation of observeQuery * feat: use sorted list for cached item * chore: rename sorted list file * feat: move merge logic inside QuerySnapshot * chore: update logging * chore: move evaluate logic to QueryPredicate * feat: add compareTo for temporal types * chore: update examples * test: add unit tests for querySnapshot * feat: add sync status * chore: move StreamGroup * feat: batch before sync * feat: duration batching * chore: create executor * chore: add license * feat: allow for no throttling * test: add tests for throttle extension * chore: remove events from QuerySnapshot * chore: remove events from executor * chore: undo change in main for unit tests * chore: undo formatting change * chore: remove temp changes to query * chore: remove temp change in post model * chore: add missing license * chore: add missing license * chore: remove check for dup event * chore: handle non-comparable fields * chore: remove comments from temporal types * chore: remove late keyword * chore: add operators to SortedList * test: add test for withSyncStatus * test: add tests for SortedList * chore: replace StreamGroup w/ merge util * chore: update comments * test: add unit test for mergeStreams * test: add tests for observeQueryExecutor * chore: removed unused ensureInitialized calls * chore: update doc comments * fix: update query field operator comparisons * test: add tests for sort comparisons * test: query predicate comparison test * test: add test for sync status cache * test: add tests for and/or/not predicates * chore: update model * chore: address initial PR comments * chore: refactor ObserveQueryExecutor * chore: refactor SortedList to use ListMixin * feat: update merge to use sync stream controller * test: observeQuery integ tests * chore: update example app * feat: start batching after model sync started * chore: removed runQueries() from example app * chore: refactor sort order, add test * chore: update import statement * chore: refactor withSubscriptionEvent * chore: add test coverage to throttle util * chore: replace custom merge util with async * chore: address formatting issue * chore: remove unused stream util * chore: undo unrelated change * Revert test model changes * Fix test model * Bump iOS version Co-authored-by: Dillon Nys <[email protected]> Co-authored-by: Dillon Nys <[email protected]>
1 parent 866d845 commit a6ca33c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2459
-254
lines changed

packages/amplify_analytics_pinpoint/ios/amplify_analytics_pinpoint.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ This code is the iOS part of the Amplify Flutter Pinpoint Analytics Plugin. The
1515
s.source = { :path => '.' }
1616
s.source_files = 'Classes/**/*'
1717
s.dependency 'Flutter'
18-
s.dependency 'Amplify', '~> 1.15.2'
19-
s.dependency 'AmplifyPlugins/AWSPinpointAnalyticsPlugin', '~> 1.15.2'
18+
s.dependency 'Amplify', '~> 1.15.3'
19+
s.dependency 'AmplifyPlugins/AWSPinpointAnalyticsPlugin', '~> 1.15.3'
2020
s.dependency 'amplify_core'
2121
s.platform = :ios, '11.0'
2222

packages/amplify_api/ios/amplify_api.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ The API module for Amplify Flutter.
1515
s.source = { :git => 'https://github.com/aws-amplify/amplify-flutter.git' }
1616
s.source_files = 'Classes/**/*'
1717
s.dependency 'Flutter'
18-
s.dependency 'Amplify', '~> 1.15.2'
19-
s.dependency 'AmplifyPlugins/AWSAPIPlugin', '~> 1.15.2'
18+
s.dependency 'Amplify', '~> 1.15.3'
19+
s.dependency 'AmplifyPlugins/AWSAPIPlugin', '~> 1.15.3'
2020
s.dependency 'amplify_core'
2121
s.platform = :ios, '11.0'
2222

packages/amplify_auth_cognito/ios/amplify_auth_cognito.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ Pod::Spec.new do |s|
1515
s.source = { :git => 'https://github.com/aws-amplify/amplify-flutter.git' }
1616
s.source_files = 'Classes/**/*'
1717
s.dependency 'Flutter'
18-
s.dependency 'Amplify', '~> 1.15.2'
19-
s.dependency 'AmplifyPlugins/AWSCognitoAuthPlugin', '~> 1.15.2'
18+
s.dependency 'Amplify', '~> 1.15.3'
19+
s.dependency 'AmplifyPlugins/AWSCognitoAuthPlugin', '~> 1.15.3'
2020
s.dependency 'ObjectMapper'
2121
s.dependency 'amplify_core'
2222
s.platform = :ios, '11.0'

packages/amplify_datastore/example/integration_test/main_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import 'query_test/query_test.dart' as query_test;
2121
import 'model_type_test.dart' as model_type_tests;
2222
import 'relationship_type_test.dart' as relationship_type_tests;
2323
import 'observe_test.dart' as observe_tests;
24+
import 'observe_query_test.dart' as observe_query_tests;
2425
import 'clear_test.dart' as clear_tests;
2526

2627
import 'utils/setup_utils.dart';
@@ -38,6 +39,7 @@ void main() async {
3839
model_type_tests.main();
3940
relationship_type_tests.main();
4041
observe_tests.main();
42+
observe_query_tests.main();
4143
clear_tests.main();
4244
});
4345
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
import 'package:amplify_datastore_example/models/ModelProvider.dart';
17+
import 'package:integration_test/integration_test.dart';
18+
import 'package:flutter_test/flutter_test.dart';
19+
import 'package:amplify_flutter/amplify.dart';
20+
21+
import 'utils/setup_utils.dart';
22+
23+
void main() {
24+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
25+
26+
group('observeQuery', () {
27+
setUp(() async {
28+
await configureDataStore();
29+
await clearDataStore();
30+
});
31+
32+
testWidgets(
33+
'should return an initial result set that is consistent with query()',
34+
(WidgetTester tester) async {
35+
List<Blog> blogs =
36+
List.generate(10, (index) => Blog(name: 'blog $index'));
37+
38+
for (var blog in blogs) {
39+
await Amplify.DataStore.save(blog);
40+
}
41+
var queryBlogs = await Amplify.DataStore.query(Blog.classType);
42+
43+
var observeQueryBlogs =
44+
(await Amplify.DataStore.observeQuery(Blog.classType).first).items;
45+
46+
expect(observeQueryBlogs.length, 10);
47+
expect(observeQueryBlogs, orderedEquals(queryBlogs));
48+
});
49+
50+
testWidgets('should emit new snapshots with updated items',
51+
(WidgetTester tester) async {
52+
List<Blog> blogs = List.generate(3, (index) => Blog(name: 'blog $index'));
53+
54+
for (var blog in blogs) {
55+
await Amplify.DataStore.save(blog);
56+
}
57+
58+
var observeQueryItemStream = Amplify.DataStore.observeQuery(
59+
Blog.classType,
60+
).map((event) => event.items);
61+
62+
Blog newBlog1 = Blog(name: 'new blog 1');
63+
Blog newBlog2 = Blog(name: 'new blog 2');
64+
Blog newBlog1Copy = newBlog1.copyWith(name: 'new name');
65+
66+
expectLater(
67+
observeQueryItemStream,
68+
emitsInOrder([
69+
orderedEquals([...blogs]),
70+
orderedEquals([...blogs, newBlog1]),
71+
orderedEquals([...blogs, newBlog1, newBlog2]),
72+
orderedEquals([...blogs, newBlog1Copy, newBlog2]),
73+
orderedEquals([...blogs, newBlog2]),
74+
]),
75+
);
76+
77+
await Amplify.DataStore.save(newBlog1);
78+
await Amplify.DataStore.save(newBlog2);
79+
await Amplify.DataStore.save(newBlog1Copy);
80+
await Amplify.DataStore.delete(newBlog1Copy);
81+
});
82+
83+
testWidgets('should respect query predicates', (WidgetTester tester) async {
84+
List<Blog> blogs = List.generate(3, (index) => Blog(name: 'blog $index'));
85+
86+
for (var blog in blogs) {
87+
await Amplify.DataStore.save(blog);
88+
}
89+
90+
var observeQueryItemStream = Amplify.DataStore.observeQuery(
91+
Blog.classType,
92+
where: Blog.NAME.contains('blog'),
93+
).map((event) => event.items);
94+
95+
Blog newBlog1 = Blog(name: 'new blog 1');
96+
Blog newBlog2 = Blog(name: 'new blog 2');
97+
Blog newBlog3 = Blog(name: 'new 3');
98+
Blog newBlog1Copy = newBlog1.copyWith(name: 'new name');
99+
100+
expectLater(
101+
observeQueryItemStream,
102+
emitsInOrder([
103+
orderedEquals([...blogs]),
104+
orderedEquals([...blogs, newBlog1]),
105+
orderedEquals([...blogs, newBlog1, newBlog2]),
106+
orderedEquals([...blogs, newBlog2]),
107+
]),
108+
);
109+
110+
await Amplify.DataStore.save(newBlog1);
111+
await Amplify.DataStore.save(newBlog2);
112+
await Amplify.DataStore.save(newBlog3);
113+
await Amplify.DataStore.save(newBlog1Copy);
114+
});
115+
116+
testWidgets('should respect sort orders', (WidgetTester tester) async {
117+
List<Blog> blogs = List.generate(3, (index) => Blog(name: 'blog $index'));
118+
119+
for (var blog in blogs) {
120+
await Amplify.DataStore.save(blog);
121+
}
122+
123+
var observeQueryItemStream = Amplify.DataStore.observeQuery(
124+
Blog.classType,
125+
sortBy: [Blog.NAME.ascending()],
126+
).map((event) => event.items);
127+
128+
Blog newBlog1 = Blog(name: 'aaa blog');
129+
Blog newBlog2 = Blog(name: 'ccc blog');
130+
Blog newBlog2Copy = newBlog2.copyWith(name: 'azz blog');
131+
132+
expectLater(
133+
observeQueryItemStream,
134+
emitsInOrder([
135+
orderedEquals([...blogs]),
136+
orderedEquals([newBlog1, ...blogs]),
137+
orderedEquals([newBlog1, ...blogs, newBlog2]),
138+
orderedEquals([newBlog1, newBlog2Copy, ...blogs]),
139+
]),
140+
);
141+
142+
await Amplify.DataStore.save(newBlog1);
143+
await Amplify.DataStore.save(newBlog2);
144+
await Amplify.DataStore.save(newBlog2Copy);
145+
});
146+
});
147+
}

0 commit comments

Comments
 (0)