Files
Momoko-Ayase f80749ffd6 Merge bfloat16-senbei workspace restructure, bump to 1.1.0
Adopts the fork's workspace split (senbei-cli / senbei-crypto / senbei-io /
senbei-metadata / senbei-pe), its structured error taxonomy, entry-transform
and layout validation, PE32 dd8 key-formula selection with a skip floor, the
CRT entry-stub dd8 oracle, and the extensionless-file scan skip.

Kept from senbei on top of the restructure:
- ManagedExe detection/routing and the CLR (COR20 + BSJB) metadata restore
  in the EXE pipeline.
- The RET+int3 padding fingerprint as the primary dd8 padding signal, ahead
  of the mutated-position 0xCC fallback.
- docs/, .github/, samples/, tests/ (moved to senbei-cli/tests), and the
  web/ wasm frontend (rewired to the split crates), all of which the fork
  had dropped.
- The fork's README compatibility matrix is not taken: it names real games,
  which the public-repo hygiene rules forbid.
- The wasm32 localtime fallback in logfile and unpack_bytes_force_exe (the
  web app's trap-recovery entry point), both lost in the restructure.

Golden corpus: 35/35 byte-identical. clippy -D warnings clean; wasm32 check
clean for the full workspace.
2026-08-30 22:31:21 +08:00

48 lines
1.4 KiB
Rust

use senbei_io::logfile::{Log, local_stamp_compact, local_stamp_display};
#[test]
fn local_stamp_compact_matches_shape() {
let s = local_stamp_compact();
// YYYYMMDD-HHMMSS → 15 chars, digit groups around dash
assert_eq!(s.len(), 15, "got {s}");
assert_eq!(&s[8..9], "-");
assert!(s.as_bytes().iter().enumerate().all(|(i, b)| {
if i == 8 {
*b == b'-'
} else {
b.is_ascii_digit()
}
}));
}
#[test]
fn local_stamp_display_matches_shape() {
let s = local_stamp_display();
// YYYY-MM-DD HH:MM:SS → 19 chars
assert_eq!(s.len(), 19, "got {s}");
assert_eq!(&s[4..5], "-");
assert_eq!(&s[7..8], "-");
assert_eq!(&s[10..11], " ");
assert_eq!(&s[13..14], ":");
assert_eq!(&s[16..17], ":");
}
#[test]
fn log_writes_timestamped_file_in_target_dir() {
let td = tempfile::tempdir().unwrap();
let log = Log::create(td.path()).unwrap();
log.step("hello");
let path = log.path().to_path_buf();
drop(log);
assert!(path.starts_with(td.path()));
let name = path.file_name().unwrap().to_string_lossy();
assert!(
name.starts_with("senbei-") && name.ends_with(".log"),
"unexpected log name: {name}"
);
// senbei-YYYYMMDD-HHMMSS.log
let core = name.trim_start_matches("senbei-").trim_end_matches(".log");
assert_eq!(core.len(), 15, "stamp in name: {name}");
assert!(std::fs::read_to_string(&path).unwrap().contains("hello"));
}