mod common;
use common::hex_to_bytes;
use o192::{
decode_sortable64, encode_sortable64, is_valid, parse, OrionIdError, ALPHABET, ID_SIZE_BYTES,
ID_SIZE_CHARS,
};
#[test]
fn alphabet_has_64_ascii_sorted_chars() {
let bytes = ALPHABET.as_bytes();
assert_eq!(bytes.len(), 64);
for window in bytes.windows(2) {
assert!(window[0] < window[1], "alphabet must be ASCII-sorted");
}
}
#[test]
fn encode_decode_roundtrips_arbitrary_bytes() {
let mut raw = [0u8; ID_SIZE_BYTES];
for (i, byte) in raw.iter_mut().enumerate() {
*byte = ((i as u8).wrapping_mul(31)).wrapping_add(7);
}
let text = encode_sortable64(&raw).expect("encode succeeds");
assert_eq!(text.len(), ID_SIZE_CHARS);
assert_eq!(decode_sortable64(&text).expect("decode succeeds"), raw);
}
#[test]
fn encode_rejects_wrong_length_input() {
assert_eq!(
encode_sortable64(&[0u8; 23]),
Err(OrionIdError::InvalidLength),
);
}
#[test]
fn decode_rejects_wrong_length_input() {
assert_eq!(
decode_sortable64("too-short"),
Err(OrionIdError::InvalidLength),
);
let too_long: String = "0".repeat(33);
assert!(matches!(
decode_sortable64(&too_long),
Err(OrionIdError::InvalidLength)
));
}
#[test]
fn decode_rejects_out_of_alphabet_characters() {
assert_eq!(
decode_sortable64("0000000000000000000000000000000+"),
Err(OrionIdError::InvalidCharacter),
);
}
#[test]
fn is_valid_returns_expected_results() {
assert!(is_valid("0007MxpLW00lEG0H8ZD4LMPsY9bfjxoT"));
assert!(!is_valid(""));
assert!(!is_valid("plus_sign_at_end_breaks_alphabet+"));
}
#[test]
fn parse_exposes_structured_fields() {
let bytes = hex_to_bytes("0000075bcd158000303900112233445566778899aabbccdd");
let id = encode_sortable64(&bytes).unwrap();
let view = parse(&id, 0).unwrap();
assert_eq!(view.relative_ms, 123_456_789);
assert_eq!(view.fraction4096, 2048);
assert_eq!(view.counter, 12_345);
assert_eq!(view.random_hex, "00112233445566778899aabbccdd");
}