Skip to content

Latest commit

 

History

History
107 lines (78 loc) · 2.64 KB

notes.md

File metadata and controls

107 lines (78 loc) · 2.64 KB

You have to write a file parser. The first test is:

use std::path::{PathBuf, Path};

#[derive(Default, Debug, PartialEq)]
struct Matrix { rows: usize, cols: usize, data: Vec<i32> }

impl<P: AsRef<Path>> From<P> for Matrix { fn from(_: P) -> Self { Default::default() } }

fn create_empty_file() -> PathBuf { "".into() }

#[test]
fn should_parse_empty_file() {
     let empty = create_empty_file();

     let matrix: Matrix = Matrix::from(empty);

     assert_eq!(matrix, Default::default())
}

Ok, create_empty_file() should do a lot of job and can be reused in other tests and fixtures: it's a good candidate to be a fixture. Let's rewrite previous example by use rstest: we'll use empty for fixture instead of create_empty_file() because when we use as fixture will be an object instead an action.

use std::path::{PathBuf, Path};

use rstest::*;

#[derive(Default, Debug, PartialEq)]
struct Matrix { rows: usize, cols: usize, data: Vec<i32> }
impl<P: AsRef<Path>> From<P> for Matrix { fn from(_: P) -> Self { Default::default() } }

#[fixture]
fn empty() -> PathBuf {
     let path = "empty_file".into();
     std::fs::File::create(&path).expect("Cannot open");
     path
}

#[rstest]
fn should_parse_empty_file(empty: PathBuf) {
     let matrix: Matrix = Matrix::from(empty);

     assert_eq!(matrix, Default::default())
}

Now our Matrix's From trait is a little bit more generic and can take every struct that implement AsRef<Path> like PathBuf do. So we can generalize our test too:

use std::path::{PathBuf, Path};

use rstest::*;

#[derive(Default, Debug, PartialEq)]
struct Matrix { rows: usize, cols: usize, data: Vec<i32> }

impl<P: AsRef<Path>> From<P> for Matrix { fn from(_: P) -> Self { Default::default() } }

#[rstest]
fn should_parse_empty_file<P>(empty: P)
     where P: AsRef<Path>
{
     let matrix: Matrix = Matrix::from(empty);

     assert_eq!(matrix, Default::default())
}

Our test is neat and clear but we have a big issue to fix: we cannot leave "empty_file" on our disk, we must remove it we are done! That is a job for Rust ownership!!

We should just wrap PathBuf in out TempFile struct and implement both Drop and AsRef<Path> traits. We'll use Drop to delete it.

use std::path::{PathBuf, Path};

use rstest::*;

struct TempFile(PathBuf);

impl Drop for TempFile {fn drop(&mut self) {
         std::fs::remove_file(&self.0).unwrap();
     }
}

impl AsRef<Path> for TempFile {
    fn as_ref(&self) -> &Path {
        &self.0
    }
}

#[fixture]
fn empty() -> TempFile {
     let path = "empty_file".into();
     std::fs::File::create(&path).expect("Cannot open");
     TempFile(path)
}