oto/test/oto_command_catalog_test.dart

97 lines
2.9 KiB
Dart

import 'dart:io';
import 'package:oto/oto/commands/command.dart';
import 'package:oto/oto/commands/command_registry.dart';
import 'package:test/test.dart';
void main() {
setUpAll(() {
registerAllCommands();
});
test('all command types are registered', () {
final registered = Command.registeredTypes.toSet();
final missing =
CommandType.values.where((t) => !registered.contains(t)).toList();
expect(
missing,
isEmpty,
reason:
'CommandType values without a Command.register() call: $missing. '
'Add registration in the relevant register*() function and call it from registerAllCommands().',
);
});
test('all registered commands expose specs', () {
final specs = Command.specs;
final missing = Command.registeredTypes
.where((t) => !specs.containsKey(t))
.toList();
expect(
missing,
isEmpty,
reason:
'Registered commands without a CommandSpec: $missing. '
'Pass spec: CommandSpec(...) to Command.register().',
);
});
test('spec sample paths exist when provided', () {
final missing = <String>[];
for (final entry in Command.specs.entries) {
final sample = entry.value.samplePath;
if (sample == null) continue;
if (!File(sample).existsSync()) {
missing.add('${entry.key} -> $sample');
}
}
expect(
missing,
isEmpty,
reason:
'CommandSpec.samplePath must point to an existing file. '
'Missing: $missing',
);
});
test('spec sample paths contain the registered command', () {
final mismatches = <String>[];
for (final entry in Command.specs.entries) {
final sample = entry.value.samplePath;
if (sample == null) continue;
final file = File(sample);
if (!file.existsSync()) continue;
final commandName = entry.key.name;
final pattern =
RegExp(r'^\s*-\s*command:\s*' + RegExp.escape(commandName) + r'\s*$');
final hasCommand = file.readAsLinesSync().any((line) {
final trimmed = line.trimLeft();
if (trimmed.startsWith('#')) return false;
return pattern.hasMatch(line);
});
if (!hasCommand) {
mismatches.add('${entry.key} -> $sample');
}
}
expect(
mismatches,
isEmpty,
reason:
'CommandSpec.samplePath must reference a sample that actually '
'includes a non-commented `- command: <Type>` line. Mismatches: '
'$mismatches',
);
});
test('spec category and dataModel are non-empty', () {
final bad = <String>[];
for (final entry in Command.specs.entries) {
final spec = entry.value;
if (spec.category.isEmpty || spec.dataModel.isEmpty) {
bad.add('${entry.key}');
}
}
expect(bad, isEmpty,
reason: 'CommandSpec.category and dataModel must be non-empty: $bad');
});
}