1pub mod source;
19pub mod targets;
20pub mod typescript;
21
22pub use source::{Builder, Module, Root};
23
24#[cfg(test)]
25mod tests {
26 use super::*;
27 use facet::Facet;
28 use phon_schema::{
29 DecodeLimits, SchemaBundleLimits, schema_bundle_from_bytes, schema_from_bytes,
30 schema_to_bytes,
31 };
32
33 #[derive(Facet)]
34 struct Point {
35 x: u32,
36 y: u32,
37 }
38
39 #[derive(Facet)]
40 #[repr(u8)]
41 #[allow(dead_code)]
42 enum Shape {
43 Circle(f64),
44 Rectangle { width: f64, height: f64 },
45 Point,
46 }
47
48 #[derive(Facet)]
49 #[allow(dead_code)]
50 struct Person {
51 name: String,
52 age: u32,
53 email: Option<String>,
54 tags: Vec<String>,
55 home: Point,
56 favorite: Shape,
57 big: u64,
58 }
59
60 fn module() -> Module {
61 Builder::new().add::<Person>().build().unwrap()
62 }
63
64 #[test]
65 fn every_schema_byte_blob_round_trips() {
67 let m = module();
68 assert!(!m.schemas.is_empty());
69 for s in &m.schemas {
70 let bytes = schema_to_bytes(s);
71 let (back, _) =
72 schema_from_bytes(&bytes, DecodeLimits::DEFAULT).expect("schema round-trips");
73 assert_eq!(&back, s, "schema {:#x} must round-trip", s.id.as_u64());
74 }
75 }
76
77 #[test]
78 fn emitted_schema_bundle_is_complete_and_admitted() {
79 let module = module();
80 let bytes = typescript::schema_bundle_bytes(&module).expect("schema bundle encodes");
81 let bundle = schema_bundle_from_bytes(&bytes, SchemaBundleLimits::default())
82 .expect("schema bundle admits");
83 assert_eq!(bundle.schemas(), module.schemas);
84 }
85
86 #[test]
87 fn typescript_renders_the_expected_shapes() {
90 let ts = typescript::render(&module());
91
92 assert!(
94 ts.contains("export interface Person {"),
95 "missing Person:\n{ts}"
96 );
97 assert!(ts.contains("name: string;"));
98 assert!(ts.contains("age: number;")); assert!(ts.contains("big: bigint;")); assert!(ts.contains("email: string | null;")); assert!(ts.contains("tags: string[];")); assert!(ts.contains("home: Point;")); assert!(ts.contains("favorite: Shape;")); assert!(ts.contains("export type Shape ="), "missing Shape:\n{ts}");
107 assert!(ts.contains(r#"{ tag: "Circle"; value: number }"#)); assert!(ts.contains(r#"{ tag: "Rectangle"; width: number; height: number }"#));
109 assert!(ts.contains(r#"{ tag: "Point" }"#)); assert!(ts.contains("export const registry = new Registry("));
113 assert!(ts.contains("export const schemaId = {"));
114 assert!(ts.contains("Person: 0x"));
115 assert!(ts.contains("export const schemaBundle = hexToBytes(\"50484f4e53434d31"));
116 assert!(!ts.contains("SCHEMA_BYTES"));
117 assert!(!ts.contains("schemaFromBytes"));
118 }
119}