diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 0000000..34d6230
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,26 @@
+[alias]
+cov = "llvm-cov"
+cov-lcov = "llvm-cov --lcov --output-path=./.coverage/lcov.info"
+cov-html = "llvm-cov --html"
+time = "build --timings --all-targets"
+
+[build]
+rustflags = [
+ "-D",
+ "warnings",
+ "-D",
+ "future-incompatible",
+ "-D",
+ "let-underscore",
+ "-D",
+ "nonstandard-style",
+ "-D",
+ "rust-2018-compatibility",
+ "-D",
+ "rust-2018-idioms",
+ "-D",
+ "rust-2021-compatibility",
+ "-D",
+ "unused",
+]
+
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..d33c180
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1 @@
+@josecelano
diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml
new file mode 100644
index 0000000..becfbc1
--- /dev/null
+++ b/.github/dependabot.yaml
@@ -0,0 +1,19 @@
+version: 2
+updates:
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: daily
+ target-branch: "develop"
+ labels:
+ - "Continuous Integration"
+ - "Dependencies"
+
+ - package-ecosystem: cargo
+ directory: /
+ schedule:
+ interval: daily
+ target-branch: "develop"
+ labels:
+ - "Build | Project System"
+ - "Dependencies"
diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml
new file mode 100644
index 0000000..4c2e45a
--- /dev/null
+++ b/.github/workflows/testing.yaml
@@ -0,0 +1,126 @@
+name: Testing
+
+on:
+ push:
+ pull_request:
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ format:
+ name: Formatting
+ runs-on: ubuntu-latest
+
+ steps:
+ - id: checkout
+ name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - id: setup
+ name: Setup Toolchain
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: nightly
+ components: rustfmt
+
+ - id: cache
+ name: Enable Workflow Cache
+ uses: Swatinem/rust-cache@v2
+
+ - id: format
+ name: Run Formatting-Checks
+ run: cargo fmt --check
+
+ check:
+ name: Static Analysis
+ runs-on: ubuntu-latest
+ needs: format
+
+ strategy:
+ matrix:
+ toolchain: [nightly, stable]
+
+ steps:
+ - id: checkout
+ name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - id: setup
+ name: Setup Toolchain
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: ${{ matrix.toolchain }}
+ components: clippy
+
+ - id: cache
+ name: Enable Workflow Cache
+ uses: Swatinem/rust-cache@v2
+
+ - id: tools
+ name: Install Tools
+ uses: taiki-e/install-action@v2
+ with:
+ tool: cargo-machete
+
+ - id: check
+ name: Run Build Checks
+ run: cargo check --tests --benches --examples --workspace --all-targets --all-features
+
+ - id: lint
+ name: Run Lint Checks
+ run: cargo clippy --tests --benches --examples --workspace --all-targets --all-features -- -D clippy::correctness -D clippy::suspicious -D clippy::complexity -D clippy::perf -D clippy::style -D clippy::pedantic
+
+ - id: docs
+ name: Lint Documentation
+ env:
+ RUSTDOCFLAGS: "-D warnings"
+ run: cargo doc --no-deps --bins --examples --workspace --all-features
+
+ - id: clean
+ name: Clean Build Directory
+ run: cargo clean
+
+ - id: deps
+ name: Check Unused Dependencies
+ run: cargo machete
+
+
+ unit:
+ name: Units
+ runs-on: ubuntu-latest
+ needs: check
+
+ strategy:
+ matrix:
+ toolchain: [nightly, stable]
+
+ steps:
+ - id: checkout
+ name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - id: setup
+ name: Setup Toolchain
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: ${{ matrix.toolchain }}
+ components: llvm-tools-preview
+
+ - id: cache
+ name: Enable Job Cache
+ uses: Swatinem/rust-cache@v2
+
+ - id: tools
+ name: Install Tools
+ uses: taiki-e/install-action@v2
+ with:
+ tool: cargo-llvm-cov, cargo-nextest
+
+ - id: test-docs
+ name: Run Documentation Tests
+ run: cargo test --doc
+
+ - id: test
+ name: Run Unit Tests
+ run: cargo test --tests --benches --examples --workspace --all-targets --all-features
diff --git a/.gitignore b/.gitignore
index ea8c4bf..c552776 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,9 @@
+.env
+**/*.rs.bk
+/.coverage/
+/.idea/
+/.vscode/launch.json
+/flamegraph.svg
/target
+callgrind.out
+perf.data*
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..934a43e
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,7 @@
+{
+ "recommendations": [
+ "streetsidesoftware.code-spell-checker",
+ "rust-lang.rust-analyzer",
+ "tamasfe.even-better-toml"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..caa48dd
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,35 @@
+{
+ "[rust]": {
+ "editor.formatOnSave": true
+ },
+ "[ignore]": { "rust-analyzer.cargo.extraEnv" : {
+ "RUSTFLAGS": "-Z profile -C codegen-units=1 -C inline-threshold=0 -C link-dead-code -C overflow-checks=off -C panic=abort -Z panic_abort_tests",
+ "RUSTDOCFLAGS": "-Z profile -C codegen-units=1 -C inline-threshold=0 -C link-dead-code -C overflow-checks=off -C panic=abort -Z panic_abort_tests",
+ "CARGO_INCREMENTAL": "0",
+ "RUST_BACKTRACE": "1"
+ }},
+ "rust-analyzer.checkOnSave": true,
+ "rust-analyzer.check.command": "clippy",
+ "rust-analyzer.check.allTargets": true,
+ "rust-analyzer.check.extraArgs": [
+ "--",
+ "-D",
+ "clippy::correctness",
+ "-D",
+ "clippy::suspicious",
+ "-W",
+ "clippy::complexity",
+ "-W",
+ "clippy::perf",
+ "-W",
+ "clippy::style",
+ "-W",
+ "clippy::pedantic"
+ ],
+ "evenBetterToml.formatter.allowedBlankLines": 1,
+ "evenBetterToml.formatter.columnWidth": 130,
+ "evenBetterToml.formatter.trailingNewline": true,
+ "evenBetterToml.formatter.reorderKeys": true,
+ "evenBetterToml.formatter.reorderArrays": true,
+
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 5f1632d..db07c5b 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# Testing in Rust
+[![Testing](https://github.com/nautilus-cyberneering/testing-in-rust/actions/workflows/testing.yaml/badge.svg)](https://github.com/nautilus-cyberneering/testing-in-rust/actions/workflows/testing.yaml)
+
A collection of articles about testing in Rust.
- [Custom mocks in Rust](./docs/custom-mocks-in-rust.md).
@@ -8,7 +10,7 @@ A collection of articles about testing in Rust.
## Links
- ["Unit Testing" book](https://www.manning.com/books/unit-testing) by [Vladimir Khorikov](https://github.com/vkhorikov).
-- [Mockall](https://github.com/asomers/mockall). A powerful mock object library for Rust().
+- [Mockall](https://github.com/asomers/mockall). A powerful mock object library for Rust.
- [Rust book. "A Use Case for Interior Mutability: Mock Objects"](https://doc.rust-lang.org/book/ch15-05-interior-mutability.html#a-use-case-for-interior-mutability-mock-objects) by [Steve Klabnik](https://steveklabnik.com/) and [Carol Nichols](http://carol-nichols.com/).
- [Mock Objects (manually) in Rust](https://paytonrules.com/post/mock-objects-in-rust/) by [Eric Smith](https://github.com/paytonrules).
- [A guide to mocking in Rust using Mockall](https://blog.logrocket.com/guide-mocking-rust-mockall/) by Manish Shivanandhan.
diff --git a/docs/custom-mocks-in-rust.md b/docs/custom-mocks-in-rust.md
index f3c6d1e..f18992a 100644
--- a/docs/custom-mocks-in-rust.md
+++ b/docs/custom-mocks-in-rust.md
@@ -72,7 +72,7 @@ fn the_tracker_should_send_a_connect_event_after_connecting() {
// Test using a custom mock for the TrackerEventSender
let event_sender = Rc::new(TrackerEventSenderMock::new());
- let tracker = Arc::new(Tracker::new(event_sender.clone()));
+ let tracker = Rc::new(Tracker::new(event_sender.clone()));
tracker.connect();
@@ -88,7 +88,7 @@ self.sent_event = Some(event);
Since the `self` reference is not mutable, you can not change the `sent_event` value.
-I needed to learn how to implement it, and [Cameron](https://github.com/da2ce7) pointed me to the solution. The not mutable `self` reference does not allow you to change the attributes in the struct, but it's not recursive. Rust has some types that allow you to change the interior mutability.
+I needed to learn how to implement it, and [Cameron](https://github.com/da2ce7) pointed me to the solution. The immutable `self` reference does not allow you to change the attributes in the struct, but it's not recursive. Rust has some types that allow you to change the interior mutability.
Rust has a pattern called the ["Interior Mutability Pattern"](https://doc.rust-lang.org/book/ch15-05-interior-mutability.html#refcellt-and-the-interior-mutability-pattern).
@@ -111,39 +111,39 @@ From the Rust book, you can see the different types to "bend" Rust rules:
The final test was like this:
```rust
- #[derive(Clone)]
- struct TrackerEventSenderMock {
- pub sent_event: RefCell