Files
clide/test/files/ignore_test.dart
T
jpmschweitzerandClaude Opus 4.7 72a3dce4a3
test / unit + widget + golden + a11y (push) Failing after 32s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 1m2s
test sweep: foundational systems — files / ipc errno / panes (T-91)
Three small foundational test additions:

- test/files/watcher_test.dart (new, 8 tests): FileChangeKind
  fromEvent across every FileSystemEvent.type + wire getter,
  FileChange.toJson, FileWatcher end-to-end (created event,
  ignored-path filtering, idempotent start, stop teardown).
- ignore_test: trailing /**, bare **, ? glob-pattern branches in
  the regex compiler.
- path_safety_test: PathOutsideRoot.toString embeds the three
  fields.
- ipc/errno_mapping_test: ENOTDIR / ENOMEM / EAGAIN branches in
  errnoToIpcError that weren't previously hit.
- panes/registry_test: RecordingEventSink.ofSubsystem filter.

Coverage: src/files/watcher.dart 10/36 -> ~ all; ignore.dart +
path_safety.dart residuals closed; ipc/errno_mapping.dart 3 added
branches; panes/event_sink.dart 100%.

Total coverage 90.53% -> 90.99%.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 10:19:07 +02:00

99 lines
3.6 KiB
Dart

import 'package:clide/clide.dart';
import 'package:test/test.dart';
void main() {
group('IgnorePattern.parse', () {
test('blank + comment lines return null', () {
expect(IgnorePattern.parse(''), isNull);
expect(IgnorePattern.parse(' '), isNull);
expect(IgnorePattern.parse('# comment'), isNull);
});
test('directory-only detected', () {
final p = IgnorePattern.parse('build/');
expect(p, isNotNull);
expect(p!.directoryOnly, isTrue);
});
test('negation detected', () {
final p = IgnorePattern.parse('!keep.txt');
expect(p!.negated, isTrue);
});
test('anchored detected', () {
final p = IgnorePattern.parse('/root-only.txt');
expect(p!.anchored, isTrue);
});
});
group('IgnoreSet', () {
test('matches unanchored name at any depth', () {
final s = IgnoreSet.parse(const ['node_modules/\n*.log\n']);
expect(s.isIgnored('node_modules', isDirectory: true), isTrue);
expect(s.isIgnored('a/b/node_modules', isDirectory: true), isTrue);
expect(s.isIgnored('a.log', isDirectory: false), isTrue);
expect(s.isIgnored('deep/nested/foo.log', isDirectory: false), isTrue);
});
test('directory-only pattern does not match files', () {
final s = IgnoreSet.parse(const ['cache/\n']);
expect(s.isIgnored('cache', isDirectory: true), isTrue);
expect(s.isIgnored('cache', isDirectory: false), isFalse);
});
test('anchored pattern stays at the root', () {
final s = IgnoreSet.parse(const ['/config.yaml\n']);
expect(s.isIgnored('config.yaml', isDirectory: false), isTrue);
expect(s.isIgnored('app/config.yaml', isDirectory: false), isFalse);
});
test('later pattern wins — negation unignores', () {
final s = IgnoreSet.parse(const ['*.log\n!keep.log\n']);
expect(s.isIgnored('a.log', isDirectory: false), isTrue);
expect(s.isIgnored('keep.log', isDirectory: false), isFalse);
});
test('layered sets preserve order', () {
final s = IgnoreSet.parse(const ['*.tmp\n', '!important.tmp\n']);
expect(s.isIgnored('x.tmp', isDirectory: false), isTrue);
expect(s.isIgnored('important.tmp', isDirectory: false), isFalse);
});
test('built-in set hides clide-owned dirs', () {
final s = IgnoreSet.builtin();
for (final d in const ['.git', '.pql', '.clide', '.dart_tool', 'build', 'node_modules']) {
expect(s.isIgnored(d, isDirectory: true), isTrue, reason: d);
}
expect(s.isIgnored('lib', isDirectory: true), isFalse);
});
test('** crosses directory boundaries', () {
final s = IgnoreSet.parse(const ['docs/**/*.draft.md\n']);
expect(
s.isIgnored('docs/deep/nested/a.draft.md', isDirectory: false),
isTrue,
);
expect(s.isIgnored('docs/a.draft.md', isDirectory: false), isTrue);
expect(s.isIgnored('other/a.draft.md', isDirectory: false), isFalse);
});
test('trailing /** matches every descendant', () {
final s = IgnoreSet.parse(['build/**']);
expect(s.isIgnored('build/a/b/c.txt', isDirectory: false), isTrue);
expect(s.isIgnored('src/a.txt', isDirectory: false), isFalse);
});
test('bare ** (not adjacent to /) matches across path separators', () {
final s = IgnoreSet.parse(['a**z']);
expect(s.isIgnored('axyz', isDirectory: false), isTrue);
expect(s.isIgnored('amiddlez', isDirectory: false), isTrue);
});
test('? matches exactly one non-slash character', () {
final s = IgnoreSet.parse(['a?c']);
expect(s.isIgnored('abc', isDirectory: false), isTrue);
expect(s.isIgnored('a/c', isDirectory: false), isFalse);
});
});
}