Use fake connection in tests
Dependencies
- [2]
J7MKV7UTRefactor UI trait, add fake ui - [3]
WGRFJRTEAdd tests, rename Status to Header, implement redirect and proper input handling - [4]
ARXVO5XAMake connection generic on the network - [5]
ONQEIR5BWIP mime-type handling - [6]
JWLMAS7USimplify tests with rstest - [7]
FZIABKEVNew tests, refactor to be more modular, improve prompt ui, add test run parameter - [8]
DBKKKHC2Initial commit - [9]
3SPNKI46Improve parsing. Add modules that were missed - [10]
AMTMTTJTUpgrade status parsing - [11]
3VVQWLOXMajor refactor: modularisation
Change contents
- replacement in src/network.rs at line 13
fn connect(url: &Url) -> Result<Self::Connection, Self::Error>;fn connect(&mut self, url: &Url) -> Result<Self::Connection, Self::Error>; - replacement in src/network.rs at line 17
verifier: V,_verifier: V, - replacement in src/network.rs at line 22
Self { verifier: ver }Self { _verifier: ver } - replacement in src/network.rs at line 30
fn connect(url: &Url) -> Result<Self::Connection, Self::Error> {fn connect(&mut self, url: &Url) -> Result<Self::Connection, Self::Error> { - edit in src/main.rs at line 39[3.2344]→[2.779:1847](∅→∅),[3.1468]→[3.2456:2462](∅→∅),[2.1847]→[3.2456:2462](∅→∅),[3.2456]→[3.2456:2462](∅→∅),[3.2678]→[3.319:321](∅→∅),[3.319]→[3.319:321](∅→∅),[3.3924]→[3.5052:5115](∅→∅)
/// User interface that records method calls and returns canned inputs#[cfg(test)]#[derive(Default)]struct FakeUi {inputs: Vec<String>,events: Vec<FUIEvent>,}#[cfg(test)]enum FUIEvent {//TODO figure out how to solve lifetime issues// and store Media in this variant// Or just convert it to a string? idkShow,Warn(String),Read(String),ReadSecret(String),}#[cfg(test)]impl FakeUi {pub fn new() -> Self {Default::default()}}#[cfg(test)]impl Ui for FakeUi {fn show(&mut self, _content: media::Media) {self.events.push(FUIEvent::Show)}fn warn<D: Display>(&mut self, warning: D) {self.events.push(FUIEvent::Warn(warning.to_string()))}fn read(&mut self, prompt: impl Display) -> Option<String> {self.events.push(FUIEvent::Read(prompt.to_string()));self.inputs.pop()}fn read_secret(&mut self, prompt: impl Display) -> Option<String> {self.events.push(FUIEvent::ReadSecret(prompt.to_string()));self.inputs.pop()}}// TODO make tests using a fake connection to a local buffer - edit in src/main.rs at line 57
use std::{cell::RefCell,fmt::Display,io::{Read, Write},rc::Rc,}; - replacement in src/main.rs at line 67
use crate::NopUi;use crate::{media, network::Network, NopUi, Ui}; - replacement in src/main.rs at line 73
crate::core::run_url::<crate::network::TcpNetwork<crate::danger::Naive>>(&mut NopUi, url);let mut net = crate::network::TcpNetwork::new(crate::danger::Naive);crate::core::run_url(&mut net, &mut NopUi, url); - replacement in src/main.rs at line 79
let body: &[u8] = b"some text\r\n";let url: Url = "gemini://gemini.circumlunar.space".parse().unwrap();let response = "20 \r\nsome text\r\n";let body = "some text\r\n";let mut fui = FakeUi::new();let mut net = FakeNet::new(FakeConn::new(response.into()));crate::core::run_url(&mut net, &mut fui, url.clone());let net_sink = Rc::try_unwrap(net.conn.0).unwrap().into_inner().sink;let net_sink = String::from_utf8(net_sink).unwrap();assert_eq!(net_sink, format!("{}\r\n", url));let ui_sink = fui.sink;assert_eq!(ui_sink.as_ref(), [FUIEvent::Show]);}/// User interface that records method calls and returns canned inputs#[derive(Default)]struct FakeUi {source: Vec<String>,sink: Vec<FUIEvent>,}#[derive(Debug, PartialEq, PartialOrd, Ord, Eq)]enum FUIEvent {//TODO figure out how to solve lifetime issues// and store Media in this variant// Or just convert it to a string? idkShow,Warn(String),Read(String),ReadSecret(String),}impl FakeUi {pub fn new() -> Self {Default::default()}}impl Ui for FakeUi {fn show(&mut self, content: media::Media) {self.sink.push(FUIEvent::Show)}fn warn<D: Display>(&mut self, warning: D) {self.sink.push(FUIEvent::Warn(warning.to_string()))}fn read(&mut self, prompt: impl Display) -> Option<String> {self.sink.push(FUIEvent::Read(prompt.to_string()));self.source.pop()}fn read_secret(&mut self, prompt: impl Display) -> Option<String> {self.sink.push(FUIEvent::ReadSecret(prompt.to_string()));self.source.pop()}}#[derive(Debug)]struct FakeNet {conn: SharedFakeConn,}impl FakeNet {fn new(conn: FakeConn) -> Self {Self {conn: SharedFakeConn(Rc::new(RefCell::new(conn))),}}}#[derive(Clone, Debug)]struct SharedFakeConn(Rc<RefCell<FakeConn>>);#[derive(Debug)]struct FakeConn {sink: Vec<u8>,source: Vec<u8>,}impl FakeConn {fn new(source: String) -> Self {Self {sink: Vec::new(),source: source.into_bytes(),}}}impl Read for SharedFakeConn {fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {self.0.borrow_mut().read(buf)}}impl Write for SharedFakeConn {fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {self.0.borrow_mut().write(buf)}fn flush(&mut self) -> std::io::Result<()> {self.0.borrow_mut().flush()}}impl Read for FakeConn {fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {(&*self.source).read(buf)}}impl Write for FakeConn {fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {self.sink.write(buf)}fn flush(&mut self) -> std::io::Result<()> {self.sink.flush()}}impl Network for FakeNet {type Error = &'static str;type Connection = SharedFakeConn;fn connect(&mut self, _: &Url) -> Result<Self::Connection, Self::Error> {Ok(self.conn.clone())} - edit in src/main.rs at line 199
// TODO make tests using a fake connection to a local buffer - replacement in src/core.rs at line 8
pub fn run<N: Network>(ui: &mut impl Ui, mut url: Url)pub fn run<N: Network>(net: &mut N, ui: &mut impl Ui, mut url: Url) - replacement in src/core.rs at line 12
while let Some(new_url) = run_url::<N>(ui, url) {while let Some(new_url) = run_url(net, ui, url) { - replacement in src/core.rs at line 17
pub(crate) fn run_url<N: Network>(ui: &mut impl Ui, url: Url) -> Option<Url>pub(crate) fn run_url<N: Network>(net: &mut N, ui: &mut impl Ui, url: Url) -> Option<Url> - replacement in src/core.rs at line 22
let mut stream = N::connect(&url).expect("Failed to connect");let mut stream = net.connect(&url).expect("Failed to connect"); - replacement in src/core.rs at line 122
.unwrap();.expect("failed to read input from ui"); - replacement in src/cli.rs at line 39
run::<TcpNetwork<danger::Naive>>(&mut cli, url);let mut net = TcpNetwork::new(danger::Naive);run(&mut net, &mut cli, url); - edit in Cargo.toml at line 19
thiserror = "1.0.43" - replacement in Cargo.lock at line 141
"syn 2.0.13","syn 2.0.23", - replacement in Cargo.lock at line 251
"syn 2.0.13","syn 2.0.23", - edit in Cargo.lock at line 304
"thiserror", - replacement in Cargo.lock at line 430
"syn 2.0.13","syn 2.0.23", - replacement in Cargo.lock at line 469
version = "1.0.56"version = "1.0.63" - replacement in Cargo.lock at line 471
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" - replacement in Cargo.lock at line 478
version = "1.0.26"version = "1.0.29" - replacement in Cargo.lock at line 480
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" - replacement in Cargo.lock at line 654
version = "2.0.13"version = "2.0.23" - replacement in Cargo.lock at line 656
checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec"checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" - edit in Cargo.lock at line 664
name = "thiserror"version = "1.0.43"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42"dependencies = ["thiserror-impl",][[package]]name = "thiserror-impl"version = "1.0.43"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f"dependencies = ["proc-macro2","quote","syn 2.0.23",][[package]]