1pub(crate) mod helper;
8pub mod normalizer;
9pub mod types;
10pub mod validator;
11
12#[cfg(test)]
13mod tests {
14 use crate::{
15 Path as _,
16 base::types::{
17 color::{RgbHex, RgbaHex},
18 finance::{E8s, E18s, Usd},
19 geo::{AddressLine, CityName, PostalCode, RegionName},
20 hash::Sha256,
21 ident::{Constant, Field, Function, Variable, Variant},
22 intl::{CountryCode, LanguageCode, PhoneNumber},
23 lang::Code,
24 num::{Degrees, Percent, PercentModifier},
25 web::{MimeType, Url},
26 },
27 build::schema_read,
28 node::Newtype,
29 };
30
31 #[test]
32 fn built_in_durable_rules_and_application_validators_have_disjoint_owners() {
33 let schema = schema_read();
34 for path in [
35 Degrees::PATH,
36 Percent::PATH,
37 PercentModifier::PATH,
38 Usd::PATH,
39 E8s::PATH,
40 E18s::PATH,
41 AddressLine::PATH,
42 CityName::PATH,
43 PostalCode::PATH,
44 RegionName::PATH,
45 ] {
46 let newtype = schema
47 .cast_node::<Newtype>(path)
48 .expect("durable built-in newtype should be registered");
49 assert_eq!(newtype.ty().rules().len(), 1, "{path}");
50 assert!(newtype.ty().validators().is_empty(), "{path}");
51 }
52
53 for path in [
54 Constant::PATH,
55 Field::PATH,
56 Function::PATH,
57 Variable::PATH,
58 Variant::PATH,
59 ] {
60 let newtype = schema
61 .cast_node::<Newtype>(path)
62 .expect("identifier built-in newtype should be registered");
63 assert_eq!(newtype.ty().rules().len(), 1, "{path}");
64 assert_eq!(newtype.ty().validators().len(), 1, "{path}");
65 }
66
67 for path in [Url::PATH, MimeType::PATH, PhoneNumber::PATH] {
68 let newtype = schema
69 .cast_node::<Newtype>(path)
70 .expect("application-only built-in newtype should be registered");
71 assert!(newtype.ty().rules().is_empty(), "{path}");
72 assert!(!newtype.ty().validators().is_empty(), "{path}");
73 }
74
75 for path in [
76 RgbHex::PATH,
77 RgbaHex::PATH,
78 Sha256::PATH,
79 CountryCode::PATH,
80 LanguageCode::PATH,
81 Code::PATH,
82 ] {
83 let newtype = schema
84 .cast_node::<Newtype>(path)
85 .expect("application-only built-in newtype should be registered");
86 assert!(newtype.ty().rules().is_empty(), "{path}");
87 assert!(!newtype.ty().validators().is_empty(), "{path}");
88 }
89
90 let mut classified = [
91 Degrees::PATH,
92 Percent::PATH,
93 PercentModifier::PATH,
94 Usd::PATH,
95 E8s::PATH,
96 E18s::PATH,
97 AddressLine::PATH,
98 CityName::PATH,
99 PostalCode::PATH,
100 RegionName::PATH,
101 Constant::PATH,
102 Field::PATH,
103 Function::PATH,
104 Variable::PATH,
105 Variant::PATH,
106 Url::PATH,
107 MimeType::PATH,
108 PhoneNumber::PATH,
109 RgbHex::PATH,
110 RgbaHex::PATH,
111 Sha256::PATH,
112 CountryCode::PATH,
113 LanguageCode::PATH,
114 Code::PATH,
115 ];
116 classified.sort_unstable();
117 let attached = schema
118 .get_nodes::<Newtype>()
119 .filter(|(_, newtype)| {
120 !newtype.ty().rules().is_empty() || !newtype.ty().validators().is_empty()
121 })
122 .map(|(path, _)| path)
123 .collect::<Vec<_>>();
124 assert_eq!(attached, classified);
125
126 for (path, expected_scale) in [(Usd::PATH, 2), (E8s::PATH, 8), (E18s::PATH, 18)] {
127 let newtype = schema
128 .cast_node::<Newtype>(path)
129 .expect("decimal built-in newtype should be registered");
130 assert_eq!(newtype.item().scale(), Some(expected_scale), "{path}");
131 }
132 drop(schema);
133 }
134}