Two test additions toward finishing src/daemon/: - test/daemon/dispatcher_test.dart (6 tests): the entire DaemonDispatcher surface — ping + version default handlers, unknown-command not-found error, register routing, isEmpty before/after registration, clear preserving ping + version. - test/daemon/git_commands_test.dart extended (14 new tests): the git.* commands the existing suite didn't reach — git.diff with paths, git.stage-hunk + git.unstage-hunk (happy + missing-patch + bad-patch GitException), git.branches, git.checkout (happy + missing + unknown), git.log with count, git.push + git.pull both with and without a local bare remote, git.stage accepting a String single-path arg via _pathList. Coverage: src/daemon/dispatcher.dart 8/22 -> 22/22 (100%); src/daemon/git_commands.dart 73/146 -> 122/146 (84%). The remaining 24 lines in git_commands are mid-call GitException catch branches that need the git client to fail after the dispatcher accepted the request. Total coverage 77.05% -> 77.92%. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
70 lines
2.3 KiB
Dart
70 lines
2.3 KiB
Dart
/// Unit tests for the daemon's command dispatcher.
|
|
library;
|
|
|
|
import 'package:clide/clide.dart';
|
|
import 'package:clide/src/daemon/dispatcher.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
IpcRequest _req(String cmd, {String id = '1', Map<String, Object?> args = const {}}) {
|
|
return IpcRequest(id: id, cmd: cmd, args: args);
|
|
}
|
|
|
|
void main() {
|
|
group('DaemonDispatcher', () {
|
|
test('ping is registered by default and returns pong + version', () async {
|
|
final d = DaemonDispatcher();
|
|
final r = await d.dispatch(_req('ping'));
|
|
expect(r.ok, isTrue);
|
|
expect(r.data['pong'], isTrue);
|
|
expect(r.data['version'], isNotNull);
|
|
expect(r.data['ts'], isA<String>());
|
|
});
|
|
|
|
test('version returns the bundled version string', () async {
|
|
final d = DaemonDispatcher();
|
|
final r = await d.dispatch(_req('version'));
|
|
expect(r.ok, isTrue);
|
|
expect(r.data['version'], clideVersion);
|
|
});
|
|
|
|
test('dispatching an unknown command produces a not-found error', () async {
|
|
final d = DaemonDispatcher();
|
|
final r = await d.dispatch(_req('nonsense'));
|
|
expect(r.ok, isFalse);
|
|
expect(r.error?.kind, IpcErrorKind.notFound);
|
|
expect(r.error?.message, contains('unknown command'));
|
|
});
|
|
|
|
test('register routes a new handler', () async {
|
|
final d = DaemonDispatcher();
|
|
d.register('echo', (req) async {
|
|
return IpcResponse.ok(id: req.id, data: {'echo': req.args['text']});
|
|
});
|
|
final r = await d.dispatch(_req('echo', args: {'text': 'hi'}));
|
|
expect(r.ok, isTrue);
|
|
expect(r.data['echo'], 'hi');
|
|
});
|
|
|
|
test('isEmpty is true for a fresh dispatcher (ping + version only)', () {
|
|
final d = DaemonDispatcher();
|
|
expect(d.isEmpty, isTrue);
|
|
d.register('something', (req) async => IpcResponse.ok(id: req.id, data: const {}));
|
|
expect(d.isEmpty, isFalse);
|
|
});
|
|
|
|
test('clear removes user handlers but keeps ping + version', () async {
|
|
final d = DaemonDispatcher();
|
|
d.register('extra', (req) async => IpcResponse.ok(id: req.id, data: const {}));
|
|
expect(d.isEmpty, isFalse);
|
|
d.clear();
|
|
expect(d.isEmpty, isTrue);
|
|
// ping still works
|
|
final r = await d.dispatch(_req('ping'));
|
|
expect(r.ok, isTrue);
|
|
// 'extra' is gone
|
|
final r2 = await d.dispatch(_req('extra'));
|
|
expect(r2.ok, isFalse);
|
|
});
|
|
});
|
|
}
|