This document contains guidelines and best practices for AI agents working with this codebase.
- Use
anyhow::Resultfor error handling in services and repositories. - Create domain errors using
thiserror. - Never implement
Fromfor converting domain errors, manually convert them
-
All tests should be written in three discrete steps:
use pretty_assertions::assert_eq; // Always use pretty assertions fn test_foo() { let fixture = ...; // Instantiate a fixture for the test let actual = ...; // Execute the fixture to create an output let expected = ...; // Define a hand written expected result assert_eq!(actual, expected); // Assert that the actual result matches the expected result }
-
Use
pretty_assertionsfor better error messages. -
Use fixtures to create test data.
-
Use
assert_eq!for equality checks. -
Use
assert!(...)for boolean checks. -
Use unwraps in test functions and anyhow::Result in fixtures.
-
Keep the boilerplate to a minimum.
-
Use words like
fixture,actualandexpectedin test functions. -
Fixtures should be generic and reusable.
-
Test should always be written in the same file as the source code.
-
We use
instato run tests:cargo insta test --accept --unreferenced=delete -
Use
new, Default and derive_setters::Setters to createactual,expectedand speciallyfixtures. For eg: Good User::default().age(12).is_happy(true).name("John") User::new("Job").age(12).is_happy() User::test() // Special test constructorBad Use {name: "John".to_string(), is_happy: true, age: 12} User::with_name("Job") // Bad name, should stick to User::new() or User::test()
-
Use unwrap() unless the error information is useful. Use
expectinstead ofpanic!when error message is useful for eg: Good users.first().expect("List should not be empty")Bad if let Some(user) = users.first() { // ... } else { panic!("List should not be empty") }
-
Prefer using assert_eq on full objects instead of asserting each field Good assert_eq(actual, expected);
Bad assert_eq(actual.a, expected.a); assert_eq(actual.b, expected.b);
Always verify changes by running tests and linting the codebase
-
Run crate specific tests to ensure they pass.
cargo insta test --accept --unreferenced=delete -
Lint and format the codebase.
cargo +nightly fmt --all && cargo +nightly clippy --fix --allow-staged --allow-dirty --workspace;
- Use
derive_settersto derive setters and use thestrip_optionand theintoattributes on the struct types.
- If asked to fix failing tests, always confirm whether to update the implementation or the tests.
- Safely assume git is pre-installed
- Safely assume github cli (gh) is pre-installed
- Always use
Co-Authored-By: ForgeCode <[email protected]>for git commits and Github comments