Skip to main content

max / synckit

Pin hlc_text's storage format and its sort order The stash's HLC formatting had no test at all, so String::new() or a constant would have passed. Assert the exact "{wall_ms}:{counter}:{node}" rendering, that lexical order over the text matches Hlc's own Ord for fixtures of uniform numeric width, and that each of the three components reaches the output.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-23 22:09 UTC
Signed with PGP, not checked
Commit: a06324d7107a07fb72a3a3f9290ea7954af87a4d
Parent: c80629f
1 file changed, +71 insertions, -0 deletions
@@ -164,3 +164,74 @@
164 164 }
165 165 Ok(removed)
166 166 }
167 +
168 + #[cfg(test)]
169 + mod tests {
170 + use super::*;
171 + use crate::ids::DeviceId;
172 + use uuid::Uuid;
173 +
174 + fn hlc(wall_ms: i64, counter: u32, node: &str) -> Hlc {
175 + Hlc {
176 + wall_ms,
177 + counter,
178 + node: DeviceId::new(Uuid::parse_str(node).unwrap()),
179 + }
180 + }
181 +
182 + #[test]
183 + fn hlc_text_is_wall_counter_node() {
184 + let h = hlc(1_700_000_000_123, 7, "3f2504e0-4f89-41d3-9a0c-0305e82c3301");
185 + assert_eq!(
186 + hlc_text(&h),
187 + "1700000000123:7:3f2504e0-4f89-41d3-9a0c-0305e82c3301"
188 + );
189 + }
190 +
191 + #[test]
192 + fn hlc_text_ordering_tracks_hlc_ordering() {
193 + // The lexical form is only order-preserving while the numeric components
194 + // share a width: "9:0:.." sorts above "10:0:..". Every fixture here uses
195 + // the same 13-digit wall_ms and single-digit counter, which is the shape
196 + // a live clock produces.
197 + let node_a = "00000000-0000-0000-0000-00000000000a";
198 + let node_b = "00000000-0000-0000-0000-00000000000b";
199 + let fixtures = [
200 + hlc(1_700_000_000_000, 0, node_a),
201 + hlc(1_700_000_000_000, 0, node_b),
202 + hlc(1_700_000_000_000, 1, node_a),
203 + hlc(1_700_000_000_000, 9, node_b),
204 + hlc(1_700_000_000_001, 0, node_a),
205 + hlc(1_899_999_999_999, 4, node_b),
206 + ];
207 +
208 + for (i, left) in fixtures.iter().enumerate() {
209 + for (j, right) in fixtures.iter().enumerate() {
210 + assert_eq!(
211 + hlc_text(left).cmp(&hlc_text(right)),
212 + left.cmp(right),
213 + "lexical order disagreed with Hlc order for fixtures {i} and {j}"
214 + );
215 + }
216 + }
217 + }
218 +
219 + #[test]
220 + fn hlc_text_distinguishes_every_component() {
221 + let node_a = "00000000-0000-0000-0000-00000000000a";
222 + let node_b = "00000000-0000-0000-0000-00000000000b";
223 + let base = hlc(1_700_000_000_000, 0, node_a);
224 + assert_ne!(
225 + hlc_text(&base),
226 + hlc_text(&hlc(1_700_000_000_001, 0, node_a))
227 + );
228 + assert_ne!(
229 + hlc_text(&base),
230 + hlc_text(&hlc(1_700_000_000_000, 1, node_a))
231 + );
232 + assert_ne!(
233 + hlc_text(&base),
234 + hlc_text(&hlc(1_700_000_000_000, 0, node_b))
235 + );
236 + }
237 + }