Metainfo refactoring
- Combine test Metainfo values into a small number of globally available values. - Serialize update URLs as `URL` insted of `String`. - Add additional `show` tests type: reform
This commit is contained in:
parent
f4f7a69069
commit
213624cf8e
|
@ -39,7 +39,6 @@ strum_macros = "0.18.0"
|
||||||
syn = "1.0.14"
|
syn = "1.0.14"
|
||||||
tempfile = "3.0.0"
|
tempfile = "3.0.0"
|
||||||
unicode-width = "0.1.0"
|
unicode-width = "0.1.0"
|
||||||
url = "2.1.1"
|
|
||||||
|
|
||||||
[dependencies.bendy]
|
[dependencies.bendy]
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -57,6 +56,10 @@ features = ["derive"]
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
features = ["default", "wrap_help"]
|
features = ["default", "wrap_help"]
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "2.1.1"
|
||||||
|
features = ["serde"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
claim = "0.3.1"
|
claim = "0.3.1"
|
||||||
temptree = "0.0.0"
|
temptree = "0.0.0"
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub(crate) struct Info {
|
||||||
with = "unwrap_or_skip",
|
with = "unwrap_or_skip",
|
||||||
rename = "update-url"
|
rename = "update-url"
|
||||||
)]
|
)]
|
||||||
pub(crate) update_url: Option<String>,
|
pub(crate) update_url: Option<Url>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Info {
|
impl Info {
|
||||||
|
|
442
src/metainfo.rs
442
src/metainfo.rs
|
@ -117,35 +117,138 @@ impl Metainfo {
|
||||||
pub(crate) fn infohash(&self) -> Result<Infohash> {
|
pub(crate) fn infohash(&self) -> Result<Infohash> {
|
||||||
self.info.infohash()
|
self.info.infohash()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn test_value_single() -> Metainfo {
|
||||||
|
Metainfo {
|
||||||
|
announce: Some("udp://announce.example:1337".into()),
|
||||||
|
announce_list: Some(vec![
|
||||||
|
vec![
|
||||||
|
"http://a.example:4567".into(),
|
||||||
|
"https://b.example:77".into(),
|
||||||
|
],
|
||||||
|
vec!["udp://c.example:88".into()],
|
||||||
|
]),
|
||||||
|
nodes: Some(vec![
|
||||||
|
"node.example:12".parse().unwrap(),
|
||||||
|
"1.1.1.1:16".parse().unwrap(),
|
||||||
|
"[2001:0db8:85a3::0000:8a2e:0370]:7334".parse().unwrap(),
|
||||||
|
]),
|
||||||
|
comment: Some("COMMENT".into()),
|
||||||
|
created_by: Some("CREATED BY".into()),
|
||||||
|
creation_date: Some(1),
|
||||||
|
encoding: Some("UTF-8".into()),
|
||||||
|
info: Info {
|
||||||
|
private: Some(true),
|
||||||
|
piece_length: Bytes(16 * 1024),
|
||||||
|
source: Some("SOURCE".into()),
|
||||||
|
name: "NAME".into(),
|
||||||
|
pieces: PieceList::from_pieces(&["fae50", "fae50"]),
|
||||||
|
mode: Mode::Single {
|
||||||
|
length: Bytes(32 * 1024),
|
||||||
|
md5sum: Some(Md5Digest::from_hex("000102030405060708090a0b0c0d0e0f")),
|
||||||
|
},
|
||||||
|
update_url: Some("https://update.example".parse().unwrap()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn test_value_single_infohash() -> &'static str {
|
||||||
|
"5d6f53772b4c20536fcce0c4c364d764a6efa39c"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn test_value_single_torrent_size() -> Bytes {
|
||||||
|
Bytes(509)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn test_value_multiple() -> Metainfo {
|
||||||
|
let mut instance = Self::test_value_single();
|
||||||
|
instance.info.mode = Mode::Multiple {
|
||||||
|
files: vec![FileInfo {
|
||||||
|
length: Bytes(32 * 1024),
|
||||||
|
path: FilePath::from_components(&["DIR", "FILE"]),
|
||||||
|
md5sum: Some(Md5Digest::from_hex("000102030405060708090a0b0c0d0e0f")),
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
instance
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn test_value_single_unset() -> Metainfo {
|
||||||
|
Metainfo {
|
||||||
|
announce: None,
|
||||||
|
announce_list: None,
|
||||||
|
nodes: None,
|
||||||
|
comment: None,
|
||||||
|
created_by: None,
|
||||||
|
creation_date: None,
|
||||||
|
encoding: None,
|
||||||
|
info: Info {
|
||||||
|
private: None,
|
||||||
|
piece_length: Bytes(1024),
|
||||||
|
source: None,
|
||||||
|
name: "NAME".into(),
|
||||||
|
pieces: PieceList::from_pieces(&["fae50"]),
|
||||||
|
mode: Mode::Single {
|
||||||
|
length: Bytes(5),
|
||||||
|
md5sum: None,
|
||||||
|
},
|
||||||
|
update_url: None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn test_value_single_unset_infohash() -> &'static str {
|
||||||
|
"a9105b0ff5f7cefeee5599ed7831749be21cc04e"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn test_value_single_unset_torrent_size() -> Bytes {
|
||||||
|
Bytes(85)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn test_value_multiple_unset() -> Metainfo {
|
||||||
|
Metainfo {
|
||||||
|
announce: None,
|
||||||
|
announce_list: None,
|
||||||
|
nodes: None,
|
||||||
|
comment: None,
|
||||||
|
created_by: None,
|
||||||
|
creation_date: None,
|
||||||
|
encoding: None,
|
||||||
|
info: Info {
|
||||||
|
private: None,
|
||||||
|
piece_length: Bytes(1024),
|
||||||
|
source: None,
|
||||||
|
name: "NAME".into(),
|
||||||
|
pieces: PieceList::from_pieces(&["fae50"]),
|
||||||
|
mode: Mode::Multiple {
|
||||||
|
files: vec![FileInfo {
|
||||||
|
length: Bytes(1024),
|
||||||
|
md5sum: None,
|
||||||
|
path: FilePath::from_components(&["a", "b"]),
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
update_url: None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn round_trip_single() {
|
fn round_trip_single() {
|
||||||
let value = Metainfo {
|
let value = Metainfo::test_value_single();
|
||||||
announce: Some("announce".into()),
|
|
||||||
announce_list: Some(vec![vec!["announce".into(), "b".into()], vec!["c".into()]]),
|
|
||||||
comment: Some("comment".into()),
|
|
||||||
created_by: Some("created by".into()),
|
|
||||||
creation_date: Some(1),
|
|
||||||
encoding: Some("UTF-8".into()),
|
|
||||||
nodes: Some(vec!["x:12".parse().unwrap(), "1.1.1.1:16".parse().unwrap()]),
|
|
||||||
info: Info {
|
|
||||||
private: Some(true),
|
|
||||||
piece_length: Bytes(16 * 1024),
|
|
||||||
source: Some("source".into()),
|
|
||||||
name: "foo".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["abc"]),
|
|
||||||
mode: Mode::Single {
|
|
||||||
length: Bytes(20),
|
|
||||||
md5sum: None,
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let bencode = bendy::serde::ser::to_bytes(&value).unwrap();
|
let bencode = bendy::serde::ser::to_bytes(&value).unwrap();
|
||||||
|
|
||||||
|
@ -156,30 +259,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn round_trip_multiple() {
|
fn round_trip_multiple() {
|
||||||
let value = Metainfo {
|
let value = Metainfo::test_value_multiple();
|
||||||
announce: Some("announce".into()),
|
|
||||||
announce_list: Some(vec![vec!["announce".into(), "b".into()], vec!["c".into()]]),
|
|
||||||
nodes: Some(vec!["x:12".parse().unwrap(), "1.1.1.1:16".parse().unwrap()]),
|
|
||||||
comment: Some("comment".into()),
|
|
||||||
created_by: Some("created by".into()),
|
|
||||||
creation_date: Some(1),
|
|
||||||
encoding: Some("UTF-8".into()),
|
|
||||||
info: Info {
|
|
||||||
private: Some(true),
|
|
||||||
piece_length: Bytes(16 * 1024),
|
|
||||||
source: Some("source".into()),
|
|
||||||
name: "foo".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["abc"]),
|
|
||||||
mode: Mode::Multiple {
|
|
||||||
files: vec![FileInfo {
|
|
||||||
length: Bytes(10),
|
|
||||||
path: FilePath::from_components(&["foo", "bar"]),
|
|
||||||
md5sum: Some(Md5Digest::from_hex("000102030405060708090a0b0c0d0e0f")),
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let bencode = bendy::serde::ser::to_bytes(&value).unwrap();
|
let bencode = bendy::serde::ser::to_bytes(&value).unwrap();
|
||||||
|
|
||||||
|
@ -192,8 +272,10 @@ mod tests {
|
||||||
let have = value.serialize().unwrap();
|
let have = value.serialize().unwrap();
|
||||||
|
|
||||||
if have != want.as_bytes() {
|
if have != want.as_bytes() {
|
||||||
|
let have = String::from_utf8_lossy(&have);
|
||||||
|
assert_eq!(have, want);
|
||||||
eprintln!("have:");
|
eprintln!("have:");
|
||||||
eprintln!("{}", String::from_utf8_lossy(&have));
|
eprintln!("{}", have);
|
||||||
eprintln!("want:");
|
eprintln!("want:");
|
||||||
eprintln!("{}", want);
|
eprintln!("{}", want);
|
||||||
panic!("Unexpected representation...");
|
panic!("Unexpected representation...");
|
||||||
|
@ -201,60 +283,40 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bencode_representation_single_some() {
|
fn bencode_representation_single_set() {
|
||||||
let value = Metainfo {
|
let value = Metainfo::test_value_single();
|
||||||
announce: Some("ANNOUNCE".into()),
|
|
||||||
announce_list: Some(vec![vec!["A".into(), "B".into()], vec!["C".into()]]),
|
|
||||||
nodes: Some(vec![
|
|
||||||
"domain:1".parse().unwrap(),
|
|
||||||
"1.1.1.1:16".parse().unwrap(),
|
|
||||||
"[1234:5678:9abc:def0:1234:5678:9abc:def0]:65000"
|
|
||||||
.parse()
|
|
||||||
.unwrap(),
|
|
||||||
]),
|
|
||||||
comment: Some("COMMENT".into()),
|
|
||||||
created_by: Some("CREATED BY".into()),
|
|
||||||
creation_date: Some(0),
|
|
||||||
encoding: Some("UTF-8".into()),
|
|
||||||
info: Info {
|
|
||||||
private: Some(true),
|
|
||||||
piece_length: Bytes(1024),
|
|
||||||
source: Some("SOURCE".into()),
|
|
||||||
name: "NAME".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["fae50"]),
|
|
||||||
mode: Mode::Single {
|
|
||||||
length: Bytes(5),
|
|
||||||
md5sum: Some(Md5Digest::from_hex("000102030405060708090a0b0c0d0e0f")),
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let want = concat!(
|
let want = concat!(
|
||||||
"d",
|
"d",
|
||||||
"8:announce", "8:ANNOUNCE",
|
"8:announce", "27:udp://announce.example:1337",
|
||||||
"13:announce-list", "l",
|
"13:announce-list", "l",
|
||||||
"l", "1:A", "1:B", "e",
|
"l",
|
||||||
"l", "1:C", "e",
|
"21:http://a.example:4567",
|
||||||
|
"20:https://b.example:77",
|
||||||
|
"e",
|
||||||
|
"l",
|
||||||
|
"18:udp://c.example:88",
|
||||||
|
"e",
|
||||||
"e",
|
"e",
|
||||||
"7:comment", "7:COMMENT",
|
"7:comment", "7:COMMENT",
|
||||||
"10:created by", "10:CREATED BY",
|
"10:created by", "10:CREATED BY",
|
||||||
"13:creation date", "i0e",
|
"13:creation date", "i1e",
|
||||||
"8:encoding", "5:UTF-8",
|
"8:encoding", "5:UTF-8",
|
||||||
"4:info", "d",
|
"4:info", "d",
|
||||||
"6:length", "i5e",
|
"6:length", "i32768e",
|
||||||
"6:md5sum", "32:000102030405060708090a0b0c0d0e0f",
|
"6:md5sum", "32:000102030405060708090a0b0c0d0e0f",
|
||||||
"4:name", "4:NAME",
|
"4:name", "4:NAME",
|
||||||
"12:piece length", "i1024e",
|
"12:piece length", "i16384e",
|
||||||
"6:pieces", "20:8,OS7d玤{Qk!Mk",
|
"6:pieces", "40:8,OS7d玤{Qk!Mk8,OS7d玤{Qk!Mk",
|
||||||
"7:private", "i1e",
|
"7:private", "i1e",
|
||||||
"6:source", "6:SOURCE",
|
"6:source", "6:SOURCE",
|
||||||
|
"10:update-url", "23:https://update.example/",
|
||||||
"e",
|
"e",
|
||||||
"5:nodes", "l",
|
"5:nodes", "l",
|
||||||
"l", "6:domain", "i1e", "e",
|
"l", "12:node.example", "i12e", "e",
|
||||||
"l", "7:1.1.1.1", "i16e", "e",
|
"l", "7:1.1.1.1", "i16e", "e",
|
||||||
"l", "39:1234:5678:9abc:def0:1234:5678:9abc:def0", "i65000e", "e",
|
"l", "23:2001:db8:85a3::8a2e:370", "i7334e", "e",
|
||||||
"e",
|
"e",
|
||||||
"e"
|
"e"
|
||||||
);
|
);
|
||||||
|
@ -263,33 +325,12 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bencode_representation_single_none() {
|
fn bencode_representation_single_unset() {
|
||||||
let value = Metainfo {
|
let value = Metainfo::test_value_single_unset();
|
||||||
announce: Some("ANNOUNCE".into()),
|
|
||||||
announce_list: None,
|
|
||||||
nodes: None,
|
|
||||||
comment: None,
|
|
||||||
created_by: None,
|
|
||||||
creation_date: None,
|
|
||||||
encoding: None,
|
|
||||||
info: Info {
|
|
||||||
private: None,
|
|
||||||
piece_length: Bytes(1024),
|
|
||||||
source: None,
|
|
||||||
name: "NAME".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["fae50"]),
|
|
||||||
mode: Mode::Single {
|
|
||||||
length: Bytes(5),
|
|
||||||
md5sum: None,
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let want = concat!(
|
let want = concat!(
|
||||||
"d",
|
"d",
|
||||||
"8:announce", "8:ANNOUNCE",
|
|
||||||
"4:info", "d",
|
"4:info", "d",
|
||||||
"6:length", "i5e",
|
"6:length", "i5e",
|
||||||
"4:name", "4:NAME",
|
"4:name", "4:NAME",
|
||||||
|
@ -303,47 +344,45 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bencode_representation_multiple_some() {
|
fn bencode_representation_multiple_set() {
|
||||||
let value = Metainfo {
|
let value = Metainfo::test_value_multiple();
|
||||||
announce: Some("ANNOUNCE".into()),
|
|
||||||
announce_list: None,
|
|
||||||
nodes: None,
|
|
||||||
comment: None,
|
|
||||||
created_by: None,
|
|
||||||
creation_date: None,
|
|
||||||
encoding: None,
|
|
||||||
info: Info {
|
|
||||||
private: None,
|
|
||||||
piece_length: Bytes(1024),
|
|
||||||
source: None,
|
|
||||||
name: "NAME".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["fae50"]),
|
|
||||||
mode: Mode::Multiple {
|
|
||||||
files: vec![FileInfo {
|
|
||||||
length: Bytes(1024),
|
|
||||||
md5sum: Some(Md5Digest::from_hex("000102030405060708090a0b0c0d0e0f")),
|
|
||||||
path: FilePath::from_components(&["a", "b"]),
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let want = concat!(
|
let want = concat!(
|
||||||
"d",
|
"d",
|
||||||
"8:announce", "8:ANNOUNCE",
|
"8:announce", "27:udp://announce.example:1337",
|
||||||
|
"13:announce-list", "l",
|
||||||
|
"l",
|
||||||
|
"21:http://a.example:4567",
|
||||||
|
"20:https://b.example:77",
|
||||||
|
"e",
|
||||||
|
"l",
|
||||||
|
"18:udp://c.example:88",
|
||||||
|
"e",
|
||||||
|
"e",
|
||||||
|
"7:comment", "7:COMMENT",
|
||||||
|
"10:created by", "10:CREATED BY",
|
||||||
|
"13:creation date", "i1e",
|
||||||
|
"8:encoding", "5:UTF-8",
|
||||||
"4:info", "d",
|
"4:info", "d",
|
||||||
"5:files", "l",
|
"5:files", "l",
|
||||||
"d",
|
"d",
|
||||||
"6:length", "i1024e",
|
"6:length", "i32768e",
|
||||||
"6:md5sum", "32:000102030405060708090a0b0c0d0e0f",
|
"6:md5sum", "32:000102030405060708090a0b0c0d0e0f",
|
||||||
"4:path", "l", "1:a", "1:b", "e",
|
"4:path", "l", "3:DIR", "4:FILE", "e",
|
||||||
"e",
|
"e",
|
||||||
"e",
|
"e",
|
||||||
"4:name", "4:NAME",
|
"4:name", "4:NAME",
|
||||||
"12:piece length", "i1024e",
|
"12:piece length", "i16384e",
|
||||||
"6:pieces", "20:8,OS7d玤{Qk!Mk",
|
"6:pieces", "40:8,OS7d玤{Qk!Mk8,OS7d玤{Qk!Mk",
|
||||||
|
"7:private", "i1e",
|
||||||
|
"6:source", "6:SOURCE",
|
||||||
|
"10:update-url", "23:https://update.example/",
|
||||||
|
"e",
|
||||||
|
"5:nodes", "l",
|
||||||
|
"l", "12:node.example", "i12e", "e",
|
||||||
|
"l", "7:1.1.1.1", "i16e", "e",
|
||||||
|
"l", "23:2001:db8:85a3::8a2e:370", "i7334e", "e",
|
||||||
"e",
|
"e",
|
||||||
"e"
|
"e"
|
||||||
);
|
);
|
||||||
|
@ -352,36 +391,12 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bencode_representation_multiple_none() {
|
fn bencode_representation_multiple_unset() {
|
||||||
let value = Metainfo {
|
let value = Metainfo::test_value_multiple_unset();
|
||||||
announce: Some("ANNOUNCE".into()),
|
|
||||||
announce_list: None,
|
|
||||||
nodes: None,
|
|
||||||
comment: None,
|
|
||||||
created_by: None,
|
|
||||||
creation_date: None,
|
|
||||||
encoding: None,
|
|
||||||
info: Info {
|
|
||||||
private: None,
|
|
||||||
piece_length: Bytes(1024),
|
|
||||||
source: None,
|
|
||||||
name: "NAME".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["fae50"]),
|
|
||||||
mode: Mode::Multiple {
|
|
||||||
files: vec![FileInfo {
|
|
||||||
length: Bytes(1024),
|
|
||||||
md5sum: None,
|
|
||||||
path: FilePath::from_components(&["a", "b"]),
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let want = concat!(
|
let want = concat!(
|
||||||
"d",
|
"d",
|
||||||
"8:announce", "8:ANNOUNCE",
|
|
||||||
"4:info", "d",
|
"4:info", "d",
|
||||||
"5:files", "l",
|
"5:files", "l",
|
||||||
"d",
|
"d",
|
||||||
|
@ -399,86 +414,45 @@ mod tests {
|
||||||
representation(value, want);
|
representation(value, want);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn private_false() {
|
|
||||||
let value = Metainfo {
|
|
||||||
announce: Some("ANNOUNCE".into()),
|
|
||||||
announce_list: None,
|
|
||||||
nodes: None,
|
|
||||||
comment: None,
|
|
||||||
created_by: None,
|
|
||||||
creation_date: None,
|
|
||||||
encoding: None,
|
|
||||||
info: Info {
|
|
||||||
private: Some(false),
|
|
||||||
piece_length: Bytes(1024),
|
|
||||||
source: None,
|
|
||||||
name: "NAME".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["fae50"]),
|
|
||||||
mode: Mode::Single {
|
|
||||||
length: Bytes(5),
|
|
||||||
md5sum: None,
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
let want = concat!(
|
|
||||||
"d",
|
|
||||||
"8:announce", "8:ANNOUNCE",
|
|
||||||
"4:info", "d",
|
|
||||||
"6:length", "i5e",
|
|
||||||
"4:name", "4:NAME",
|
|
||||||
"12:piece length", "i1024e",
|
|
||||||
"6:pieces", "20:8,OS7d玤{Qk!Mk",
|
|
||||||
"7:private", "i0e",
|
|
||||||
"e",
|
|
||||||
"e"
|
|
||||||
);
|
|
||||||
|
|
||||||
representation(value, want);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn trackers() {
|
fn trackers() {
|
||||||
let mut metainfo = Metainfo {
|
fn assert_trackers_eq(metainfo: &Metainfo, want: &[&str]) {
|
||||||
announce: Some("http://foo".into()),
|
let want = want
|
||||||
announce_list: None,
|
.iter()
|
||||||
nodes: None,
|
.cloned()
|
||||||
comment: None,
|
.map(Url::parse)
|
||||||
created_by: None,
|
.collect::<Result<Vec<Url>, url::ParseError>>()
|
||||||
creation_date: None,
|
.unwrap();
|
||||||
encoding: None,
|
let have = metainfo.trackers().collect::<Result<Vec<Url>>>().unwrap();
|
||||||
info: Info {
|
assert_eq!(have, want);
|
||||||
private: Some(false),
|
}
|
||||||
piece_length: Bytes(1024),
|
|
||||||
source: None,
|
|
||||||
name: "NAME".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["fae50"]),
|
|
||||||
mode: Mode::Single {
|
|
||||||
length: Bytes(5),
|
|
||||||
md5sum: None,
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let trackers = metainfo.trackers().collect::<Result<Vec<Url>>>().unwrap();
|
let mut metainfo = Metainfo::test_value_single();
|
||||||
assert_eq!(trackers, &["http://foo".parse().unwrap()]);
|
|
||||||
|
assert_trackers_eq(
|
||||||
|
&metainfo,
|
||||||
|
&[
|
||||||
|
"udp://announce.example:1337",
|
||||||
|
"http://a.example:4567",
|
||||||
|
"https://b.example:77",
|
||||||
|
"udp://c.example:88",
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
metainfo.announce_list = Some(vec![
|
metainfo.announce_list = Some(vec![
|
||||||
vec!["http://bar".into(), "http://baz".into()],
|
vec![
|
||||||
vec!["http://foo".into()],
|
"udp://announce.example:1337".into(),
|
||||||
|
"https://b.example:77".into(),
|
||||||
|
],
|
||||||
|
vec!["udp://c.example:88".into()],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let trackers = metainfo.trackers().collect::<Result<Vec<Url>>>().unwrap();
|
assert_trackers_eq(
|
||||||
assert_eq!(
|
&metainfo,
|
||||||
trackers,
|
|
||||||
&[
|
&[
|
||||||
"http://foo".parse().unwrap(),
|
"udp://announce.example:1337",
|
||||||
"http://bar".parse().unwrap(),
|
"https://b.example:77",
|
||||||
"http://baz".parse().unwrap(),
|
"udp://c.example:88",
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,13 +382,13 @@ impl Create {
|
||||||
}
|
}
|
||||||
|
|
||||||
let info = Info {
|
let info = Info {
|
||||||
source: self.source,
|
|
||||||
piece_length: content.piece_length,
|
|
||||||
name: content.name,
|
name: content.name,
|
||||||
|
piece_length: content.piece_length,
|
||||||
|
source: self.source,
|
||||||
|
update_url: self.update_url,
|
||||||
mode,
|
mode,
|
||||||
pieces,
|
pieces,
|
||||||
private,
|
private,
|
||||||
update_url: self.update_url.map(|url| url.to_string()),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let metainfo = Metainfo {
|
let metainfo = Metainfo {
|
||||||
|
@ -3187,8 +3187,8 @@ Content Size 9 bytes
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
let metainfo = env.load_metainfo("foo.torrent");
|
let metainfo = env.load_metainfo("foo.torrent");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
metainfo.info.update_url.as_deref(),
|
metainfo.info.update_url,
|
||||||
Some("https://www.a_real_url.com/")
|
Some("https://www.a_real_url.com/".parse().unwrap())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,31 +111,53 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn output() -> Result<()> {
|
fn output() -> Result<()> {
|
||||||
let metainfo = Metainfo {
|
let metainfo = Metainfo::test_value_single();
|
||||||
announce: Some("announce".into()),
|
|
||||||
announce_list: Some(vec![vec!["announce".into(), "b".into()], vec!["c".into()]]),
|
#[rustfmt::skip]
|
||||||
nodes: Some(vec![
|
let want_human_readable = format!(
|
||||||
"x:12".parse().unwrap(),
|
" Name NAME
|
||||||
"1.1.1.1:16".parse().unwrap(),
|
Comment COMMENT
|
||||||
"[2001:0db8:85a3::0000:8a2e:0370]:7334".parse().unwrap(),
|
Creation Date 1970-01-01 00:00:01 UTC
|
||||||
]),
|
Created By CREATED BY
|
||||||
comment: Some("comment".into()),
|
Source SOURCE
|
||||||
created_by: Some("created by".into()),
|
Info Hash {}
|
||||||
creation_date: Some(1),
|
Torrent Size {}
|
||||||
encoding: Some("UTF-8".into()),
|
Content Size 32 KiB
|
||||||
info: Info {
|
Private yes
|
||||||
private: Some(true),
|
Tracker udp://announce.example:1337
|
||||||
piece_length: Bytes(16 * 1024),
|
Announce List Tier 1: http://a.example:4567
|
||||||
source: Some("source".into()),
|
https://b.example:77
|
||||||
name: "foo".into(),
|
Tier 2: udp://c.example:88
|
||||||
pieces: PieceList::from_pieces(&["xyz", "abc"]),
|
Update URL https://update.example/
|
||||||
mode: Mode::Single {
|
DHT Nodes node.example:12
|
||||||
length: Bytes(20),
|
1.1.1.1:16
|
||||||
md5sum: None,
|
[2001:db8:85a3::8a2e:370]:7334
|
||||||
},
|
Piece Size 16 KiB
|
||||||
update_url: None,
|
Piece Count 2
|
||||||
},
|
File Count 1
|
||||||
};
|
Files NAME
|
||||||
|
", Metainfo::test_value_single_infohash(), Metainfo::test_value_single_torrent_size());
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let want_machine_readable = format!("\
|
||||||
|
name\tNAME
|
||||||
|
comment\tCOMMENT
|
||||||
|
creation date\t1970-01-01 00:00:01 UTC
|
||||||
|
created by\tCREATED BY
|
||||||
|
source\tSOURCE
|
||||||
|
info hash\t{}
|
||||||
|
torrent size\t{}
|
||||||
|
content size\t32768
|
||||||
|
private\tyes
|
||||||
|
tracker\tudp://announce.example:1337
|
||||||
|
announce list\thttp://a.example:4567\thttps://b.example:77\tudp://c.example:88
|
||||||
|
update url\thttps://update.example/
|
||||||
|
dht nodes\tnode.example:12\t1.1.1.1:16\t[2001:db8:85a3::8a2e:370]:7334
|
||||||
|
piece size\t16384
|
||||||
|
piece count\t2
|
||||||
|
file count\t1
|
||||||
|
files\tNAME
|
||||||
|
", Metainfo::test_value_single_infohash(), Metainfo::test_value_single_torrent_size().count());
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut env = TestEnvBuilder::new()
|
let mut env = TestEnvBuilder::new()
|
||||||
|
@ -150,29 +172,7 @@ mod tests {
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
|
|
||||||
let have = env.out();
|
let have = env.out();
|
||||||
let want = " Name foo
|
assert_eq!(have, want_human_readable);
|
||||||
Comment comment
|
|
||||||
Creation Date 1970-01-01 00:00:01 UTC
|
|
||||||
Created By created by
|
|
||||||
Source source
|
|
||||||
Info Hash e12253978dc6d50db11d05747abcea1ad03b51c5
|
|
||||||
Torrent Size 339 bytes
|
|
||||||
Content Size 20 bytes
|
|
||||||
Private yes
|
|
||||||
Tracker announce
|
|
||||||
Announce List Tier 1: announce
|
|
||||||
b
|
|
||||||
Tier 2: c
|
|
||||||
DHT Nodes x:12
|
|
||||||
1.1.1.1:16
|
|
||||||
[2001:db8:85a3::8a2e:370]:7334
|
|
||||||
Piece Size 16 KiB
|
|
||||||
Piece Count 2
|
|
||||||
File Count 1
|
|
||||||
Files foo
|
|
||||||
";
|
|
||||||
|
|
||||||
assert_eq!(have, want);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -188,29 +188,8 @@ Announce List Tier 1: announce
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
|
|
||||||
let have = env.out();
|
let have = env.out();
|
||||||
let want = " Name foo
|
|
||||||
Comment comment
|
|
||||||
Creation Date 1970-01-01 00:00:01 UTC
|
|
||||||
Created By created by
|
|
||||||
Source source
|
|
||||||
Info Hash e12253978dc6d50db11d05747abcea1ad03b51c5
|
|
||||||
Torrent Size 339 bytes
|
|
||||||
Content Size 20 bytes
|
|
||||||
Private yes
|
|
||||||
Tracker announce
|
|
||||||
Announce List Tier 1: announce
|
|
||||||
b
|
|
||||||
Tier 2: c
|
|
||||||
DHT Nodes x:12
|
|
||||||
1.1.1.1:16
|
|
||||||
[2001:db8:85a3::8a2e:370]:7334
|
|
||||||
Piece Size 16 KiB
|
|
||||||
Piece Count 2
|
|
||||||
File Count 1
|
|
||||||
Files foo
|
|
||||||
";
|
|
||||||
|
|
||||||
assert_eq!(have, want);
|
assert_eq!(have, want_human_readable);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -225,26 +204,8 @@ Announce List Tier 1: announce
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
|
|
||||||
let have = env.out();
|
let have = env.out();
|
||||||
let want = "\
|
|
||||||
name\tfoo
|
|
||||||
comment\tcomment
|
|
||||||
creation date\t1970-01-01 00:00:01 UTC
|
|
||||||
created by\tcreated by
|
|
||||||
source\tsource
|
|
||||||
info hash\te12253978dc6d50db11d05747abcea1ad03b51c5
|
|
||||||
torrent size\t339
|
|
||||||
content size\t20
|
|
||||||
private\tyes
|
|
||||||
tracker\tannounce
|
|
||||||
announce list\tannounce\tb\tc
|
|
||||||
dht nodes\tx:12\t1.1.1.1:16\t[2001:db8:85a3::8a2e:370]:7334
|
|
||||||
piece size\t16384
|
|
||||||
piece count\t2
|
|
||||||
file count\t1
|
|
||||||
files\tfoo
|
|
||||||
";
|
|
||||||
|
|
||||||
assert_eq!(have, want);
|
assert_eq!(have, want_machine_readable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -252,31 +213,7 @@ files\tfoo
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tier_list_with_main() -> Result<()> {
|
fn tier_list_with_main() -> Result<()> {
|
||||||
let metainfo = Metainfo {
|
let metainfo = Metainfo::test_value_single();
|
||||||
announce: Some("a".into()),
|
|
||||||
announce_list: Some(vec![vec!["x".into()], vec!["y".into()], vec!["z".into()]]),
|
|
||||||
comment: Some("comment".into()),
|
|
||||||
created_by: Some("created by".into()),
|
|
||||||
nodes: Some(vec![
|
|
||||||
"x:12".parse().unwrap(),
|
|
||||||
"1.1.1.1:16".parse().unwrap(),
|
|
||||||
"[2001:0db8:85a3::0000:8a2e:0370]:7334".parse().unwrap(),
|
|
||||||
]),
|
|
||||||
creation_date: Some(1),
|
|
||||||
encoding: Some("UTF-8".into()),
|
|
||||||
info: Info {
|
|
||||||
private: Some(true),
|
|
||||||
piece_length: Bytes(16 * 1024),
|
|
||||||
source: Some("source".into()),
|
|
||||||
name: "foo".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["xyz", "abc"]),
|
|
||||||
mode: Mode::Single {
|
|
||||||
length: Bytes(20),
|
|
||||||
md5sum: None,
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut env = TestEnvBuilder::new()
|
let mut env = TestEnvBuilder::new()
|
||||||
|
@ -291,27 +228,34 @@ files\tfoo
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
|
|
||||||
let have = env.out();
|
let have = env.out();
|
||||||
let want = " Name foo
|
|
||||||
Comment comment
|
#[rustfmt::skip]
|
||||||
|
let want = format!(
|
||||||
|
" Name NAME
|
||||||
|
Comment COMMENT
|
||||||
Creation Date 1970-01-01 00:00:01 UTC
|
Creation Date 1970-01-01 00:00:01 UTC
|
||||||
Created By created by
|
Created By CREATED BY
|
||||||
Source source
|
Source SOURCE
|
||||||
Info Hash e12253978dc6d50db11d05747abcea1ad03b51c5
|
Info Hash {}
|
||||||
Torrent Size 327 bytes
|
Torrent Size {}
|
||||||
Content Size 20 bytes
|
Content Size 32 KiB
|
||||||
Private yes
|
Private yes
|
||||||
Tracker a
|
Tracker udp://announce.example:1337
|
||||||
Announce List Tier 1: x
|
Announce List Tier 1: http://a.example:4567
|
||||||
Tier 2: y
|
https://b.example:77
|
||||||
Tier 3: z
|
Tier 2: udp://c.example:88
|
||||||
DHT Nodes x:12
|
Update URL https://update.example/
|
||||||
|
DHT Nodes node.example:12
|
||||||
1.1.1.1:16
|
1.1.1.1:16
|
||||||
[2001:db8:85a3::8a2e:370]:7334
|
[2001:db8:85a3::8a2e:370]:7334
|
||||||
Piece Size 16 KiB
|
Piece Size 16 KiB
|
||||||
Piece Count 2
|
Piece Count 2
|
||||||
File Count 1
|
File Count 1
|
||||||
Files foo
|
Files NAME
|
||||||
";
|
",
|
||||||
|
Metainfo::test_value_single_infohash(),
|
||||||
|
Metainfo::test_value_single_torrent_size()
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(have, want);
|
assert_eq!(have, want);
|
||||||
}
|
}
|
||||||
|
@ -328,24 +272,31 @@ Announce List Tier 1: x
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
|
|
||||||
let have = env.out();
|
let have = env.out();
|
||||||
let want = "\
|
|
||||||
name\tfoo
|
#[rustfmt::skip]
|
||||||
comment\tcomment
|
let want = format!(
|
||||||
|
"\
|
||||||
|
name\tNAME
|
||||||
|
comment\tCOMMENT
|
||||||
creation date\t1970-01-01 00:00:01 UTC
|
creation date\t1970-01-01 00:00:01 UTC
|
||||||
created by\tcreated by
|
created by\tCREATED BY
|
||||||
source\tsource
|
source\tSOURCE
|
||||||
info hash\te12253978dc6d50db11d05747abcea1ad03b51c5
|
info hash\t{}
|
||||||
torrent size\t327
|
torrent size\t{}
|
||||||
content size\t20
|
content size\t32768
|
||||||
private\tyes
|
private\tyes
|
||||||
tracker\ta
|
tracker\tudp://announce.example:1337
|
||||||
announce list\tx\ty\tz
|
announce list\thttp://a.example:4567\thttps://b.example:77\tudp://c.example:88
|
||||||
dht nodes\tx:12\t1.1.1.1:16\t[2001:db8:85a3::8a2e:370]:7334
|
update url\thttps://update.example/
|
||||||
|
dht nodes\tnode.example:12\t1.1.1.1:16\t[2001:db8:85a3::8a2e:370]:7334
|
||||||
piece size\t16384
|
piece size\t16384
|
||||||
piece count\t2
|
piece count\t2
|
||||||
file count\t1
|
file count\t1
|
||||||
files\tfoo
|
files\tNAME
|
||||||
";
|
",
|
||||||
|
Metainfo::test_value_single_infohash(),
|
||||||
|
Metainfo::test_value_single_torrent_size().count()
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(have, want);
|
assert_eq!(have, want);
|
||||||
}
|
}
|
||||||
|
@ -355,31 +306,13 @@ files\tfoo
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tier_list_without_main() -> Result<()> {
|
fn tier_list_without_main() -> Result<()> {
|
||||||
let metainfo = Metainfo {
|
let mut metainfo = Metainfo::test_value_single();
|
||||||
announce: Some("a".into()),
|
|
||||||
announce_list: Some(vec![vec!["b".into()], vec!["c".into()], vec!["a".into()]]),
|
metainfo.announce_list = Some(vec![
|
||||||
comment: Some("comment".into()),
|
vec!["B".into()],
|
||||||
nodes: Some(vec![
|
vec!["C".into()],
|
||||||
"x:12".parse().unwrap(),
|
vec!["ANNOUNCE".into()],
|
||||||
"1.1.1.1:16".parse().unwrap(),
|
]);
|
||||||
"[2001:0db8:85a3::8a2e:0370]:7334".parse().unwrap(),
|
|
||||||
]),
|
|
||||||
created_by: Some("created by".into()),
|
|
||||||
creation_date: Some(1),
|
|
||||||
encoding: Some("UTF-8".into()),
|
|
||||||
info: Info {
|
|
||||||
private: Some(true),
|
|
||||||
piece_length: Bytes(16 * 1024),
|
|
||||||
source: Some("source".into()),
|
|
||||||
name: "foo".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["abc"]),
|
|
||||||
mode: Mode::Single {
|
|
||||||
length: Bytes(20),
|
|
||||||
md5sum: None,
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut env = TestEnvBuilder::new()
|
let mut env = TestEnvBuilder::new()
|
||||||
|
@ -394,27 +327,34 @@ files\tfoo
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
|
|
||||||
let have = env.out();
|
let have = env.out();
|
||||||
let want = " Name foo
|
|
||||||
Comment comment
|
#[rustfmt::skip]
|
||||||
|
let want = format!(
|
||||||
|
" Name NAME
|
||||||
|
Comment COMMENT
|
||||||
Creation Date 1970-01-01 00:00:01 UTC
|
Creation Date 1970-01-01 00:00:01 UTC
|
||||||
Created By created by
|
Created By CREATED BY
|
||||||
Source source
|
Source SOURCE
|
||||||
Info Hash b9cd9cae5748518c99d00d8ae86c0162510be4d9
|
Info Hash {}
|
||||||
Torrent Size 307 bytes
|
Torrent Size {}
|
||||||
Content Size 20 bytes
|
Content Size 32 KiB
|
||||||
Private yes
|
Private yes
|
||||||
Tracker a
|
Tracker udp://announce.example:1337
|
||||||
Announce List Tier 1: b
|
Announce List Tier 1: B
|
||||||
Tier 2: c
|
Tier 2: C
|
||||||
Tier 3: a
|
Tier 3: ANNOUNCE
|
||||||
DHT Nodes x:12
|
Update URL https://update.example/
|
||||||
|
DHT Nodes node.example:12
|
||||||
1.1.1.1:16
|
1.1.1.1:16
|
||||||
[2001:db8:85a3::8a2e:370]:7334
|
[2001:db8:85a3::8a2e:370]:7334
|
||||||
Piece Size 16 KiB
|
Piece Size 16 KiB
|
||||||
Piece Count 1
|
Piece Count 2
|
||||||
File Count 1
|
File Count 1
|
||||||
Files foo
|
Files NAME
|
||||||
";
|
",
|
||||||
|
Metainfo::test_value_single_infohash(),
|
||||||
|
Bytes(Metainfo::test_value_single_torrent_size().count() - 50)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(have, want);
|
assert_eq!(have, want);
|
||||||
}
|
}
|
||||||
|
@ -431,24 +371,30 @@ Announce List Tier 1: b
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
|
|
||||||
let have = env.out();
|
let have = env.out();
|
||||||
let want = "\
|
|
||||||
name\tfoo
|
#[rustfmt::skip]
|
||||||
comment\tcomment
|
let want = format!("\
|
||||||
|
name\tNAME
|
||||||
|
comment\tCOMMENT
|
||||||
creation date\t1970-01-01 00:00:01 UTC
|
creation date\t1970-01-01 00:00:01 UTC
|
||||||
created by\tcreated by
|
created by\tCREATED BY
|
||||||
source\tsource
|
source\tSOURCE
|
||||||
info hash\tb9cd9cae5748518c99d00d8ae86c0162510be4d9
|
info hash\t{}
|
||||||
torrent size\t307
|
torrent size\t{}
|
||||||
content size\t20
|
content size\t32768
|
||||||
private\tyes
|
private\tyes
|
||||||
tracker\ta
|
tracker\tudp://announce.example:1337
|
||||||
announce list\tb\tc\ta
|
announce list\tB\tC\tANNOUNCE
|
||||||
dht nodes\tx:12\t1.1.1.1:16\t[2001:db8:85a3::8a2e:370]:7334
|
update url\thttps://update.example/
|
||||||
|
dht nodes\tnode.example:12\t1.1.1.1:16\t[2001:db8:85a3::8a2e:370]:7334
|
||||||
piece size\t16384
|
piece size\t16384
|
||||||
piece count\t1
|
piece count\t2
|
||||||
file count\t1
|
file count\t1
|
||||||
files\tfoo
|
files\tNAME
|
||||||
";
|
",
|
||||||
|
Metainfo::test_value_single_infohash(),
|
||||||
|
Metainfo::test_value_single_torrent_size().count() - 50
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(have, want);
|
assert_eq!(have, want);
|
||||||
}
|
}
|
||||||
|
@ -458,31 +404,9 @@ files\tfoo
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn trackerless() -> Result<()> {
|
fn trackerless() -> Result<()> {
|
||||||
let metainfo = Metainfo {
|
let mut metainfo = Metainfo::test_value_single();
|
||||||
announce: None,
|
metainfo.announce = None;
|
||||||
announce_list: None,
|
metainfo.announce_list = None;
|
||||||
comment: Some("comment".into()),
|
|
||||||
nodes: Some(vec![
|
|
||||||
"x:12".parse().unwrap(),
|
|
||||||
"1.1.1.1:16".parse().unwrap(),
|
|
||||||
"[2001:0db8:85a3::8a2e:0370]:7334".parse().unwrap(),
|
|
||||||
]),
|
|
||||||
created_by: Some("created by".into()),
|
|
||||||
creation_date: Some(1),
|
|
||||||
encoding: Some("UTF-8".into()),
|
|
||||||
info: Info {
|
|
||||||
private: Some(true),
|
|
||||||
piece_length: Bytes(16 * 1024),
|
|
||||||
source: Some("source".into()),
|
|
||||||
name: "foo".into(),
|
|
||||||
pieces: PieceList::from_pieces(&["abc"]),
|
|
||||||
mode: Mode::Single {
|
|
||||||
length: Bytes(20),
|
|
||||||
md5sum: None,
|
|
||||||
},
|
|
||||||
update_url: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut env = TestEnvBuilder::new()
|
let mut env = TestEnvBuilder::new()
|
||||||
|
@ -497,23 +421,29 @@ files\tfoo
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
|
|
||||||
let have = env.out();
|
let have = env.out();
|
||||||
let want = " Name foo
|
|
||||||
Comment comment
|
#[rustfmt::skip]
|
||||||
|
let want = format!(" Name NAME
|
||||||
|
Comment COMMENT
|
||||||
Creation Date 1970-01-01 00:00:01 UTC
|
Creation Date 1970-01-01 00:00:01 UTC
|
||||||
Created By created by
|
Created By CREATED BY
|
||||||
Source source
|
Source SOURCE
|
||||||
Info Hash b9cd9cae5748518c99d00d8ae86c0162510be4d9
|
Info Hash {}
|
||||||
Torrent Size 261 bytes
|
Torrent Size {}
|
||||||
Content Size 20 bytes
|
Content Size 32 KiB
|
||||||
Private yes
|
Private yes
|
||||||
DHT Nodes x:12
|
Update URL https://update.example/
|
||||||
|
DHT Nodes node.example:12
|
||||||
1.1.1.1:16
|
1.1.1.1:16
|
||||||
[2001:db8:85a3::8a2e:370]:7334
|
[2001:db8:85a3::8a2e:370]:7334
|
||||||
Piece Size 16 KiB
|
Piece Size 16 KiB
|
||||||
Piece Count 1
|
Piece Count 2
|
||||||
File Count 1
|
File Count 1
|
||||||
Files foo
|
Files NAME
|
||||||
";
|
",
|
||||||
|
Metainfo::test_value_single_infohash(),
|
||||||
|
Bytes(Metainfo::test_value_single_torrent_size().count() - 130)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(have, want);
|
assert_eq!(have, want);
|
||||||
}
|
}
|
||||||
|
@ -530,22 +460,99 @@ Creation Date 1970-01-01 00:00:01 UTC
|
||||||
env.assert_ok();
|
env.assert_ok();
|
||||||
|
|
||||||
let have = env.out();
|
let have = env.out();
|
||||||
let want = "\
|
#[rustfmt::skip]
|
||||||
name\tfoo
|
let want = format!(
|
||||||
comment\tcomment
|
"\
|
||||||
|
name\tNAME
|
||||||
|
comment\tCOMMENT
|
||||||
creation date\t1970-01-01 00:00:01 UTC
|
creation date\t1970-01-01 00:00:01 UTC
|
||||||
created by\tcreated by
|
created by\tCREATED BY
|
||||||
source\tsource
|
source\tSOURCE
|
||||||
info hash\tb9cd9cae5748518c99d00d8ae86c0162510be4d9
|
info hash\t{}
|
||||||
torrent size\t261
|
torrent size\t{}
|
||||||
content size\t20
|
content size\t32768
|
||||||
private\tyes
|
private\tyes
|
||||||
dht nodes\tx:12\t1.1.1.1:16\t[2001:db8:85a3::8a2e:370]:7334
|
update url\thttps://update.example/
|
||||||
|
dht nodes\tnode.example:12\t1.1.1.1:16\t[2001:db8:85a3::8a2e:370]:7334
|
||||||
piece size\t16384
|
piece size\t16384
|
||||||
|
piece count\t2
|
||||||
|
file count\t1
|
||||||
|
files\tNAME
|
||||||
|
",
|
||||||
|
Metainfo::test_value_single_infohash(),
|
||||||
|
Metainfo::test_value_single_torrent_size().count() - 130
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(have, want);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unset() -> Result<()> {
|
||||||
|
let metainfo = Metainfo::test_value_single_unset();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut env = TestEnvBuilder::new()
|
||||||
|
.arg_slice(&["imdl", "torrent", "show", "--input", "foo.torrent"])
|
||||||
|
.out_is_term()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let path = env.resolve("foo.torrent")?;
|
||||||
|
|
||||||
|
metainfo.dump(path).unwrap();
|
||||||
|
|
||||||
|
env.assert_ok();
|
||||||
|
|
||||||
|
let have = env.out();
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let want = format!(" Name NAME
|
||||||
|
Info Hash {}
|
||||||
|
Torrent Size {}
|
||||||
|
Content Size 5 bytes
|
||||||
|
Private no
|
||||||
|
Piece Size 1 KiB
|
||||||
|
Piece Count 1
|
||||||
|
File Count 1
|
||||||
|
Files NAME
|
||||||
|
",
|
||||||
|
Metainfo::test_value_single_unset_infohash(),
|
||||||
|
Metainfo::test_value_single_unset_torrent_size()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(have, want);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut env = TestEnvBuilder::new()
|
||||||
|
.arg_slice(&["imdl", "torrent", "show", "--input", "foo.torrent"])
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let path = env.resolve("foo.torrent")?;
|
||||||
|
|
||||||
|
metainfo.dump(path).unwrap();
|
||||||
|
|
||||||
|
env.assert_ok();
|
||||||
|
|
||||||
|
let have = env.out();
|
||||||
|
#[rustfmt::skip]
|
||||||
|
let want = format!(
|
||||||
|
"\
|
||||||
|
name\tNAME
|
||||||
|
info hash\t{}
|
||||||
|
torrent size\t{}
|
||||||
|
content size\t5
|
||||||
|
private\tno
|
||||||
|
piece size\t1024
|
||||||
piece count\t1
|
piece count\t1
|
||||||
file count\t1
|
file count\t1
|
||||||
files\tfoo
|
files\tNAME
|
||||||
";
|
",
|
||||||
|
Metainfo::test_value_single_unset_infohash(),
|
||||||
|
Metainfo::test_value_single_unset_torrent_size().count()
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(have, want);
|
assert_eq!(have, want);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,10 @@ impl TorrentSummary {
|
||||||
table.tiers("Announce List", value);
|
table.tiers("Announce List", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(update_url) = &self.metainfo.info.update_url {
|
||||||
|
table.row("Update URL", update_url);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(nodes) = &self.metainfo.nodes {
|
if let Some(nodes) = &self.metainfo.nodes {
|
||||||
table.list(
|
table.list(
|
||||||
"DHT Nodes",
|
"DHT Nodes",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user