//! IFC 출력 스냅샷 테스트 (insta) — 회귀 방지용. //! //! IfcGUID 는 UUIDv4 무작위라 매 실행마다 달라지므로 `mask_guids()` 로 //! `GUID-XXX` 형태로 정규화한 뒤 스냅샷 비교. //! //! 실행: //! ```bash //! cargo test -p cimery-ifc --test snapshot_tests //! # 새 baseline 채택: INSTA_UPDATE=always cargo test ... //! ``` use cimery_ifc::{BridgeExportParams, IfcSectionKind, export_bridge}; /// GUID 정규화 — `'...'` 22자 IFC GUID 를 `'GUID'` 로 치환. /// (IFC GUID charset: 0-9A-Za-z_$) fn mask_guids(ifc: &str) -> String { // 22자 = [0-9A-Za-z_$]{22} 로 정확 매치. let mut out = String::with_capacity(ifc.len()); let chars: Vec = ifc.chars().collect(); let mut i = 0; while i < chars.len() { if chars[i] == '\'' && i + 23 < chars.len() && chars[i + 23] == '\'' { // i+1 ~ i+22 검사. let all_guid_chars = (1..=22).all(|k| is_guid_char(chars[i + k])); if all_guid_chars { out.push_str("'GUID'"); i += 24; continue; } } out.push(chars[i]); i += 1; } out } fn is_guid_char(c: char) -> bool { c.is_ascii_alphanumeric() || c == '_' || c == '$' } #[test] fn single_span_psc_i_default() { let p = BridgeExportParams::default(); let ifc = export_bridge(&p); insta::assert_snapshot!(mask_guids(&ifc)); } #[test] fn two_span_multi_column() { let p = BridgeExportParams { span_count: 2, girder_count: 3, ..Default::default() }; let ifc = export_bridge(&p); insta::assert_snapshot!(mask_guids(&ifc)); } #[test] fn skewed_15_deg() { let p = BridgeExportParams { skew_deg: 15.0, girder_count: 2, ..Default::default() }; let ifc = export_bridge(&p); insta::assert_snapshot!(mask_guids(&ifc)); } #[test] fn camber_50mm_subdivides() { let p = BridgeExportParams { camber_mid_mm: 50.0, girder_count: 2, ..Default::default() }; let ifc = export_bridge(&p); insta::assert_snapshot!(mask_guids(&ifc)); } #[test] fn rectangle_section_no_profile_poly() { let p = BridgeExportParams { section_kind: IfcSectionKind::Rectangle, girder_count: 2, ..Default::default() }; let ifc = export_bridge(&p); insta::assert_snapshot!(mask_guids(&ifc)); } #[test] fn parapets_off() { let p = BridgeExportParams { show_parapets: false, girder_count: 2, ..Default::default() }; let ifc = export_bridge(&p); insta::assert_snapshot!(mask_guids(&ifc)); } // ─── mask_guids 유닛 테스트 ─────────────────────────────────────────────── #[test] fn mask_guids_replaces_22_char_token() { let before = "IFCPROJECT('2JBHBMFGp5w3sCd6sd_Oz$',$,...)"; let after = mask_guids(before); assert!(after.contains("'GUID'")); assert!(!after.contains("2JBHBMFGp5w3sCd6sd_Oz$")); } #[test] fn mask_guids_leaves_short_strings_alone() { let before = "lit('Bridge Alignment')"; let after = mask_guids(before); assert_eq!(before, after); }