An ATProto Lexicon validator for Gleam.
1import gleam/json
2import gleeunit
3import gleeunit/should
4import honk/validation/context
5import honk/validation/primitive/string
6
7pub fn main() {
8 gleeunit.main()
9}
10
11// Test valid string schema
12pub fn valid_string_schema_test() {
13 let schema =
14 json.object([
15 #("type", json.string("string")),
16 #("minLength", json.int(1)),
17 #("maxLength", json.int(100)),
18 ])
19
20 let assert Ok(ctx) = context.builder() |> context.build
21 let result = string.validate_schema(schema, ctx)
22 result |> should.be_ok
23}
24
25// Test string schema with format
26pub fn string_with_format_test() {
27 let schema =
28 json.object([
29 #("type", json.string("string")),
30 #("format", json.string("uri")),
31 ])
32
33 let assert Ok(ctx) = context.builder() |> context.build
34 let result = string.validate_schema(schema, ctx)
35 result |> should.be_ok
36}
37
38// Test string schema with enum
39pub fn string_with_enum_test() {
40 let schema =
41 json.object([
42 #("type", json.string("string")),
43 #(
44 "enum",
45 json.array(
46 [json.string("red"), json.string("green"), json.string("blue")],
47 fn(x) { x },
48 ),
49 ),
50 ])
51
52 let assert Ok(ctx) = context.builder() |> context.build
53 let result = string.validate_schema(schema, ctx)
54 result |> should.be_ok
55}
56
57// Test invalid string schema (minLength > maxLength)
58pub fn invalid_length_constraints_test() {
59 let schema =
60 json.object([
61 #("type", json.string("string")),
62 #("minLength", json.int(100)),
63 #("maxLength", json.int(10)),
64 ])
65
66 let assert Ok(ctx) = context.builder() |> context.build
67 let result = string.validate_schema(schema, ctx)
68 result |> should.be_error
69}
70
71// Test valid string data
72pub fn valid_string_data_test() {
73 let schema =
74 json.object([
75 #("type", json.string("string")),
76 #("minLength", json.int(1)),
77 #("maxLength", json.int(10)),
78 ])
79
80 let data = json.string("hello")
81
82 let assert Ok(ctx) = context.builder() |> context.build
83 let result = string.validate_data(data, schema, ctx)
84 result |> should.be_ok
85}
86
87// Test string data below minLength
88pub fn string_below_min_length_test() {
89 let schema =
90 json.object([
91 #("type", json.string("string")),
92 #("minLength", json.int(10)),
93 ])
94
95 let data = json.string("short")
96
97 let assert Ok(ctx) = context.builder() |> context.build
98 let result = string.validate_data(data, schema, ctx)
99 result |> should.be_error
100}
101
102// Test string data above maxLength
103pub fn string_above_max_length_test() {
104 let schema =
105 json.object([
106 #("type", json.string("string")),
107 #("maxLength", json.int(5)),
108 ])
109
110 let data = json.string("this is too long")
111
112 let assert Ok(ctx) = context.builder() |> context.build
113 let result = string.validate_data(data, schema, ctx)
114 result |> should.be_error
115}
116
117// Test string data with enum validation
118pub fn string_enum_valid_test() {
119 let schema =
120 json.object([
121 #("type", json.string("string")),
122 #(
123 "enum",
124 json.array([json.string("red"), json.string("blue")], fn(x) { x }),
125 ),
126 ])
127
128 let data = json.string("red")
129
130 let assert Ok(ctx) = context.builder() |> context.build
131 let result = string.validate_data(data, schema, ctx)
132 result |> should.be_ok
133}
134
135// Test string data with enum validation (invalid value)
136pub fn string_enum_invalid_test() {
137 let schema =
138 json.object([
139 #("type", json.string("string")),
140 #(
141 "enum",
142 json.array([json.string("red"), json.string("blue")], fn(x) { x }),
143 ),
144 ])
145
146 let data = json.string("green")
147
148 let assert Ok(ctx) = context.builder() |> context.build
149 let result = string.validate_data(data, schema, ctx)
150 result |> should.be_error
151}
152
153// Test wrong type (number instead of string)
154pub fn wrong_type_test() {
155 let schema = json.object([#("type", json.string("string"))])
156
157 let data = json.int(42)
158
159 let assert Ok(ctx) = context.builder() |> context.build
160 let result = string.validate_data(data, schema, ctx)
161 result |> should.be_error
162}
163
164// ========== NEGATIVE VALUE SCHEMA VALIDATION TESTS ==========
165
166// Test invalid string schema with negative minLength
167pub fn invalid_negative_min_length_test() {
168 let schema =
169 json.object([
170 #("type", json.string("string")),
171 #("minLength", json.int(-1)),
172 ])
173
174 let assert Ok(ctx) = context.builder() |> context.build
175 let result = string.validate_schema(schema, ctx)
176 result |> should.be_error
177}
178
179// Test invalid string schema with negative maxLength
180pub fn invalid_negative_max_length_test() {
181 let schema =
182 json.object([
183 #("type", json.string("string")),
184 #("maxLength", json.int(-5)),
185 ])
186
187 let assert Ok(ctx) = context.builder() |> context.build
188 let result = string.validate_schema(schema, ctx)
189 result |> should.be_error
190}
191
192// Test invalid string schema with negative minGraphemes
193pub fn invalid_negative_min_graphemes_test() {
194 let schema =
195 json.object([
196 #("type", json.string("string")),
197 #("minGraphemes", json.int(-10)),
198 ])
199
200 let assert Ok(ctx) = context.builder() |> context.build
201 let result = string.validate_schema(schema, ctx)
202 result |> should.be_error
203}
204
205// Test invalid string schema with negative maxGraphemes
206pub fn invalid_negative_max_graphemes_test() {
207 let schema =
208 json.object([
209 #("type", json.string("string")),
210 #("maxGraphemes", json.int(-3)),
211 ])
212
213 let assert Ok(ctx) = context.builder() |> context.build
214 let result = string.validate_schema(schema, ctx)
215 result |> should.be_error
216}