Nothing to see here, move along meow
1use lancer_core::net::{
2 bytes_eq, next_token, parse_decimal_u16, parse_ip, parse_ipv6, skip_spaces, write_ip_decimal,
3 write_ipv6, write_u8_decimal, write_u16_decimal,
4};
5use proptest::prelude::*;
6
7#[test]
8fn parse_ip_valid_simple() {
9 assert_eq!(parse_ip(b"1.2.3.4"), Some([1, 2, 3, 4]));
10}
11
12#[test]
13fn parse_ip_all_zeros() {
14 assert_eq!(parse_ip(b"0.0.0.0"), Some([0, 0, 0, 0]));
15}
16
17#[test]
18fn parse_ip_all_max() {
19 assert_eq!(parse_ip(b"255.255.255.255"), Some([255, 255, 255, 255]));
20}
21
22#[test]
23fn parse_ip_rejects_empty() {
24 assert_eq!(parse_ip(b""), None);
25}
26
27#[test]
28fn parse_ip_rejects_overflow_octet() {
29 assert_eq!(parse_ip(b"256.0.0.0"), None);
30}
31
32#[test]
33fn parse_ip_rejects_too_few_octets() {
34 assert_eq!(parse_ip(b"1.2.3"), None);
35}
36
37#[test]
38fn parse_ip_rejects_too_many_octets() {
39 assert_eq!(parse_ip(b"1.2.3.4.5"), None);
40}
41
42#[test]
43fn parse_ip_rejects_alpha() {
44 assert_eq!(parse_ip(b"abc"), None);
45}
46
47#[test]
48fn parse_ip_rejects_trailing_dot() {
49 assert_eq!(parse_ip(b"1.2.3.4."), None);
50}
51
52#[test]
53fn parse_ip_rejects_leading_dot() {
54 assert_eq!(parse_ip(b".1.2.3"), None);
55}
56
57#[test]
58fn parse_ipv6_loopback() {
59 let expected = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
60 assert_eq!(parse_ipv6(b"::1"), Some(expected));
61}
62
63#[test]
64fn parse_ipv6_link_local() {
65 let result = parse_ipv6(b"fe80::1").unwrap();
66 assert_eq!(result[0], 0xfe);
67 assert_eq!(result[1], 0x80);
68 assert_eq!(result[15], 1);
69 assert!((2..15).all(|i| result[i] == 0));
70}
71
72#[test]
73fn parse_ipv6_full_form() {
74 let result = parse_ipv6(b"2001:0db8:0000:0000:0000:0000:0000:0001").unwrap();
75 assert_eq!(result[0], 0x20);
76 assert_eq!(result[1], 0x01);
77 assert_eq!(result[2], 0x0d);
78 assert_eq!(result[3], 0xb8);
79 assert_eq!(result[15], 0x01);
80}
81
82#[test]
83fn parse_ipv6_all_zeros() {
84 let expected = [0u8; 16];
85 assert_eq!(parse_ipv6(b"::"), Some(expected));
86}
87
88#[test]
89fn parse_ipv6_rejects_empty() {
90 assert_eq!(parse_ipv6(b""), None);
91}
92
93#[test]
94fn parse_ipv6_rejects_triple_colon() {
95 assert_eq!(parse_ipv6(b":::1"), None);
96}
97
98#[test]
99fn parse_ipv6_rejects_too_many_groups() {
100 assert_eq!(parse_ipv6(b"1:2:3:4:5:6:7:8:9"), None);
101}
102
103#[test]
104fn parse_ipv6_rejects_overlong_group() {
105 assert_eq!(parse_ipv6(b"12345::1"), None);
106}
107
108#[test]
109fn write_u8_decimal_boundaries() {
110 let cases: &[(u8, &[u8])] = &[(0, b"0"), (1, b"1"), (127, b"127"), (255, b"255")];
111 cases.iter().for_each(|&(val, expected)| {
112 let mut buf = [0u8; 3];
113 let len = write_u8_decimal(&mut buf, val);
114 assert_eq!(&buf[..len], expected, "write_u8_decimal({val})");
115 });
116}
117
118#[test]
119fn write_u16_decimal_boundaries() {
120 let cases: &[(u16, &[u8])] = &[(0, b"0"), (1, b"1"), (256, b"256"), (65535, b"65535")];
121 cases.iter().for_each(|&(val, expected)| {
122 let mut buf = [0u8; 5];
123 let len = write_u16_decimal(&mut buf, val);
124 assert_eq!(&buf[..len], expected, "write_u16_decimal({val})");
125 });
126}
127
128#[test]
129fn parse_decimal_u16_rejects_overflow() {
130 assert_eq!(parse_decimal_u16(b"65536"), None);
131}
132
133#[test]
134fn parse_decimal_u16_rejects_empty() {
135 assert_eq!(parse_decimal_u16(b""), None);
136}
137
138#[test]
139fn parse_decimal_u16_rejects_non_digit() {
140 assert_eq!(parse_decimal_u16(b"12x3"), None);
141}
142
143#[test]
144fn parse_decimal_u16_valid() {
145 assert_eq!(parse_decimal_u16(b"0"), Some(0));
146 assert_eq!(parse_decimal_u16(b"65535"), Some(65535));
147 assert_eq!(parse_decimal_u16(b"1234"), Some(1234));
148}
149
150#[test]
151fn skip_spaces_empty() {
152 assert_eq!(skip_spaces(b""), &[] as &[u8]);
153}
154
155#[test]
156fn skip_spaces_all_spaces() {
157 assert_eq!(skip_spaces(b" "), &[] as &[u8]);
158}
159
160#[test]
161fn skip_spaces_leading() {
162 assert_eq!(skip_spaces(b" hello"), b"hello");
163}
164
165#[test]
166fn skip_spaces_no_spaces() {
167 assert_eq!(skip_spaces(b"hello"), b"hello");
168}
169
170#[test]
171fn next_token_basic() {
172 let (tok, rest) = next_token(b"foo bar baz");
173 assert_eq!(tok, b"foo");
174 let (tok2, rest2) = next_token(rest);
175 assert_eq!(tok2, b"bar");
176 let (tok3, rest3) = next_token(rest2);
177 assert_eq!(tok3, b"baz");
178 assert_eq!(rest3, &[] as &[u8]);
179}
180
181#[test]
182fn next_token_multiple_spaces() {
183 let (tok, rest) = next_token(b" foo bar");
184 assert_eq!(tok, b"foo");
185 let (tok2, _) = next_token(rest);
186 assert_eq!(tok2, b"bar");
187}
188
189#[test]
190fn next_token_empty() {
191 let (tok, rest) = next_token(b"");
192 assert_eq!(tok, &[] as &[u8]);
193 assert_eq!(rest, &[] as &[u8]);
194}
195
196#[test]
197fn bytes_eq_identity() {
198 assert!(bytes_eq(b"hello", b"hello"));
199}
200
201#[test]
202fn bytes_eq_length_mismatch() {
203 assert!(!bytes_eq(b"hello", b"hell"));
204}
205
206#[test]
207fn bytes_eq_content_mismatch() {
208 assert!(!bytes_eq(b"hello", b"world"));
209}
210
211#[test]
212fn bytes_eq_empty() {
213 assert!(bytes_eq(b"", b""));
214}
215
216proptest! {
217 #[test]
218 fn ipv4_write_parse_round_trip(a in 0u8..=255, b in 0u8..=255, c in 0u8..=255, d in 0u8..=255) {
219 let octets = [a, b, c, d];
220 let mut buf = [0u8; 15];
221 let len = write_ip_decimal(&mut buf, &octets);
222 let parsed = parse_ip(&buf[..len]).unwrap();
223 prop_assert_eq!(parsed, octets);
224 }
225
226 #[test]
227 fn ipv4_write_max_length(a in 0u8..=255, b in 0u8..=255, c in 0u8..=255, d in 0u8..=255) {
228 let octets = [a, b, c, d];
229 let mut buf = [0u8; 15];
230 let len = write_ip_decimal(&mut buf, &octets);
231 prop_assert!(len <= 15, "write_ip_decimal produced {len} bytes");
232 }
233
234 #[test]
235 fn ipv6_write_parse_round_trip(bytes in proptest::collection::vec(any::<u8>(), 16..=16)) {
236 let mut octets = [0u8; 16];
237 octets.copy_from_slice(&bytes);
238 let mut buf = [0u8; 39];
239 let len = write_ipv6(&mut buf, &octets);
240 let parsed = parse_ipv6(&buf[..len]).unwrap();
241 prop_assert_eq!(parsed, octets);
242 }
243
244 #[test]
245 fn u8_write_parse_round_trip(val in 0u8..=255) {
246 let mut buf = [0u8; 3];
247 let len = write_u8_decimal(&mut buf, val);
248 let parsed = parse_decimal_u16(&buf[..len]).unwrap();
249 prop_assert_eq!(parsed, val as u16);
250 }
251
252 #[test]
253 fn u16_write_parse_round_trip(val in 0u16..=65535) {
254 let mut buf = [0u8; 5];
255 let len = write_u16_decimal(&mut buf, val);
256 let parsed = parse_decimal_u16(&buf[..len]).unwrap();
257 prop_assert_eq!(parsed, val);
258 }
259}