From 331e76e904c465aaf1c59d5b7d32b03d15a9b02f Mon Sep 17 00:00:00 2001 From: dshukertjr Date: Thu, 17 Oct 2024 12:19:59 +0900 Subject: [PATCH 1/2] chore: tidy up the code --- lib/src/mock_supabase_http_client.dart | 146 +++++++++++++++---------- test/mock_supabase_test.dart | 34 ++++-- 2 files changed, 113 insertions(+), 67 deletions(-) diff --git a/lib/src/mock_supabase_http_client.dart b/lib/src/mock_supabase_http_client.dart index e4e054d..3291777 100644 --- a/lib/src/mock_supabase_http_client.dart +++ b/lib/src/mock_supabase_http_client.dart @@ -542,69 +542,29 @@ class MockSupabaseHttpClient extends BaseClient { final value = postrestFilter.substring(4); return (row) => row[columnName].toString() != value; } else if (postrestFilter.startsWith('gt.')) { - final value = postrestFilter.substring(3); - - if (DateTime.tryParse(value) != null) { - final dateTime = DateTime.parse(value); - - return (row) { - final rowDate = DateTime.tryParse(row[columnName].toString()); - return rowDate != null && rowDate.isAfter(dateTime); - }; - } else if (num.tryParse(value) != null) { - return (row) => row[columnName] > num.tryParse(value); - } else { - throw UnimplementedError('Unsupported value type'); - } + return _handleComparison( + operator: 'gt', + value: postrestFilter.substring(3), + columnName: columnName, + ); } else if (postrestFilter.startsWith('lt.')) { - final value = postrestFilter.substring(3); - - if (DateTime.tryParse(value) != null) { - final dateTime = DateTime.parse(value); - - return (row) { - final rowDate = DateTime.tryParse(row[columnName].toString()); - return rowDate != null && rowDate.isBefore(dateTime); - }; - } else if (num.tryParse(value) != null) { - return (row) => row[columnName] < num.tryParse(value); - } else { - throw UnimplementedError('Unsupported value type'); - } + return _handleComparison( + operator: 'lt', + value: postrestFilter.substring(3), + columnName: columnName, + ); } else if (postrestFilter.startsWith('gte.')) { - final value = postrestFilter.substring(4); - - if (DateTime.tryParse(value) != null) { - final dateTime = DateTime.parse(value); - - return (row) { - final rowDate = DateTime.tryParse(row[columnName].toString()); - if (rowDate == null) return false; - return rowDate.isAtSameMomentAs(dateTime) || - rowDate.isAfter(dateTime); - }; - } else if (num.tryParse(value) != null) { - return (row) => row[columnName] >= num.tryParse(value); - } else { - throw UnimplementedError('Unsupported value type'); - } + return _handleComparison( + operator: 'gte', + value: postrestFilter.substring(4), + columnName: columnName, + ); } else if (postrestFilter.startsWith('lte.')) { - final value = postrestFilter.substring(4); - - if (DateTime.tryParse(value) != null) { - final dateTime = DateTime.parse(value); - - return (row) { - final rowDate = DateTime.tryParse(row[columnName].toString()); - if (rowDate == null) return false; - return rowDate.isAtSameMomentAs(dateTime) || - rowDate.isBefore(dateTime); - }; - } else if (num.tryParse(value) != null) { - return (row) => row[columnName] <= num.tryParse(value); - } else { - throw UnimplementedError('Unsupported value type'); - } + return _handleComparison( + operator: 'lte', + value: postrestFilter.substring(4), + columnName: columnName, + ); } else if (postrestFilter.startsWith('like.')) { final value = postrestFilter.substring(5); final regex = RegExp(value.replaceAll('%', '.*')); @@ -664,6 +624,72 @@ class MockSupabaseHttpClient extends BaseClient { return (row) => true; } + /// Handles comparison operations for date and numeric values. + /// + /// This function creates a filter based on the given comparison [operator], + /// [value], and [columnName]. It supports both date and numeric comparisons. + /// + /// [operator] can be 'gt', 'lt', 'gte', or 'lte'. + /// [value] is the string representation of the value to compare against. + /// [columnName] is the name of the column to compare in each row. + /// + /// Returns a function that takes a row and returns a boolean indicating + /// whether the row matches the comparison criteria. + bool Function(Map row) _handleComparison({ + required String operator, + required String value, + required String columnName, + }) { + // Check if the value is a valid date + if (DateTime.tryParse(value) != null) { + final dateTime = DateTime.parse(value); + return (row) { + final rowDate = DateTime.tryParse(row[columnName].toString()); + if (rowDate == null) return false; + // Perform date comparison based on the operator + switch (operator) { + case 'gt': + return rowDate.isAfter(dateTime); + case 'lt': + return rowDate.isBefore(dateTime); + case 'gte': + return rowDate.isAtSameMomentAs(dateTime) || + rowDate.isAfter(dateTime); + case 'lte': + return rowDate.isAtSameMomentAs(dateTime) || + rowDate.isBefore(dateTime); + default: + throw UnimplementedError('Unsupported operator: $operator'); + } + }; + } + // Check if the value is a valid number + else if (num.tryParse(value) != null) { + final numValue = num.parse(value); + return (row) { + final rowValue = num.tryParse(row[columnName].toString()); + if (rowValue == null) return false; + // Perform numeric comparison based on the operator + switch (operator) { + case 'gt': + return rowValue > numValue; + case 'lt': + return rowValue < numValue; + case 'gte': + return rowValue >= numValue; + case 'lte': + return rowValue <= numValue; + default: + throw UnimplementedError('Unsupported operator: $operator'); + } + }; + } + // Throw an error if the value is neither a date nor a number + else { + throw UnimplementedError('Unsupported value type'); + } + } + StreamedResponse _createResponse(dynamic data, {int statusCode = 200, required BaseRequest request, diff --git a/test/mock_supabase_test.dart b/test/mock_supabase_test.dart index 0495a33..3d26fb5 100644 --- a/test/mock_supabase_test.dart +++ b/test/mock_supabase_test.dart @@ -707,17 +707,22 @@ void main() { 'title': 'Third post', 'author_id': 1, 'createdAt': '2021-08-03 11:26:15.307+00' + }, + { + 'title': 'Fourth post', + 'author_id': 2, + 'createdAt': '2021-08-04 11:26:15.307+00' } ]); final count = await mockSupabase .from('data') .count() - .gt('createdAt', '2021-08-02 10:26:15.307+00'); + .gt('createdAt', '2021-08-02 11:26:15.307+00'); expect(count, 2); }); - test('count with gte. filter with datetime format', () async { + test('count with gte filter with datetime format', () async { await mockSupabase.from('data').insert([ { 'title': 'First post', @@ -733,6 +738,11 @@ void main() { 'title': 'Third post', 'author_id': 1, 'createdAt': '2021-08-03 11:26:15.307+00' + }, + { + 'title': 'Fourth post', + 'author_id': 2, + 'createdAt': '2021-08-04 11:26:15.307+00' } ]); @@ -741,7 +751,7 @@ void main() { .count() .gte('createdAt', '2021-08-02 11:26:15.307+00'); - expect(count, 2); + expect(count, 3); }); test('count with lt filter with datetime format', () async { @@ -760,17 +770,22 @@ void main() { 'title': 'Third post', 'author_id': 1, 'createdAt': '2021-08-03 11:26:15.307+00' + }, + { + 'title': 'Fourth post', + 'author_id': 2, + 'createdAt': '2021-08-04 11:26:15.307+00' } ]); final count = await mockSupabase .from('data') .count() - .lt('createdAt', '2021-08-02 12:26:15.307+00'); + .lt('createdAt', '2021-08-03 11:26:15.307+00'); expect(count, 2); }); - test('count with lte. filter with datetime format', () async { + test('count with lte filter with datetime format', () async { await mockSupabase.from('data').insert([ { 'title': 'First post', @@ -786,15 +801,20 @@ void main() { 'title': 'Third post', 'author_id': 1, 'createdAt': '2021-08-03 11:26:15.307+00' + }, + { + 'title': 'Fourth post', + 'author_id': 2, + 'createdAt': '2021-08-04 11:26:15.307+00' } ]); final count = await mockSupabase .from('data') .count() - .lte('createdAt', '2021-08-02 11:26:15.307+00'); + .lte('createdAt', '2021-08-03 11:26:15.307+00'); - expect(count, 2); + expect(count, 3); }); test('count with data and filter', () async { From e8c2ecb8f6de4be32f50f5ae603b4afba262cfae Mon Sep 17 00:00:00 2001 From: dshukertjr Date: Thu, 17 Oct 2024 12:21:09 +0900 Subject: [PATCH 2/2] chore: publish v0.0.3+1 --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06a691d..317aabd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.3+1 + +- fix: Add support to datetime on gt. gte. lt. lte. filter [#8](https://github.com/supabase-community/mock_supabase_http_client/pull/8) + ## 0.0.3 - feat: Add support for count and select with count. [#6](https://github.com/supabase-community/mock_supabase_http_client/pull/6) diff --git a/pubspec.yaml b/pubspec.yaml index e3dc8ab..4bc08a2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: mock_supabase_http_client description: A mock Supabase client for testing API calls without making actual http requests for Dart/Flutter apps that use Supabase. -version: 0.0.3 +version: 0.0.3+1 homepage: 'https://supabase.com' repository: https://github.com/supabase-community/mock_supabase_http_client