Files
mizan/protocol/mizan-codegen/tests/upload_codegen.rs
2026-06-04 04:20:05 -04:00

80 lines
2.0 KiB
Rust

//! Upload type-shape lowers to TS `File` across cardinalities. Separate from
//! the byte-parity baselines (which mustn't carry an upload field — the
//! three-way AFI parity gate includes the Rust adapter, which doesn't wire
//! uploads yet).
use std::path::PathBuf;
use mizan_codegen::config::{Config, SourceConfig};
use mizan_codegen::emit::stage1::Stage1;
use mizan_codegen::emit::CodegenTarget;
use mizan_codegen::fetch::parse_ir_from_str;
const UPLOAD_IR: &str = r#"
type "SetAvatarInput" {
struct {
field "user_id" {
primitive "integer"
}
field "avatar" {
upload max-size=5242880 {
content-type "image/png"
content-type "image/jpeg"
}
}
field "photos" {
list {
upload
}
}
field "thumb" required=#false {
optional {
upload
}
}
}
}
type "setAvatarOutput" {
alias {
primitive "string"
}
}
function "set_avatar" {
camel "setAvatar"
has-input #true
input "SetAvatarInput"
output "setAvatarOutput"
transport "http"
affects "user"
}
"#;
fn cfg() -> Config {
Config {
project_id: None,
output: PathBuf::from("/tmp"),
targets: vec!["stage1".to_string()],
source: SourceConfig { fastapi: None, django: None, rust: None, script: None },
rust_kernel: None,
rust_crate_name: None,
}
}
#[test]
fn upload_fields_lower_to_file_type() {
let ir = parse_ir_from_str(UPLOAD_IR).expect("upload IR parses");
let files = Stage1.emit(&ir, &cfg());
let types = files
.iter()
.find(|f| f.rel_path.to_string_lossy().contains("types.ts"))
.expect("types.ts emitted");
let src = &types.content;
assert!(src.contains("avatar: File"), "required upload → File:\n{src}");
assert!(src.contains("File[]"), "list[upload] → File[]:\n{src}");
assert!(src.contains("File | null"), "optional upload → File | null:\n{src}");
}