No file has Compose's default name any more, so .env's COMPOSE_FILE is always set, naming compose.learn.yaml first (.env.example sets it). compose.yaml stays as a link to compose.learn.yaml for the one deploy that switches learn.halkyon.eu's .env over: the deploy's merge runs with the COMPOSE_FILE from before. A later commit removes it. BREAKING CHANGE: an instance's deploy/.env must set COMPOSE_FILE, starting with compose.learn.yaml, before the link goes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
184 lines
6.5 KiB
Dart
184 lines
6.5 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:test/test.dart';
|
|
|
|
import '../tool/src/check_files.dart';
|
|
|
|
void main() {
|
|
test("our own Dart files are formatted: the apps', the shared packages', the "
|
|
"tools'", () {
|
|
for (final path in [
|
|
'apps/learn/halkyon_learn_flutter/lib/main.dart',
|
|
'apps/learn/halkyon_learn_server/lib/server.dart',
|
|
'apps/learn/halkyon_learn_server/test/integration/auth/account_test.dart',
|
|
'apps/todo/halkyon_todo_flutter/lib/main.dart',
|
|
'packages/halkyon_app/lib/halkyon_app.dart',
|
|
'packages/halkyon_base_server/lib/src/auth/email.dart',
|
|
// SRP's client half, written by hand beside the module's generated
|
|
// client, and its tests.
|
|
'packages/halkyon_base_client/lib/srp.dart',
|
|
'packages/halkyon_base_client/lib/src/srp/srp_client.dart',
|
|
'packages/halkyon_base_client/test/srp_client_test.dart',
|
|
'packages/halkyon_keys/lib/src/account_keys.dart',
|
|
'tool/check.dart',
|
|
]) {
|
|
expect(isOwnDartFile(path), isTrue, reason: path);
|
|
}
|
|
});
|
|
|
|
test('what a generator writes is left as it wrote it', () {
|
|
for (final path in [
|
|
// The client packages, Serverpod's from top to bottom, but for the
|
|
// module's SRP.
|
|
'apps/learn/halkyon_learn_client/lib/src/protocol/client.dart',
|
|
'apps/todo/halkyon_todo_client/lib/halkyon_todo_client.dart',
|
|
'packages/halkyon_base_client/lib/src/protocol/protocol.dart',
|
|
'packages/halkyon_base_client/lib/halkyon_base_client.dart',
|
|
// A server's generated sources and test tools.
|
|
'apps/learn/halkyon_learn_server/lib/src/generated/protocol.dart',
|
|
'packages/halkyon_base_server/lib/src/generated/endpoints.dart',
|
|
'apps/learn/halkyon_learn_server/test/integration/test_tools/serverpod_test_tools.dart',
|
|
// gen-l10n's localizations, the app's and the shared packages'.
|
|
'apps/learn/halkyon_learn_flutter/lib/l10n/app_localizations.dart',
|
|
'apps/learn/halkyon_learn_flutter/lib/l10n/app_localizations_de.dart',
|
|
'packages/halkyon_ui/lib/l10n/halkyon_ui_localizations_en.dart',
|
|
'packages/halkyon_app/lib/l10n/halkyon_app_localizations.dart',
|
|
]) {
|
|
expect(isOwnDartFile(path), isFalse, reason: path);
|
|
}
|
|
});
|
|
|
|
test('the files of other languages are no Dart files', () {
|
|
expect(isOwnDartFile('tool/app_icons.py'), isFalse);
|
|
expect(
|
|
isOwnDartFile('packages/halkyon_app/lib/l10n/halkyon_app_en.arb'),
|
|
isFalse,
|
|
);
|
|
});
|
|
|
|
group('what changed since a commit', () {
|
|
const packages = {
|
|
'halkyon_app': 'packages/halkyon_app',
|
|
'halkyon_ui': 'packages/halkyon_ui',
|
|
'halkyon_ui_example': 'packages/halkyon_ui/example',
|
|
'halkyon_learn_flutter': 'apps/learn/halkyon_learn_flutter',
|
|
};
|
|
|
|
test('touches the packages its files are in, the innermost one', () {
|
|
expect(
|
|
packagesTouched([
|
|
'packages/halkyon_app/lib/src/app/app_frame.dart',
|
|
'packages/halkyon_app/test/app/instance_gate_test.dart',
|
|
'packages/halkyon_ui/example/lib/main.dart',
|
|
], packages),
|
|
['halkyon_app', 'halkyon_ui_example'],
|
|
);
|
|
});
|
|
|
|
test("files of no package (docs, tools, deploy) touch none: the tools' "
|
|
'own tests run anyway', () {
|
|
expect(
|
|
packagesTouched([
|
|
'docs/adr/0015-one-repository.md',
|
|
'tool/check.dart',
|
|
'deploy/compose.learn.yaml',
|
|
], packages),
|
|
isEmpty,
|
|
);
|
|
});
|
|
|
|
test("the root's pubspec, lock or lint rules touch every package", () {
|
|
for (final path in [
|
|
'pubspec.yaml',
|
|
'pubspec.lock',
|
|
'analysis_options.yaml',
|
|
]) {
|
|
expect(packagesTouched([path], packages), isNull, reason: path);
|
|
}
|
|
});
|
|
});
|
|
|
|
test("Melos' filters take every package, or those touched and what "
|
|
'depends on them', () {
|
|
expect(melosFilters(), isEmpty);
|
|
expect(melosFilters(touched: ['halkyon_app', 'halkyon_ui']), [
|
|
'--scope=halkyon_app',
|
|
'--scope=halkyon_ui',
|
|
'--include-dependents',
|
|
]);
|
|
});
|
|
|
|
group('the generated code', () {
|
|
test("the CLI's version is the one the lock holds Serverpod at", () {
|
|
const lock = '''
|
|
packages:
|
|
serverpod:
|
|
dependency: transitive
|
|
description:
|
|
name: serverpod
|
|
sha256: "0"
|
|
url: "https://pub.dev"
|
|
source: hosted
|
|
version: "4.0.4"
|
|
sdks:
|
|
dart: ">=3.13.0 <4.0.0"
|
|
''';
|
|
expect(lockedVersion(lock, 'serverpod'), '4.0.4');
|
|
expect(lockedVersion(lock, 'serverpod_cli'), isNull);
|
|
expect(
|
|
serverpodCliVersion('Some notice\nServerpod version: 4.0.4\n'),
|
|
'4.0.4',
|
|
);
|
|
expect(serverpodCliVersion('serverpod: command not found'), isNull);
|
|
});
|
|
|
|
test('CI installs the CLI at the version the lock holds Serverpod at, so '
|
|
"check.dart's comparison holds there too", () {
|
|
final pinned = RegExp(
|
|
r'^\s*SERVERPOD_VERSION: (\S+)$',
|
|
multiLine: true,
|
|
).firstMatch(File('.forgejo/workflows/ci.yaml').readAsStringSync());
|
|
expect(
|
|
pinned?.group(1),
|
|
lockedVersion(File('pubspec.lock').readAsStringSync(), 'serverpod'),
|
|
);
|
|
});
|
|
|
|
test('differs where the generator changed, removed or added a file', () {
|
|
final before = {
|
|
'apps/learn/halkyon_learn_server/lib/src/studyset/studyset.spy.yaml':
|
|
'a',
|
|
'apps/learn/halkyon_learn_server/lib/src/generated/protocol.dart': 'b',
|
|
};
|
|
final after = {
|
|
...before,
|
|
// Written anew from the changed model.
|
|
'apps/learn/halkyon_learn_server/lib/src/generated/protocol.dart': 'c',
|
|
// A model's class no longer generated.
|
|
'apps/learn/halkyon_learn_client/lib/src/protocol/gone.dart':
|
|
absentFile,
|
|
// A new model's class.
|
|
'apps/learn/halkyon_learn_client/lib/src/protocol/new.dart': 'd',
|
|
};
|
|
expect(differingFiles(before, after), [
|
|
'apps/learn/halkyon_learn_client/lib/src/protocol/gone.dart',
|
|
'apps/learn/halkyon_learn_client/lib/src/protocol/new.dart',
|
|
'apps/learn/halkyon_learn_server/lib/src/generated/protocol.dart',
|
|
]);
|
|
});
|
|
|
|
test('a file written back as committed differs from its change before, '
|
|
'and changes the generator left alone count for nothing', () {
|
|
expect(
|
|
differingFiles(
|
|
{
|
|
'apps/todo/halkyon_todo_client/lib/src/protocol/client.dart': 'a',
|
|
'apps/todo/halkyon_todo_server/lib/src/greeting.dart': 'b',
|
|
},
|
|
{'apps/todo/halkyon_todo_server/lib/src/greeting.dart': 'b'},
|
|
),
|
|
['apps/todo/halkyon_todo_client/lib/src/protocol/client.dart'],
|
|
);
|
|
});
|
|
});
|
|
}
|