@@ -18,6 +18,7 @@ class Books {
1818 static const title = TableColumn <String >('title' );
1919 static const tags = TableColumn <List <String >>('tags' );
2020 static const ageRange = TableColumn <String >('age_range' );
21+ static const metadata = TableColumn <Map <String , dynamic >>('metadata' );
2122}
2223
2324class MockHttpClient extends BaseClient {
@@ -227,6 +228,50 @@ void main() {
227228 test ('negating a filter twice throws' , () {
228229 expect (() => Books .id.eq (1 ).not ().not (), throwsStateError);
229230 });
231+
232+ test ('negated json containment encodes the value as json' , () async {
233+ await client
234+ .table (Books .table)
235+ .select ()
236+ .where (Books .metadata.contains ({'a' : 1 }).not ());
237+
238+ expect (requestParameters ()['metadata' ], 'not.cs.{"a":1}' );
239+ });
240+
241+ test ('whereAny encodes json containment values' , () async {
242+ await client.table (Books .table).select ().whereAny ([
243+ Books .metadata.contains ({'a' : 1 }),
244+ Books .id.eq (1 ),
245+ ]);
246+
247+ expect (
248+ requestParameters ()['or' ],
249+ r'(metadata.cs."{\"a\":1}",id.eq.1)' ,
250+ );
251+ });
252+
253+ test ('whereAny without filters throws' , () {
254+ expect (
255+ () => client.table (Books .table).select ().whereAny ([]),
256+ throwsArgumentError,
257+ );
258+ });
259+ });
260+
261+ group ('asStream' , () {
262+ test ('returns a broadcast stream that supports multiple listeners' , () {
263+ httpClient.responseBody = bookRows;
264+
265+ final stream = client.table (Books .table).select ().asStream ();
266+
267+ expect (stream.isBroadcast, isTrue);
268+ stream.listen (
269+ expectAsync1 ((books) {
270+ expect (books, hasLength (2 ));
271+ }),
272+ );
273+ stream.listen (expectAsync1 ((books) {}));
274+ });
230275 });
231276
232277 group ('transforms' , () {
0 commit comments