From e1ad1564188963cc3d94b17ab16361fbf3c0f0c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Wed, 21 Jan 2026 13:26:39 +0100 Subject: [PATCH 01/14] fix: Configure Codecov for mono-repo structure - Add ignore paths for examples, benchmark, and doc directories - Split coverage upload into separate steps with flags for each package - Associate each lcov.info file with its corresponding package flag --- .github/workflows/dart-tests.yaml | 21 +++++++++++++++++++-- codecov.yml | 13 +++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dart-tests.yaml b/.github/workflows/dart-tests.yaml index d63fab81..217a370a 100644 --- a/.github/workflows/dart-tests.yaml +++ b/.github/workflows/dart-tests.yaml @@ -160,12 +160,29 @@ jobs: fi done - - name: Upload Coverage + - name: Upload Coverage (relic_core) uses: codecov/codecov-action@v5 if: ${{ matrix.os == 'ubuntu-latest' && matrix.dart_sdk == '3.8.1' && matrix.deps == 'upgrade' && !cancelled() }} with: token: ${{ secrets.CODECOV_TOKEN }} - files: packages/relic_core/coverage/lcov.info,packages/relic_io/coverage/lcov.info,packages/relic/coverage/lcov.info + files: packages/relic_core/coverage/lcov.info + flags: relic_core + + - name: Upload Coverage (relic_io) + uses: codecov/codecov-action@v5 + if: ${{ matrix.os == 'ubuntu-latest' && matrix.dart_sdk == '3.8.1' && matrix.deps == 'upgrade' && !cancelled() }} + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: packages/relic_io/coverage/lcov.info + flags: relic_io + + - name: Upload Coverage (relic) + uses: codecov/codecov-action@v5 + if: ${{ matrix.os == 'ubuntu-latest' && matrix.dart_sdk == '3.8.1' && matrix.deps == 'upgrade' && !cancelled() }} + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: packages/relic/coverage/lcov.info + flags: relic docs-markdown-lint: name: Markdown lint for docs diff --git a/codecov.yml b/codecov.yml index 4e37e9f8..092262ba 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,9 +3,22 @@ coverage: project: default: target: auto + paths: + - "packages/relic_core/**" + - "packages/relic_io/**" + - "packages/relic/**" patch: default: target: auto + paths: + - "packages/relic_core/**" + - "packages/relic_io/**" + - "packages/relic/**" + +ignore: + - "packages/examples/**" + - "packages/benchmark/**" + - "doc/**" flag_management: individual_flags: From e75eb66414ac27e145c22a3135414af17906a07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 14:52:59 +0100 Subject: [PATCH 02/14] fix: Add --scope-output flags to coverage collection for cross-package coverage --- .github/workflows/dart-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dart-tests.yaml b/.github/workflows/dart-tests.yaml index 217a370a..0362d2c2 100644 --- a/.github/workflows/dart-tests.yaml +++ b/.github/workflows/dart-tests.yaml @@ -156,7 +156,7 @@ jobs: for package in packages/relic_core packages/relic_io packages/relic; do if [ -d "$package/test" ]; then echo "Running coverage for $package" - (cd "$package" && dart pub global run coverage:test_with_coverage --branch-coverage -- --reporter=failures-only) + (cd "$package" && dart pub global run coverage:test_with_coverage --branch-coverage --scope-output=relic --scope-output=relic_core --scope-output=relic_io -- --reporter=failures-only) fi done From cc5844e951f70a303d372fcae687c15028991280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 14:53:17 +0100 Subject: [PATCH 03/14] refactor: Create shared test utilities in relic_core --- packages/relic/test/util/test_util.dart | 138 +---------------- .../relic_core/lib/src/test/test_util.dart | 139 ++++++++++++++++++ 2 files changed, 141 insertions(+), 136 deletions(-) create mode 100644 packages/relic_core/lib/src/test/test_util.dart diff --git a/packages/relic/test/util/test_util.dart b/packages/relic/test/util/test_util.dart index 0816d3d6..dcaf2fa8 100644 --- a/packages/relic/test/util/test_util.dart +++ b/packages/relic/test/util/test_util.dart @@ -1,59 +1,10 @@ -import 'dart:async'; -import 'dart:convert'; import 'dart:io'; -import 'package:meta/meta.dart'; import 'package:relic/relic.dart'; import 'package:test/test.dart'; -final helloBytes = utf8.encode('hello,'); - -final worldBytes = utf8.encode(' world'); - -typedef SyncHandler = Result Function(Request); - -/// A simple, synchronous handler. -/// -/// By default, replies with a status code 200, empty headers, and -/// `Hello from ${req.url.path}`. -SyncHandler createSyncHandler({ - final int statusCode = 200, - final Headers? headers, - final Body? body, -}) { - return (final Request req) { - return Response( - statusCode, - headers: headers ?? Headers.empty(), - body: body ?? Body.fromString('Hello from ${req.url.path}'), - ); - }; -} - -final SyncHandler syncHandler = createSyncHandler(); - -/// Calls [createSyncHandler] and wraps the response in a [Future]. -Future asyncHandler(final Request req) async { - return syncHandler(req); -} - -/// Makes a simple GET request to [handler] and returns the result. -Future makeSimpleRequest( - final Handler handler, [ - final Request? request, -]) async { - final newCtx = await handler((request ?? _defaultRequest)); - if (newCtx is! Response) throw ArgumentError(newCtx); - return newCtx; -} - -final _defaultRequest = RequestInternal.create( - Method.get, - localhostUri, - Object(), -); - -final localhostUri = Uri.parse('http://localhost/'); +// Re-export shared test utilities from relic_core +export 'package:relic_core/src/test/test_util.dart'; final isOhNoStateError = isA().having( (final e) => e.message, @@ -72,88 +23,3 @@ Future testServe( await server.mountAndStart(handler); return server; } - -/// Like [group], but takes a [variants] argument and creates a group for each -/// variant. -/// -/// Setup multiple groups of tests where each group gets a different parameter -/// value. The [descriptionBuilder] is used to produce a description for each -/// group based on the [variants]. For each variant the [body] is executed to -/// setup tests and sub-groups. -/// -/// This is useful for running the same tests against multiple configurations, -/// implementations, or inputs. -/// -/// Example: -/// ```dart -/// parameterizedGroup( -/// (protocol) => 'Testing protocol: $protocol', -/// (protocol) { -/// test('connects successfully', () { -/// // Test using the protocol parameter -/// }); -/// }, -/// variants: ['http', 'https', 'ws'], -/// ); -/// ``` -@isTestGroup -void parameterizedGroup( - final String Function(T) descriptionBuilder, - final void Function(T) body, { - required final Iterable variants, -}) { - for (final v in variants) { - group(descriptionBuilder(v), () => body(v)); - } -} - -/// Like [test,] but takes a [variants] argument and creates a test-case -/// for each variant. -/// -/// Setup multiple test cases where each test case gets a different parameter -/// value. The [descriptionBuilder] is used to produce a description for each -/// test case based on the [variants]. For each variant the [body] is executed. -/// -/// This is useful for testing the same functionality against multiple inputs -/// or configurations. -/// -/// Example: -/// ```dart -/// parameterizedTest( -/// (value) => 'Test with value: $value', -/// (value) { -/// expect(value * 2, greaterThan(value)); -/// }, -/// variants: [1, 2, 3, 4, 5], -/// ); -/// ``` -@isTest -void parameterizedTest( - final String Function(T) descriptionBuilder, - final void Function(T) body, { - required final Iterable variants, -}) { - for (final v in variants) { - test(descriptionBuilder(v), () => body(v)); - } -} - -/// Creates a [test] with a single [expect]. -/// -/// A convenience method that creates a test with a [description] that -/// validates the single expectation that [actual] matches [expected]. -/// -/// Example: -/// ```dart -/// singleTest('1 + 1 equals 2', 1 + 1, 2); -/// ``` -@isTest -void singleTest( - final String description, - final dynamic actual, - final dynamic expected, -) { - test(description, () { - expect(actual, expected); - }); -} diff --git a/packages/relic_core/lib/src/test/test_util.dart b/packages/relic_core/lib/src/test/test_util.dart new file mode 100644 index 00000000..3a222379 --- /dev/null +++ b/packages/relic_core/lib/src/test/test_util.dart @@ -0,0 +1,139 @@ +import 'dart:convert'; + +import 'package:meta/meta.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:test/test.dart'; + +final helloBytes = utf8.encode('hello,'); + +final worldBytes = utf8.encode(' world'); + +typedef SyncHandler = Result Function(Request); + +/// A simple, synchronous handler. +/// +/// By default, replies with a status code 200, empty headers, and +/// `Hello from ${req.url.path}`. +SyncHandler createSyncHandler({ + final int statusCode = 200, + final Headers? headers, + final Body? body, +}) { + return (final Request req) { + return Response( + statusCode, + headers: headers ?? Headers.empty(), + body: body ?? Body.fromString('Hello from ${req.url.path}'), + ); + }; +} + +final SyncHandler syncHandler = createSyncHandler(); + +/// Calls [createSyncHandler] and wraps the response in a [Future]. +Future asyncHandler(final Request req) async { + return syncHandler(req); +} + +/// Makes a simple GET request to [handler] and returns the result. +Future makeSimpleRequest( + final Handler handler, [ + final Request? request, +]) async { + final newCtx = await handler((request ?? _defaultRequest)); + if (newCtx is! Response) throw ArgumentError(newCtx); + return newCtx; +} + +final _defaultRequest = RequestInternal.create( + Method.get, + localhostUri, + Object(), +); + +final localhostUri = Uri.parse('http://localhost/'); + +/// Like [group], but takes a [variants] argument and creates a group for each +/// variant. +/// +/// Setup multiple groups of tests where each group gets a different parameter +/// value. The [descriptionBuilder] is used to produce a description for each +/// group based on the [variants]. For each variant the [body] is executed to +/// setup tests and sub-groups. +/// +/// This is useful for running the same tests against multiple configurations, +/// implementations, or inputs. +/// +/// Example: +/// ```dart +/// parameterizedGroup( +/// (protocol) => 'Testing protocol: $protocol', +/// (protocol) { +/// test('connects successfully', () { +/// // Test using the protocol parameter +/// }); +/// }, +/// variants: ['http', 'https', 'ws'], +/// ); +/// ``` +@isTestGroup +void parameterizedGroup( + final String Function(T) descriptionBuilder, + final void Function(T) body, { + required final Iterable variants, +}) { + for (final v in variants) { + group(descriptionBuilder(v), () => body(v)); + } +} + +/// Like [test,] but takes a [variants] argument and creates a test-case +/// for each variant. +/// +/// Setup multiple test cases where each test case gets a different parameter +/// value. The [descriptionBuilder] is used to produce a description for each +/// test case based on the [variants]. For each variant the [body] is executed. +/// +/// This is useful for testing the same functionality against multiple inputs +/// or configurations. +/// +/// Example: +/// ```dart +/// parameterizedTest( +/// (value) => 'Test with value: $value', +/// (value) { +/// expect(value * 2, greaterThan(value)); +/// }, +/// variants: [1, 2, 3, 4, 5], +/// ); +/// ``` +@isTest +void parameterizedTest( + final String Function(T) descriptionBuilder, + final void Function(T) body, { + required final Iterable variants, +}) { + for (final v in variants) { + test(descriptionBuilder(v), () => body(v)); + } +} + +/// Creates a [test] with a single [expect]. +/// +/// A convenience method that creates a test with a [description] that +/// validates the single expectation that [actual] matches [expected]. +/// +/// Example: +/// ```dart +/// singleTest('1 + 1 equals 2', 1 + 1, 2); +/// ``` +@isTest +void singleTest( + final String description, + final dynamic actual, + final dynamic expected, +) { + test(description, () { + expect(actual, expected); + }); +} From 475364dad11fa387e3313de3b0a0ed3e2d6a12cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 14:54:47 +0100 Subject: [PATCH 04/14] refactor: Move handler tests to relic_core --- .../test/handler/cascade_test.dart | 29 +++++-------------- .../test/handler/pipeline_test.dart | 5 ++-- 2 files changed, 10 insertions(+), 24 deletions(-) rename packages/{relic => relic_core}/test/handler/cascade_test.dart (89%) rename packages/{relic => relic_core}/test/handler/pipeline_test.dart (95%) diff --git a/packages/relic/test/handler/cascade_test.dart b/packages/relic_core/test/handler/cascade_test.dart similarity index 89% rename from packages/relic/test/handler/cascade_test.dart rename to packages/relic_core/test/handler/cascade_test.dart index 3154c620..41dd5451 100644 --- a/packages/relic/test/handler/cascade_test.dart +++ b/packages/relic_core/test/handler/cascade_test.dart @@ -1,8 +1,7 @@ -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_core/src/test/test_util.dart'; import 'package:test/test.dart'; -import '../util/test_util.dart'; - void main() { group('Given a cascade with several handlers', () { late Handler handler; @@ -11,9 +10,7 @@ void main() { .add( respondWith((final request) { if (request.headers['one']?.first == 'false') { - return Response.notFound( - body: Body.fromString('handler 1'), - ); + return Response.notFound(body: Body.fromString('handler 1')); } else { return Response.ok(body: Body.fromString('handler 1')); } @@ -22,9 +19,7 @@ void main() { .add( respondWith((final request) { if (request.headers['two']?.first == 'false') { - return Response.notFound( - body: Body.fromString('handler 2'), - ); + return Response.notFound(body: Body.fromString('handler 2')); } else { return Response.ok(body: Body.fromString('handler 2')); } @@ -33,9 +28,7 @@ void main() { .add( respondWith((final request) { if (request.headers['three']?.first == 'false') { - return Response.notFound( - body: Body.fromString('handler 3'), - ); + return Response.notFound(body: Body.fromString('handler 3')); } else { return Response.ok(body: Body.fromString('handler 3')); } @@ -123,9 +116,7 @@ void main() { ), ) .add( - respondWith( - (_) => Response.ok(body: Body.fromString('handler 2')), - ), + respondWith((_) => Response.ok(body: Body.fromString('handler 2'))), ) .handler; @@ -141,9 +132,7 @@ void main() { final handler = Cascade() .add(respondWith((_) => Response(405))) .add( - respondWith( - (_) => Response.ok(body: Body.fromString('handler 2')), - ), + respondWith((_) => Response.ok(body: Body.fromString('handler 2'))), ) .handler; @@ -169,9 +158,7 @@ void main() { ), ) .add( - respondWith( - (_) => Response.ok(body: Body.fromString('handler 4')), - ), + respondWith((_) => Response.ok(body: Body.fromString('handler 4'))), ) .handler; diff --git a/packages/relic/test/handler/pipeline_test.dart b/packages/relic_core/test/handler/pipeline_test.dart similarity index 95% rename from packages/relic/test/handler/pipeline_test.dart rename to packages/relic_core/test/handler/pipeline_test.dart index b3b52940..ec584fc4 100644 --- a/packages/relic/test/handler/pipeline_test.dart +++ b/packages/relic_core/test/handler/pipeline_test.dart @@ -1,8 +1,7 @@ -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_core/src/test/test_util.dart'; import 'package:test/test.dart'; -import '../util/test_util.dart'; - void main() { var accessLocation = 0; From 05ac0a6f1858ac454e63d60e1c4bc61b6b7e1107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 14:56:29 +0100 Subject: [PATCH 05/14] refactor: Move message tests to relic_core --- packages/{relic => relic_core}/test/message/message_test.dart | 4 ++-- packages/{relic => relic_core}/test/message/request_test.dart | 4 ++-- .../{relic => relic_core}/test/message/response_test.dart | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename packages/{relic => relic_core}/test/message/message_test.dart (98%) rename packages/{relic => relic_core}/test/message/request_test.dart (98%) rename packages/{relic => relic_core}/test/message/response_test.dart (98%) diff --git a/packages/relic/test/message/message_test.dart b/packages/relic_core/test/message/message_test.dart similarity index 98% rename from packages/relic/test/message/message_test.dart rename to packages/relic_core/test/message/message_test.dart index da96beee..b333f1d2 100644 --- a/packages/relic/test/message/message_test.dart +++ b/packages/relic_core/test/message/message_test.dart @@ -2,10 +2,10 @@ import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; -import '../util/test_util.dart'; +import 'package:relic_core/src/test/test_util.dart'; class _TestMessage extends Message { _TestMessage( diff --git a/packages/relic/test/message/request_test.dart b/packages/relic_core/test/message/request_test.dart similarity index 98% rename from packages/relic/test/message/request_test.dart rename to packages/relic_core/test/message/request_test.dart index 0608de2f..5d2265d1 100644 --- a/packages/relic/test/message/request_test.dart +++ b/packages/relic_core/test/message/request_test.dart @@ -2,10 +2,10 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:http_parser/http_parser.dart'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; -import '../util/test_util.dart'; +import 'package:relic_core/src/test/test_util.dart'; Request _request({final Headers? headers, final Body? body}) { return RequestInternal.create( diff --git a/packages/relic/test/message/response_test.dart b/packages/relic_core/test/message/response_test.dart similarity index 98% rename from packages/relic/test/message/response_test.dart rename to packages/relic_core/test/message/response_test.dart index 2f9264b7..aea5668f 100644 --- a/packages/relic/test/message/response_test.dart +++ b/packages/relic_core/test/message/response_test.dart @@ -3,10 +3,10 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:http_parser/http_parser.dart'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; -import '../util/test_util.dart'; +import 'package:relic_core/src/test/test_util.dart'; void main() { group('Given a response with a String body', () { From 5201aec69d9b3add11cd778c4c5455cd6b674f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 14:57:23 +0100 Subject: [PATCH 06/14] refactor: Move middleware tests to relic_core --- packages/relic/test/util/test_util.dart | 7 ------- packages/relic_core/lib/src/test/test_util.dart | 6 ++++++ .../test/middleware_extra}/create_middleware_test.dart | 4 ++-- .../test/middleware_extra}/log_middleware_test.dart | 4 ++-- .../test/middleware_extra}/routing_middleware_test.dart | 4 ++-- 5 files changed, 12 insertions(+), 13 deletions(-) rename packages/{relic/test/middleware => relic_core/test/middleware_extra}/create_middleware_test.dart (99%) rename packages/{relic/test/middleware => relic_core/test/middleware_extra}/log_middleware_test.dart (95%) rename packages/{relic/test/middleware => relic_core/test/middleware_extra}/routing_middleware_test.dart (99%) diff --git a/packages/relic/test/util/test_util.dart b/packages/relic/test/util/test_util.dart index dcaf2fa8..b6c78339 100644 --- a/packages/relic/test/util/test_util.dart +++ b/packages/relic/test/util/test_util.dart @@ -1,17 +1,10 @@ import 'dart:io'; import 'package:relic/relic.dart'; -import 'package:test/test.dart'; // Re-export shared test utilities from relic_core export 'package:relic_core/src/test/test_util.dart'; -final isOhNoStateError = isA().having( - (final e) => e.message, - 'message', - 'oh no', -); - Future testServe( final Handler handler, { final SecurityContext? context, diff --git a/packages/relic_core/lib/src/test/test_util.dart b/packages/relic_core/lib/src/test/test_util.dart index 3a222379..bf22ecd9 100644 --- a/packages/relic_core/lib/src/test/test_util.dart +++ b/packages/relic_core/lib/src/test/test_util.dart @@ -53,6 +53,12 @@ final _defaultRequest = RequestInternal.create( final localhostUri = Uri.parse('http://localhost/'); +final isOhNoStateError = isA().having( + (final e) => e.message, + 'message', + 'oh no', +); + /// Like [group], but takes a [variants] argument and creates a group for each /// variant. /// diff --git a/packages/relic/test/middleware/create_middleware_test.dart b/packages/relic_core/test/middleware_extra/create_middleware_test.dart similarity index 99% rename from packages/relic/test/middleware/create_middleware_test.dart rename to packages/relic_core/test/middleware_extra/create_middleware_test.dart index 7978d2ef..45269438 100644 --- a/packages/relic/test/middleware/create_middleware_test.dart +++ b/packages/relic_core/test/middleware_extra/create_middleware_test.dart @@ -2,10 +2,10 @@ import 'dart:async'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; -import '../util/test_util.dart'; +import 'package:relic_core/src/test/test_util.dart'; void main() { test( diff --git a/packages/relic/test/middleware/log_middleware_test.dart b/packages/relic_core/test/middleware_extra/log_middleware_test.dart similarity index 95% rename from packages/relic/test/middleware/log_middleware_test.dart rename to packages/relic_core/test/middleware_extra/log_middleware_test.dart index 2659933f..4d30297e 100644 --- a/packages/relic/test/middleware/log_middleware_test.dart +++ b/packages/relic_core/test/middleware_extra/log_middleware_test.dart @@ -1,7 +1,7 @@ -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; -import '../util/test_util.dart'; +import 'package:relic_core/src/test/test_util.dart'; void main() { late bool gotLog; diff --git a/packages/relic/test/middleware/routing_middleware_test.dart b/packages/relic_core/test/middleware_extra/routing_middleware_test.dart similarity index 99% rename from packages/relic/test/middleware/routing_middleware_test.dart rename to packages/relic_core/test/middleware_extra/routing_middleware_test.dart index 1436d181..499ab8bc 100644 --- a/packages/relic/test/middleware/routing_middleware_test.dart +++ b/packages/relic_core/test/middleware_extra/routing_middleware_test.dart @@ -1,7 +1,7 @@ -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; -import '../util/test_util.dart'; +import 'package:relic_core/src/test/test_util.dart'; Request _request( final String path, { From 3ed20362f31ed4539ba7705119f74b30b492db48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 14:58:48 +0100 Subject: [PATCH 07/14] refactor: Move query and exception tests to relic_core --- .../{relic => relic_core}/test/query/query_param_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename packages/{relic => relic_core}/test/query/query_param_test.dart (97%) diff --git a/packages/relic/test/query/query_param_test.dart b/packages/relic_core/test/query/query_param_test.dart similarity index 97% rename from packages/relic/test/query/query_param_test.dart rename to packages/relic_core/test/query/query_param_test.dart index 7bbfb0d6..0384c21a 100644 --- a/packages/relic/test/query/query_param_test.dart +++ b/packages/relic_core/test/query/query_param_test.dart @@ -1,7 +1,7 @@ -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; -import '../util/test_util.dart'; +import 'package:relic_core/src/test/test_util.dart'; /// Tests for QueryParam and QueryParameters. /// From 2f91dc6a3f50798a56590b04ff0c4fbc9b330279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 14:59:34 +0100 Subject: [PATCH 08/14] refactor: Move static tests to relic_io --- packages/relic_io/pubspec.yaml | 6 ++++++ .../test/static/alternative_root_test.dart | 3 ++- .../{relic => relic_io}/test/static/basic_file_test.dart | 3 ++- .../test/static/cache_busting_config_test.dart | 3 ++- .../test/static/cache_busting_static_handler_test.dart | 3 ++- .../{relic => relic_io}/test/static/cache_control_test.dart | 3 ++- .../{relic => relic_io}/test/static/content_type_test.dart | 6 ++++-- .../test/static/create_file_handler_test.dart | 3 ++- .../test/static/default_handler_test.dart | 3 ++- .../{relic => relic_io}/test/static/get_handler_test.dart | 3 ++- .../test/static/if_modified_since_test.dart | 3 ++- .../{relic => relic_io}/test/static/if_none_match_test.dart | 3 ++- packages/{relic => relic_io}/test/static/if_range_test.dart | 3 ++- packages/{relic => relic_io}/test/static/mounted_test.dart | 3 ++- .../{relic => relic_io}/test/static/not_found_test.dart | 3 ++- .../test/static/range_edge_cases_test.dart | 3 ++- packages/{relic => relic_io}/test/static/range_test.dart | 3 ++- .../{relic => relic_io}/test/static/symbolic_link_test.dart | 3 ++- packages/{relic => relic_io}/test/static/test_util.dart | 3 ++- .../test/static/unsupported_methods_test.dart | 3 ++- 20 files changed, 46 insertions(+), 20 deletions(-) rename packages/{relic => relic_io}/test/static/alternative_root_test.dart (96%) rename packages/{relic => relic_io}/test/static/basic_file_test.dart (99%) rename packages/{relic => relic_io}/test/static/cache_busting_config_test.dart (99%) rename packages/{relic => relic_io}/test/static/cache_busting_static_handler_test.dart (99%) rename packages/{relic => relic_io}/test/static/cache_control_test.dart (97%) rename packages/{relic => relic_io}/test/static/content_type_test.dart (97%) rename packages/{relic => relic_io}/test/static/create_file_handler_test.dart (98%) rename packages/{relic => relic_io}/test/static/default_handler_test.dart (95%) rename packages/{relic => relic_io}/test/static/get_handler_test.dart (95%) rename packages/{relic => relic_io}/test/static/if_modified_since_test.dart (97%) rename packages/{relic => relic_io}/test/static/if_none_match_test.dart (98%) rename packages/{relic => relic_io}/test/static/if_range_test.dart (97%) rename packages/{relic => relic_io}/test/static/mounted_test.dart (91%) rename packages/{relic => relic_io}/test/static/not_found_test.dart (97%) rename packages/{relic => relic_io}/test/static/range_edge_cases_test.dart (99%) rename packages/{relic => relic_io}/test/static/range_test.dart (98%) rename packages/{relic => relic_io}/test/static/symbolic_link_test.dart (97%) rename packages/{relic => relic_io}/test/static/test_util.dart (94%) rename packages/{relic => relic_io}/test/static/unsupported_methods_test.dart (97%) diff --git a/packages/relic_io/pubspec.yaml b/packages/relic_io/pubspec.yaml index 67302719..4980732e 100644 --- a/packages/relic_io/pubspec.yaml +++ b/packages/relic_io/pubspec.yaml @@ -22,3 +22,9 @@ dependencies: stack_trace: ^1.10.0 stream_channel: ^2.1.1 web_socket: ^1.0.1 + +dev_dependencies: + lints: ">=5.0.0 <7.0.0" + serverpod_lints: ^3.0.0 + test: ^1.25.10 + test_descriptor: ^2.0.1 diff --git a/packages/relic/test/static/alternative_root_test.dart b/packages/relic_io/test/static/alternative_root_test.dart similarity index 96% rename from packages/relic/test/static/alternative_root_test.dart rename to packages/relic_io/test/static/alternative_root_test.dart index d8b3feca..fb9d524b 100644 --- a/packages/relic/test/static/alternative_root_test.dart +++ b/packages/relic_io/test/static/alternative_root_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/basic_file_test.dart b/packages/relic_io/test/static/basic_file_test.dart similarity index 99% rename from packages/relic/test/static/basic_file_test.dart rename to packages/relic_io/test/static/basic_file_test.dart index cdb4c622..9a41b28b 100644 --- a/packages/relic/test/static/basic_file_test.dart +++ b/packages/relic_io/test/static/basic_file_test.dart @@ -3,7 +3,8 @@ import 'dart:io'; import 'package:mime/mime.dart' as mime; import 'package:path/path.dart' as p; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/cache_busting_config_test.dart b/packages/relic_io/test/static/cache_busting_config_test.dart similarity index 99% rename from packages/relic/test/static/cache_busting_config_test.dart rename to packages/relic_io/test/static/cache_busting_config_test.dart index d2509b76..a9fbb69f 100644 --- a/packages/relic/test/static/cache_busting_config_test.dart +++ b/packages/relic_io/test/static/cache_busting_config_test.dart @@ -1,7 +1,8 @@ import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/cache_busting_static_handler_test.dart b/packages/relic_io/test/static/cache_busting_static_handler_test.dart similarity index 99% rename from packages/relic/test/static/cache_busting_static_handler_test.dart rename to packages/relic_io/test/static/cache_busting_static_handler_test.dart index 7d452191..f5081c24 100644 --- a/packages/relic/test/static/cache_busting_static_handler_test.dart +++ b/packages/relic_io/test/static/cache_busting_static_handler_test.dart @@ -1,7 +1,8 @@ import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/cache_control_test.dart b/packages/relic_io/test/static/cache_control_test.dart similarity index 97% rename from packages/relic/test/static/cache_control_test.dart rename to packages/relic_io/test/static/cache_control_test.dart index 62187618..cfa109af 100644 --- a/packages/relic/test/static/cache_control_test.dart +++ b/packages/relic_io/test/static/cache_control_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/content_type_test.dart b/packages/relic_io/test/static/content_type_test.dart similarity index 97% rename from packages/relic/test/static/content_type_test.dart rename to packages/relic_io/test/static/content_type_test.dart index c8254d35..11effb15 100644 --- a/packages/relic/test/static/content_type_test.dart +++ b/packages/relic_io/test/static/content_type_test.dart @@ -1,11 +1,13 @@ import 'dart:io'; import 'package:mime/mime.dart'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; -import '../util/test_util.dart'; +import 'package:relic_core/src/test/test_util.dart'; + import 'test_util.dart'; // Provides the makeRequest helper void main() { diff --git a/packages/relic/test/static/create_file_handler_test.dart b/packages/relic_io/test/static/create_file_handler_test.dart similarity index 98% rename from packages/relic/test/static/create_file_handler_test.dart rename to packages/relic_io/test/static/create_file_handler_test.dart index 4c2c440d..82bd7679 100644 --- a/packages/relic/test/static/create_file_handler_test.dart +++ b/packages/relic_io/test/static/create_file_handler_test.dart @@ -1,7 +1,8 @@ import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/default_handler_test.dart b/packages/relic_io/test/static/default_handler_test.dart similarity index 95% rename from packages/relic/test/static/default_handler_test.dart rename to packages/relic_io/test/static/default_handler_test.dart index 9cafd25e..84900eed 100644 --- a/packages/relic/test/static/default_handler_test.dart +++ b/packages/relic_io/test/static/default_handler_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/get_handler_test.dart b/packages/relic_io/test/static/get_handler_test.dart similarity index 95% rename from packages/relic/test/static/get_handler_test.dart rename to packages/relic_io/test/static/get_handler_test.dart index ee9153fa..2ca750e3 100644 --- a/packages/relic/test/static/get_handler_test.dart +++ b/packages/relic_io/test/static/get_handler_test.dart @@ -1,7 +1,8 @@ import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/if_modified_since_test.dart b/packages/relic_io/test/static/if_modified_since_test.dart similarity index 97% rename from packages/relic/test/static/if_modified_since_test.dart rename to packages/relic_io/test/static/if_modified_since_test.dart index 583251d3..4147e334 100644 --- a/packages/relic/test/static/if_modified_since_test.dart +++ b/packages/relic_io/test/static/if_modified_since_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/if_none_match_test.dart b/packages/relic_io/test/static/if_none_match_test.dart similarity index 98% rename from packages/relic/test/static/if_none_match_test.dart rename to packages/relic_io/test/static/if_none_match_test.dart index 68421e63..7e1bb806 100644 --- a/packages/relic/test/static/if_none_match_test.dart +++ b/packages/relic_io/test/static/if_none_match_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/if_range_test.dart b/packages/relic_io/test/static/if_range_test.dart similarity index 97% rename from packages/relic/test/static/if_range_test.dart rename to packages/relic_io/test/static/if_range_test.dart index b11d502e..38e04ea4 100644 --- a/packages/relic/test/static/if_range_test.dart +++ b/packages/relic_io/test/static/if_range_test.dart @@ -1,7 +1,8 @@ import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/mounted_test.dart b/packages/relic_io/test/static/mounted_test.dart similarity index 91% rename from packages/relic/test/static/mounted_test.dart rename to packages/relic_io/test/static/mounted_test.dart index 733f3673..bd132976 100644 --- a/packages/relic/test/static/mounted_test.dart +++ b/packages/relic_io/test/static/mounted_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/not_found_test.dart b/packages/relic_io/test/static/not_found_test.dart similarity index 97% rename from packages/relic/test/static/not_found_test.dart rename to packages/relic_io/test/static/not_found_test.dart index 45f0aa26..ff9ab4c6 100644 --- a/packages/relic/test/static/not_found_test.dart +++ b/packages/relic_io/test/static/not_found_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/range_edge_cases_test.dart b/packages/relic_io/test/static/range_edge_cases_test.dart similarity index 99% rename from packages/relic/test/static/range_edge_cases_test.dart rename to packages/relic_io/test/static/range_edge_cases_test.dart index 59db43d6..069c4d56 100644 --- a/packages/relic/test/static/range_edge_cases_test.dart +++ b/packages/relic_io/test/static/range_edge_cases_test.dart @@ -3,7 +3,8 @@ library; import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/range_test.dart b/packages/relic_io/test/static/range_test.dart similarity index 98% rename from packages/relic/test/static/range_test.dart rename to packages/relic_io/test/static/range_test.dart index 30d656e8..c58fd7ce 100644 --- a/packages/relic/test/static/range_test.dart +++ b/packages/relic_io/test/static/range_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/symbolic_link_test.dart b/packages/relic_io/test/static/symbolic_link_test.dart similarity index 97% rename from packages/relic/test/static/symbolic_link_test.dart rename to packages/relic_io/test/static/symbolic_link_test.dart index 2e96bf36..cb478b3e 100644 --- a/packages/relic/test/static/symbolic_link_test.dart +++ b/packages/relic_io/test/static/symbolic_link_test.dart @@ -1,7 +1,8 @@ import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic/test/static/test_util.dart b/packages/relic_io/test/static/test_util.dart similarity index 94% rename from packages/relic/test/static/test_util.dart rename to packages/relic_io/test/static/test_util.dart index f76fd891..818518b4 100644 --- a/packages/relic/test/static/test_util.dart +++ b/packages/relic_io/test/static/test_util.dart @@ -1,6 +1,7 @@ import 'dart:async'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; /// Makes a simple GET request to [handler] and returns the result. diff --git a/packages/relic/test/static/unsupported_methods_test.dart b/packages/relic_io/test/static/unsupported_methods_test.dart similarity index 97% rename from packages/relic/test/static/unsupported_methods_test.dart rename to packages/relic_io/test/static/unsupported_methods_test.dart index 92ae272e..eeac2569 100644 --- a/packages/relic/test/static/unsupported_methods_test.dart +++ b/packages/relic_io/test/static/unsupported_methods_test.dart @@ -1,6 +1,7 @@ import 'dart:io'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; From 7dbdf152ff488aed818583f35295238aea403c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 15:02:33 +0100 Subject: [PATCH 09/14] refactor: Move web_socket tests to relic_io --- packages/relic_io/pubspec.yaml | 1 + packages/relic_io/test/util/test_util.dart | 29 +++++++++++++++++++ .../test/web_socket/web_socket_test.dart | 4 +-- 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 packages/relic_io/test/util/test_util.dart rename packages/{relic => relic_io}/test/web_socket/web_socket_test.dart (99%) diff --git a/packages/relic_io/pubspec.yaml b/packages/relic_io/pubspec.yaml index 4980732e..64d290a8 100644 --- a/packages/relic_io/pubspec.yaml +++ b/packages/relic_io/pubspec.yaml @@ -28,3 +28,4 @@ dev_dependencies: serverpod_lints: ^3.0.0 test: ^1.25.10 test_descriptor: ^2.0.1 + web_socket_channel: ^3.0.3 diff --git a/packages/relic_io/test/util/test_util.dart b/packages/relic_io/test/util/test_util.dart new file mode 100644 index 00000000..31866084 --- /dev/null +++ b/packages/relic_io/test/util/test_util.dart @@ -0,0 +1,29 @@ +import 'dart:io'; + +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; + +// Re-export shared test utilities from relic_core +export 'package:relic_core/src/test/test_util.dart'; + +/// Extension methods for RelicServer +extension RelicServerTestEx on RelicServer { + /// Fake [url] property for the [RelicServer] for testing purposes. + /// + /// In general a server cannot know what URL it is being accessed by before an + /// actual request arrives, but for testing purposes we can infer a local URL + /// based on the server's port. + Uri get url => Uri.http('localhost:$port'); +} + +Future testServe( + final Handler handler, { + final SecurityContext? context, +}) async { + final server = RelicServer( + () => + IOAdapter.bind(InternetAddress.loopbackIPv4, port: 0, context: context), + ); + await server.mountAndStart(handler); + return server; +} diff --git a/packages/relic/test/web_socket/web_socket_test.dart b/packages/relic_io/test/web_socket/web_socket_test.dart similarity index 99% rename from packages/relic/test/web_socket/web_socket_test.dart rename to packages/relic_io/test/web_socket/web_socket_test.dart index 8562ce5b..fcc63ce5 100644 --- a/packages/relic/test/web_socket/web_socket_test.dart +++ b/packages/relic_io/test/web_socket/web_socket_test.dart @@ -4,12 +4,12 @@ import 'dart:io' as io; import 'dart:isolate'; import 'dart:typed_data'; -import 'package:relic/relic.dart'; +import 'package:relic_core/relic_core.dart'; +import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:web_socket/web_socket.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; -import '../headers/headers_test_utils.dart'; import '../util/test_util.dart'; RelicServer? _server; From 509cc79c58d3f7da7f82b3abf854f87bd106cc4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 15:18:29 +0100 Subject: [PATCH 10/14] fix: Remove unused imports --- packages/relic_io/test/static/alternative_root_test.dart | 1 - packages/relic_io/test/static/cache_busting_config_test.dart | 1 - packages/relic_io/test/static/get_handler_test.dart | 1 - packages/relic_io/test/static/symbolic_link_test.dart | 1 - 4 files changed, 4 deletions(-) diff --git a/packages/relic_io/test/static/alternative_root_test.dart b/packages/relic_io/test/static/alternative_root_test.dart index fb9d524b..05cdbb9f 100644 --- a/packages/relic_io/test/static/alternative_root_test.dart +++ b/packages/relic_io/test/static/alternative_root_test.dart @@ -1,6 +1,5 @@ import 'dart:io'; -import 'package:relic_core/relic_core.dart'; import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic_io/test/static/cache_busting_config_test.dart b/packages/relic_io/test/static/cache_busting_config_test.dart index a9fbb69f..018629f5 100644 --- a/packages/relic_io/test/static/cache_busting_config_test.dart +++ b/packages/relic_io/test/static/cache_busting_config_test.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:relic_core/relic_core.dart'; import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic_io/test/static/get_handler_test.dart b/packages/relic_io/test/static/get_handler_test.dart index 2ca750e3..81b46052 100644 --- a/packages/relic_io/test/static/get_handler_test.dart +++ b/packages/relic_io/test/static/get_handler_test.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:relic_core/relic_core.dart'; import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; diff --git a/packages/relic_io/test/static/symbolic_link_test.dart b/packages/relic_io/test/static/symbolic_link_test.dart index cb478b3e..ed710895 100644 --- a/packages/relic_io/test/static/symbolic_link_test.dart +++ b/packages/relic_io/test/static/symbolic_link_test.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:relic_core/relic_core.dart'; import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; From ea39d4af0b5169b69b213d785a464d84b0cdbd31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 15:22:48 +0100 Subject: [PATCH 11/14] build: Add melos coverage script and use it in CI --- .github/workflows/dart-tests.yaml | 7 +------ pubspec.yaml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dart-tests.yaml b/.github/workflows/dart-tests.yaml index 0362d2c2..c2e467c0 100644 --- a/.github/workflows/dart-tests.yaml +++ b/.github/workflows/dart-tests.yaml @@ -153,12 +153,7 @@ jobs: if: ${{ matrix.os == 'ubuntu-latest' && matrix.dart_sdk == '3.8.1' && matrix.deps == 'upgrade' }} run: | dart pub global activate coverage - for package in packages/relic_core packages/relic_io packages/relic; do - if [ -d "$package/test" ]; then - echo "Running coverage for $package" - (cd "$package" && dart pub global run coverage:test_with_coverage --branch-coverage --scope-output=relic --scope-output=relic_core --scope-output=relic_io -- --reporter=failures-only) - fi - done + melos run coverage --no-select - name: Upload Coverage (relic_core) uses: codecov/codecov-action@v5 diff --git a/pubspec.yaml b/pubspec.yaml index f87bc37e..828f3cb4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -29,6 +29,20 @@ melos: dirExists: test description: Run tests in all packages + coverage: + run: >- + dart pub global run coverage:test_with_coverage --branch-coverage + --scope-output=relic + --scope-output=relic_core + --scope-output=relic_io + exec: + concurrency: 1 # for saner output + packageFilters: + flutter: false + dependsOn: test + dirExists: test + description: Run tests with coverage collection for all packages + check: steps: - dart analyze --fatal-infos . From 87fc3544181f3530e1f6c8c623b82e79638686be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 16:07:20 +0100 Subject: [PATCH 12/14] refactor: Extract test utilities into separate test_utils package --- packages/relic/pubspec.yaml | 2 ++ .../relic/test/adapter/connection_info_test.dart | 3 +-- .../relic/test/headers/basic/host_header_test.dart | 2 +- packages/relic/test/headers/header_test.dart | 2 +- .../headers/typed/authorization_header_test.dart | 2 +- packages/relic/test/message/apply_headers_test.dart | 3 +-- packages/relic/test/path/path_param_test.dart | 3 +-- .../test/relic_server_connections_info_test.dart | 3 +-- packages/relic/test/relic_server_serve_test.dart | 1 + packages/relic/test/relic_server_test.dart | 2 +- packages/relic/test/router/router_methods_test.dart | 3 +-- packages/relic/test/util/test_util.dart | 3 --- packages/relic_core/pubspec.yaml | 2 ++ packages/relic_core/test/handler/cascade_test.dart | 2 +- packages/relic_core/test/handler/pipeline_test.dart | 2 +- packages/relic_core/test/message/message_test.dart | 3 +-- packages/relic_core/test/message/request_test.dart | 3 +-- packages/relic_core/test/message/response_test.dart | 3 +-- .../middleware_extra/create_middleware_test.dart | 3 +-- .../test/middleware_extra/log_middleware_test.dart | 3 +-- .../middleware_extra/routing_middleware_test.dart | 3 +-- packages/relic_core/test/query/query_param_test.dart | 3 +-- packages/relic_io/pubspec.yaml | 2 ++ packages/relic_io/test/static/content_type_test.dart | 3 +-- packages/relic_io/test/util/test_util.dart | 2 +- .../lib/src/test_utils_base.dart} | 0 packages/test_utils/lib/test_utils.dart | 1 + packages/test_utils/pubspec.yaml | 12 ++++++++++++ pubspec.yaml | 6 ++++-- 29 files changed, 44 insertions(+), 38 deletions(-) rename packages/{relic_core/lib/src/test/test_util.dart => test_utils/lib/src/test_utils_base.dart} (100%) create mode 100644 packages/test_utils/lib/test_utils.dart create mode 100644 packages/test_utils/pubspec.yaml diff --git a/packages/relic/pubspec.yaml b/packages/relic/pubspec.yaml index 81f0e295..abe07b0d 100644 --- a/packages/relic/pubspec.yaml +++ b/packages/relic/pubspec.yaml @@ -30,6 +30,8 @@ dev_dependencies: serverpod_lints: ^3.0.0 test: ^1.25.10 test_descriptor: ^2.0.1 + test_utils: + path: ../test_utils vm_service: ^15.0.0 web_socket: ^1.0.1 web_socket_channel: ^3.0.3 diff --git a/packages/relic/test/adapter/connection_info_test.dart b/packages/relic/test/adapter/connection_info_test.dart index bf2bc38f..4897a583 100644 --- a/packages/relic/test/adapter/connection_info_test.dart +++ b/packages/relic/test/adapter/connection_info_test.dart @@ -1,7 +1,6 @@ import 'package:relic/relic.dart'; import 'package:test/test.dart'; - -import '../util/test_util.dart'; +import 'package:test_utils/test_utils.dart'; void main() { group('SocketAddress', () { diff --git a/packages/relic/test/headers/basic/host_header_test.dart b/packages/relic/test/headers/basic/host_header_test.dart index 0f12eb26..ecec9755 100644 --- a/packages/relic/test/headers/basic/host_header_test.dart +++ b/packages/relic/test/headers/basic/host_header_test.dart @@ -3,8 +3,8 @@ library; import 'package:relic/relic.dart'; import 'package:test/test.dart'; +import 'package:test_utils/test_utils.dart'; -import '../../util/test_util.dart'; import '../headers_test_utils.dart'; /// Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host diff --git a/packages/relic/test/headers/header_test.dart b/packages/relic/test/headers/header_test.dart index 99bd2bb6..4218bc1a 100644 --- a/packages/relic/test/headers/header_test.dart +++ b/packages/relic/test/headers/header_test.dart @@ -1,7 +1,7 @@ import 'package:relic/relic.dart'; import 'package:test/test.dart'; +import 'package:test_utils/test_utils.dart'; -import '../util/test_util.dart'; import 'headers_test_utils.dart'; void main() { diff --git a/packages/relic/test/headers/typed/authorization_header_test.dart b/packages/relic/test/headers/typed/authorization_header_test.dart index d83fc2b0..fed6605c 100644 --- a/packages/relic/test/headers/typed/authorization_header_test.dart +++ b/packages/relic/test/headers/typed/authorization_header_test.dart @@ -2,8 +2,8 @@ import 'dart:convert'; import 'package:relic/relic.dart'; import 'package:test/test.dart'; +import 'package:test_utils/test_utils.dart'; -import '../../util/test_util.dart'; import '../docs/strict_validation_docs.dart'; import '../headers_test_utils.dart'; diff --git a/packages/relic/test/message/apply_headers_test.dart b/packages/relic/test/message/apply_headers_test.dart index 92797c99..cff5523f 100644 --- a/packages/relic/test/message/apply_headers_test.dart +++ b/packages/relic/test/message/apply_headers_test.dart @@ -7,8 +7,7 @@ import 'package:http_parser/http_parser.dart'; import 'package:mockito/mockito.dart'; import 'package:relic/relic.dart'; import 'package:test/test.dart'; - -import '../util/test_util.dart'; +import 'package:test_utils/test_utils.dart'; class HttpHeadersMock extends Mock implements HttpHeaders { final Map> _headers = {}; diff --git a/packages/relic/test/path/path_param_test.dart b/packages/relic/test/path/path_param_test.dart index 6c5a195a..9195e50a 100644 --- a/packages/relic/test/path/path_param_test.dart +++ b/packages/relic/test/path/path_param_test.dart @@ -1,7 +1,6 @@ import 'package:relic/relic.dart'; import 'package:test/test.dart'; - -import '../util/test_util.dart'; +import 'package:test_utils/test_utils.dart'; /// Tests for PathParam and PathParameters. /// diff --git a/packages/relic/test/relic_server_connections_info_test.dart b/packages/relic/test/relic_server_connections_info_test.dart index 51dc3c17..6701b6c8 100644 --- a/packages/relic/test/relic_server_connections_info_test.dart +++ b/packages/relic/test/relic_server_connections_info_test.dart @@ -4,8 +4,7 @@ import 'dart:io'; import 'package:http/http.dart' as http; import 'package:relic/relic.dart'; import 'package:test/test.dart'; - -import 'util/test_util.dart'; +import 'package:test_utils/test_utils.dart'; Handler _createDelayedHandler() { return (final req) async { diff --git a/packages/relic/test/relic_server_serve_test.dart b/packages/relic/test/relic_server_serve_test.dart index 1bea2bb9..b01e26eb 100644 --- a/packages/relic/test/relic_server_serve_test.dart +++ b/packages/relic/test/relic_server_serve_test.dart @@ -8,6 +8,7 @@ import 'package:http/http.dart' as http; import 'package:http_parser/http_parser.dart' as parser; import 'package:relic/relic.dart'; import 'package:test/test.dart'; +import 'package:test_utils/test_utils.dart'; import 'package:web_socket/web_socket.dart'; import 'headers/headers_test_utils.dart'; diff --git a/packages/relic/test/relic_server_test.dart b/packages/relic/test/relic_server_test.dart index 9a88a942..c3194af9 100644 --- a/packages/relic/test/relic_server_test.dart +++ b/packages/relic/test/relic_server_test.dart @@ -3,9 +3,9 @@ import 'dart:io'; import 'package:http/http.dart' as http; import 'package:relic/relic.dart'; import 'package:test/test.dart'; +import 'package:test_utils/test_utils.dart'; import 'headers/headers_test_utils.dart'; -import 'util/test_util.dart'; void main() { // Use concrete type to ensure extensions are applied diff --git a/packages/relic/test/router/router_methods_test.dart b/packages/relic/test/router/router_methods_test.dart index 4e5103ef..9380761b 100644 --- a/packages/relic/test/router/router_methods_test.dart +++ b/packages/relic/test/router/router_methods_test.dart @@ -1,7 +1,6 @@ import 'package:relic/relic.dart'; import 'package:test/test.dart'; - -import '../util/test_util.dart'; +import 'package:test_utils/test_utils.dart'; void main() { group('Router Method Specific Tests', () { diff --git a/packages/relic/test/util/test_util.dart b/packages/relic/test/util/test_util.dart index b6c78339..b68c5c9a 100644 --- a/packages/relic/test/util/test_util.dart +++ b/packages/relic/test/util/test_util.dart @@ -2,9 +2,6 @@ import 'dart:io'; import 'package:relic/relic.dart'; -// Re-export shared test utilities from relic_core -export 'package:relic_core/src/test/test_util.dart'; - Future testServe( final Handler handler, { final SecurityContext? context, diff --git a/packages/relic_core/pubspec.yaml b/packages/relic_core/pubspec.yaml index 0db6a926..fb03680b 100644 --- a/packages/relic_core/pubspec.yaml +++ b/packages/relic_core/pubspec.yaml @@ -34,3 +34,5 @@ dev_dependencies: mockito: ^5.4.4 serverpod_lints: ^3.0.0 test: ^1.25.10 + test_utils: + path: ../test_utils diff --git a/packages/relic_core/test/handler/cascade_test.dart b/packages/relic_core/test/handler/cascade_test.dart index 41dd5451..4a8aa453 100644 --- a/packages/relic_core/test/handler/cascade_test.dart +++ b/packages/relic_core/test/handler/cascade_test.dart @@ -1,5 +1,5 @@ import 'package:relic_core/relic_core.dart'; -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; import 'package:test/test.dart'; void main() { diff --git a/packages/relic_core/test/handler/pipeline_test.dart b/packages/relic_core/test/handler/pipeline_test.dart index ec584fc4..ac8fbcd5 100644 --- a/packages/relic_core/test/handler/pipeline_test.dart +++ b/packages/relic_core/test/handler/pipeline_test.dart @@ -1,5 +1,5 @@ import 'package:relic_core/relic_core.dart'; -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; import 'package:test/test.dart'; void main() { diff --git a/packages/relic_core/test/message/message_test.dart b/packages/relic_core/test/message/message_test.dart index b333f1d2..8cc22a28 100644 --- a/packages/relic_core/test/message/message_test.dart +++ b/packages/relic_core/test/message/message_test.dart @@ -4,8 +4,7 @@ import 'dart:typed_data'; import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; - -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; class _TestMessage extends Message { _TestMessage( diff --git a/packages/relic_core/test/message/request_test.dart b/packages/relic_core/test/message/request_test.dart index 5d2265d1..65e52a9f 100644 --- a/packages/relic_core/test/message/request_test.dart +++ b/packages/relic_core/test/message/request_test.dart @@ -4,8 +4,7 @@ import 'dart:typed_data'; import 'package:http_parser/http_parser.dart'; import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; - -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; Request _request({final Headers? headers, final Body? body}) { return RequestInternal.create( diff --git a/packages/relic_core/test/message/response_test.dart b/packages/relic_core/test/message/response_test.dart index aea5668f..9d42a7a0 100644 --- a/packages/relic_core/test/message/response_test.dart +++ b/packages/relic_core/test/message/response_test.dart @@ -5,8 +5,7 @@ import 'dart:typed_data'; import 'package:http_parser/http_parser.dart'; import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; - -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; void main() { group('Given a response with a String body', () { diff --git a/packages/relic_core/test/middleware_extra/create_middleware_test.dart b/packages/relic_core/test/middleware_extra/create_middleware_test.dart index 45269438..83b1981f 100644 --- a/packages/relic_core/test/middleware_extra/create_middleware_test.dart +++ b/packages/relic_core/test/middleware_extra/create_middleware_test.dart @@ -4,8 +4,7 @@ import 'dart:async'; import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; - -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; void main() { test( diff --git a/packages/relic_core/test/middleware_extra/log_middleware_test.dart b/packages/relic_core/test/middleware_extra/log_middleware_test.dart index 4d30297e..3347b695 100644 --- a/packages/relic_core/test/middleware_extra/log_middleware_test.dart +++ b/packages/relic_core/test/middleware_extra/log_middleware_test.dart @@ -1,7 +1,6 @@ import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; - -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; void main() { late bool gotLog; diff --git a/packages/relic_core/test/middleware_extra/routing_middleware_test.dart b/packages/relic_core/test/middleware_extra/routing_middleware_test.dart index 499ab8bc..d39c10ef 100644 --- a/packages/relic_core/test/middleware_extra/routing_middleware_test.dart +++ b/packages/relic_core/test/middleware_extra/routing_middleware_test.dart @@ -1,7 +1,6 @@ import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; - -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; Request _request( final String path, { diff --git a/packages/relic_core/test/query/query_param_test.dart b/packages/relic_core/test/query/query_param_test.dart index 0384c21a..b64965c2 100644 --- a/packages/relic_core/test/query/query_param_test.dart +++ b/packages/relic_core/test/query/query_param_test.dart @@ -1,7 +1,6 @@ import 'package:relic_core/relic_core.dart'; import 'package:test/test.dart'; - -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; /// Tests for QueryParam and QueryParameters. /// diff --git a/packages/relic_io/pubspec.yaml b/packages/relic_io/pubspec.yaml index 64d290a8..2e6ec131 100644 --- a/packages/relic_io/pubspec.yaml +++ b/packages/relic_io/pubspec.yaml @@ -28,4 +28,6 @@ dev_dependencies: serverpod_lints: ^3.0.0 test: ^1.25.10 test_descriptor: ^2.0.1 + test_utils: + path: ../test_utils web_socket_channel: ^3.0.3 diff --git a/packages/relic_io/test/static/content_type_test.dart b/packages/relic_io/test/static/content_type_test.dart index 11effb15..f52ef8d9 100644 --- a/packages/relic_io/test/static/content_type_test.dart +++ b/packages/relic_io/test/static/content_type_test.dart @@ -5,8 +5,7 @@ import 'package:relic_core/relic_core.dart'; import 'package:relic_io/relic_io.dart'; import 'package:test/test.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; - -import 'package:relic_core/src/test/test_util.dart'; +import 'package:test_utils/test_utils.dart'; import 'test_util.dart'; // Provides the makeRequest helper diff --git a/packages/relic_io/test/util/test_util.dart b/packages/relic_io/test/util/test_util.dart index 31866084..dd1270e2 100644 --- a/packages/relic_io/test/util/test_util.dart +++ b/packages/relic_io/test/util/test_util.dart @@ -4,7 +4,7 @@ import 'package:relic_core/relic_core.dart'; import 'package:relic_io/relic_io.dart'; // Re-export shared test utilities from relic_core -export 'package:relic_core/src/test/test_util.dart'; +export '../util/test_util.dart'; /// Extension methods for RelicServer extension RelicServerTestEx on RelicServer { diff --git a/packages/relic_core/lib/src/test/test_util.dart b/packages/test_utils/lib/src/test_utils_base.dart similarity index 100% rename from packages/relic_core/lib/src/test/test_util.dart rename to packages/test_utils/lib/src/test_utils_base.dart diff --git a/packages/test_utils/lib/test_utils.dart b/packages/test_utils/lib/test_utils.dart new file mode 100644 index 00000000..e558c765 --- /dev/null +++ b/packages/test_utils/lib/test_utils.dart @@ -0,0 +1 @@ +export 'src/test_utils_base.dart'; diff --git a/packages/test_utils/pubspec.yaml b/packages/test_utils/pubspec.yaml new file mode 100644 index 00000000..769a9cb5 --- /dev/null +++ b/packages/test_utils/pubspec.yaml @@ -0,0 +1,12 @@ +name: test_utils +description: Test utils for Relic packages +publish_to: none + +resolution: workspace + +environment: + sdk: ^3.8.0 + +dev_dependencies: + lints: ^6.0.0 + test: ^1.25.6 diff --git a/pubspec.yaml b/pubspec.yaml index 828f3cb4..f96d2dfc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,11 +5,13 @@ environment: sdk: ^3.8.0 workspace: - - packages/benchmark - - packages/examples - packages/relic - packages/relic_core - packages/relic_io + # Internal support packages (not published) + - packages/benchmark + - packages/examples + - packages/test_utils dev_dependencies: melos: ^7.4.0-dev.0 # Special support for Dart 3.8 (see https://github.com/invertase/melos/pull/979) From 310bbe6f6c825784bbf45a9fd8de57ac37470a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 16:40:49 +0100 Subject: [PATCH 13/14] chore: Tigthen contraints --- packages/relic/pubspec.yaml | 4 ++-- packages/relic_core/pubspec.yaml | 4 ++-- packages/relic_io/pubspec.yaml | 4 ++-- packages/test_utils/pubspec.yaml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/relic/pubspec.yaml b/packages/relic/pubspec.yaml index abe07b0d..dad2ca9e 100644 --- a/packages/relic/pubspec.yaml +++ b/packages/relic/pubspec.yaml @@ -22,9 +22,9 @@ dev_dependencies: async: ^2.13.0 http: ^1.5.0 http_parser: ^4.0.2 - lints: ">=5.0.0 <7.0.0" + lints: ^6.0.0 meta: ^1.17.0 - mime: ">=1.0.6 <3.0.0" + mime: ^2.0.0 mockito: ^5.4.4 path: ^1.8.3 serverpod_lints: ^3.0.0 diff --git a/packages/relic_core/pubspec.yaml b/packages/relic_core/pubspec.yaml index fb03680b..ca0db609 100644 --- a/packages/relic_core/pubspec.yaml +++ b/packages/relic_core/pubspec.yaml @@ -21,7 +21,7 @@ dependencies: crypto: ^3.0.0 http_parser: ^4.0.2 meta: ^1.17.0 - mime: ">=1.0.6 <3.0.0" + mime: ^2.0.0 path: ^1.8.3 stack_trace: ^1.10.0 stream_channel: ^2.1.1 @@ -30,7 +30,7 @@ dependencies: web_socket_channel: ^3.0.3 dev_dependencies: - lints: ">=5.0.0 <7.0.0" + lints: ^6.0.0 mockito: ^5.4.4 serverpod_lints: ^3.0.0 test: ^1.25.10 diff --git a/packages/relic_io/pubspec.yaml b/packages/relic_io/pubspec.yaml index 2e6ec131..37ec6b55 100644 --- a/packages/relic_io/pubspec.yaml +++ b/packages/relic_io/pubspec.yaml @@ -16,7 +16,7 @@ resolution: workspace dependencies: crypto: ^3.0.0 - mime: ">=1.0.6 <3.0.0" + mime: ^2.0.0 path: ^1.8.3 relic_core: ^0.14.0 stack_trace: ^1.10.0 @@ -24,7 +24,7 @@ dependencies: web_socket: ^1.0.1 dev_dependencies: - lints: ">=5.0.0 <7.0.0" + lints: ^6.0.0 serverpod_lints: ^3.0.0 test: ^1.25.10 test_descriptor: ^2.0.1 diff --git a/packages/test_utils/pubspec.yaml b/packages/test_utils/pubspec.yaml index 769a9cb5..637417a7 100644 --- a/packages/test_utils/pubspec.yaml +++ b/packages/test_utils/pubspec.yaml @@ -9,4 +9,4 @@ environment: dev_dependencies: lints: ^6.0.0 - test: ^1.25.6 + test: ^1.25.10 From 50ae39f01babe4014dc1705fba2fa47fd3271bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Overg=C3=A5rd=20Nielsen?= Date: Fri, 23 Jan 2026 16:43:59 +0100 Subject: [PATCH 14/14] ci: Rename CI yaml file --- .github/workflows/{dart-tests.yaml => ci.yaml} | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename .github/workflows/{dart-tests.yaml => ci.yaml} (99%) diff --git a/.github/workflows/dart-tests.yaml b/.github/workflows/ci.yaml similarity index 99% rename from .github/workflows/dart-tests.yaml rename to .github/workflows/ci.yaml index c2e467c0..7c1fb06d 100644 --- a/.github/workflows/dart-tests.yaml +++ b/.github/workflows/ci.yaml @@ -16,10 +16,9 @@ env: jobs: analyze: name: Analyze - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest strategy: matrix: - os: [ubuntu-latest] dart_sdk: # ${{ env.LOWEST_DART_SDK }} won't work at job level as env context not available for strategy ¯\_(ツ)_/¯ # (see https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#context-availability)