agy-superpowers 5.1.4 → 5.1.5

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 (182) hide show
  1. package/package.json +1 -1
  2. package/template/agent/skills/rust-developer/SKILL.md +281 -0
  3. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +231 -0
  4. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +124 -0
  5. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +131 -0
  6. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +132 -0
  7. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +95 -0
  8. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +141 -0
  9. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +125 -0
  10. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +127 -0
  11. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +120 -0
  12. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +131 -0
  13. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +156 -0
  14. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +122 -0
  15. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +167 -0
  16. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +134 -0
  17. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +143 -0
  18. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +121 -0
  19. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +143 -0
  20. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +187 -0
  21. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +165 -0
  22. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +177 -0
  23. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +163 -0
  24. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +146 -0
  25. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +142 -0
  26. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +160 -0
  27. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +125 -0
  28. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +162 -0
  29. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +177 -0
  30. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +184 -0
  31. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +168 -0
  32. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +182 -0
  33. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +199 -0
  34. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +175 -0
  35. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +185 -0
  36. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +203 -0
  37. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +171 -0
  38. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +158 -0
  39. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +195 -0
  40. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +171 -0
  41. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +156 -0
  42. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +191 -0
  43. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +198 -0
  44. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +154 -0
  45. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +167 -0
  46. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +169 -0
  47. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +172 -0
  48. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +189 -0
  49. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +113 -0
  50. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +147 -0
  51. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +122 -0
  52. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +161 -0
  53. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +149 -0
  54. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +138 -0
  55. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +169 -0
  56. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +116 -0
  57. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +128 -0
  58. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +136 -0
  59. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +131 -0
  60. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +179 -0
  61. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +144 -0
  62. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +152 -0
  63. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +145 -0
  64. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +133 -0
  65. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +152 -0
  66. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +124 -0
  67. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +115 -0
  68. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +151 -0
  69. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +130 -0
  70. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +155 -0
  71. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +171 -0
  72. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +138 -0
  73. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +107 -0
  74. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +154 -0
  75. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +118 -0
  76. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +157 -0
  77. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +133 -0
  78. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +131 -0
  79. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +136 -0
  80. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +135 -0
  81. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +122 -0
  82. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +172 -0
  83. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +168 -0
  84. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +142 -0
  85. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +168 -0
  86. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +147 -0
  87. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +158 -0
  88. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +139 -0
  89. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +147 -0
  90. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +149 -0
  91. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +174 -0
  92. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +159 -0
  93. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +138 -0
  94. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +142 -0
  95. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +156 -0
  96. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +172 -0
  97. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +164 -0
  98. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +99 -0
  99. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +104 -0
  100. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +94 -0
  101. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +78 -0
  102. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +76 -0
  103. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +123 -0
  104. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +127 -0
  105. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +129 -0
  106. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +131 -0
  107. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +142 -0
  108. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +86 -0
  109. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +154 -0
  110. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +118 -0
  111. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +92 -0
  112. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +65 -0
  113. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +101 -0
  114. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +161 -0
  115. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +187 -0
  116. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +142 -0
  117. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +152 -0
  118. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +141 -0
  119. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +181 -0
  120. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +160 -0
  121. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +171 -0
  122. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +130 -0
  123. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +167 -0
  124. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +144 -0
  125. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +154 -0
  126. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +141 -0
  127. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +95 -0
  128. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +135 -0
  129. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +124 -0
  130. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +135 -0
  131. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +134 -0
  132. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +134 -0
  133. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +105 -0
  134. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +65 -0
  135. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +97 -0
  136. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +122 -0
  137. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +119 -0
  138. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +153 -0
  139. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +136 -0
  140. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +133 -0
  141. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +120 -0
  142. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +137 -0
  143. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +134 -0
  144. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +150 -0
  145. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +123 -0
  146. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +113 -0
  147. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +175 -0
  148. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +149 -0
  149. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +142 -0
  150. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +133 -0
  151. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +148 -0
  152. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +130 -0
  153. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +120 -0
  154. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +155 -0
  155. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +139 -0
  156. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +135 -0
  157. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +162 -0
  158. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +186 -0
  159. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +162 -0
  160. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +160 -0
  161. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +151 -0
  162. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +171 -0
  163. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +142 -0
  164. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +168 -0
  165. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +151 -0
  166. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +144 -0
  167. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +189 -0
  168. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +226 -0
  169. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +161 -0
  170. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +130 -0
  171. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +154 -0
  172. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +127 -0
  173. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +154 -0
  174. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +142 -0
  175. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +146 -0
  176. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +160 -0
  177. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +159 -0
  178. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +144 -0
  179. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +137 -0
  180. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +188 -0
  181. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +143 -0
  182. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +131 -0
@@ -0,0 +1,162 @@
1
+ # proj-workspace-large
2
+
3
+ > Use workspaces for large projects
4
+
5
+ ## Why It Matters
6
+
7
+ Cargo workspaces manage multiple related crates under one repository. They share a single `Cargo.lock`, build cache, and can be versioned together. For large projects, workspaces improve build times, enforce modularity, and simplify dependency management.
8
+
9
+ ## Bad
10
+
11
+ ```
12
+ # Separate repositories for each crate
13
+ my-app-core/
14
+ my-app-cli/
15
+ my-app-server/
16
+ my-app-common/
17
+
18
+ # Each has its own Cargo.lock
19
+ # Dependencies may drift
20
+ # Cross-crate development is painful
21
+ ```
22
+
23
+ ## Good
24
+
25
+ ```
26
+ my-app/
27
+ ├── Cargo.toml # Workspace root
28
+ ├── Cargo.lock # Shared lock file
29
+ ├── crates/
30
+ │ ├── core/
31
+ │ │ ├── Cargo.toml
32
+ │ │ └── src/
33
+ │ ├── cli/
34
+ │ │ ├── Cargo.toml
35
+ │ │ └── src/
36
+ │ ├── server/
37
+ │ │ ├── Cargo.toml
38
+ │ │ └── src/
39
+ │ └── common/
40
+ │ ├── Cargo.toml
41
+ │ └── src/
42
+ └── README.md
43
+ ```
44
+
45
+ ## Workspace Cargo.toml
46
+
47
+ ```toml
48
+ # Root Cargo.toml
49
+ [workspace]
50
+ resolver = "2" # Use the new resolver
51
+ members = [
52
+ "crates/core",
53
+ "crates/cli",
54
+ "crates/server",
55
+ "crates/common",
56
+ ]
57
+
58
+ # Shared dependencies - all crates use same versions
59
+ [workspace.dependencies]
60
+ tokio = { version = "1.0", features = ["full"] }
61
+ serde = { version = "1.0", features = ["derive"] }
62
+ tracing = "0.1"
63
+ anyhow = "1.0"
64
+
65
+ # Shared lints
66
+ [workspace.lints.rust]
67
+ unsafe_code = "forbid"
68
+
69
+ [workspace.lints.clippy]
70
+ all = "warn"
71
+ ```
72
+
73
+ ## Member Crate Cargo.toml
74
+
75
+ ```toml
76
+ # crates/core/Cargo.toml
77
+ [package]
78
+ name = "my-app-core"
79
+ version = "0.1.0"
80
+ edition = "2021"
81
+
82
+ [dependencies]
83
+ # Inherit from workspace
84
+ tokio = { workspace = true }
85
+ serde = { workspace = true }
86
+
87
+ # Crate-specific dependencies
88
+ uuid = "1.0"
89
+
90
+ # Internal dependency
91
+ my-app-common = { path = "../common" }
92
+
93
+ [lints]
94
+ workspace = true # Inherit workspace lints
95
+ ```
96
+
97
+ ## When to Use Workspaces
98
+
99
+ | Scenario | Recommendation |
100
+ |----------|----------------|
101
+ | Single binary/library | No workspace needed |
102
+ | Library + CLI | Maybe, depends on size |
103
+ | Multiple related crates | Yes |
104
+ | Shared internal libraries | Yes |
105
+ | Microservices mono-repo | Yes |
106
+ | Plugin architecture | Yes |
107
+
108
+ ## Benefits
109
+
110
+ | Aspect | Single Crate | Workspace |
111
+ |--------|--------------|-----------|
112
+ | Build cache | Crate only | Shared across all |
113
+ | Dependency versions | Per-crate | Synchronized |
114
+ | Compile times | Full rebuild | Incremental |
115
+ | Modularity | Files/modules | Crate boundaries |
116
+ | Publishing | Single crate | Independent |
117
+
118
+ ## Commands
119
+
120
+ ```bash
121
+ # Build all crates
122
+ cargo build --workspace
123
+
124
+ # Build specific crate
125
+ cargo build -p my-app-core
126
+
127
+ # Test all crates
128
+ cargo test --workspace
129
+
130
+ # Run specific binary
131
+ cargo run -p my-app-cli
132
+
133
+ # Check all
134
+ cargo check --workspace
135
+ ```
136
+
137
+ ## Pattern: Virtual Workspace
138
+
139
+ Root Cargo.toml is workspace-only (no `[package]`):
140
+
141
+ ```toml
142
+ [workspace]
143
+ members = ["crates/*"]
144
+
145
+ [workspace.dependencies]
146
+ # ...
147
+ ```
148
+
149
+ ## Pattern: Crate Interdependencies
150
+
151
+ ```toml
152
+ # crates/server/Cargo.toml
153
+ [dependencies]
154
+ my-app-core = { path = "../core" }
155
+ my-app-common = { path = "../common" }
156
+ ```
157
+
158
+ ## See Also
159
+
160
+ - [proj-workspace-deps](./proj-workspace-deps.md) - Workspace dependencies
161
+ - [proj-bin-dir](./proj-bin-dir.md) - Multiple binaries
162
+ - [proj-lib-main-split](./proj-lib-main-split.md) - Lib/main separation
@@ -0,0 +1,160 @@
1
+ # test-arrange-act-assert
2
+
3
+ > Structure tests with clear Arrange, Act, Assert sections
4
+
5
+ ## Why It Matters
6
+
7
+ The AAA pattern makes tests readable and maintainable. Each section has a clear purpose: set up test data, execute the code under test, verify the results. This structure helps identify what's being tested and makes tests easier to debug when they fail.
8
+
9
+ ## Bad
10
+
11
+ ```rust
12
+ #[test]
13
+ fn test_user() {
14
+ assert_eq!(User::new("alice", "alice@example.com").unwrap().name(), "alice");
15
+ assert!(User::new("", "email@example.com").is_err());
16
+ let u = User::new("bob", "bob@example.com").unwrap();
17
+ assert!(u.validate());
18
+ assert_eq!(u.email(), "bob@example.com");
19
+ }
20
+ // Multiple concerns, hard to understand, hard to debug
21
+ ```
22
+
23
+ ## Good
24
+
25
+ ```rust
26
+ #[test]
27
+ fn new_user_has_correct_name() {
28
+ // Arrange
29
+ let name = "alice";
30
+ let email = "alice@example.com";
31
+
32
+ // Act
33
+ let user = User::new(name, email).unwrap();
34
+
35
+ // Assert
36
+ assert_eq!(user.name(), "alice");
37
+ }
38
+
39
+ #[test]
40
+ fn user_creation_fails_with_empty_name() {
41
+ // Arrange
42
+ let name = "";
43
+ let email = "email@example.com";
44
+
45
+ // Act
46
+ let result = User::new(name, email);
47
+
48
+ // Assert
49
+ assert!(result.is_err());
50
+ assert!(matches!(result, Err(UserError::EmptyName)));
51
+ }
52
+ ```
53
+
54
+ ## With Comments
55
+
56
+ ```rust
57
+ #[test]
58
+ fn order_total_includes_tax() {
59
+ // Arrange
60
+ let mut order = Order::new();
61
+ order.add_item(Item::new("Widget", 100.00));
62
+ order.add_item(Item::new("Gadget", 50.00));
63
+ let tax_rate = 0.10;
64
+
65
+ // Act
66
+ let total = order.calculate_total(tax_rate);
67
+
68
+ // Assert
69
+ let expected = (100.00 + 50.00) * 1.10;
70
+ assert_eq!(total, expected);
71
+ }
72
+ ```
73
+
74
+ ## Complex Arrange
75
+
76
+ ```rust
77
+ #[test]
78
+ fn search_returns_matching_documents() {
79
+ // Arrange
80
+ let mut index = SearchIndex::new();
81
+ index.add_document(Document::new(1, "rust programming"));
82
+ index.add_document(Document::new(2, "python programming"));
83
+ index.add_document(Document::new(3, "rust web development"));
84
+
85
+ let query = Query::new("rust");
86
+
87
+ // Act
88
+ let results = index.search(&query);
89
+
90
+ // Assert
91
+ assert_eq!(results.len(), 2);
92
+ assert!(results.iter().any(|d| d.id == 1));
93
+ assert!(results.iter().any(|d| d.id == 3));
94
+ }
95
+ ```
96
+
97
+ ## Async Tests
98
+
99
+ ```rust
100
+ #[tokio::test]
101
+ async fn fetch_user_returns_user_data() {
102
+ // Arrange
103
+ let client = TestClient::new();
104
+ let user_id = 42;
105
+
106
+ // Act
107
+ let result = client.fetch_user(user_id).await;
108
+
109
+ // Assert
110
+ assert!(result.is_ok());
111
+ let user = result.unwrap();
112
+ assert_eq!(user.id, user_id);
113
+ }
114
+ ```
115
+
116
+ ## Helper Functions
117
+
118
+ ```rust
119
+ #[cfg(test)]
120
+ mod tests {
121
+ use super::*;
122
+
123
+ // Arrange helpers
124
+ fn create_test_user() -> User {
125
+ User::new("test", "test@example.com").unwrap()
126
+ }
127
+
128
+ fn create_order_with_items(items: &[(&str, f64)]) -> Order {
129
+ let mut order = Order::new();
130
+ for (name, price) in items {
131
+ order.add_item(Item::new(name, *price));
132
+ }
133
+ order
134
+ }
135
+
136
+ // Assert helpers
137
+ fn assert_order_total(order: &Order, expected: f64) {
138
+ let total = order.calculate_total(0.0);
139
+ assert!((total - expected).abs() < 0.01);
140
+ }
141
+
142
+ #[test]
143
+ fn order_total_sums_items() {
144
+ // Arrange
145
+ let order = create_order_with_items(&[
146
+ ("A", 10.0),
147
+ ("B", 20.0),
148
+ ]);
149
+
150
+ // Act & Assert
151
+ assert_order_total(&order, 30.0);
152
+ }
153
+ }
154
+ ```
155
+
156
+ ## See Also
157
+
158
+ - [test-descriptive-names](./test-descriptive-names.md) - Test naming
159
+ - [test-fixture-raii](./test-fixture-raii.md) - Test setup/teardown
160
+ - [test-mock-traits](./test-mock-traits.md) - Mocking dependencies
@@ -0,0 +1,151 @@
1
+ # test-cfg-test-module
2
+
3
+ > Put unit tests in `#[cfg(test)] mod tests { }` within each module
4
+
5
+ ## Why It Matters
6
+
7
+ The `#[cfg(test)]` attribute ensures test code is only compiled during `cargo test`, not in release builds. Placing tests in a `tests` submodule within the same file keeps tests close to the code they test while maintaining separation. This is Rust's idiomatic unit test pattern.
8
+
9
+ ## Bad
10
+
11
+ ```rust
12
+ // Tests without cfg(test) - compiled into release binary
13
+ mod tests {
14
+ #[test]
15
+ fn test_something() { ... } // Included in release build!
16
+ }
17
+
18
+ // Tests in separate file without access to private items
19
+ // src/my_module.rs
20
+ fn private_helper() { ... }
21
+
22
+ // tests/my_module_test.rs
23
+ // Can't access private_helper!
24
+ ```
25
+
26
+ ## Good
27
+
28
+ ```rust
29
+ // src/my_module.rs
30
+
31
+ fn public_api() -> i32 {
32
+ private_helper() * 2
33
+ }
34
+
35
+ fn private_helper() -> i32 {
36
+ 21
37
+ }
38
+
39
+ #[cfg(test)]
40
+ mod tests {
41
+ use super::*; // Access to private items
42
+
43
+ #[test]
44
+ fn test_public_api() {
45
+ assert_eq!(public_api(), 42);
46
+ }
47
+
48
+ #[test]
49
+ fn test_private_helper() {
50
+ assert_eq!(private_helper(), 21); // Can test private!
51
+ }
52
+ }
53
+ ```
54
+
55
+ ## Module Structure
56
+
57
+ ```rust
58
+ // src/lib.rs
59
+ mod parser;
60
+ mod lexer;
61
+ mod ast;
62
+
63
+ // src/parser.rs
64
+ pub fn parse(input: &str) -> Result<Ast, Error> {
65
+ let tokens = tokenize(input)?;
66
+ build_ast(tokens)
67
+ }
68
+
69
+ fn tokenize(input: &str) -> Result<Vec<Token>, Error> { ... }
70
+ fn build_ast(tokens: Vec<Token>) -> Result<Ast, Error> { ... }
71
+
72
+ #[cfg(test)]
73
+ mod tests {
74
+ use super::*;
75
+
76
+ #[test]
77
+ fn test_parse_simple() {
78
+ let ast = parse("1 + 2").unwrap();
79
+ assert_eq!(ast.evaluate(), 3);
80
+ }
81
+
82
+ #[test]
83
+ fn test_tokenize() {
84
+ let tokens = tokenize("1 + 2").unwrap();
85
+ assert_eq!(tokens.len(), 3);
86
+ }
87
+ }
88
+ ```
89
+
90
+ ## Test Helpers
91
+
92
+ ```rust
93
+ #[cfg(test)]
94
+ mod tests {
95
+ use super::*;
96
+
97
+ // Test-only helpers
98
+ fn create_test_data() -> Data {
99
+ Data {
100
+ id: 1,
101
+ name: "test".into(),
102
+ values: vec![1, 2, 3],
103
+ }
104
+ }
105
+
106
+ fn assert_valid(data: &Data) {
107
+ assert!(data.id > 0);
108
+ assert!(!data.name.is_empty());
109
+ }
110
+
111
+ #[test]
112
+ fn test_processing() {
113
+ let data = create_test_data();
114
+ let result = process(&data);
115
+ assert_valid(&result);
116
+ }
117
+ }
118
+ ```
119
+
120
+ ## Multiple Test Modules
121
+
122
+ ```rust
123
+ // For larger test suites, use submodules
124
+ #[cfg(test)]
125
+ mod tests {
126
+ use super::*;
127
+
128
+ mod parsing {
129
+ use super::*;
130
+
131
+ #[test]
132
+ fn test_parse_number() { ... }
133
+
134
+ #[test]
135
+ fn test_parse_string() { ... }
136
+ }
137
+
138
+ mod validation {
139
+ use super::*;
140
+
141
+ #[test]
142
+ fn test_validate_range() { ... }
143
+ }
144
+ }
145
+ ```
146
+
147
+ ## See Also
148
+
149
+ - [test-use-super](./test-use-super.md) - Importing from parent module
150
+ - [test-integration-dir](./test-integration-dir.md) - Integration tests
151
+ - [test-descriptive-names](./test-descriptive-names.md) - Test naming
@@ -0,0 +1,171 @@
1
+ # test-criterion-bench
2
+
3
+ > Use `criterion` for benchmarking
4
+
5
+ ## Why It Matters
6
+
7
+ Criterion provides statistically rigorous benchmarking with warmup, multiple iterations, outlier detection, and comparison between runs. It's far more reliable than simple timing with `Instant::now()`.
8
+
9
+ ## Setup
10
+
11
+ ```toml
12
+ # Cargo.toml
13
+ [dev-dependencies]
14
+ criterion = "0.5"
15
+
16
+ [[bench]]
17
+ name = "my_benchmark"
18
+ harness = false
19
+ ```
20
+
21
+ ## Basic Benchmark
22
+
23
+ ```rust
24
+ // benches/my_benchmark.rs
25
+ use criterion::{black_box, criterion_group, criterion_main, Criterion};
26
+
27
+ fn fibonacci(n: u64) -> u64 {
28
+ match n {
29
+ 0 => 0,
30
+ 1 => 1,
31
+ n => fibonacci(n - 1) + fibonacci(n - 2),
32
+ }
33
+ }
34
+
35
+ fn bench_fibonacci(c: &mut Criterion) {
36
+ c.bench_function("fib 20", |b| {
37
+ b.iter(|| fibonacci(black_box(20)))
38
+ });
39
+ }
40
+
41
+ criterion_group!(benches, bench_fibonacci);
42
+ criterion_main!(benches);
43
+ ```
44
+
45
+ ## black_box is Critical
46
+
47
+ ```rust
48
+ // BAD: Compiler may optimize away the computation
49
+ b.iter(|| fibonacci(20)); // Result unused, might be eliminated
50
+
51
+ // GOOD: black_box prevents optimization
52
+ b.iter(|| fibonacci(black_box(20)));
53
+
54
+ // Also wrap the result if needed
55
+ b.iter(|| black_box(fibonacci(black_box(20))));
56
+ ```
57
+
58
+ ## Comparing Implementations
59
+
60
+ ```rust
61
+ fn bench_comparison(c: &mut Criterion) {
62
+ let mut group = c.benchmark_group("String concat");
63
+
64
+ let data = "hello";
65
+
66
+ group.bench_function("format!", |b| {
67
+ b.iter(|| format!("{}{}", black_box(data), " world"))
68
+ });
69
+
70
+ group.bench_function("push_str", |b| {
71
+ b.iter(|| {
72
+ let mut s = String::from(black_box(data));
73
+ s.push_str(" world");
74
+ s
75
+ })
76
+ });
77
+
78
+ group.bench_function("concat", |b| {
79
+ b.iter(|| [black_box(data), " world"].concat())
80
+ });
81
+
82
+ group.finish();
83
+ }
84
+ ```
85
+
86
+ ## Parameterized Benchmarks
87
+
88
+ ```rust
89
+ fn bench_vec_push(c: &mut Criterion) {
90
+ let mut group = c.benchmark_group("Vec::push");
91
+
92
+ for size in [100, 1000, 10000].iter() {
93
+ group.bench_with_input(
94
+ BenchmarkId::from_parameter(size),
95
+ size,
96
+ |b, &size| {
97
+ b.iter(|| {
98
+ let mut v = Vec::new();
99
+ for i in 0..size {
100
+ v.push(black_box(i));
101
+ }
102
+ v
103
+ });
104
+ },
105
+ );
106
+ }
107
+
108
+ group.finish();
109
+ }
110
+ ```
111
+
112
+ ## Throughput Measurement
113
+
114
+ ```rust
115
+ use criterion::Throughput;
116
+
117
+ fn bench_parse(c: &mut Criterion) {
118
+ let input = "a]ong string to parse...";
119
+
120
+ let mut group = c.benchmark_group("Parser");
121
+ group.throughput(Throughput::Bytes(input.len() as u64));
122
+
123
+ group.bench_function("parse", |b| {
124
+ b.iter(|| parse(black_box(input)))
125
+ });
126
+
127
+ group.finish();
128
+ }
129
+ ```
130
+
131
+ ## Running Benchmarks
132
+
133
+ ```bash
134
+ # Run all benchmarks
135
+ cargo bench
136
+
137
+ # Run specific benchmark
138
+ cargo bench -- fib
139
+
140
+ # Save baseline for comparison
141
+ cargo bench -- --save-baseline main
142
+
143
+ # Compare against baseline
144
+ cargo bench -- --baseline main
145
+ ```
146
+
147
+ ## Evidence from tokio
148
+
149
+ ```rust
150
+ // https://github.com/tokio-rs/tokio/blob/master/benches/sync_mpsc.rs
151
+ use criterion::{criterion_group, criterion_main, Criterion};
152
+
153
+ fn send_data<T: Default, const SIZE: usize>(
154
+ g: &mut BenchmarkGroup<WallTime>,
155
+ prefix: &str
156
+ ) {
157
+ let rt = rt();
158
+ g.bench_function(format!("{prefix}_{SIZE}"), |b| {
159
+ b.iter(|| {
160
+ let (tx, mut rx) = mpsc::channel::<T>(SIZE);
161
+ rt.block_on(tx.send(T::default())).unwrap();
162
+ rt.block_on(rx.recv()).unwrap();
163
+ })
164
+ });
165
+ }
166
+ ```
167
+
168
+ ## See Also
169
+
170
+ - [perf-profile-first](perf-profile-first.md) - Profile before optimizing
171
+ - [perf-black-box-bench](perf-black-box-bench.md) - Use black_box in benchmarks