@@ -55,6 +55,27 @@ function _test_default_name_generation
5555 _assert_eq " $HOME /work/my-app.v2" " $location " ' default bookmark name is sanitized basename'
5656end
5757
58+ function _test_save_requires_force_to_overwrite
59+ _prepare_dir " $HOME /work/overwrite-one"
60+ save_bookmark overwrite_target
61+ _assert_status 0 $status ' first save for overwrite_target succeeds'
62+
63+ _prepare_dir " $HOME /work/overwrite-two"
64+ save_bookmark overwrite_target > /dev/null 2> /dev/null
65+ _assert_status 1 $status ' save_bookmark rejects overwrite without --force'
66+
67+ set -l location (print_bookmark overwrite_target)
68+ _assert_status 0 $status ' existing bookmark remains after rejected overwrite'
69+ _assert_eq " $HOME /work/overwrite-one" " $location " ' rejected overwrite keeps original path'
70+
71+ save_bookmark --force overwrite_target
72+ _assert_status 0 $status ' save_bookmark --force overwrites existing bookmark'
73+
74+ set -l updated_location (print_bookmark overwrite_target)
75+ _assert_status 0 $status ' forced overwrite is readable'
76+ _assert_eq " $HOME /work/overwrite-two" " $updated_location " ' forced overwrite updates bookmark path'
77+ end
78+
5879function _test_go_to_and_delete
5980 _prepare_dir " $HOME /projects/alpha"
6081 save_bookmark alpha
@@ -72,6 +93,36 @@ function _test_go_to_and_delete
7293 _assert_status 1 $status ' deleted bookmark no longer resolves'
7394end
7495
96+ function _test_rename_bookmark
97+ _prepare_dir " $HOME /projects/rename-path"
98+ save_bookmark rename_old
99+ _assert_status 0 $status ' save bookmark for rename succeeds'
100+
101+ rename_bookmark rename_old rename_new
102+ _assert_status 0 $status ' rename_bookmark succeeds'
103+
104+ print_bookmark rename_old > /dev/null 2> /dev/null
105+ _assert_status 1 $status ' old bookmark name is removed after rename'
106+
107+ set -l new_location (print_bookmark rename_new)
108+ _assert_status 0 $status ' new bookmark name resolves after rename'
109+ _assert_eq " $HOME /projects/rename-path" " $new_location " ' rename_bookmark preserves original path'
110+ end
111+
112+ function _test_bookmark_exists
113+ _prepare_dir " $HOME /projects/exists-path"
114+ save_bookmark exists_target
115+ _assert_status 0 $status ' save bookmark for exists test succeeds'
116+
117+ set -l existing_output (bookmark_exists exists_target)
118+ _assert_status 0 $status ' bookmark_exists returns success for existing bookmark'
119+ _assert_eq ' ' " $existing_output " ' bookmark_exists does not print output for existing bookmark'
120+
121+ set -l missing_output (bookmark_exists missing_target)
122+ _assert_status 1 $status ' bookmark_exists returns failure for missing bookmark'
123+ _assert_eq ' ' " $missing_output " ' bookmark_exists does not print output for missing bookmark'
124+ end
125+
75126function _test_legacy_file_compatibility
76127 command mkdir -p -- " $HOME /legacy/location"
77128 printf ' export DIR_legacy="\\ $HOME /legacy/location"\ n' > " $SDIRS "
@@ -93,6 +144,91 @@ function _test_invalid_name_rejected
93144 _assert_status 1 $status ' invalid bookmark names are rejected'
94145end
95146
147+ function _test_list_names_only
148+ _prepare_dir " $HOME /work/names-one"
149+ save_bookmark names_only_a
150+ _assert_status 0 $status ' save first names-only bookmark succeeds'
151+
152+ _prepare_dir " $HOME /work/names-two"
153+ save_bookmark names_only_b
154+ _assert_status 0 $status ' save second names-only bookmark succeeds'
155+
156+ set -l names_output (list_bookmarks --names-only )
157+ _assert_status 0 $status ' list_bookmarks --names-only succeeds'
158+
159+ contains -- names_only_a $names_output
160+ _assert_true $status ' names-only output includes first bookmark name'
161+
162+ contains -- names_only_b $names_output
163+ _assert_true $status ' names-only output includes second bookmark name'
164+
165+ string match -q ' */*' -- " $names_output "
166+ _assert_status 1 $status ' names-only output does not include paths'
167+ end
168+
169+ function _test_argument_validation
170+ print_bookmark one two > /dev/null 2> /dev/null
171+ _assert_status 1 $status ' print_bookmark rejects extra arguments'
172+
173+ print_bookmark --unknown > /dev/null 2> /dev/null
174+ _assert_status 1 $status ' print_bookmark rejects unknown options'
175+
176+ go_to_bookmark one two > /dev/null 2> /dev/null
177+ _assert_status 1 $status ' go_to_bookmark rejects extra arguments'
178+
179+ go_to_bookmark --unknown > /dev/null 2> /dev/null
180+ _assert_status 1 $status ' go_to_bookmark rejects unknown options'
181+
182+ delete_bookmark one two > /dev/null 2> /dev/null
183+ _assert_status 1 $status ' delete_bookmark rejects extra arguments'
184+
185+ delete_bookmark --unknown > /dev/null 2> /dev/null
186+ _assert_status 1 $status ' delete_bookmark rejects unknown options'
187+
188+ bookmark_exists one two > /dev/null 2> /dev/null
189+ _assert_status 1 $status ' bookmark_exists rejects extra arguments'
190+
191+ bookmark_exists --unknown > /dev/null 2> /dev/null
192+ _assert_status 1 $status ' bookmark_exists rejects unknown options'
193+
194+ rename_bookmark old --unknown > /dev/null 2> /dev/null
195+ _assert_status 1 $status ' rename_bookmark rejects unknown options'
196+
197+ rename_bookmark bad-name new_name > /dev/null 2> /dev/null
198+ _assert_status 1 $status ' rename_bookmark validates old bookmark names'
199+
200+ save_bookmark first second > /dev/null 2> /dev/null
201+ _assert_status 1 $status ' save_bookmark rejects extra positional arguments'
202+
203+ save_bookmark --unknown > /dev/null 2> /dev/null
204+ _assert_status 1 $status ' save_bookmark rejects unknown options'
205+
206+ list_bookmarks extra > /dev/null 2> /dev/null
207+ _assert_status 1 $status ' list_bookmarks rejects unexpected arguments'
208+
209+ fishmarks_doctor --unknown > /dev/null 2> /dev/null
210+ _assert_status 1 $status ' fishmarks_doctor rejects unknown options'
211+ end
212+
213+ function _test_help_output
214+ set -l commands \
215+ save_bookmark \
216+ rename_bookmark \
217+ bookmark_exists \
218+ go_to_bookmark \
219+ print_bookmark \
220+ delete_bookmark \
221+ list_bookmarks \
222+ fishmarks_doctor
223+
224+ for command_name in $commands
225+ set -l help_output ($command_name --help )
226+ _assert_status 0 $status " $command_name --help succeeds"
227+ string match -q ' *save_bookmark*' -- " $help_output "
228+ _assert_true $status " $command_name --help includes command list"
229+ end
230+ end
231+
96232function _test_shell_escaped_paths
97233 set -l special_path " $HOME /work/special \" q\" \$ d\\ b"
98234 _prepare_dir " $special_path "
@@ -161,15 +297,43 @@ function _test_conf_aliases
161297 _assert_status 0 $status ' alias l is configured by conf.d script'
162298end
163299
300+ function _test_fishmarks_doctor
301+ set -l original_sdirs " $SDIRS "
302+
303+ set -gx SDIRS " $HOME /.sdirs_doctor_ok"
304+ command mkdir -p -- " $HOME /doctor/ok"
305+ printf ' \ n' > " $SDIRS "
306+ printf ' # fishmarks comments are ignored\ n' >> " $SDIRS "
307+ printf ' export DIR_ok="\\ $HOME /doctor/ok"\ n' >> " $SDIRS "
308+ fishmarks_doctor > /dev/null
309+ _assert_status 0 $status ' fishmarks_doctor succeeds for clean bookmark file'
310+
311+ set -gx SDIRS " $HOME /.sdirs_doctor_bad"
312+ printf ' not a bookmark\ n' > " $SDIRS "
313+ printf ' export DIR_dup="\\ $HOME /doctor/missing"\ n' >> " $SDIRS "
314+ printf ' export DIR_dup="\\ $HOME /doctor/missing-two"\ n' >> " $SDIRS "
315+ fishmarks_doctor > /dev/null 2> /dev/null
316+ _assert_status 1 $status ' fishmarks_doctor reports malformed, duplicate, or missing directories'
317+
318+ set -gx SDIRS " $original_sdirs "
319+ end
320+
164321_test_save_and_print
165322_test_default_name_generation
323+ _test_save_requires_force_to_overwrite
166324_test_go_to_and_delete
325+ _test_rename_bookmark
326+ _test_bookmark_exists
167327_test_legacy_file_compatibility
168328_test_invalid_name_rejected
329+ _test_list_names_only
330+ _test_argument_validation
169331_test_shell_escaped_paths
170332_test_rejects_newline_paths
171333_test_version_command
172334_test_conf_aliases
335+ _test_fishmarks_doctor
336+ _test_help_output
173337
174338if test $failures -gt 0
175339 printf ' \ n%d of %d assertions failed\ n' " $failures " " $assertions "
0 commit comments