diff --git a/src/zipper.rs b/src/zipper.rs index 9916df38..84f4fd6c 100644 --- a/src/zipper.rs +++ b/src/zipper.rs @@ -1119,9 +1119,10 @@ fn k_path_default_internal(z: &mut if z.depth() == base_idx + k { return true } } } - //A sibling step replaces the last byte rather than adding one, so the observer sees the old - //byte retracted before the new one arrives + if z.depth() == base_idx { return false } if let Some(byte) = z.to_next_sibling_byte() { + //A sibling step replaces the last byte rather than adding one, so the observer sees the old + //byte retracted before the new one arrives obs.ascend(1); obs.descend_to_byte(byte); if z.depth() == base_idx + k { return true } @@ -4817,6 +4818,22 @@ pub(crate) mod zipper_iteration_tests { crate::zipper::zipper_iteration_tests::run_test(&mut temp_store, $make_z, b"", crate::zipper::zipper_iteration_tests::k_path_zero) } + #[test] + fn [<$z_name _k_path_walk_at_a_leaf>]() { + use crate::zipper::zipper_iteration_tests::{k_path_walk_at_a_leaf, run_test}; + const LEAF_KEYS: &[&[u8]] = &[&[1u8]]; + for (keys, path, has_child) in [ + (&[][..], &[][..], false), + (LEAF_KEYS, &[1u8][..], false), + (LEAF_KEYS, &[][..], true), + ] { + let mut temp_store = $read_keys(keys); + run_test(&mut temp_store, $make_z, b"", |zipper| { + k_path_walk_at_a_leaf(zipper, path, has_child) + }); + } + } + #[test] fn [<$z_name _k_path_test2>]() { let paths = crate::zipper::zipper_iteration_tests::k_path_test2_paths(); @@ -4942,6 +4959,19 @@ pub(crate) mod zipper_iteration_tests { assert_eq!(zipper.path(), b"a"); } + /// A k-path walk must stop at an empty root or leaf without stepping to a sibling. + pub fn k_path_walk_at_a_leaf(mut zipper: Z, path: &[u8], has_child: bool) { + for k in 0..3 { + zipper.reset(); + zipper.descend_to(path); + let found = zipper.descend_first_k_path(k); + assert_eq!(found, has_child && k == 1, "{path:?} k={k}"); + if !found { + assert_eq!(zipper.path(), path, "{path:?} k={k}"); + } + } + } + /// This is a toy encoding where `:n:` precedes a symbol `n` characters long pub const K_PATH_TEST1_KEYS: &[&[u8]] = &[ b":5:above:3:the:4:fray:",