97 lines
2.9 KiB
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');
|
|
});
|
|
}
|