1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
use zagan_bet::version::{
compatible, hello_line, is_newer, parse_hello, Version, VERSION,
};
#[test]
fn versions_parse_and_reject_nonsense() {
assert_eq!(
Version::parse("4.0.0"),
Some(Version {
major: 4,
minor: 0,
patch: 0
})
);
assert_eq!(
Version::parse("v4.1.2"),
Some(Version {
major: 4,
minor: 1,
patch: 2
})
);
assert_eq!(
Version::parse("4.0.0-rc1").map(|v| (v.major, v.minor, v.patch)),
Some((4, 0, 0))
);
assert_eq!(
Version::parse("4.0.0+build7").map(|v| v.patch),
Some(0)
);
for bad in ["", "4", "4.0", "4.0.0.1", "x.0.0", "4.x.0", "4.0.0-"] {
assert!(Version::parse(bad).is_none(), "{bad:?} should not parse");
}
assert!(Version::parse(VERSION).is_some(), "the build version must parse");
}
#[test]
fn compatibility_is_major_and_minor_only() {
assert!(compatible("4.0.0", "4.0.9"));
assert!(compatible("4.2.7", "4.2.1"));
assert!(!compatible("4.0.0", "4.1.0"));
assert!(!compatible("4.0.0", "5.0.0"));
assert!(!compatible("nope", "4.0.0"));
}
#[test]
fn newer_versions_are_ordered_by_major_minor_patch() {
assert!(is_newer("4.0.1", "4.0.0"));
assert!(is_newer("4.1.0", "4.0.9"));
assert!(is_newer("5.0.0", "4.9.9"));
assert!(!is_newer("4.0.0", "4.0.0"));
assert!(!is_newer("4.0.0", "4.0.1"));
assert!(!is_newer("nonsense", "4.0.0"));
}
#[test]
fn the_hello_reply_round_trips() {
let line = hello_line("4.0.0", "4.1.2", "https://zagan.example/");
let reply = parse_hello(&line).expect("parse a generated reply");
assert_eq!(reply.version, "4.0.0");
assert_eq!(reply.latest, "4.1.2");
assert_eq!(reply.url, "https://zagan.example/");
assert!(parse_hello("HELLO 4.0.0 url=https://x/").is_none(), "latest is required");
assert!(parse_hello("HELLO 4.0.0 latest=4.0.0").is_none(), "url is required");
assert!(parse_hello("PONG").is_none());
assert!(parse_hello("HELLO").is_none());
}
/// The GUI is a client, so it must ship in lockstep with the TUI and server.
/// Keep `gui/Cargo.toml` at the same version as the root package.
#[test]
fn the_gui_member_uses_the_same_version() {
let gui_manifest = include_str!("../gui/Cargo.toml");
let gui_version = gui_manifest
.lines()
.find_map(|line| line.trim().strip_prefix("version = "))
.expect("gui/Cargo.toml declares a version")
.trim_matches('"');
assert_eq!(gui_version, VERSION);
}
/// egui's dependency tree must never enter the TUI or server build graph.
/// The GUI is a workspace member that depends on this package, never the
/// other way round.
#[test]
fn the_root_package_does_not_depend_on_the_gui() {
let manifest = include_str!("../Cargo.toml");
for forbidden in ["eframe", "egui"] {
assert!(
!manifest.contains(forbidden),
"the root package must not depend on {forbidden}"
);
}
}
|