mod fafb_json;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn sdk_version() -> String {
env!("CARGO_PKG_VERSION").to_string()
}
#[wasm_bindgen]
pub fn score_faf(yaml: String) -> Result<String, JsValue> {
faf_kernel::score(&yaml)
.map(|r| r.to_json())
.map_err(|e| JsValue::from_str(&e))
}
#[wasm_bindgen]
pub fn validate_faf(yaml: String) -> bool {
use serde_yaml_ng::Value;
matches!(
serde_yaml_ng::from_str::<Value>(&yaml),
Ok(Value::Mapping(_))
)
}
#[wasm_bindgen]
pub fn compile_fafb(yaml: String) -> Result<Vec<u8>, JsValue> {
fafb_json::compile_fafb(&yaml).map_err(|e| JsValue::from_str(&e))
}
#[wasm_bindgen]
pub fn decompile_fafb(bytes: &[u8]) -> Result<String, JsValue> {
fafb_json::decompile_fafb(bytes).map_err(|e| JsValue::from_str(&e))
}
#[wasm_bindgen]
pub fn score_fafb(bytes: &[u8]) -> Result<String, JsValue> {
fafb_json::score_fafb(bytes).map_err(|e| JsValue::from_str(&e))
}
#[wasm_bindgen]
pub fn fafb_info(bytes: &[u8]) -> Result<String, JsValue> {
fafb_json::fafb_info(bytes).map_err(|e| JsValue::from_str(&e))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sdk_version_is_3x() {
assert!(sdk_version().starts_with("3."));
}
#[test]
fn test_validate_faf_accepts_mapping() {
assert!(validate_faf("project:\n name: test".to_string()));
}
#[test]
fn test_validate_faf_rejects_non_mapping() {
assert!(!validate_faf("just a string".to_string()));
assert!(!validate_faf("- list\n- items".to_string()));
assert!(!validate_faf("42".to_string()));
}
#[test]
fn test_validate_faf_rejects_broken_yaml() {
assert!(!validate_faf("[invalid: yaml: {{{".to_string()));
}
#[test]
fn test_score_faf_is_always_33() {
let result = score_faf("project:\n name: test".to_string()).unwrap();
assert!(result.contains("\"score\":"));
assert!(result.contains("\"tier\":"));
assert!(result.contains("\"total\":33"));
}
#[test]
fn test_canonical_tiers_not_medals() {
let result = score_faf("project:\n name: test".to_string()).unwrap();
assert!(!result.contains("🥇") && !result.contains("🥈") && !result.contains("🥉"));
}
#[test]
fn test_compile_decompile_fafb_roundtrip_v2() {
let yaml = "faf_version: 2.5.0\nproject:\n name: test\n".to_string();
let bytes = compile_fafb(yaml).unwrap();
assert_eq!(&bytes[0..4], b"FAFB");
assert_eq!(bytes[4], 2); let json = decompile_fafb(&bytes).unwrap();
assert!(json.contains("\"sections\":"));
assert!(json.contains("\"version\":\"2.0\""));
}
#[test]
fn test_score_fafb_from_compiled() {
let yaml = "faf_version: 2.5.0\nproject:\n name: test\n".to_string();
let bytes = compile_fafb(yaml).unwrap();
let score = score_fafb(&bytes).unwrap();
assert!(score.contains("\"score\":"));
assert!(score.contains("\"total\":33"));
}
#[test]
fn test_fafb_info_from_compiled() {
let yaml = "faf_version: 2.5.0\nproject:\n name: test\n".to_string();
let bytes = compile_fafb(yaml).unwrap();
let info = fafb_info(&bytes).unwrap();
assert!(info.contains("\"section_count\":"));
assert!(!info.contains("\"content\":"));
}
}