@funnycode/myclaude 0.1.67 → 0.1.68
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.
- package/LICENSE +21 -21
- package/dist/myclaude.js +15090 -12419
- package/dist/myclaude.mjs +15090 -12419
- package/package.json +125 -125
- package/seed/marketplaces/ecc/.claude/commands/add-language-rules.md +39 -0
- package/seed/marketplaces/ecc/.claude/commands/database-migration.md +36 -0
- package/seed/marketplaces/ecc/.claude/commands/feature-development.md +38 -0
- package/seed/marketplaces/ecc/.claude/ecc-tools.json +334 -0
- package/seed/marketplaces/ecc/.claude/enterprise/controls.md +15 -0
- package/seed/marketplaces/ecc/.claude/homunculus/instincts/inherited/everything-claude-code-instincts.yaml +162 -0
- package/seed/marketplaces/ecc/.claude/identity.json +14 -0
- package/seed/marketplaces/ecc/.claude/package-manager.json +4 -0
- package/seed/marketplaces/ecc/.claude/research/everything-claude-code-research-playbook.md +21 -0
- package/seed/marketplaces/ecc/.claude/rules/everything-claude-code-guardrails.md +43 -0
- package/seed/marketplaces/ecc/.claude/rules/node.md +56 -0
- package/seed/marketplaces/ecc/.claude/skills/everything-claude-code/SKILL.md +442 -0
- package/seed/marketplaces/ecc/.claude/team/everything-claude-code-team-config.json +15 -0
- package/seed/marketplaces/ecc/.opencode/package-lock.json +169 -169
- package/seed/marketplaces/ecc/.vscode/settings.json +17 -0
- package/seed/marketplaces/ecc/commands/aside.md +164 -164
- package/seed/marketplaces/ecc/commands/auto-update.md +28 -28
- package/seed/marketplaces/ecc/commands/build-fix.md +66 -66
- package/seed/marketplaces/ecc/commands/checkpoint.md +78 -78
- package/seed/marketplaces/ecc/commands/code-review.md +289 -289
- package/seed/marketplaces/ecc/commands/cost-report.md +107 -107
- package/seed/marketplaces/ecc/commands/cpp-build.md +173 -173
- package/seed/marketplaces/ecc/commands/cpp-review.md +132 -132
- package/seed/marketplaces/ecc/commands/cpp-test.md +251 -251
- package/seed/marketplaces/ecc/commands/ecc-guide.md +93 -93
- package/seed/marketplaces/ecc/commands/evolve.md +178 -178
- package/seed/marketplaces/ecc/commands/fastapi-review.md +39 -39
- package/seed/marketplaces/ecc/commands/feature-dev.md +49 -49
- package/seed/marketplaces/ecc/commands/flutter-build.md +164 -164
- package/seed/marketplaces/ecc/commands/flutter-review.md +116 -116
- package/seed/marketplaces/ecc/commands/flutter-test.md +144 -144
- package/seed/marketplaces/ecc/commands/gan-build.md +103 -103
- package/seed/marketplaces/ecc/commands/gan-design.md +39 -39
- package/seed/marketplaces/ecc/commands/go-build.md +183 -183
- package/seed/marketplaces/ecc/commands/go-review.md +148 -148
- package/seed/marketplaces/ecc/commands/go-test.md +268 -268
- package/seed/marketplaces/ecc/commands/gradle-build.md +70 -70
- package/seed/marketplaces/ecc/commands/harness-audit.md +84 -84
- package/seed/marketplaces/ecc/commands/hookify-configure.md +14 -14
- package/seed/marketplaces/ecc/commands/hookify-help.md +46 -46
- package/seed/marketplaces/ecc/commands/hookify-list.md +21 -21
- package/seed/marketplaces/ecc/commands/hookify.md +50 -50
- package/seed/marketplaces/ecc/commands/instinct-export.md +66 -66
- package/seed/marketplaces/ecc/commands/instinct-import.md +114 -114
- package/seed/marketplaces/ecc/commands/instinct-status.md +59 -59
- package/seed/marketplaces/ecc/commands/jira.md +106 -106
- package/seed/marketplaces/ecc/commands/kotlin-build.md +174 -174
- package/seed/marketplaces/ecc/commands/kotlin-review.md +140 -140
- package/seed/marketplaces/ecc/commands/kotlin-test.md +312 -312
- package/seed/marketplaces/ecc/commands/learn-eval.md +116 -116
- package/seed/marketplaces/ecc/commands/learn.md +74 -74
- package/seed/marketplaces/ecc/commands/loop-start.md +36 -36
- package/seed/marketplaces/ecc/commands/loop-status.md +77 -77
- package/seed/marketplaces/ecc/commands/marketing-campaign.md +129 -129
- package/seed/marketplaces/ecc/commands/model-route.md +30 -30
- package/seed/marketplaces/ecc/commands/multi-backend.md +162 -162
- package/seed/marketplaces/ecc/commands/multi-execute.md +319 -319
- package/seed/marketplaces/ecc/commands/multi-frontend.md +162 -162
- package/seed/marketplaces/ecc/commands/multi-plan.md +272 -272
- package/seed/marketplaces/ecc/commands/multi-workflow.md +195 -195
- package/seed/marketplaces/ecc/commands/plan-prd.md +160 -160
- package/seed/marketplaces/ecc/commands/plan.md +200 -200
- package/seed/marketplaces/ecc/commands/pm2.md +276 -276
- package/seed/marketplaces/ecc/commands/pr.md +184 -184
- package/seed/marketplaces/ecc/commands/project-init.md +86 -86
- package/seed/marketplaces/ecc/commands/projects.md +39 -39
- package/seed/marketplaces/ecc/commands/promote.md +41 -41
- package/seed/marketplaces/ecc/commands/prp-commit.md +112 -112
- package/seed/marketplaces/ecc/commands/prp-implement.md +385 -385
- package/seed/marketplaces/ecc/commands/prp-plan.md +502 -502
- package/seed/marketplaces/ecc/commands/prp-pr.md +184 -184
- package/seed/marketplaces/ecc/commands/prp-prd.md +447 -447
- package/seed/marketplaces/ecc/commands/prune.md +31 -31
- package/seed/marketplaces/ecc/commands/python-review.md +297 -297
- package/seed/marketplaces/ecc/commands/quality-gate.md +33 -33
- package/seed/marketplaces/ecc/commands/refactor-clean.md +84 -84
- package/seed/marketplaces/ecc/commands/resume-session.md +156 -156
- package/seed/marketplaces/ecc/commands/review-pr.md +37 -37
- package/seed/marketplaces/ecc/commands/rust-build.md +187 -187
- package/seed/marketplaces/ecc/commands/rust-review.md +142 -142
- package/seed/marketplaces/ecc/commands/rust-test.md +308 -308
- package/seed/marketplaces/ecc/commands/santa-loop.md +175 -175
- package/seed/marketplaces/ecc/commands/save-session.md +275 -275
- package/seed/marketplaces/ecc/commands/security-scan.md +92 -92
- package/seed/marketplaces/ecc/commands/sessions.md +339 -339
- package/seed/marketplaces/ecc/commands/setup-pm.md +80 -80
- package/seed/marketplaces/ecc/commands/skill-create.md +174 -174
- package/seed/marketplaces/ecc/commands/skill-health.md +54 -54
- package/seed/marketplaces/ecc/commands/test-coverage.md +73 -73
- package/seed/marketplaces/ecc/commands/update-codemaps.md +76 -76
- package/seed/marketplaces/ecc/commands/update-docs.md +88 -88
- package/seed/marketplaces/ecc/skills/accessibility/SKILL.md +146 -146
- package/seed/marketplaces/ecc/skills/agent-architecture-audit/SKILL.md +256 -256
- package/seed/marketplaces/ecc/skills/agent-eval/SKILL.md +145 -145
- package/seed/marketplaces/ecc/skills/agent-harness-construction/SKILL.md +73 -73
- package/seed/marketplaces/ecc/skills/agent-introspection-debugging/SKILL.md +153 -153
- package/seed/marketplaces/ecc/skills/agent-payment-x402/SKILL.md +224 -224
- package/seed/marketplaces/ecc/skills/agent-sort/SKILL.md +215 -215
- package/seed/marketplaces/ecc/skills/agentic-engineering/SKILL.md +63 -63
- package/seed/marketplaces/ecc/skills/agentic-os/SKILL.md +387 -387
- package/seed/marketplaces/ecc/skills/ai-first-engineering/SKILL.md +51 -51
- package/seed/marketplaces/ecc/skills/ai-regression-testing/SKILL.md +385 -385
- package/seed/marketplaces/ecc/skills/android-clean-architecture/SKILL.md +339 -339
- package/seed/marketplaces/ecc/skills/angular-developer/SKILL.md +154 -154
- package/seed/marketplaces/ecc/skills/angular-developer/references/angular-animations.md +160 -160
- package/seed/marketplaces/ecc/skills/angular-developer/references/angular-aria.md +410 -410
- package/seed/marketplaces/ecc/skills/angular-developer/references/cli.md +86 -86
- package/seed/marketplaces/ecc/skills/angular-developer/references/component-harnesses.md +59 -59
- package/seed/marketplaces/ecc/skills/angular-developer/references/component-styling.md +91 -91
- package/seed/marketplaces/ecc/skills/angular-developer/references/components.md +117 -117
- package/seed/marketplaces/ecc/skills/angular-developer/references/creating-services.md +97 -97
- package/seed/marketplaces/ecc/skills/angular-developer/references/data-resolvers.md +69 -69
- package/seed/marketplaces/ecc/skills/angular-developer/references/define-routes.md +67 -67
- package/seed/marketplaces/ecc/skills/angular-developer/references/defining-providers.md +72 -72
- package/seed/marketplaces/ecc/skills/angular-developer/references/di-fundamentals.md +120 -120
- package/seed/marketplaces/ecc/skills/angular-developer/references/e2e-testing.md +56 -56
- package/seed/marketplaces/ecc/skills/angular-developer/references/effects.md +83 -83
- package/seed/marketplaces/ecc/skills/angular-developer/references/hierarchical-injectors.md +43 -43
- package/seed/marketplaces/ecc/skills/angular-developer/references/host-elements.md +80 -80
- package/seed/marketplaces/ecc/skills/angular-developer/references/injection-context.md +63 -63
- package/seed/marketplaces/ecc/skills/angular-developer/references/inputs.md +101 -101
- package/seed/marketplaces/ecc/skills/angular-developer/references/linked-signal.md +59 -59
- package/seed/marketplaces/ecc/skills/angular-developer/references/loading-strategies.md +61 -61
- package/seed/marketplaces/ecc/skills/angular-developer/references/mcp.md +108 -108
- package/seed/marketplaces/ecc/skills/angular-developer/references/navigate-to-routes.md +69 -69
- package/seed/marketplaces/ecc/skills/angular-developer/references/outputs.md +86 -86
- package/seed/marketplaces/ecc/skills/angular-developer/references/reactive-forms.md +122 -122
- package/seed/marketplaces/ecc/skills/angular-developer/references/rendering-strategies.md +44 -44
- package/seed/marketplaces/ecc/skills/angular-developer/references/resource.md +77 -77
- package/seed/marketplaces/ecc/skills/angular-developer/references/route-animations.md +56 -56
- package/seed/marketplaces/ecc/skills/angular-developer/references/route-guards.md +52 -52
- package/seed/marketplaces/ecc/skills/angular-developer/references/router-lifecycle.md +45 -45
- package/seed/marketplaces/ecc/skills/angular-developer/references/router-testing.md +87 -87
- package/seed/marketplaces/ecc/skills/angular-developer/references/show-routes-with-outlets.md +68 -68
- package/seed/marketplaces/ecc/skills/angular-developer/references/signal-forms.md +795 -795
- package/seed/marketplaces/ecc/skills/angular-developer/references/signals-overview.md +94 -94
- package/seed/marketplaces/ecc/skills/angular-developer/references/tailwind-css.md +69 -69
- package/seed/marketplaces/ecc/skills/angular-developer/references/template-driven-forms.md +114 -114
- package/seed/marketplaces/ecc/skills/angular-developer/references/testing-fundamentals.md +65 -65
- package/seed/marketplaces/ecc/skills/api-connector-builder/SKILL.md +120 -120
- package/seed/marketplaces/ecc/skills/api-design/SKILL.md +523 -523
- package/seed/marketplaces/ecc/skills/architecture-decision-records/SKILL.md +179 -179
- package/seed/marketplaces/ecc/skills/article-writing/SKILL.md +79 -79
- package/seed/marketplaces/ecc/skills/automation-audit-ops/SKILL.md +142 -142
- package/seed/marketplaces/ecc/skills/autonomous-agent-harness/SKILL.md +273 -273
- package/seed/marketplaces/ecc/skills/autonomous-loops/SKILL.md +610 -610
- package/seed/marketplaces/ecc/skills/backend-patterns/SKILL.md +561 -561
- package/seed/marketplaces/ecc/skills/benchmark/SKILL.md +93 -93
- package/seed/marketplaces/ecc/skills/benchmark-optimization-loop/SKILL.md +69 -69
- package/seed/marketplaces/ecc/skills/blender-motion-state-inspection/SKILL.md +164 -164
- package/seed/marketplaces/ecc/skills/blueprint/SKILL.md +105 -105
- package/seed/marketplaces/ecc/skills/brand-voice/SKILL.md +97 -97
- package/seed/marketplaces/ecc/skills/brand-voice/references/voice-profile-schema.md +55 -55
- package/seed/marketplaces/ecc/skills/browser-qa/SKILL.md +87 -87
- package/seed/marketplaces/ecc/skills/bun-runtime/SKILL.md +84 -84
- package/seed/marketplaces/ecc/skills/canary-watch/SKILL.md +107 -107
- package/seed/marketplaces/ecc/skills/carrier-relationship-management/SKILL.md +212 -212
- package/seed/marketplaces/ecc/skills/cisco-ios-patterns/SKILL.md +163 -163
- package/seed/marketplaces/ecc/skills/ck/SKILL.md +147 -147
- package/seed/marketplaces/ecc/skills/ck/commands/forget.mjs +44 -44
- package/seed/marketplaces/ecc/skills/ck/commands/info.mjs +24 -24
- package/seed/marketplaces/ecc/skills/ck/commands/init.mjs +143 -143
- package/seed/marketplaces/ecc/skills/ck/commands/list.mjs +40 -40
- package/seed/marketplaces/ecc/skills/ck/commands/migrate.mjs +202 -202
- package/seed/marketplaces/ecc/skills/ck/commands/resume.mjs +36 -36
- package/seed/marketplaces/ecc/skills/ck/commands/save.mjs +210 -210
- package/seed/marketplaces/ecc/skills/ck/commands/shared.mjs +387 -387
- package/seed/marketplaces/ecc/skills/ck/hooks/session-start.mjs +224 -224
- package/seed/marketplaces/ecc/skills/claude-devfleet/SKILL.md +103 -103
- package/seed/marketplaces/ecc/skills/click-path-audit/SKILL.md +244 -244
- package/seed/marketplaces/ecc/skills/clickhouse-io/SKILL.md +439 -439
- package/seed/marketplaces/ecc/skills/code-tour/SKILL.md +236 -236
- package/seed/marketplaces/ecc/skills/codebase-onboarding/SKILL.md +233 -233
- package/seed/marketplaces/ecc/skills/coding-standards/SKILL.md +549 -549
- package/seed/marketplaces/ecc/skills/compose-multiplatform-patterns/SKILL.md +299 -299
- package/seed/marketplaces/ecc/skills/configure-ecc/SKILL.md +384 -384
- package/seed/marketplaces/ecc/skills/connections-optimizer/SKILL.md +189 -189
- package/seed/marketplaces/ecc/skills/content-engine/SKILL.md +131 -131
- package/seed/marketplaces/ecc/skills/content-hash-cache-pattern/SKILL.md +161 -161
- package/seed/marketplaces/ecc/skills/context-budget/SKILL.md +135 -135
- package/seed/marketplaces/ecc/skills/continuous-agent-loop/SKILL.md +45 -45
- package/seed/marketplaces/ecc/skills/continuous-learning/SKILL.md +131 -131
- package/seed/marketplaces/ecc/skills/continuous-learning/config.json +18 -18
- package/seed/marketplaces/ecc/skills/continuous-learning/evaluate-session.sh +69 -69
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/SKILL.md +360 -360
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/agents/observer-loop.sh +322 -322
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/agents/observer.md +198 -198
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/agents/session-guardian.sh +150 -150
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/agents/start-observer.sh +248 -248
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/config.json +8 -8
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/hooks/observe.sh +498 -498
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/scripts/detect-project.sh +322 -322
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/scripts/instinct-cli.py +1826 -1826
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/scripts/lib/homunculus-dir.sh +31 -31
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/scripts/migrate-homunculus.sh +62 -62
- package/seed/marketplaces/ecc/skills/continuous-learning-v2/scripts/test_parse_instinct.py +1018 -1018
- package/seed/marketplaces/ecc/skills/cost-aware-llm-pipeline/SKILL.md +183 -183
- package/seed/marketplaces/ecc/skills/cost-tracking/SKILL.md +147 -147
- package/seed/marketplaces/ecc/skills/council/SKILL.md +203 -203
- package/seed/marketplaces/ecc/skills/cpp-coding-standards/SKILL.md +723 -723
- package/seed/marketplaces/ecc/skills/cpp-testing/SKILL.md +324 -324
- package/seed/marketplaces/ecc/skills/crosspost/SKILL.md +111 -111
- package/seed/marketplaces/ecc/skills/csharp-testing/SKILL.md +321 -321
- package/seed/marketplaces/ecc/skills/customer-billing-ops/SKILL.md +140 -140
- package/seed/marketplaces/ecc/skills/customs-trade-compliance/SKILL.md +263 -263
- package/seed/marketplaces/ecc/skills/dart-flutter-patterns/SKILL.md +563 -563
- package/seed/marketplaces/ecc/skills/dashboard-builder/SKILL.md +108 -108
- package/seed/marketplaces/ecc/skills/data-scraper-agent/SKILL.md +764 -764
- package/seed/marketplaces/ecc/skills/data-throughput-accelerator/SKILL.md +72 -72
- package/seed/marketplaces/ecc/skills/database-migrations/SKILL.md +429 -429
- package/seed/marketplaces/ecc/skills/deep-research/SKILL.md +159 -159
- package/seed/marketplaces/ecc/skills/defi-amm-security/SKILL.md +166 -166
- package/seed/marketplaces/ecc/skills/deployment-patterns/SKILL.md +427 -427
- package/seed/marketplaces/ecc/skills/design-system/SKILL.md +82 -82
- package/seed/marketplaces/ecc/skills/django-celery/SKILL.md +457 -457
- package/seed/marketplaces/ecc/skills/django-patterns/SKILL.md +734 -734
- package/seed/marketplaces/ecc/skills/django-security/SKILL.md +593 -593
- package/seed/marketplaces/ecc/skills/django-tdd/SKILL.md +729 -729
- package/seed/marketplaces/ecc/skills/django-verification/SKILL.md +469 -469
- package/seed/marketplaces/ecc/skills/dmux-workflows/SKILL.md +191 -191
- package/seed/marketplaces/ecc/skills/docker-patterns/SKILL.md +364 -364
- package/seed/marketplaces/ecc/skills/documentation-lookup/SKILL.md +90 -90
- package/seed/marketplaces/ecc/skills/dotnet-patterns/SKILL.md +321 -321
- package/seed/marketplaces/ecc/skills/e2e-testing/SKILL.md +326 -326
- package/seed/marketplaces/ecc/skills/ecc-guide/SKILL.md +189 -189
- package/seed/marketplaces/ecc/skills/ecc-tools-cost-audit/SKILL.md +160 -160
- package/seed/marketplaces/ecc/skills/email-ops/SKILL.md +121 -121
- package/seed/marketplaces/ecc/skills/energy-procurement/SKILL.md +228 -228
- package/seed/marketplaces/ecc/skills/enterprise-agent-ops/SKILL.md +50 -50
- package/seed/marketplaces/ecc/skills/error-handling/SKILL.md +376 -376
- package/seed/marketplaces/ecc/skills/eval-harness/SKILL.md +270 -270
- package/seed/marketplaces/ecc/skills/evm-token-decimals/SKILL.md +130 -130
- package/seed/marketplaces/ecc/skills/exa-search/SKILL.md +107 -107
- package/seed/marketplaces/ecc/skills/fal-ai-media/SKILL.md +288 -288
- package/seed/marketplaces/ecc/skills/fastapi-patterns/SKILL.md +327 -327
- package/seed/marketplaces/ecc/skills/finance-billing-ops/SKILL.md +127 -127
- package/seed/marketplaces/ecc/skills/flox-environments/SKILL.md +496 -496
- package/seed/marketplaces/ecc/skills/flutter-dart-code-review/SKILL.md +435 -435
- package/seed/marketplaces/ecc/skills/foundation-models-on-device/SKILL.md +243 -243
- package/seed/marketplaces/ecc/skills/frontend-a11y/SKILL.md +446 -446
- package/seed/marketplaces/ecc/skills/frontend-design-direction/SKILL.md +92 -92
- package/seed/marketplaces/ecc/skills/frontend-patterns/SKILL.md +642 -642
- package/seed/marketplaces/ecc/skills/frontend-slides/SKILL.md +184 -184
- package/seed/marketplaces/ecc/skills/frontend-slides/STYLE_PRESETS.md +330 -330
- package/seed/marketplaces/ecc/skills/frontend-slides/animation-patterns.md +122 -122
- package/seed/marketplaces/ecc/skills/frontend-slides/html-template.md +419 -419
- package/seed/marketplaces/ecc/skills/frontend-slides/scripts/export-pdf.sh +418 -418
- package/seed/marketplaces/ecc/skills/frontend-slides/scripts/extract-pptx.py +96 -96
- package/seed/marketplaces/ecc/skills/frontend-slides/viewport-base.css +153 -153
- package/seed/marketplaces/ecc/skills/fsharp-testing/SKILL.md +280 -280
- package/seed/marketplaces/ecc/skills/gan-style-harness/SKILL.md +278 -278
- package/seed/marketplaces/ecc/skills/gateguard/SKILL.md +125 -125
- package/seed/marketplaces/ecc/skills/git-workflow/SKILL.md +715 -715
- package/seed/marketplaces/ecc/skills/github-ops/SKILL.md +144 -144
- package/seed/marketplaces/ecc/skills/golang-patterns/SKILL.md +674 -674
- package/seed/marketplaces/ecc/skills/golang-testing/SKILL.md +720 -720
- package/seed/marketplaces/ecc/skills/google-workspace-ops/SKILL.md +95 -95
- package/seed/marketplaces/ecc/skills/healthcare-cdss-patterns/SKILL.md +245 -245
- package/seed/marketplaces/ecc/skills/healthcare-emr-patterns/SKILL.md +159 -159
- package/seed/marketplaces/ecc/skills/healthcare-eval-harness/SKILL.md +207 -207
- package/seed/marketplaces/ecc/skills/healthcare-phi-compliance/SKILL.md +145 -145
- package/seed/marketplaces/ecc/skills/hermes-imports/SKILL.md +88 -88
- package/seed/marketplaces/ecc/skills/hexagonal-architecture/SKILL.md +276 -276
- package/seed/marketplaces/ecc/skills/hipaa-compliance/SKILL.md +78 -78
- package/seed/marketplaces/ecc/skills/homelab-network-readiness/SKILL.md +169 -169
- package/seed/marketplaces/ecc/skills/homelab-network-setup/SKILL.md +129 -129
- package/seed/marketplaces/ecc/skills/homelab-pihole-dns/SKILL.md +274 -274
- package/seed/marketplaces/ecc/skills/homelab-vlan-segmentation/SKILL.md +311 -311
- package/seed/marketplaces/ecc/skills/homelab-wireguard-vpn/SKILL.md +305 -305
- package/seed/marketplaces/ecc/skills/hookify-rules/SKILL.md +128 -128
- package/seed/marketplaces/ecc/skills/inventory-demand-planning/SKILL.md +247 -247
- package/seed/marketplaces/ecc/skills/investor-materials/SKILL.md +96 -96
- package/seed/marketplaces/ecc/skills/investor-outreach/SKILL.md +91 -91
- package/seed/marketplaces/ecc/skills/ios-icon-gen/SKILL.md +157 -157
- package/seed/marketplaces/ecc/skills/ios-icon-gen/scripts/generate_icons.swift +258 -258
- package/seed/marketplaces/ecc/skills/ios-icon-gen/scripts/iconify_gen.sh +235 -235
- package/seed/marketplaces/ecc/skills/iterative-retrieval/SKILL.md +211 -211
- package/seed/marketplaces/ecc/skills/ito-basket-compare/SKILL.md +63 -63
- package/seed/marketplaces/ecc/skills/ito-data-atlas-agent/SKILL.md +63 -63
- package/seed/marketplaces/ecc/skills/ito-market-intelligence/SKILL.md +60 -60
- package/seed/marketplaces/ecc/skills/ito-trade-planner/SKILL.md +67 -67
- package/seed/marketplaces/ecc/skills/java-coding-standards/SKILL.md +383 -383
- package/seed/marketplaces/ecc/skills/jira-integration/SKILL.md +293 -293
- package/seed/marketplaces/ecc/skills/jpa-patterns/SKILL.md +151 -151
- package/seed/marketplaces/ecc/skills/knowledge-ops/SKILL.md +154 -154
- package/seed/marketplaces/ecc/skills/kotlin-coroutines-flows/SKILL.md +284 -284
- package/seed/marketplaces/ecc/skills/kotlin-exposed-patterns/SKILL.md +719 -719
- package/seed/marketplaces/ecc/skills/kotlin-ktor-patterns/SKILL.md +689 -689
- package/seed/marketplaces/ecc/skills/kotlin-patterns/SKILL.md +711 -711
- package/seed/marketplaces/ecc/skills/kotlin-testing/SKILL.md +824 -824
- package/seed/marketplaces/ecc/skills/laravel-patterns/SKILL.md +415 -415
- package/seed/marketplaces/ecc/skills/laravel-plugin-discovery/SKILL.md +229 -229
- package/seed/marketplaces/ecc/skills/laravel-security/SKILL.md +285 -285
- package/seed/marketplaces/ecc/skills/laravel-tdd/SKILL.md +283 -283
- package/seed/marketplaces/ecc/skills/laravel-verification/SKILL.md +179 -179
- package/seed/marketplaces/ecc/skills/latency-critical-systems/SKILL.md +73 -73
- package/seed/marketplaces/ecc/skills/lead-intelligence/SKILL.md +321 -321
- package/seed/marketplaces/ecc/skills/lead-intelligence/agents/enrichment-agent.md +85 -85
- package/seed/marketplaces/ecc/skills/lead-intelligence/agents/mutual-mapper.md +75 -75
- package/seed/marketplaces/ecc/skills/lead-intelligence/agents/outreach-drafter.md +98 -98
- package/seed/marketplaces/ecc/skills/lead-intelligence/agents/signal-scorer.md +60 -60
- package/seed/marketplaces/ecc/skills/liquid-glass-design/SKILL.md +279 -279
- package/seed/marketplaces/ecc/skills/llm-trading-agent-security/SKILL.md +146 -146
- package/seed/marketplaces/ecc/skills/logistics-exception-management/SKILL.md +222 -222
- package/seed/marketplaces/ecc/skills/make-interfaces-feel-better/SKILL.md +151 -151
- package/seed/marketplaces/ecc/skills/manim-video/SKILL.md +89 -89
- package/seed/marketplaces/ecc/skills/manim-video/assets/network_graph_scene.py +52 -52
- package/seed/marketplaces/ecc/skills/market-research/SKILL.md +75 -75
- package/seed/marketplaces/ecc/skills/marketing-campaign/SKILL.md +113 -113
- package/seed/marketplaces/ecc/skills/mcp-server-patterns/SKILL.md +69 -69
- package/seed/marketplaces/ecc/skills/messages-ops/SKILL.md +104 -104
- package/seed/marketplaces/ecc/skills/mle-workflow/SKILL.md +346 -346
- package/seed/marketplaces/ecc/skills/motion-advanced/SKILL.md +596 -596
- package/seed/marketplaces/ecc/skills/motion-foundations/SKILL.md +299 -299
- package/seed/marketplaces/ecc/skills/motion-patterns/SKILL.md +435 -435
- package/seed/marketplaces/ecc/skills/motion-ui/SKILL.md +575 -575
- package/seed/marketplaces/ecc/skills/mysql-patterns/SKILL.md +412 -412
- package/seed/marketplaces/ecc/skills/nanoclaw-repl/SKILL.md +33 -33
- package/seed/marketplaces/ecc/skills/nestjs-patterns/SKILL.md +230 -230
- package/seed/marketplaces/ecc/skills/netmiko-ssh-automation/SKILL.md +173 -173
- package/seed/marketplaces/ecc/skills/network-bgp-diagnostics/SKILL.md +167 -167
- package/seed/marketplaces/ecc/skills/network-config-validation/SKILL.md +210 -210
- package/seed/marketplaces/ecc/skills/network-interface-health/SKILL.md +152 -152
- package/seed/marketplaces/ecc/skills/nextjs-turbopack/SKILL.md +57 -57
- package/seed/marketplaces/ecc/skills/nodejs-keccak256/SKILL.md +102 -102
- package/seed/marketplaces/ecc/skills/nutrient-document-processing/SKILL.md +167 -167
- package/seed/marketplaces/ecc/skills/nuxt4-patterns/SKILL.md +100 -100
- package/seed/marketplaces/ecc/skills/openclaw-persona-forge/SKILL.md +288 -288
- package/seed/marketplaces/ecc/skills/openclaw-persona-forge/gacha.py +224 -224
- package/seed/marketplaces/ecc/skills/openclaw-persona-forge/gacha.sh +5 -5
- package/seed/marketplaces/ecc/skills/openclaw-persona-forge/references/avatar-style.md +124 -124
- package/seed/marketplaces/ecc/skills/openclaw-persona-forge/references/boundary-rules.md +53 -53
- package/seed/marketplaces/ecc/skills/openclaw-persona-forge/references/error-handling.md +53 -53
- package/seed/marketplaces/ecc/skills/openclaw-persona-forge/references/identity-tension.md +48 -48
- package/seed/marketplaces/ecc/skills/openclaw-persona-forge/references/naming-system.md +39 -39
- package/seed/marketplaces/ecc/skills/openclaw-persona-forge/references/output-template.md +166 -166
- package/seed/marketplaces/ecc/skills/opensource-pipeline/SKILL.md +255 -255
- package/seed/marketplaces/ecc/skills/parallel-execution-optimizer/SKILL.md +72 -72
- package/seed/marketplaces/ecc/skills/perl-patterns/SKILL.md +504 -504
- package/seed/marketplaces/ecc/skills/perl-security/SKILL.md +503 -503
- package/seed/marketplaces/ecc/skills/perl-testing/SKILL.md +475 -475
- package/seed/marketplaces/ecc/skills/plan-orchestrate/SKILL.md +262 -262
- package/seed/marketplaces/ecc/skills/plankton-code-quality/SKILL.md +236 -236
- package/seed/marketplaces/ecc/skills/postgres-patterns/SKILL.md +147 -147
- package/seed/marketplaces/ecc/skills/prediction-market-oracle-research/SKILL.md +63 -63
- package/seed/marketplaces/ecc/skills/prediction-market-risk-review/SKILL.md +60 -60
- package/seed/marketplaces/ecc/skills/prisma-patterns/SKILL.md +371 -371
- package/seed/marketplaces/ecc/skills/product-capability/SKILL.md +141 -141
- package/seed/marketplaces/ecc/skills/product-lens/SKILL.md +92 -92
- package/seed/marketplaces/ecc/skills/production-audit/SKILL.md +206 -206
- package/seed/marketplaces/ecc/skills/production-scheduling/SKILL.md +238 -238
- package/seed/marketplaces/ecc/skills/project-flow-ops/SKILL.md +111 -111
- package/seed/marketplaces/ecc/skills/prompt-optimizer/SKILL.md +398 -398
- package/seed/marketplaces/ecc/skills/python-patterns/SKILL.md +750 -750
- package/seed/marketplaces/ecc/skills/python-testing/SKILL.md +816 -816
- package/seed/marketplaces/ecc/skills/pytorch-patterns/SKILL.md +396 -396
- package/seed/marketplaces/ecc/skills/quality-nonconformance/SKILL.md +260 -260
- package/seed/marketplaces/ecc/skills/quarkus-patterns/SKILL.md +722 -722
- package/seed/marketplaces/ecc/skills/quarkus-security/SKILL.md +467 -467
- package/seed/marketplaces/ecc/skills/quarkus-tdd/SKILL.md +811 -811
- package/seed/marketplaces/ecc/skills/quarkus-verification/SKILL.md +479 -479
- package/seed/marketplaces/ecc/skills/ralphinho-rfc-pipeline/SKILL.md +67 -67
- package/seed/marketplaces/ecc/skills/recsys-pipeline-architect/SKILL.md +114 -114
- package/seed/marketplaces/ecc/skills/recursive-decision-ledger/SKILL.md +79 -79
- package/seed/marketplaces/ecc/skills/redis-patterns/SKILL.md +403 -403
- package/seed/marketplaces/ecc/skills/regex-vs-llm-structured-text/SKILL.md +220 -220
- package/seed/marketplaces/ecc/skills/remotion-video-creation/SKILL.md +43 -43
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/3d.md +86 -86
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/animations.md +29 -29
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/assets/charts-bar-chart.tsx +173 -173
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/assets/text-animations-typewriter.tsx +100 -100
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/assets/text-animations-word-highlight.tsx +108 -108
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/assets.md +78 -78
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/audio.md +172 -172
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/calculate-metadata.md +104 -104
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/can-decode.md +75 -75
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/charts.md +58 -58
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/compositions.md +146 -146
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/display-captions.md +126 -126
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/extract-frames.md +229 -229
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/fonts.md +152 -152
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/get-audio-duration.md +58 -58
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/get-video-dimensions.md +68 -68
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/get-video-duration.md +58 -58
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/gifs.md +138 -138
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/images.md +130 -130
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/import-srt-captions.md +67 -67
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/lottie.md +67 -67
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/measuring-dom-nodes.md +34 -34
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/measuring-text.md +143 -143
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/sequencing.md +106 -106
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/tailwind.md +11 -11
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/text-animations.md +20 -20
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/timing.md +179 -179
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/transcribe-captions.md +19 -19
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/transitions.md +122 -122
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/trimming.md +52 -52
- package/seed/marketplaces/ecc/skills/remotion-video-creation/rules/videos.md +171 -171
- package/seed/marketplaces/ecc/skills/repo-scan/SKILL.md +78 -78
- package/seed/marketplaces/ecc/skills/research-ops/SKILL.md +112 -112
- package/seed/marketplaces/ecc/skills/returns-reverse-logistics/SKILL.md +240 -240
- package/seed/marketplaces/ecc/skills/rules-distill/SKILL.md +264 -264
- package/seed/marketplaces/ecc/skills/rules-distill/scripts/scan-rules.sh +58 -58
- package/seed/marketplaces/ecc/skills/rules-distill/scripts/scan-skills.sh +129 -129
- package/seed/marketplaces/ecc/skills/rust-patterns/SKILL.md +499 -499
- package/seed/marketplaces/ecc/skills/rust-testing/SKILL.md +500 -500
- package/seed/marketplaces/ecc/skills/safety-guard/SKILL.md +75 -75
- package/seed/marketplaces/ecc/skills/santa-method/SKILL.md +306 -306
- package/seed/marketplaces/ecc/skills/scientific-db-pubmed-database/SKILL.md +175 -175
- package/seed/marketplaces/ecc/skills/scientific-db-uspto-database/SKILL.md +177 -177
- package/seed/marketplaces/ecc/skills/scientific-pkg-gget/SKILL.md +166 -166
- package/seed/marketplaces/ecc/skills/scientific-thinking-literature-review/SKILL.md +192 -192
- package/seed/marketplaces/ecc/skills/scientific-thinking-scholar-evaluation/SKILL.md +160 -160
- package/seed/marketplaces/ecc/skills/search-first/SKILL.md +182 -182
- package/seed/marketplaces/ecc/skills/security-bounty-hunter/SKILL.md +99 -99
- package/seed/marketplaces/ecc/skills/security-review/SKILL.md +503 -503
- package/seed/marketplaces/ecc/skills/security-review/cloud-infrastructure-security.md +361 -361
- package/seed/marketplaces/ecc/skills/security-scan/SKILL.md +165 -165
- package/seed/marketplaces/ecc/skills/seo/SKILL.md +154 -154
- package/seed/marketplaces/ecc/skills/skill-comply/SKILL.md +58 -58
- package/seed/marketplaces/ecc/skills/skill-comply/fixtures/compliant_trace.jsonl +5 -5
- package/seed/marketplaces/ecc/skills/skill-comply/fixtures/noncompliant_trace.jsonl +3 -3
- package/seed/marketplaces/ecc/skills/skill-comply/fixtures/tdd_spec.yaml +44 -44
- package/seed/marketplaces/ecc/skills/skill-comply/prompts/classifier.md +24 -24
- package/seed/marketplaces/ecc/skills/skill-comply/prompts/scenario_generator.md +62 -62
- package/seed/marketplaces/ecc/skills/skill-comply/prompts/spec_generator.md +42 -42
- package/seed/marketplaces/ecc/skills/skill-comply/pyproject.toml +15 -15
- package/seed/marketplaces/ecc/skills/skill-comply/scripts/classifier.py +85 -85
- package/seed/marketplaces/ecc/skills/skill-comply/scripts/grader.py +124 -124
- package/seed/marketplaces/ecc/skills/skill-comply/scripts/parser.py +107 -107
- package/seed/marketplaces/ecc/skills/skill-comply/scripts/report.py +170 -170
- package/seed/marketplaces/ecc/skills/skill-comply/scripts/run.py +127 -127
- package/seed/marketplaces/ecc/skills/skill-comply/scripts/runner.py +186 -186
- package/seed/marketplaces/ecc/skills/skill-comply/scripts/scenario_generator.py +70 -70
- package/seed/marketplaces/ecc/skills/skill-comply/scripts/spec_generator.py +72 -72
- package/seed/marketplaces/ecc/skills/skill-comply/scripts/utils.py +13 -13
- package/seed/marketplaces/ecc/skills/skill-comply/tests/test_grader.py +197 -197
- package/seed/marketplaces/ecc/skills/skill-comply/tests/test_parser.py +90 -90
- package/seed/marketplaces/ecc/skills/skill-comply/tests/test_runner.py +172 -172
- package/seed/marketplaces/ecc/skills/skill-scout/SKILL.md +140 -140
- package/seed/marketplaces/ecc/skills/skill-stocktake/SKILL.md +194 -194
- package/seed/marketplaces/ecc/skills/skill-stocktake/scripts/quick-diff.sh +87 -87
- package/seed/marketplaces/ecc/skills/skill-stocktake/scripts/save-results.sh +56 -56
- package/seed/marketplaces/ecc/skills/skill-stocktake/scripts/scan.sh +170 -170
- package/seed/marketplaces/ecc/skills/social-graph-ranker/SKILL.md +154 -154
- package/seed/marketplaces/ecc/skills/social-publisher/SKILL.md +115 -115
- package/seed/marketplaces/ecc/skills/springboot-patterns/SKILL.md +314 -314
- package/seed/marketplaces/ecc/skills/springboot-security/SKILL.md +272 -272
- package/seed/marketplaces/ecc/skills/springboot-tdd/SKILL.md +158 -158
- package/seed/marketplaces/ecc/skills/springboot-verification/SKILL.md +231 -231
- package/seed/marketplaces/ecc/skills/strategic-compact/SKILL.md +131 -131
- package/seed/marketplaces/ecc/skills/swift-actor-persistence/SKILL.md +143 -143
- package/seed/marketplaces/ecc/skills/swift-concurrency-6-2/SKILL.md +216 -216
- package/seed/marketplaces/ecc/skills/swift-protocol-di-testing/SKILL.md +190 -190
- package/seed/marketplaces/ecc/skills/swiftui-patterns/SKILL.md +259 -259
- package/seed/marketplaces/ecc/skills/tdd-workflow/SKILL.md +463 -463
- package/seed/marketplaces/ecc/skills/team-builder/SKILL.md +168 -168
- package/seed/marketplaces/ecc/skills/terminal-ops/SKILL.md +109 -109
- package/seed/marketplaces/ecc/skills/tinystruct-patterns/SKILL.md +203 -203
- package/seed/marketplaces/ecc/skills/tinystruct-patterns/references/architecture.md +90 -90
- package/seed/marketplaces/ecc/skills/tinystruct-patterns/references/data-handling.md +60 -60
- package/seed/marketplaces/ecc/skills/tinystruct-patterns/references/database.md +99 -99
- package/seed/marketplaces/ecc/skills/tinystruct-patterns/references/routing.md +64 -64
- package/seed/marketplaces/ecc/skills/tinystruct-patterns/references/system-usage.md +97 -97
- package/seed/marketplaces/ecc/skills/tinystruct-patterns/references/testing.md +72 -72
- package/seed/marketplaces/ecc/skills/token-budget-advisor/SKILL.md +133 -133
- package/seed/marketplaces/ecc/skills/ui-demo/SKILL.md +465 -465
- package/seed/marketplaces/ecc/skills/ui-to-vue/SKILL.md +134 -134
- package/seed/marketplaces/ecc/skills/uncloud/SKILL.md +343 -343
- package/seed/marketplaces/ecc/skills/unified-notifications-ops/SKILL.md +187 -187
- package/seed/marketplaces/ecc/skills/verification-loop/SKILL.md +126 -126
- package/seed/marketplaces/ecc/skills/video-editing/SKILL.md +310 -310
- package/seed/marketplaces/ecc/skills/videodb/SKILL.md +374 -374
- package/seed/marketplaces/ecc/skills/videodb/reference/api-reference.md +550 -550
- package/seed/marketplaces/ecc/skills/videodb/reference/capture-reference.md +407 -407
- package/seed/marketplaces/ecc/skills/videodb/reference/capture.md +101 -101
- package/seed/marketplaces/ecc/skills/videodb/reference/editor.md +443 -443
- package/seed/marketplaces/ecc/skills/videodb/reference/generative.md +331 -331
- package/seed/marketplaces/ecc/skills/videodb/reference/rtstream-reference.md +564 -564
- package/seed/marketplaces/ecc/skills/videodb/reference/rtstream.md +65 -65
- package/seed/marketplaces/ecc/skills/videodb/reference/search.md +230 -230
- package/seed/marketplaces/ecc/skills/videodb/reference/streaming.md +406 -406
- package/seed/marketplaces/ecc/skills/videodb/reference/use-cases.md +118 -118
- package/seed/marketplaces/ecc/skills/videodb/scripts/ws_listener.py +282 -282
- package/seed/marketplaces/ecc/skills/visa-doc-translate/README.md +86 -86
- package/seed/marketplaces/ecc/skills/visa-doc-translate/SKILL.md +117 -117
- package/seed/marketplaces/ecc/skills/vite-patterns/SKILL.md +449 -449
- package/seed/marketplaces/ecc/skills/windows-desktop-e2e/SKILL.md +887 -887
- package/seed/marketplaces/ecc/skills/workspace-surface-audit/SKILL.md +125 -125
- package/seed/marketplaces/ecc/skills/x-api/SKILL.md +234 -234
- package/dist/SKILL-r7zmg5v7.md +0 -3
- package/dist/cli-mvr5k580.md +0 -3
- package/dist/server-zyhc2a9z.md +0 -3
|
@@ -1,280 +1,280 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: fsharp-testing
|
|
3
|
-
description: F# testing patterns with xUnit, FsUnit, Unquote, FsCheck property-based testing, integration tests, and test organization best practices.
|
|
4
|
-
origin: ECC
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# F# Testing Patterns
|
|
8
|
-
|
|
9
|
-
Comprehensive testing patterns for F# applications using xUnit, FsUnit, Unquote, FsCheck, and modern .NET testing practices.
|
|
10
|
-
|
|
11
|
-
## When to Activate
|
|
12
|
-
|
|
13
|
-
- Writing new tests for F# code
|
|
14
|
-
- Reviewing test quality and coverage
|
|
15
|
-
- Setting up test infrastructure for F# projects
|
|
16
|
-
- Debugging flaky or slow tests
|
|
17
|
-
|
|
18
|
-
## Test Framework Stack
|
|
19
|
-
|
|
20
|
-
| Tool | Purpose |
|
|
21
|
-
|---|---|
|
|
22
|
-
| **xUnit** | Test framework (standard .NET ecosystem choice) |
|
|
23
|
-
| **FsUnit.xUnit** | F#-friendly assertion syntax for xUnit |
|
|
24
|
-
| **Unquote** | Assertion library using F# quotations for clear failure messages |
|
|
25
|
-
| **FsCheck.xUnit** | Property-based testing integrated with xUnit |
|
|
26
|
-
| **NSubstitute** | Mocking .NET dependencies |
|
|
27
|
-
| **Testcontainers** | Real infrastructure in integration tests |
|
|
28
|
-
| **WebApplicationFactory** | ASP.NET Core integration tests |
|
|
29
|
-
|
|
30
|
-
## Unit Tests with xUnit + FsUnit
|
|
31
|
-
|
|
32
|
-
### Basic Test Structure
|
|
33
|
-
|
|
34
|
-
```fsharp
|
|
35
|
-
module OrderServiceTests
|
|
36
|
-
|
|
37
|
-
open Xunit
|
|
38
|
-
open FsUnit.Xunit
|
|
39
|
-
|
|
40
|
-
[<Fact>]
|
|
41
|
-
let ``create sets status to Pending`` () =
|
|
42
|
-
let order = Order.create "cust-1" [ validItem ]
|
|
43
|
-
order.Status |> should equal Pending
|
|
44
|
-
|
|
45
|
-
[<Fact>]
|
|
46
|
-
let ``confirm changes status to Confirmed`` () =
|
|
47
|
-
let order = Order.create "cust-1" [ validItem ]
|
|
48
|
-
let confirmed = Order.confirm order
|
|
49
|
-
confirmed.Status |> should be (ofCase <@ Confirmed @>)
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Assertions with Unquote
|
|
53
|
-
|
|
54
|
-
Unquote uses F# quotations so failure messages show the full expression that failed, not just "expected X got Y".
|
|
55
|
-
|
|
56
|
-
```fsharp
|
|
57
|
-
module OrderValidationTests
|
|
58
|
-
|
|
59
|
-
open Xunit
|
|
60
|
-
open Swensen.Unquote
|
|
61
|
-
|
|
62
|
-
[<Fact>]
|
|
63
|
-
let ``PlaceOrder returns success when request is valid`` () =
|
|
64
|
-
let request = { CustomerId = "cust-123"; Items = [ validItem ] }
|
|
65
|
-
let result = OrderService.placeOrder request
|
|
66
|
-
test <@ Result.isOk result @>
|
|
67
|
-
|
|
68
|
-
[<Fact>]
|
|
69
|
-
let ``order total sums item prices`` () =
|
|
70
|
-
let items = [ { Sku = "A"; Quantity = 2; Price = 10m }
|
|
71
|
-
{ Sku = "B"; Quantity = 1; Price = 5m } ]
|
|
72
|
-
let total = Order.calculateTotal items
|
|
73
|
-
test <@ total = 25m @>
|
|
74
|
-
|
|
75
|
-
[<Fact>]
|
|
76
|
-
let ``validated email rejects empty input`` () =
|
|
77
|
-
let result = ValidatedEmail.create ""
|
|
78
|
-
test <@ Result.isError result @>
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Async Tests
|
|
82
|
-
|
|
83
|
-
```fsharp
|
|
84
|
-
[<Fact>]
|
|
85
|
-
let ``PlaceOrder returns success when request is valid`` () = task {
|
|
86
|
-
let deps = createTestDeps ()
|
|
87
|
-
let request = { CustomerId = "cust-123"; Items = [ validItem ] }
|
|
88
|
-
|
|
89
|
-
let! result = OrderService.placeOrder deps request
|
|
90
|
-
|
|
91
|
-
test <@ Result.isOk result @>
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
[<Fact>]
|
|
95
|
-
let ``PlaceOrder returns error when items are empty`` () = task {
|
|
96
|
-
let deps = createTestDeps ()
|
|
97
|
-
let request = { CustomerId = "cust-123"; Items = [] }
|
|
98
|
-
|
|
99
|
-
let! result = OrderService.placeOrder deps request
|
|
100
|
-
|
|
101
|
-
test <@ Result.isError result @>
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Parameterized Tests with Theory
|
|
106
|
-
|
|
107
|
-
```fsharp
|
|
108
|
-
[<Theory>]
|
|
109
|
-
[<InlineData("")>]
|
|
110
|
-
[<InlineData(" ")>]
|
|
111
|
-
let ``PlaceOrder rejects empty customer ID`` (customerId: string) =
|
|
112
|
-
let request = { CustomerId = customerId; Items = [ validItem ] }
|
|
113
|
-
let result = OrderService.placeOrder request
|
|
114
|
-
result |> should be (ofCase <@ Error @>)
|
|
115
|
-
|
|
116
|
-
[<Theory>]
|
|
117
|
-
[<InlineData("", false)>]
|
|
118
|
-
[<InlineData("a", false)>]
|
|
119
|
-
[<InlineData("user@example.com", true)>]
|
|
120
|
-
[<InlineData("user+tag@example.co.uk", true)>]
|
|
121
|
-
let ``IsValidEmail returns expected result`` (email: string, expected: bool) =
|
|
122
|
-
test <@ EmailValidator.isValid email = expected @>
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
## Property-Based Testing with FsCheck
|
|
126
|
-
|
|
127
|
-
### Using FsCheck.xUnit
|
|
128
|
-
|
|
129
|
-
```fsharp
|
|
130
|
-
open FsCheck
|
|
131
|
-
open FsCheck.Xunit
|
|
132
|
-
|
|
133
|
-
[<Property>]
|
|
134
|
-
let ``order total is always non-negative`` (items: NonEmptyList<PositiveInt * decimal>) =
|
|
135
|
-
let orderItems =
|
|
136
|
-
items.Get
|
|
137
|
-
|> List.map (fun (qty, price) ->
|
|
138
|
-
{ Sku = "SKU"; Quantity = qty.Get; Price = abs price })
|
|
139
|
-
let total = Order.calculateTotal orderItems
|
|
140
|
-
total >= 0m
|
|
141
|
-
|
|
142
|
-
[<Property>]
|
|
143
|
-
let ``serialization roundtrips`` (order: Order) =
|
|
144
|
-
let json = JsonSerializer.Serialize order
|
|
145
|
-
let deserialized = JsonSerializer.Deserialize<Order> json
|
|
146
|
-
deserialized = order
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
### Custom Generators
|
|
150
|
-
|
|
151
|
-
```fsharp
|
|
152
|
-
type OrderGenerators =
|
|
153
|
-
static member ValidEmail () =
|
|
154
|
-
gen {
|
|
155
|
-
let! user = Gen.elements [ "alice"; "bob"; "carol" ]
|
|
156
|
-
let! domain = Gen.elements [ "example.com"; "test.org" ]
|
|
157
|
-
return $"{user}@{domain}"
|
|
158
|
-
}
|
|
159
|
-
|> Arb.fromGen
|
|
160
|
-
|
|
161
|
-
[<Property(Arbitrary = [| typeof<OrderGenerators> |])>]
|
|
162
|
-
let ``valid emails pass validation`` (email: string) =
|
|
163
|
-
EmailValidator.isValid email
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## Mocking Dependencies
|
|
167
|
-
|
|
168
|
-
### Function Stubs (Preferred)
|
|
169
|
-
|
|
170
|
-
```fsharp
|
|
171
|
-
let createTestDeps () =
|
|
172
|
-
let mutable savedOrders = []
|
|
173
|
-
{ FindOrder = fun id -> task { return Map.tryFind id testData }
|
|
174
|
-
SaveOrder = fun order -> task { savedOrders <- order :: savedOrders }
|
|
175
|
-
SendNotification = fun _ -> Task.CompletedTask }
|
|
176
|
-
|
|
177
|
-
[<Fact>]
|
|
178
|
-
let ``PlaceOrder saves the confirmed order`` () = task {
|
|
179
|
-
let mutable saved = []
|
|
180
|
-
let deps =
|
|
181
|
-
{ createTestDeps () with
|
|
182
|
-
SaveOrder = fun order -> task { saved <- order :: saved } }
|
|
183
|
-
|
|
184
|
-
let! _ = OrderService.placeOrder deps validRequest
|
|
185
|
-
|
|
186
|
-
test <@ saved.Length = 1 @>
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### NSubstitute for .NET Interfaces
|
|
191
|
-
|
|
192
|
-
```fsharp
|
|
193
|
-
open NSubstitute
|
|
194
|
-
|
|
195
|
-
[<Fact>]
|
|
196
|
-
let ``calls repository with correct ID`` () = task {
|
|
197
|
-
let repo = Substitute.For<IOrderRepository>()
|
|
198
|
-
repo.FindByIdAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
|
|
199
|
-
.Returns(Task.FromResult(Some testOrder))
|
|
200
|
-
|
|
201
|
-
let service = OrderService(repo)
|
|
202
|
-
let! _ = service.GetOrder(testOrder.Id, CancellationToken.None)
|
|
203
|
-
|
|
204
|
-
do! repo.Received(1).FindByIdAsync(testOrder.Id, Arg.Any<CancellationToken>())
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## ASP.NET Core Integration Tests
|
|
209
|
-
|
|
210
|
-
```fsharp
|
|
211
|
-
type OrderApiTests (factory: WebApplicationFactory<Program>) =
|
|
212
|
-
interface IClassFixture<WebApplicationFactory<Program>>
|
|
213
|
-
|
|
214
|
-
let client =
|
|
215
|
-
factory.WithWebHostBuilder(fun builder ->
|
|
216
|
-
builder.ConfigureServices(fun services ->
|
|
217
|
-
services.RemoveAll<DbContextOptions<AppDbContext>>() |> ignore
|
|
218
|
-
services.AddDbContext<AppDbContext>(fun options ->
|
|
219
|
-
options.UseInMemoryDatabase("TestDb") |> ignore) |> ignore))
|
|
220
|
-
.CreateClient()
|
|
221
|
-
|
|
222
|
-
[<Fact>]
|
|
223
|
-
member _.``GET order returns 404 when not found`` () = task {
|
|
224
|
-
let! response = client.GetAsync($"/api/orders/{Guid.NewGuid()}")
|
|
225
|
-
test <@ response.StatusCode = HttpStatusCode.NotFound @>
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
## Test Organization
|
|
230
|
-
|
|
231
|
-
```
|
|
232
|
-
tests/
|
|
233
|
-
MyApp.Tests/
|
|
234
|
-
Unit/
|
|
235
|
-
OrderServiceTests.fs
|
|
236
|
-
PaymentServiceTests.fs
|
|
237
|
-
Integration/
|
|
238
|
-
OrderApiTests.fs
|
|
239
|
-
OrderRepositoryTests.fs
|
|
240
|
-
Properties/
|
|
241
|
-
OrderPropertyTests.fs
|
|
242
|
-
Helpers/
|
|
243
|
-
TestData.fs
|
|
244
|
-
TestDeps.fs
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
## Common Anti-Patterns
|
|
248
|
-
|
|
249
|
-
| Anti-Pattern | Fix |
|
|
250
|
-
|---|---|
|
|
251
|
-
| Testing implementation details | Test behavior and outcomes |
|
|
252
|
-
| Mutable shared test state | Fresh state per test |
|
|
253
|
-
| `Thread.Sleep` in async tests | Use `Task.Delay` with timeout, or polling helpers |
|
|
254
|
-
| Asserting on `sprintf` output | Assert on typed values and pattern matches |
|
|
255
|
-
| Ignoring `CancellationToken` | Always pass and verify cancellation |
|
|
256
|
-
| Skipping property-based tests | Use FsCheck for any function with clear invariants |
|
|
257
|
-
|
|
258
|
-
## Related Skills
|
|
259
|
-
|
|
260
|
-
- `dotnet-patterns` - Idiomatic .NET patterns, dependency injection, and architecture
|
|
261
|
-
- `csharp-testing` - C# testing patterns (shared infrastructure like WebApplicationFactory and Testcontainers applies to F# too)
|
|
262
|
-
|
|
263
|
-
## Running Tests
|
|
264
|
-
|
|
265
|
-
```bash
|
|
266
|
-
# Run all tests
|
|
267
|
-
dotnet test
|
|
268
|
-
|
|
269
|
-
# Run with coverage
|
|
270
|
-
dotnet test --collect:"XPlat Code Coverage"
|
|
271
|
-
|
|
272
|
-
# Run specific project
|
|
273
|
-
dotnet test tests/MyApp.Tests/
|
|
274
|
-
|
|
275
|
-
# Filter by test name
|
|
276
|
-
dotnet test --filter "FullyQualifiedName~OrderService"
|
|
277
|
-
|
|
278
|
-
# Watch mode during development
|
|
279
|
-
dotnet watch test --project tests/MyApp.Tests/
|
|
280
|
-
```
|
|
1
|
+
---
|
|
2
|
+
name: fsharp-testing
|
|
3
|
+
description: F# testing patterns with xUnit, FsUnit, Unquote, FsCheck property-based testing, integration tests, and test organization best practices.
|
|
4
|
+
origin: ECC
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# F# Testing Patterns
|
|
8
|
+
|
|
9
|
+
Comprehensive testing patterns for F# applications using xUnit, FsUnit, Unquote, FsCheck, and modern .NET testing practices.
|
|
10
|
+
|
|
11
|
+
## When to Activate
|
|
12
|
+
|
|
13
|
+
- Writing new tests for F# code
|
|
14
|
+
- Reviewing test quality and coverage
|
|
15
|
+
- Setting up test infrastructure for F# projects
|
|
16
|
+
- Debugging flaky or slow tests
|
|
17
|
+
|
|
18
|
+
## Test Framework Stack
|
|
19
|
+
|
|
20
|
+
| Tool | Purpose |
|
|
21
|
+
|---|---|
|
|
22
|
+
| **xUnit** | Test framework (standard .NET ecosystem choice) |
|
|
23
|
+
| **FsUnit.xUnit** | F#-friendly assertion syntax for xUnit |
|
|
24
|
+
| **Unquote** | Assertion library using F# quotations for clear failure messages |
|
|
25
|
+
| **FsCheck.xUnit** | Property-based testing integrated with xUnit |
|
|
26
|
+
| **NSubstitute** | Mocking .NET dependencies |
|
|
27
|
+
| **Testcontainers** | Real infrastructure in integration tests |
|
|
28
|
+
| **WebApplicationFactory** | ASP.NET Core integration tests |
|
|
29
|
+
|
|
30
|
+
## Unit Tests with xUnit + FsUnit
|
|
31
|
+
|
|
32
|
+
### Basic Test Structure
|
|
33
|
+
|
|
34
|
+
```fsharp
|
|
35
|
+
module OrderServiceTests
|
|
36
|
+
|
|
37
|
+
open Xunit
|
|
38
|
+
open FsUnit.Xunit
|
|
39
|
+
|
|
40
|
+
[<Fact>]
|
|
41
|
+
let ``create sets status to Pending`` () =
|
|
42
|
+
let order = Order.create "cust-1" [ validItem ]
|
|
43
|
+
order.Status |> should equal Pending
|
|
44
|
+
|
|
45
|
+
[<Fact>]
|
|
46
|
+
let ``confirm changes status to Confirmed`` () =
|
|
47
|
+
let order = Order.create "cust-1" [ validItem ]
|
|
48
|
+
let confirmed = Order.confirm order
|
|
49
|
+
confirmed.Status |> should be (ofCase <@ Confirmed @>)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Assertions with Unquote
|
|
53
|
+
|
|
54
|
+
Unquote uses F# quotations so failure messages show the full expression that failed, not just "expected X got Y".
|
|
55
|
+
|
|
56
|
+
```fsharp
|
|
57
|
+
module OrderValidationTests
|
|
58
|
+
|
|
59
|
+
open Xunit
|
|
60
|
+
open Swensen.Unquote
|
|
61
|
+
|
|
62
|
+
[<Fact>]
|
|
63
|
+
let ``PlaceOrder returns success when request is valid`` () =
|
|
64
|
+
let request = { CustomerId = "cust-123"; Items = [ validItem ] }
|
|
65
|
+
let result = OrderService.placeOrder request
|
|
66
|
+
test <@ Result.isOk result @>
|
|
67
|
+
|
|
68
|
+
[<Fact>]
|
|
69
|
+
let ``order total sums item prices`` () =
|
|
70
|
+
let items = [ { Sku = "A"; Quantity = 2; Price = 10m }
|
|
71
|
+
{ Sku = "B"; Quantity = 1; Price = 5m } ]
|
|
72
|
+
let total = Order.calculateTotal items
|
|
73
|
+
test <@ total = 25m @>
|
|
74
|
+
|
|
75
|
+
[<Fact>]
|
|
76
|
+
let ``validated email rejects empty input`` () =
|
|
77
|
+
let result = ValidatedEmail.create ""
|
|
78
|
+
test <@ Result.isError result @>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Async Tests
|
|
82
|
+
|
|
83
|
+
```fsharp
|
|
84
|
+
[<Fact>]
|
|
85
|
+
let ``PlaceOrder returns success when request is valid`` () = task {
|
|
86
|
+
let deps = createTestDeps ()
|
|
87
|
+
let request = { CustomerId = "cust-123"; Items = [ validItem ] }
|
|
88
|
+
|
|
89
|
+
let! result = OrderService.placeOrder deps request
|
|
90
|
+
|
|
91
|
+
test <@ Result.isOk result @>
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
[<Fact>]
|
|
95
|
+
let ``PlaceOrder returns error when items are empty`` () = task {
|
|
96
|
+
let deps = createTestDeps ()
|
|
97
|
+
let request = { CustomerId = "cust-123"; Items = [] }
|
|
98
|
+
|
|
99
|
+
let! result = OrderService.placeOrder deps request
|
|
100
|
+
|
|
101
|
+
test <@ Result.isError result @>
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Parameterized Tests with Theory
|
|
106
|
+
|
|
107
|
+
```fsharp
|
|
108
|
+
[<Theory>]
|
|
109
|
+
[<InlineData("")>]
|
|
110
|
+
[<InlineData(" ")>]
|
|
111
|
+
let ``PlaceOrder rejects empty customer ID`` (customerId: string) =
|
|
112
|
+
let request = { CustomerId = customerId; Items = [ validItem ] }
|
|
113
|
+
let result = OrderService.placeOrder request
|
|
114
|
+
result |> should be (ofCase <@ Error @>)
|
|
115
|
+
|
|
116
|
+
[<Theory>]
|
|
117
|
+
[<InlineData("", false)>]
|
|
118
|
+
[<InlineData("a", false)>]
|
|
119
|
+
[<InlineData("user@example.com", true)>]
|
|
120
|
+
[<InlineData("user+tag@example.co.uk", true)>]
|
|
121
|
+
let ``IsValidEmail returns expected result`` (email: string, expected: bool) =
|
|
122
|
+
test <@ EmailValidator.isValid email = expected @>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Property-Based Testing with FsCheck
|
|
126
|
+
|
|
127
|
+
### Using FsCheck.xUnit
|
|
128
|
+
|
|
129
|
+
```fsharp
|
|
130
|
+
open FsCheck
|
|
131
|
+
open FsCheck.Xunit
|
|
132
|
+
|
|
133
|
+
[<Property>]
|
|
134
|
+
let ``order total is always non-negative`` (items: NonEmptyList<PositiveInt * decimal>) =
|
|
135
|
+
let orderItems =
|
|
136
|
+
items.Get
|
|
137
|
+
|> List.map (fun (qty, price) ->
|
|
138
|
+
{ Sku = "SKU"; Quantity = qty.Get; Price = abs price })
|
|
139
|
+
let total = Order.calculateTotal orderItems
|
|
140
|
+
total >= 0m
|
|
141
|
+
|
|
142
|
+
[<Property>]
|
|
143
|
+
let ``serialization roundtrips`` (order: Order) =
|
|
144
|
+
let json = JsonSerializer.Serialize order
|
|
145
|
+
let deserialized = JsonSerializer.Deserialize<Order> json
|
|
146
|
+
deserialized = order
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Custom Generators
|
|
150
|
+
|
|
151
|
+
```fsharp
|
|
152
|
+
type OrderGenerators =
|
|
153
|
+
static member ValidEmail () =
|
|
154
|
+
gen {
|
|
155
|
+
let! user = Gen.elements [ "alice"; "bob"; "carol" ]
|
|
156
|
+
let! domain = Gen.elements [ "example.com"; "test.org" ]
|
|
157
|
+
return $"{user}@{domain}"
|
|
158
|
+
}
|
|
159
|
+
|> Arb.fromGen
|
|
160
|
+
|
|
161
|
+
[<Property(Arbitrary = [| typeof<OrderGenerators> |])>]
|
|
162
|
+
let ``valid emails pass validation`` (email: string) =
|
|
163
|
+
EmailValidator.isValid email
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Mocking Dependencies
|
|
167
|
+
|
|
168
|
+
### Function Stubs (Preferred)
|
|
169
|
+
|
|
170
|
+
```fsharp
|
|
171
|
+
let createTestDeps () =
|
|
172
|
+
let mutable savedOrders = []
|
|
173
|
+
{ FindOrder = fun id -> task { return Map.tryFind id testData }
|
|
174
|
+
SaveOrder = fun order -> task { savedOrders <- order :: savedOrders }
|
|
175
|
+
SendNotification = fun _ -> Task.CompletedTask }
|
|
176
|
+
|
|
177
|
+
[<Fact>]
|
|
178
|
+
let ``PlaceOrder saves the confirmed order`` () = task {
|
|
179
|
+
let mutable saved = []
|
|
180
|
+
let deps =
|
|
181
|
+
{ createTestDeps () with
|
|
182
|
+
SaveOrder = fun order -> task { saved <- order :: saved } }
|
|
183
|
+
|
|
184
|
+
let! _ = OrderService.placeOrder deps validRequest
|
|
185
|
+
|
|
186
|
+
test <@ saved.Length = 1 @>
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### NSubstitute for .NET Interfaces
|
|
191
|
+
|
|
192
|
+
```fsharp
|
|
193
|
+
open NSubstitute
|
|
194
|
+
|
|
195
|
+
[<Fact>]
|
|
196
|
+
let ``calls repository with correct ID`` () = task {
|
|
197
|
+
let repo = Substitute.For<IOrderRepository>()
|
|
198
|
+
repo.FindByIdAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
|
|
199
|
+
.Returns(Task.FromResult(Some testOrder))
|
|
200
|
+
|
|
201
|
+
let service = OrderService(repo)
|
|
202
|
+
let! _ = service.GetOrder(testOrder.Id, CancellationToken.None)
|
|
203
|
+
|
|
204
|
+
do! repo.Received(1).FindByIdAsync(testOrder.Id, Arg.Any<CancellationToken>())
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## ASP.NET Core Integration Tests
|
|
209
|
+
|
|
210
|
+
```fsharp
|
|
211
|
+
type OrderApiTests (factory: WebApplicationFactory<Program>) =
|
|
212
|
+
interface IClassFixture<WebApplicationFactory<Program>>
|
|
213
|
+
|
|
214
|
+
let client =
|
|
215
|
+
factory.WithWebHostBuilder(fun builder ->
|
|
216
|
+
builder.ConfigureServices(fun services ->
|
|
217
|
+
services.RemoveAll<DbContextOptions<AppDbContext>>() |> ignore
|
|
218
|
+
services.AddDbContext<AppDbContext>(fun options ->
|
|
219
|
+
options.UseInMemoryDatabase("TestDb") |> ignore) |> ignore))
|
|
220
|
+
.CreateClient()
|
|
221
|
+
|
|
222
|
+
[<Fact>]
|
|
223
|
+
member _.``GET order returns 404 when not found`` () = task {
|
|
224
|
+
let! response = client.GetAsync($"/api/orders/{Guid.NewGuid()}")
|
|
225
|
+
test <@ response.StatusCode = HttpStatusCode.NotFound @>
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Test Organization
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
tests/
|
|
233
|
+
MyApp.Tests/
|
|
234
|
+
Unit/
|
|
235
|
+
OrderServiceTests.fs
|
|
236
|
+
PaymentServiceTests.fs
|
|
237
|
+
Integration/
|
|
238
|
+
OrderApiTests.fs
|
|
239
|
+
OrderRepositoryTests.fs
|
|
240
|
+
Properties/
|
|
241
|
+
OrderPropertyTests.fs
|
|
242
|
+
Helpers/
|
|
243
|
+
TestData.fs
|
|
244
|
+
TestDeps.fs
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Common Anti-Patterns
|
|
248
|
+
|
|
249
|
+
| Anti-Pattern | Fix |
|
|
250
|
+
|---|---|
|
|
251
|
+
| Testing implementation details | Test behavior and outcomes |
|
|
252
|
+
| Mutable shared test state | Fresh state per test |
|
|
253
|
+
| `Thread.Sleep` in async tests | Use `Task.Delay` with timeout, or polling helpers |
|
|
254
|
+
| Asserting on `sprintf` output | Assert on typed values and pattern matches |
|
|
255
|
+
| Ignoring `CancellationToken` | Always pass and verify cancellation |
|
|
256
|
+
| Skipping property-based tests | Use FsCheck for any function with clear invariants |
|
|
257
|
+
|
|
258
|
+
## Related Skills
|
|
259
|
+
|
|
260
|
+
- `dotnet-patterns` - Idiomatic .NET patterns, dependency injection, and architecture
|
|
261
|
+
- `csharp-testing` - C# testing patterns (shared infrastructure like WebApplicationFactory and Testcontainers applies to F# too)
|
|
262
|
+
|
|
263
|
+
## Running Tests
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
# Run all tests
|
|
267
|
+
dotnet test
|
|
268
|
+
|
|
269
|
+
# Run with coverage
|
|
270
|
+
dotnet test --collect:"XPlat Code Coverage"
|
|
271
|
+
|
|
272
|
+
# Run specific project
|
|
273
|
+
dotnet test tests/MyApp.Tests/
|
|
274
|
+
|
|
275
|
+
# Filter by test name
|
|
276
|
+
dotnet test --filter "FullyQualifiedName~OrderService"
|
|
277
|
+
|
|
278
|
+
# Watch mode during development
|
|
279
|
+
dotnet watch test --project tests/MyApp.Tests/
|
|
280
|
+
```
|