Skip to content

Commit 9956347

Browse files
committed
Add more tests for better explicit coverage of important features
1 parent cb63c56 commit 9956347

File tree

6 files changed

+205
-0
lines changed

6 files changed

+205
-0
lines changed

gix-url/tests/url/access.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,48 @@ fn password() -> crate::Result {
5454
Ok(())
5555
}
5656

57+
#[test]
58+
fn mutation_roundtrip() -> crate::Result {
59+
let mut url = gix_url::parse("https://user@host/path".into())?;
60+
url.set_user(Some("newuser".into()));
61+
url.set_password(Some("secret".into()));
62+
63+
let serialized = url.to_bstring();
64+
let reparsed = gix_url::parse(serialized.as_ref())?;
65+
66+
assert_eq!(url, reparsed);
67+
assert_eq!(reparsed.user(), Some("newuser"));
68+
assert_eq!(reparsed.password(), Some("secret"));
69+
70+
Ok(())
71+
}
72+
73+
#[test]
74+
fn from_bytes_roundtrip() -> crate::Result {
75+
let original = "https://user:password@example.com:8080/path/to/repo";
76+
let url = gix_url::parse(original.into())?;
77+
78+
let bytes = url.to_bstring();
79+
let from_bytes = gix_url::Url::from_bytes(bytes.as_ref())?;
80+
81+
assert_eq!(url, from_bytes);
82+
assert_eq!(from_bytes.to_bstring(), bytes);
83+
84+
Ok(())
85+
}
86+
87+
#[test]
88+
fn from_bytes_with_non_utf8_path() -> crate::Result {
89+
let url = gix_url::parse(b"/path/to\xff/repo".as_slice().into())?;
90+
let bytes = url.to_bstring();
91+
let from_bytes = gix_url::Url::from_bytes(bytes.as_ref())?;
92+
93+
assert_eq!(url, from_bytes);
94+
assert_eq!(from_bytes.path, url.path);
95+
96+
Ok(())
97+
}
98+
5799
#[test]
58100
fn user_argument_safety() -> crate::Result {
59101
let url = gix_url::parse("ssh://-Fconfigfile@foo/bar".into())?;

gix-url/tests/url/parse/file.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,28 @@ mod unix {
215215
url(Scheme::File, None, "x:", None, b"/path/to/git"),
216216
)
217217
}
218+
219+
#[test]
220+
fn file_url_with_ipv6_and_user() -> crate::Result {
221+
assert_url_roundtrip(
222+
"file://User@[::1]/repo",
223+
gix_url::Url::from_parts(
224+
Scheme::File,
225+
Some("User".into()),
226+
None,
227+
Some("[::1]".into()),
228+
None,
229+
b"/repo".into(),
230+
false,
231+
)?,
232+
)
233+
}
234+
235+
#[test]
236+
fn file_url_with_ipv6() -> crate::Result {
237+
assert_url_roundtrip(
238+
"file://[::1]/repo",
239+
url(Scheme::File, None, "[::1]", None, b"/repo"),
240+
)
241+
}
218242
}

gix-url/tests/url/parse/http.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,35 @@ fn http_missing_path() -> crate::Result {
9494
assert_url("http://host.xz", url(Scheme::Http, None, "host.xz", None, b"/"))?;
9595
Ok(())
9696
}
97+
98+
#[test]
99+
fn http_with_ipv6() -> crate::Result {
100+
assert_url_roundtrip("http://[::1]/repo", url(Scheme::Http, None, "[::1]", None, b"/repo"))
101+
}
102+
103+
#[test]
104+
fn http_with_ipv6_and_port() -> crate::Result {
105+
assert_url_roundtrip("http://[::1]:8080/repo", url(Scheme::Http, None, "[::1]", 8080, b"/repo"))
106+
}
107+
108+
#[test]
109+
fn https_with_ipv6_user_and_port() -> crate::Result {
110+
assert_url_roundtrip(
111+
"https://user@[2001:db8::1]:8443/repo",
112+
url(Scheme::Https, "user", "[2001:db8::1]", 8443, b"/repo"),
113+
)
114+
}
115+
116+
#[test]
117+
fn percent_encoded_path() -> crate::Result {
118+
let url = gix_url::parse("https://example.com/path/with%20spaces/file".into())?;
119+
assert_eq!(url.path, "/path/with%20spaces/file", "paths are not decoded");
120+
Ok(())
121+
}
122+
123+
#[test]
124+
fn percent_encoded_international_path() -> crate::Result {
125+
let url = gix_url::parse("https://example.com/caf%C3%A9".into())?;
126+
assert_eq!(url.path, "/caf%C3%A9", "international characters remain encoded in path");
127+
Ok(())
128+
}

gix-url/tests/url/parse/invalid.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,21 @@ fn file_missing_host_path_separator() {
3939
fn missing_port_despite_indication() {
4040
assert_matches!(parse("ssh://host.xz:"), Err(MissingRepositoryPath { .. }));
4141
}
42+
43+
#[test]
44+
fn port_zero_is_invalid() {
45+
assert_matches!(parse("ssh://host.xz:0/path"), Err(Url { .. }));
46+
}
47+
48+
#[test]
49+
fn port_too_large() {
50+
assert_matches!(parse("ssh://host.xz:65536/path"), Err(Url { .. }));
51+
assert_matches!(parse("ssh://host.xz:99999/path"), Err(Url { .. }));
52+
}
53+
54+
#[test]
55+
fn invalid_port_format() {
56+
let url = parse("ssh://host.xz:abc/path").expect("non-numeric port is treated as part of host");
57+
assert_eq!(url.host(), Some("host.xz:abc"), "port parse failure makes it part of hostname");
58+
assert_eq!(url.port, None);
59+
}

gix-url/tests/url/parse/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ mod radicle {
107107

108108
mod http;
109109

110+
mod ports {
111+
use crate::parse::{assert_url_roundtrip, url};
112+
use gix_url::Scheme;
113+
114+
#[test]
115+
fn max_valid_port() -> crate::Result {
116+
assert_url_roundtrip(
117+
"ssh://host.xz:65535/repo",
118+
url(Scheme::Ssh, None, "host.xz", 65535, b"/repo"),
119+
)
120+
}
121+
122+
#[test]
123+
fn port_one() -> crate::Result {
124+
assert_url_roundtrip("ssh://host.xz:1/repo", url(Scheme::Ssh, None, "host.xz", 1, b"/repo"))
125+
}
126+
}
127+
110128
mod git {
111129
use gix_url::Scheme;
112130

@@ -119,6 +137,21 @@ mod git {
119137
url(Scheme::Git, None, "example.com", None, b"~byron/hello"),
120138
)
121139
}
140+
141+
#[test]
142+
fn default_port_is_9418() -> crate::Result {
143+
let url = url(Scheme::Git, None, "example.com", None, b"/repo");
144+
assert_eq!(url.port_or_default(), Some(9418));
145+
Ok(())
146+
}
147+
148+
#[test]
149+
fn git_with_explicit_port() -> crate::Result {
150+
assert_url_roundtrip(
151+
"git://example.com:1234/repo",
152+
url(Scheme::Git, None, "example.com", 1234, b"/repo"),
153+
)
154+
}
122155
}
123156

124157
mod unknown {

gix-url/tests/url/parse/ssh.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,59 @@ fn bad_alternative_form_with_port() -> crate::Result {
233233
assert_eq!(url, "ssh://host.xz:21/");
234234
Ok(())
235235
}
236+
237+
#[test]
238+
fn ipv6_address_without_port() -> crate::Result {
239+
let url = assert_url("ssh://[::1]/repo", url(Scheme::Ssh, None, "::1", None, b"/repo"))?;
240+
assert_eq!(url.host(), Some("::1"), "brackets are stripped for SSH");
241+
Ok(())
242+
}
243+
244+
#[test]
245+
fn ipv6_address_with_port() -> crate::Result {
246+
let url = assert_url("ssh://[::1]:22/repo", url(Scheme::Ssh, None, "::1", 22, b"/repo"))?;
247+
assert_eq!(url.host(), Some("::1"));
248+
assert_eq!(url.port, Some(22));
249+
Ok(())
250+
}
251+
252+
#[test]
253+
fn ipv6_address_with_user() -> crate::Result {
254+
let url = assert_url("ssh://user@[::1]/repo", url(Scheme::Ssh, "user", "::1", None, b"/repo"))?;
255+
assert_eq!(url.host(), Some("::1"));
256+
assert_eq!(url.user(), Some("user"));
257+
Ok(())
258+
}
259+
260+
#[test]
261+
fn ipv6_address_with_user_and_port() -> crate::Result {
262+
let url = assert_url("ssh://user@[::1]:22/repo", url(Scheme::Ssh, "user", "::1", 22, b"/repo"))?;
263+
assert_eq!(url.host(), Some("::1"));
264+
assert_eq!(url.user(), Some("user"));
265+
assert_eq!(url.port, Some(22));
266+
Ok(())
267+
}
268+
269+
#[test]
270+
fn ipv6_full_address() -> crate::Result {
271+
let url = assert_url("ssh://[2001:db8::1]/repo", url(Scheme::Ssh, None, "2001:db8::1", None, b"/repo"))?;
272+
assert_eq!(url.host(), Some("2001:db8::1"));
273+
Ok(())
274+
}
275+
276+
#[test]
277+
fn ipv6_address_scp_like() -> crate::Result {
278+
let url = assert_url("[::1]:repo", url_alternate(Scheme::Ssh, None, "::1", None, b"repo"))?;
279+
assert_eq!(url.host(), Some("::1"), "SCP-like format with IPv6");
280+
Ok(())
281+
}
282+
283+
#[test]
284+
fn ipv6_address_scp_like_with_user() -> crate::Result {
285+
let result = gix_url::parse("user@[::1]:repo".into());
286+
assert!(
287+
result.is_err(),
288+
"SCP-like format with brackets is not supported - Git doesn't support this either"
289+
);
290+
Ok(())
291+
}

0 commit comments

Comments
 (0)