mirror of
https://github.com/kuhyx/todo-app.git
synced 2026-11-11 20:53:59 +01:00
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file-length / file length <= 250 lines (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Four optional note fields (repo, done_check, by, evidence) in the crdt_sync record, written only when set, so editing a plain idea stays wire-identical to v3 (note_repository_sync_compat_test). The log is schemaless: no stored schema version; the legacy sqlite reader stays at v3. NoteFilter gains a sources facet (ideas / every repo task / one repo); search also matches the repo. The notes list shows only open ideas by default (no badge); the filter sheet adds Ideas, Repo tasks and one chip per repo when repo tasks exist. The per-note sheet shows the task fields read-only. BACKLOG.md markers carry the new attributes, entity-escaped. CLI: --repo --done-check --by on add, --close <id> --evidence (refused without), --list [--repo] [--status], --search, and every id flag takes a unique 8-character prefix. --list prints id8, status, priority, repo, title. install_hooks.sh: the wrapper finds pre-commit's generated hook next to itself, so commits from a git worktree (where .git is a file) work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
2.0 KiB
Dart
77 lines
2.0 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:todo/cli/note_lookup.dart';
|
|
import 'package:todo/data/note.dart';
|
|
|
|
import 'cli_harness.dart';
|
|
|
|
void main() {
|
|
final notes = [
|
|
fixtureNote('abcdefgh', 'Exact'),
|
|
fixtureNote('abcdefgh-2', 'Longer'),
|
|
fixtureNote('12345678-a', 'First\nbody'),
|
|
fixtureNote('12345678-b', 'Second'),
|
|
fixtureNote('99999999-z', 'Only', repo: 'kuhyx/todo'),
|
|
];
|
|
|
|
test('an exact id wins over a longer id sharing it as prefix', () {
|
|
expect(findNote(notes, 'abcdefgh').text, 'Exact');
|
|
});
|
|
|
|
test('a unique prefix of at least 8 characters resolves', () {
|
|
expect(findNote(notes, '99999999').text, 'Only');
|
|
expect(findNote(notes, '99999999-').text, 'Only');
|
|
});
|
|
|
|
test('an ambiguous prefix names every candidate', () {
|
|
expect(
|
|
() => findNote(notes, '12345678'),
|
|
throwsA(
|
|
isA<NoteLookupError>().having(
|
|
(e) => e.toString(),
|
|
'message',
|
|
allOf([
|
|
contains('2 notes'),
|
|
contains('12345678-a First'),
|
|
contains('12345678-b Second'),
|
|
]),
|
|
),
|
|
),
|
|
);
|
|
});
|
|
|
|
test('an unknown id is not found', () {
|
|
expect(
|
|
() => findNote(notes, 'ffffffff'),
|
|
throwsA(
|
|
isA<NoteLookupError>().having(
|
|
(e) => e.message,
|
|
'message',
|
|
'no live note with id ffffffff',
|
|
),
|
|
),
|
|
);
|
|
});
|
|
|
|
test('a short non-exact id is not prefix-matched', () {
|
|
expect(
|
|
() => findNote(notes, 'abc'),
|
|
throwsA(
|
|
isA<NoteLookupError>().having(
|
|
(e) => e.message,
|
|
'message',
|
|
allOf(contains('no live note with id abc'), contains('8 characters')),
|
|
),
|
|
),
|
|
);
|
|
});
|
|
|
|
test('listLine: 8-char id, status, priority, repo, title', () {
|
|
expect(
|
|
listLine(notes[2].copyWith(status: Status.inProgress)),
|
|
'12345678\tin_progress\tmedium\t-\tFirst',
|
|
);
|
|
expect(listLine(notes[4]), '99999999\ttodo\tmedium\tkuhyx/todo\tOnly');
|
|
expect(listLine(fixtureNote('abc', 'Short')), startsWith('abc\t'));
|
|
});
|
|
}
|