agy-superpowers 5.2.2 → 5.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/rules/scratch-scripts.md +37 -0
  4. package/template/agent/rules/superpowers.md +4 -51
  5. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  6. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  7. package/template/agent/skills/api-design/SKILL.md +0 -193
  8. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  9. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  10. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  11. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  12. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  13. package/template/agent/skills/community-manager/SKILL.md +0 -115
  14. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  15. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  16. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  17. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  18. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  19. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  20. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  21. package/template/agent/skills/game-design/SKILL.md +0 -194
  22. package/template/agent/skills/game-developer/SKILL.md +0 -175
  23. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  24. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  25. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  26. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  27. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  28. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  29. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  30. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  31. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  32. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  33. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  34. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  35. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  36. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  37. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  38. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  39. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  40. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  41. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  42. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  43. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  44. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  45. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  46. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  47. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  48. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  49. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  50. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  53. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  54. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  55. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  56. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  57. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  58. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  59. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  60. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  61. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  62. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  63. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  64. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  65. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  68. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  69. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  70. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  71. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  72. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  73. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  74. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  75. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  76. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  77. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  78. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  79. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  80. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  83. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  84. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  85. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  86. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  87. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  88. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  89. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  90. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  91. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  92. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  93. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  94. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  95. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  96. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  97. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  98. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  99. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  100. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  101. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  102. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  103. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  104. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  105. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  106. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  107. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  108. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  109. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  110. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  111. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  112. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  113. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  114. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  115. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  116. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  117. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  118. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  119. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  120. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  121. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  122. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  123. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  124. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  125. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  126. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  127. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  128. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  129. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  132. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  133. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  134. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  135. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  136. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  137. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  138. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  139. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  140. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  141. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  142. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  143. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  144. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  148. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  149. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  150. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  151. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  152. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  153. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  154. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  155. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  156. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  157. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  158. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  159. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  160. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  161. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  162. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  163. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  164. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  165. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  166. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  167. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  168. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  169. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  170. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  171. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  172. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  173. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  174. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  175. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  176. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  177. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  178. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  179. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  180. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  181. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  182. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  183. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  184. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  185. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  186. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  187. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  188. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  189. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  190. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  191. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  192. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  193. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  194. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  195. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  196. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  197. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  198. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  199. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  200. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  201. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  202. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  203. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  204. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  205. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  206. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  207. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  208. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  209. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  210. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  211. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  212. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  213. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  214. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  215. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  216. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  217. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  218. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  219. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  220. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,144 +0,0 @@
1
- # test-integration-dir
2
-
3
- > Put integration tests in the `tests/` directory
4
-
5
- ## Why It Matters
6
-
7
- Integration tests live in `tests/` at the crate root, separate from `src/`. Each file in `tests/` is compiled as a separate crate, testing your library's public API as external users would. This separation ensures you're testing the real public interface, not implementation details.
8
-
9
- ## Structure
10
-
11
- ```
12
- my_project/
13
- ├── Cargo.toml
14
- ├── src/
15
- │ ├── lib.rs
16
- │ └── internal.rs
17
- └── tests/
18
- ├── integration_test.rs # Each file is a separate test binary
19
- ├── api_tests.rs
20
- └── common/ # Shared test utilities
21
- └── mod.rs
22
- ```
23
-
24
- ## Bad
25
-
26
- ```rust
27
- // src/lib.rs
28
- // Mixing integration test logic in library code
29
- #[test]
30
- fn integration_test_full_workflow() {
31
- // This is a unit test location, not integration
32
- }
33
- ```
34
-
35
- ## Good
36
-
37
- ```rust
38
- // tests/integration_test.rs
39
- use my_crate::{Client, Config}; // Uses public API only
40
-
41
- #[test]
42
- fn test_full_workflow() {
43
- let config = Config::default();
44
- let client = Client::new(config);
45
-
46
- let result = client.process("input");
47
- assert!(result.is_ok());
48
- }
49
-
50
- #[test]
51
- fn test_error_handling() {
52
- let client = Client::new(Config::strict());
53
-
54
- let result = client.process("invalid");
55
- assert!(matches!(result, Err(Error::InvalidInput { .. })));
56
- }
57
- ```
58
-
59
- ## Shared Test Utilities
60
-
61
- ```rust
62
- // tests/common/mod.rs
63
- use my_crate::Config;
64
-
65
- pub fn test_config() -> Config {
66
- Config {
67
- timeout: Duration::from_secs(5),
68
- retries: 3,
69
- debug: true,
70
- }
71
- }
72
-
73
- pub fn setup_test_environment() {
74
- // Set up test fixtures
75
- }
76
-
77
- // tests/api_tests.rs
78
- mod common;
79
-
80
- use my_crate::Client;
81
-
82
- #[test]
83
- fn test_with_shared_config() {
84
- common::setup_test_environment();
85
- let client = Client::new(common::test_config());
86
- // ...
87
- }
88
- ```
89
-
90
- ## Organizing Many Tests
91
-
92
- ```rust
93
- // tests/api/mod.rs
94
- mod auth;
95
- mod users;
96
- mod orders;
97
-
98
- // tests/api/auth.rs
99
- use my_crate::auth::{login, logout};
100
-
101
- #[test]
102
- fn test_login_success() { ... }
103
-
104
- #[test]
105
- fn test_login_invalid_credentials() { ... }
106
-
107
- // tests/api/users.rs
108
- use my_crate::users::{create_user, get_user};
109
-
110
- #[test]
111
- fn test_create_user() { ... }
112
- ```
113
-
114
- ## Integration vs Unit Tests
115
-
116
- | Unit Tests | Integration Tests |
117
- |------------|-------------------|
118
- | In `src/` with `#[cfg(test)]` | In `tests/` directory |
119
- | Access private items | Public API only |
120
- | Test individual functions | Test module interactions |
121
- | Fast, isolated | May be slower |
122
- | `cargo test --lib` | `cargo test --test '*'` |
123
-
124
- ## Running Specific Tests
125
-
126
- ```bash
127
- # Run all tests
128
- cargo test
129
-
130
- # Run only integration tests
131
- cargo test --test '*'
132
-
133
- # Run specific integration test file
134
- cargo test --test integration_test
135
-
136
- # Run tests matching pattern
137
- cargo test --test api_tests test_login
138
- ```
139
-
140
- ## See Also
141
-
142
- - [test-cfg-test-module](./test-cfg-test-module.md) - Unit test modules
143
- - [test-descriptive-names](./test-descriptive-names.md) - Test naming
144
- - [test-tokio-async](./test-tokio-async.md) - Async integration tests
@@ -1,189 +0,0 @@
1
- # test-mock-traits
2
-
3
- > Use traits for dependencies to enable mocking in tests
4
-
5
- ## Why It Matters
6
-
7
- Concrete dependencies make testing hard—you can't easily test error paths, timeouts, or edge cases without real external systems. Extracting dependencies behind traits lets you inject test doubles (mocks, fakes, stubs), enabling isolated unit tests that run fast and cover edge cases.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- struct UserService {
13
- db: PostgresConnection, // Concrete type - hard to test
14
- }
15
-
16
- impl UserService {
17
- async fn get_user(&self, id: u64) -> Result<User, Error> {
18
- // Directly calls Postgres - needs real database to test
19
- self.db.query("SELECT * FROM users WHERE id = $1", &[&id]).await
20
- }
21
- }
22
-
23
- // Test requires real Postgres instance
24
- #[tokio::test]
25
- async fn test_get_user() {
26
- let db = PostgresConnection::connect("postgres://...").await?;
27
- let service = UserService { db };
28
- // Slow, flaky, can't test error paths
29
- }
30
- ```
31
-
32
- ## Good
33
-
34
- ```rust
35
- // Define trait for dependency
36
- #[async_trait]
37
- trait UserRepository: Send + Sync {
38
- async fn find_by_id(&self, id: u64) -> Result<Option<User>, DbError>;
39
- async fn save(&self, user: &User) -> Result<(), DbError>;
40
- }
41
-
42
- // Production implementation
43
- struct PostgresUserRepo {
44
- pool: PgPool,
45
- }
46
-
47
- #[async_trait]
48
- impl UserRepository for PostgresUserRepo {
49
- async fn find_by_id(&self, id: u64) -> Result<Option<User>, DbError> {
50
- sqlx::query_as("SELECT * FROM users WHERE id = $1")
51
- .bind(id)
52
- .fetch_optional(&self.pool)
53
- .await
54
- }
55
- // ...
56
- }
57
-
58
- // Service depends on trait, not concrete type
59
- struct UserService<R: UserRepository> {
60
- repo: R,
61
- }
62
-
63
- impl<R: UserRepository> UserService<R> {
64
- async fn get_user(&self, id: u64) -> Result<User, Error> {
65
- self.repo.find_by_id(id).await?
66
- .ok_or(Error::NotFound)
67
- }
68
- }
69
-
70
- // Test with mock
71
- #[cfg(test)]
72
- mod tests {
73
- struct MockUserRepo {
74
- users: HashMap<u64, User>,
75
- }
76
-
77
- #[async_trait]
78
- impl UserRepository for MockUserRepo {
79
- async fn find_by_id(&self, id: u64) -> Result<Option<User>, DbError> {
80
- Ok(self.users.get(&id).cloned())
81
- }
82
- // ...
83
- }
84
-
85
- #[tokio::test]
86
- async fn test_get_user_found() {
87
- let mut mock = MockUserRepo { users: HashMap::new() };
88
- mock.users.insert(1, User { id: 1, name: "Alice".into() });
89
-
90
- let service = UserService { repo: mock };
91
- let user = service.get_user(1).await.unwrap();
92
-
93
- assert_eq!(user.name, "Alice");
94
- }
95
-
96
- #[tokio::test]
97
- async fn test_get_user_not_found() {
98
- let mock = MockUserRepo { users: HashMap::new() };
99
- let service = UserService { repo: mock };
100
-
101
- let result = service.get_user(999).await;
102
- assert!(matches!(result, Err(Error::NotFound)));
103
- }
104
- }
105
- ```
106
-
107
- ## mockall Crate
108
-
109
- ```rust
110
- use mockall::*;
111
- use mockall::predicate::*;
112
-
113
- #[automock]
114
- #[async_trait]
115
- trait Database: Send + Sync {
116
- async fn query(&self, sql: &str) -> Result<Vec<Row>, Error>;
117
- }
118
-
119
- #[tokio::test]
120
- async fn test_with_mockall() {
121
- let mut mock = MockDatabase::new();
122
-
123
- mock.expect_query()
124
- .with(eq("SELECT 1"))
125
- .times(1)
126
- .returning(|_| Ok(vec![Row::new()]));
127
-
128
- let result = mock.query("SELECT 1").await;
129
- assert!(result.is_ok());
130
- }
131
- ```
132
-
133
- ## Testing Error Paths
134
-
135
- ```rust
136
- #[async_trait]
137
- trait HttpClient: Send + Sync {
138
- async fn get(&self, url: &str) -> Result<Response, HttpError>;
139
- }
140
-
141
- struct FailingClient;
142
-
143
- #[async_trait]
144
- impl HttpClient for FailingClient {
145
- async fn get(&self, _url: &str) -> Result<Response, HttpError> {
146
- Err(HttpError::Timeout) // Always fails
147
- }
148
- }
149
-
150
- #[tokio::test]
151
- async fn test_handles_timeout() {
152
- let client = FailingClient;
153
- let service = ApiService { client };
154
-
155
- let result = service.fetch_data().await;
156
- assert!(matches!(result, Err(Error::NetworkError(_))));
157
- }
158
- ```
159
-
160
- ## Dynamic Dispatch Alternative
161
-
162
- ```rust
163
- // When you don't want generics everywhere
164
- struct UserService {
165
- repo: Box<dyn UserRepository>,
166
- }
167
-
168
- impl UserService {
169
- fn new(repo: impl UserRepository + 'static) -> Self {
170
- Self { repo: Box::new(repo) }
171
- }
172
- }
173
-
174
- // Slight runtime cost but cleaner API
175
- ```
176
-
177
- ## Cargo.toml
178
-
179
- ```toml
180
- [dev-dependencies]
181
- mockall = "0.11"
182
- async-trait = "0.1" # For async trait mocking
183
- ```
184
-
185
- ## See Also
186
-
187
- - [api-sealed-trait](./api-sealed-trait.md) - Trait design
188
- - [test-proptest-properties](./test-proptest-properties.md) - Property-based testing
189
- - [proj-lib-main-split](./proj-lib-main-split.md) - Testable architecture
@@ -1,226 +0,0 @@
1
- # test-mockall-mocking
2
-
3
- > Use mockall for trait mocking
4
-
5
- ## Why It Matters
6
-
7
- Unit tests should isolate the code under test from external dependencies (databases, APIs, file systems). Mockall generates mock implementations of traits, allowing you to control and verify behavior without real dependencies.
8
-
9
- ## Setup
10
-
11
- ```toml
12
- # Cargo.toml
13
- [dev-dependencies]
14
- mockall = "0.12"
15
- ```
16
-
17
- ## Basic Usage
18
-
19
- ```rust
20
- use mockall::automock;
21
-
22
- #[automock]
23
- trait Database {
24
- fn get_user(&self, id: u64) -> Option<User>;
25
- fn save_user(&self, user: &User) -> Result<(), Error>;
26
- }
27
-
28
- #[cfg(test)]
29
- mod tests {
30
- use super::*;
31
- use mockall::predicate::*;
32
-
33
- #[test]
34
- fn test_get_user() {
35
- let mut mock = MockDatabase::new();
36
-
37
- mock.expect_get_user()
38
- .with(eq(42))
39
- .returning(|_| Some(User { id: 42, name: "Alice".into() }));
40
-
41
- let service = UserService::new(mock);
42
- let user = service.find_user(42);
43
-
44
- assert_eq!(user.unwrap().name, "Alice");
45
- }
46
- }
47
- ```
48
-
49
- ## Expectations
50
-
51
- ```rust
52
- #[cfg(test)]
53
- mod tests {
54
- use super::*;
55
-
56
- #[test]
57
- fn test_save_calls() {
58
- let mut mock = MockDatabase::new();
59
-
60
- // Expect exactly one call
61
- mock.expect_save_user()
62
- .times(1)
63
- .returning(|_| Ok(()));
64
-
65
- // Expect call with specific argument
66
- mock.expect_get_user()
67
- .with(eq(42))
68
- .returning(|_| Some(User::default()));
69
-
70
- // Expect multiple calls
71
- mock.expect_get_user()
72
- .times(3..) // At least 3 times
73
- .returning(|_| None);
74
-
75
- // Expectations are verified on drop
76
- }
77
- }
78
- ```
79
-
80
- ## Predicates
81
-
82
- ```rust
83
- use mockall::predicate::*;
84
-
85
- mock.expect_process()
86
- .with(eq(42)) // Exact match
87
- .returning(|_| Ok(()));
88
-
89
- mock.expect_validate()
90
- .with(function(|s: &str| s.len() > 5)) // Custom predicate
91
- .returning(|_| true);
92
-
93
- mock.expect_search()
94
- .withf(|query, limit| { // Multiple args
95
- query.len() < 100 && *limit <= 1000
96
- })
97
- .returning(|_, _| vec![]);
98
- ```
99
-
100
- ## Sequences
101
-
102
- ```rust
103
- use mockall::Sequence;
104
-
105
- #[test]
106
- fn test_ordered_calls() {
107
- let mut seq = Sequence::new();
108
- let mut mock = MockDatabase::new();
109
-
110
- mock.expect_connect()
111
- .times(1)
112
- .in_sequence(&mut seq)
113
- .returning(|| Ok(()));
114
-
115
- mock.expect_query()
116
- .times(1)
117
- .in_sequence(&mut seq)
118
- .returning(|_| Ok(vec![]));
119
-
120
- mock.expect_disconnect()
121
- .times(1)
122
- .in_sequence(&mut seq)
123
- .returning(|| Ok(()));
124
- }
125
- ```
126
-
127
- ## Return Values
128
-
129
- ```rust
130
- // Fixed value
131
- mock.expect_count().returning(|| 42);
132
-
133
- // Based on input
134
- mock.expect_double().returning(|x| x * 2);
135
-
136
- // Different values per call
137
- mock.expect_next()
138
- .times(3)
139
- .returning(|| 1)
140
- .returning(|| 2)
141
- .returning(|| 3);
142
-
143
- // Return owned values
144
- mock.expect_get_name()
145
- .returning(|| "Alice".to_string());
146
- ```
147
-
148
- ## Mocking External Traits
149
-
150
- ```rust
151
- // For traits you don't own
152
- #[cfg_attr(test, mockall::automock)]
153
- trait HttpClient {
154
- fn get(&self, url: &str) -> Result<Response, Error>;
155
- }
156
-
157
- // In production
158
- struct RealHttpClient;
159
- impl HttpClient for RealHttpClient {
160
- fn get(&self, url: &str) -> Result<Response, Error> { /* ... */ }
161
- }
162
-
163
- // In tests
164
- #[cfg(test)]
165
- fn mock_client() -> MockHttpClient {
166
- let mut mock = MockHttpClient::new();
167
- mock.expect_get()
168
- .returning(|_| Ok(Response::new(200, "OK")));
169
- mock
170
- }
171
- ```
172
-
173
- ## Async Mocking
174
-
175
- ```rust
176
- #[automock]
177
- #[async_trait]
178
- trait AsyncDatabase {
179
- async fn fetch(&self, id: u64) -> Option<Data>;
180
- }
181
-
182
- #[tokio::test]
183
- async fn test_async() {
184
- let mut mock = MockAsyncDatabase::new();
185
-
186
- mock.expect_fetch()
187
- .returning(|_| Some(Data::default()));
188
-
189
- let result = mock.fetch(1).await;
190
- assert!(result.is_some());
191
- }
192
- ```
193
-
194
- ## Design for Testability
195
-
196
- ```rust
197
- // Accept trait, not concrete type
198
- struct Service<D: Database> {
199
- db: D,
200
- }
201
-
202
- impl<D: Database> Service<D> {
203
- fn new(db: D) -> Self {
204
- Self { db }
205
- }
206
- }
207
-
208
- // Tests use mock
209
- #[test]
210
- fn test_service() {
211
- let mock = MockDatabase::new();
212
- let service = Service::new(mock);
213
- }
214
-
215
- // Production uses real implementation
216
- fn main() {
217
- let db = PostgresDatabase::connect();
218
- let service = Service::new(db);
219
- }
220
- ```
221
-
222
- ## See Also
223
-
224
- - [test-mock-traits](./test-mock-traits.md) - Mock trait design
225
- - [test-proptest-properties](./test-proptest-properties.md) - Property testing
226
- - [test-arrange-act-assert](./test-arrange-act-assert.md) - Test structure
@@ -1,161 +0,0 @@
1
- # test-proptest-properties
2
-
3
- > Use proptest for property-based testing
4
-
5
- ## Why It Matters
6
-
7
- Property-based testing generates random inputs to verify that properties hold across all possible values, not just hand-picked examples. Proptest finds edge cases you wouldn't think to test manually—empty strings, integer overflows, unicode edge cases.
8
-
9
- ## Setup
10
-
11
- ```toml
12
- # Cargo.toml
13
- [dev-dependencies]
14
- proptest = "1.0"
15
- ```
16
-
17
- ## Basic Usage
18
-
19
- ```rust
20
- use proptest::prelude::*;
21
-
22
- proptest! {
23
- #[test]
24
- fn test_reverse_reverse_is_identity(s in ".*") {
25
- let reversed: String = s.chars().rev().collect();
26
- let double_reversed: String = reversed.chars().rev().collect();
27
- assert_eq!(s, double_reversed);
28
- }
29
-
30
- #[test]
31
- fn test_sort_is_idempotent(mut v in prop::collection::vec(any::<i32>(), 0..100)) {
32
- v.sort();
33
- let sorted = v.clone();
34
- v.sort();
35
- assert_eq!(v, sorted);
36
- }
37
- }
38
- ```
39
-
40
- ## Common Strategies
41
-
42
- ```rust
43
- use proptest::prelude::*;
44
-
45
- proptest! {
46
- // Any type implementing Arbitrary
47
- #[test]
48
- fn test_i32(x in any::<i32>()) { }
49
-
50
- // Regex-based string generation
51
- #[test]
52
- fn test_email(email in "[a-z]+@[a-z]+\\.[a-z]{2,3}") { }
53
-
54
- // Ranges
55
- #[test]
56
- fn test_range(x in 0..100i32) { }
57
-
58
- // Collections
59
- #[test]
60
- fn test_vec(v in prop::collection::vec(any::<i32>(), 0..10)) { }
61
-
62
- // Optionals
63
- #[test]
64
- fn test_option(opt in prop::option::of(any::<i32>())) { }
65
- }
66
- ```
67
-
68
- ## Custom Strategies
69
-
70
- ```rust
71
- use proptest::prelude::*;
72
-
73
- #[derive(Debug, Clone)]
74
- struct User {
75
- name: String,
76
- age: u8,
77
- }
78
-
79
- fn user_strategy() -> impl Strategy<Value = User> {
80
- ("[a-zA-Z]{1,20}", 0..120u8)
81
- .prop_map(|(name, age)| User { name, age })
82
- }
83
-
84
- proptest! {
85
- #[test]
86
- fn test_user(user in user_strategy()) {
87
- assert!(user.age < 150);
88
- assert!(!user.name.is_empty());
89
- }
90
- }
91
-
92
- // Or derive Arbitrary
93
- use proptest_derive::Arbitrary;
94
-
95
- #[derive(Debug, Arbitrary)]
96
- struct Point {
97
- x: i32,
98
- y: i32,
99
- }
100
- ```
101
-
102
- ## Properties to Test
103
-
104
- | Property | Example |
105
- |----------|---------|
106
- | Roundtrip | `decode(encode(x)) == x` |
107
- | Idempotence | `f(f(x)) == f(x)` |
108
- | Commutativity | `f(a, b) == f(b, a)` |
109
- | Associativity | `f(f(a, b), c) == f(a, f(b, c))` |
110
- | Identity | `f(x, identity) == x` |
111
- | Invariants | `len(push(v, x)) == len(v) + 1` |
112
-
113
- ## Example: Parser Roundtrip
114
-
115
- ```rust
116
- proptest! {
117
- #[test]
118
- fn parse_roundtrip(config in valid_config_strategy()) {
119
- let serialized = config.to_string();
120
- let parsed = Config::parse(&serialized).unwrap();
121
- assert_eq!(config, parsed);
122
- }
123
- }
124
- ```
125
-
126
- ## Shrinking
127
-
128
- Proptest automatically shrinks failing inputs to minimal cases:
129
-
130
- ```rust
131
- // If this fails with vec![100, 50, 75, 25, 0]
132
- // Proptest will shrink to vec![1, 0] (minimal failing case)
133
- proptest! {
134
- #[test]
135
- fn test_sorted(v in prop::collection::vec(0..1000i32, 1..100)) {
136
- let sorted = is_sorted(&v);
137
- // This will fail and shrink
138
- }
139
- }
140
- ```
141
-
142
- ## Configuration
143
-
144
- ```rust
145
- proptest! {
146
- #![proptest_config(ProptestConfig {
147
- cases: 1000, // More test cases
148
- max_shrink_iters: 10000, // More shrinking
149
- ..ProptestConfig::default()
150
- })]
151
-
152
- #[test]
153
- fn extensive_test(x in any::<i32>()) { }
154
- }
155
- ```
156
-
157
- ## See Also
158
-
159
- - [test-criterion-bench](./test-criterion-bench.md) - Benchmarking
160
- - [test-mockall-mocking](./test-mockall-mocking.md) - Mocking
161
- - [test-arrange-act-assert](./test-arrange-act-assert.md) - Test structure