1#[cfg(test)]
22mod test {
23 use crate::{
24 architecture::{self, Architecture},
25 build_profile::BuildProfile,
26 dependency::{
27 ArchConstraint, ArchConstraints, BuildProfileConstraint, BuildProfileConstraints,
28 Dependency, Package, Relation, VersionConstraint, VersionOperator,
29 },
30 version::Version,
31 };
32
33 macro_rules! check_parse_fails {
34 ($name:ident, $dep:expr) => {
35 #[test]
36 fn $name() {
37 assert!($dep.parse::<Dependency>().is_err());
38 }
39 };
40 }
41
42 check_parse_fails!(double_arch_constraints, "foo [amd64] [arm64]");
43 check_parse_fails!(double_version_constraint, "foo (= 1.0) (= 2.0)");
44 check_parse_fails!(invalid_version_constraint, "foo (1.0)");
45 check_parse_fails!(non_alpha_package, "💩");
46 check_parse_fails!(spacy_package, "a space");
47 check_parse_fails!(unknown_relation, "foo {bar}");
48 check_parse_fails!(no_package_arch_constraints, "[amd64]");
49 check_parse_fails!(no_package_arch, ":amd64");
50
51 macro_rules! check_matches {
52 ($name:ident, ( $( $dep:expr ),+ ), $check:expr) => {
53 #[test]
54 fn $name() {
55 $(
56 {
57 let dep: Dependency = $dep.parse().unwrap();
58 assert_eq!($check, dep, "expected {:?}, got {:?}", $check, dep);
59 }
60 )*
61 }
62 };
63
64 ($name:ident, $dep:expr, $check:expr) => {
65 check_matches!($name, ($dep), $check);
66 };
67 }
68
69 macro_rules! check_round_trips {
70 ($name:ident, ( $( $dep:expr ),+ ), $check:expr) => {
71 #[test]
72 fn $name() {
73 $(
74 {
75 let dep: Dependency = $dep.parse().unwrap();
76 assert_eq!($check, dep.to_string());
77 }
78 )*
79 }
80 };
81
82 ($name:ident, $dep:expr, $check:expr) => {
83 check_round_trips!($name, ($dep), $check);
84 };
85 }
86
87 macro_rules! simple_package {
88 ($package:expr) => {
89 Dependency {
90 relations: vec![Relation {
91 packages: vec![$package],
92 }],
93 }
94 };
95 }
96
97 check_matches!(check_empty, "", Dependency { relations: vec![] });
98 check_matches!(
99 check_simple,
100 "foo",
101 simple_package!(Package {
102 name: "foo".to_owned(),
103 ..Default::default()
104 })
105 );
106 check_matches!(
107 check_simple_arch,
108 "foo:armhf",
109 simple_package!(Package {
110 name: "foo".to_owned(),
111 arch: Some(architecture::ARMHF),
112 ..Default::default()
113 })
114 );
115 check_matches!(
116 check_simple_packages,
117 "foo, bar | baz",
118 Dependency {
119 relations: vec![
120 Relation {
121 packages: vec![Package {
122 name: "foo".to_owned(),
123 ..Default::default()
124 },]
125 },
126 Relation {
127 packages: vec![
128 Package {
129 name: "bar".to_owned(),
130 ..Default::default()
131 },
132 Package {
133 name: "baz".to_owned(),
134 ..Default::default()
135 },
136 ]
137 }
138 ],
139 }
140 );
141 check_matches!(
142 check_versioned_gte,
143 "foo (>= 1.0)",
144 simple_package!(Package {
145 name: "foo".to_owned(),
146 version_constraint: Some(VersionConstraint {
147 operator: VersionOperator::GreaterThanOrEqual,
148 version: Version::from_parts(None, "1.0", None).unwrap(),
149 }),
150 ..Default::default()
151 })
152 );
153
154 check_matches!(
155 check_versioned_lte,
156 "foo (<= 1.0)",
157 simple_package!(Package {
158 name: "foo".to_owned(),
159 version_constraint: Some(VersionConstraint {
160 operator: VersionOperator::LessThanOrEqual,
161 version: Version::from_parts(None, "1.0", None).unwrap(),
162 }),
163 ..Default::default()
164 })
165 );
166
167 check_matches!(
168 check_versioned_eq,
169 "foo (= 1.0)",
170 simple_package!(Package {
171 name: "foo".to_owned(),
172 version_constraint: Some(VersionConstraint {
173 operator: VersionOperator::Equal,
174 version: Version::from_parts(None, "1.0", None).unwrap(),
175 }),
176 ..Default::default()
177 })
178 );
179
180 check_matches!(
181 check_versioned_eq2,
182 "foo (== 1.0)",
183 simple_package!(Package {
184 name: "foo".to_owned(),
185 version_constraint: Some(VersionConstraint {
186 operator: VersionOperator::Equal,
187 version: Version::from_parts(None, "1.0", None).unwrap(),
188 }),
189 ..Default::default()
190 })
191 );
192
193 check_matches!(
194 check_versioned_gt,
195 "foo (>> 1.0)",
196 simple_package!(Package {
197 name: "foo".to_owned(),
198 version_constraint: Some(VersionConstraint {
199 operator: VersionOperator::GreaterThan,
200 version: Version::from_parts(None, "1.0", None).unwrap(),
201 }),
202 ..Default::default()
203 })
204 );
205
206 check_matches!(
207 check_versioned_lt,
208 "foo (<< 1.0)",
209 simple_package!(Package {
210 name: "foo".to_owned(),
211 version_constraint: Some(VersionConstraint {
212 operator: VersionOperator::LessThan,
213 version: Version::from_parts(None, "1.0", None).unwrap(),
214 }),
215 ..Default::default()
216 })
217 );
218
219 check_matches!(
220 check_arch_qualified,
221 "foo [armhf]",
222 simple_package!(Package {
223 name: "foo".to_owned(),
224 arch_constraints: Some(ArchConstraints {
225 arches: vec![ArchConstraint {
226 negated: false,
227 arch: architecture::ARMHF,
228 }]
229 }),
230 ..Default::default()
231 })
232 );
233 check_matches!(
234 check_arch_qualified2,
235 "foo [armhf amd64]",
236 simple_package!(Package {
237 name: "foo".to_owned(),
238 arch_constraints: Some(ArchConstraints {
239 arches: vec![
240 ArchConstraint {
241 negated: false,
242 arch: architecture::ARMHF,
243 },
244 ArchConstraint {
245 negated: false,
246 arch: architecture::AMD64,
247 },
248 ]
249 }),
250 ..Default::default()
251 })
252 );
253 check_matches!(
254 check_arch_qualified_not,
255 "foo [!armhf !amd64]",
256 simple_package!(Package {
257 name: "foo".to_owned(),
258 arch_constraints: Some(ArchConstraints {
259 arches: vec![
260 ArchConstraint {
261 negated: true,
262 arch: architecture::ARMHF,
263 },
264 ArchConstraint {
265 negated: true,
266 arch: architecture::AMD64,
267 },
268 ]
269 }),
270 ..Default::default()
271 })
272 );
273
274 check_matches!(
275 check_build_profile,
276 "foo <buildprofile1>",
277 simple_package!(Package {
278 name: "foo".to_owned(),
279 build_profile_restriction_formula: Some(
280 vec![BuildProfileConstraints {
281 build_profiles: vec![BuildProfileConstraint {
282 negated: false,
283 build_profile: BuildProfile::Unknown("buildprofile1".to_owned()),
284 }]
285 }]
286 .into()
287 ),
288 ..Default::default()
289 })
290 );
291
292 check_matches!(
293 check_build_profile_multiple,
294 "foo <buildprofile1 cross>",
295 simple_package!(Package {
296 name: "foo".to_owned(),
297 build_profile_restriction_formula: Some(
298 vec![BuildProfileConstraints {
299 build_profiles: vec![
300 BuildProfileConstraint {
301 negated: false,
302 build_profile: BuildProfile::Unknown("buildprofile1".to_owned()),
303 },
304 BuildProfileConstraint {
305 negated: false,
306 build_profile: BuildProfile::Cross,
307 },
308 ]
309 }]
310 .into()
311 ),
312 ..Default::default()
313 })
314 );
315 check_matches!(
316 build_profile_multiple_not,
317 "foo <buildprofile1 !cross>",
318 simple_package!(Package {
319 name: "foo".to_owned(),
320 build_profile_restriction_formula: Some(
321 vec![BuildProfileConstraints {
322 build_profiles: vec![
323 BuildProfileConstraint {
324 negated: false,
325 build_profile: BuildProfile::Unknown("buildprofile1".to_owned()),
326 },
327 BuildProfileConstraint {
328 negated: true,
329 build_profile: BuildProfile::Cross,
330 },
331 ]
332 }]
333 .into()
334 ),
335 ..Default::default()
336 })
337 );
338
339 check_matches!(
340 check_spaces,
341 ("foo", " foo", "foo "),
342 simple_package!(Package {
343 name: "foo".to_owned(),
344 ..Default::default()
345 })
346 );
347
348 check_matches!(
349 check_spaces_version,
350 (
351 "foo(=1.0)",
352 "foo (= 1.0)",
353 "foo (=1.0)",
354 " foo ( = 1.0 )"
355 ),
356 simple_package!(Package {
357 name: "foo".to_owned(),
358 version_constraint: Some(VersionConstraint {
359 operator: VersionOperator::Equal,
360 version: Version::from_parts(None, "1.0", None).unwrap(),
361 }),
362 ..Default::default()
363 })
364 );
365
366 check_matches!(
367 check_spaces_build_profile,
368 (
369 "foo<foo>",
370 "foo <foo>",
371 "foo <foo>",
372 "foo < foo>",
373 "foo <foo >",
374 "foo < foo >"
375 ),
376 simple_package!(Package {
377 name: "foo".to_owned(),
378 build_profile_restriction_formula: Some(
379 vec![BuildProfileConstraints {
380 build_profiles: vec![BuildProfileConstraint {
381 negated: false,
382 build_profile: BuildProfile::Unknown("foo".to_owned()),
383 }],
384 }]
385 .into()
386 ),
387 ..Default::default()
388 })
389 );
390
391 check_matches!(
392 check_spaces_build_profile_not,
393 (
394 "foo<!foo>",
395 "foo <!foo>",
396 "foo <!foo>",
397 "foo < !foo>",
398 "foo <!foo >",
399 "foo < !foo >",
400 " foo <!foo>",
401 " foo < ! foo >",
402 " foo < ! foo >"
403 ),
404 simple_package!(Package {
405 name: "foo".to_owned(),
406 build_profile_restriction_formula: Some(
407 vec![BuildProfileConstraints {
408 build_profiles: vec![BuildProfileConstraint {
409 negated: true,
410 build_profile: BuildProfile::Unknown("foo".to_owned()),
411 }],
412 }]
413 .into()
414 ),
415 ..Default::default()
416 })
417 );
418
419 check_matches!(
420 check_spaces_build_profiles,
421 (
422 "foo<!foo bar>",
423 "foo <!foo bar>",
424 "foo <!foo bar>",
425 "foo < !foo bar>",
426 "foo <!foo bar >",
427 "foo <!foo bar>",
428 "foo < !foo bar >",
429 " foo <!foo bar>",
430 " foo < ! foo bar >",
431 " foo < ! foo bar >"
432 ),
433 simple_package!(Package {
434 name: "foo".to_owned(),
435 build_profile_restriction_formula: Some(
436 vec![BuildProfileConstraints {
437 build_profiles: vec![
438 BuildProfileConstraint {
439 negated: true,
440 build_profile: BuildProfile::Unknown("foo".to_owned()),
441 },
442 BuildProfileConstraint {
443 negated: false,
444 build_profile: BuildProfile::Unknown("bar".to_owned())
445 }
446 ],
447 }]
448 .into()
449 ),
450 ..Default::default()
451 })
452 );
453
454 check_round_trips!(
455 rt_build_profile_pkg,
456 "foo <pkg.foo-bar.baz>",
457 "foo <pkg.foo-bar.baz>"
458 );
459 check_round_trips!(rt_build_profile_multi, "foo <foo> <bar>", "foo <foo> <bar>");
460
461 check_round_trips!(rt_simple, ("foo", " foo", " foo "), "foo");
462 check_round_trips!(
463 rt_relations,
464 (
465 "foo, bar",
466 "foo, bar",
467 " foo, bar ",
468 " foo , bar ",
469 "foo, bar ",
470 " foo, bar"
471 ),
472 "foo, bar"
473 );
474 check_round_trips!(
475 rt_poss,
476 (
477 "foo,bar|baz",
478 "foo, bar | baz",
479 "foo , bar | baz",
480 " foo, bar | baz",
481 "foo, bar | baz ",
482 " foo, bar | baz"
483 ),
484 "foo, bar | baz"
485 );
486 check_round_trips!(
487 rt_constraints,
488 (
489 "foo (= 1.0) [arch1 !arch2] <buildprofile1 !buildprofile2>",
490 "foo (== 1.0) [arch1 !arch2] <buildprofile1 !buildprofile2>",
491 "foo [arch1 !arch2] (= 1.0) <buildprofile1 !buildprofile2>",
492 "foo [arch1 !arch2] <buildprofile1 !buildprofile2> (= 1.0)",
493 "foo <buildprofile1 !buildprofile2> (= 1.0) [arch1 !arch2]",
494 "foo <buildprofile1 !buildprofile2> [arch1 !arch2] (= 1.0)"
495 ),
496 "foo (= 1.0) [arch1 !arch2] <buildprofile1 !buildprofile2>"
497 );
498
499 check_matches!(
500 check_arch_tuple_match,
501 "foo [linux-any]",
502 simple_package!(Package {
503 name: "foo".to_owned(),
504 arch_constraints: Some(ArchConstraints {
505 arches: vec![ArchConstraint {
506 negated: false,
507 arch: Architecture::from_parts("any", "any", "linux", "any").unwrap(),
508 },]
509 }),
510 ..Default::default()
511 })
512 );
513
514 check_matches!(
515 check_newlines,
516 "\
517foo,
518bar | baz
519",
520 Dependency {
521 relations: vec![
522 Relation {
523 packages: vec![Package {
524 name: "foo".to_owned(),
525 ..Default::default()
526 },]
527 },
528 Relation {
529 packages: vec![
530 Package {
531 name: "bar".to_owned(),
532 ..Default::default()
533 },
534 Package {
535 name: "baz".to_owned(),
536 ..Default::default()
537 },
538 ]
539 }
540 ],
541 }
542 );
543}
544
545