diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..634b2004 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,3 @@ +[alias] +t = "test --release" +c = "tarpaulin --out html --release --lib --fail-under 100" diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 31000a27..3447c343 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -10,13 +10,35 @@ env: CARGO_TERM_COLOR: always jobs: - build: + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: cargo fmt -- --check + clippy: runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: cargo clippy -- -D warnings + + test: + strategy: + matrix: + # https://docs.github.com/en/actions/using-jobs/choosing-the-runner-for-a-job#choosing-github-hosted-runners + os: [windows-latest, ubuntu-latest, macos-13] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - run: cargo t + coverage: + runs-on: macos-13 steps: - uses: actions/checkout@v3 - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose + - run: cargo install cargo-tarpaulin + - run: cargo c + - uses: actions/upload-artifact@v3 + with: + path: tarpaulin-report.html + if: always() \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6985cf1b..c4ee3822 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb +tarpaulin-report.html diff --git a/blockset/src/io.rs b/blockset/src/io.rs new file mode 100644 index 00000000..6ddb84ed --- /dev/null +++ b/blockset/src/io.rs @@ -0,0 +1,48 @@ +use std::io::{self, Read}; + +trait Io { + type File: Read; + fn open(&mut self, path: &str) -> io::Result; + fn read_to_string(&mut self, path: &str) -> io::Result { + let mut file = self.open(path)?; + let mut result = String::default(); + file.read_to_string(&mut result)?; + Ok(result) + } +} + +#[cfg(test)] +mod test { + use std::{ + collections::HashMap, + io::{self, Cursor}, + }; + + use super::Io; + + struct MockIo { + file_map: HashMap>, + } + + impl Io for MockIo { + type File = Cursor>; + + fn open(&mut self, path: &str) -> io::Result { + self.file_map + .get(path) + .map(|data| Cursor::new(data.clone())) + .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "file not found")) + } + } + + #[test] + fn test() { + let mut io = MockIo { + file_map: HashMap::default(), + }; + io.file_map + .insert("test.txt".to_string(), "Hello, world!".as_bytes().to_vec()); + let result = io.read_to_string("test.txt").unwrap(); + assert_eq!(result, "Hello, world!"); + } +} diff --git a/blockset/src/lib.rs b/blockset/src/lib.rs index 7d12d9af..6352663e 100644 --- a/blockset/src/lib.rs +++ b/blockset/src/lib.rs @@ -1,14 +1 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +mod io;