[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71H77T06V6YVV8H40BC5WWH":3,"skill-same:01M71H77T06V6YVV8H40BC5WWH":59},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":34,"linkOnly":35,"markdownContent":36,"markdownBody":37,"frontMatter":38,"refName":39,"commitSha":40,"skillDirectory":41,"forksCount":13,"repositoryHtmlUrl":42,"repositoryHomepageUrl":6,"ownerHtmlUrl":43,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":44,"install":45,"resources":58},"01M71H77T06V6YVV8H40BC5WWH","03-property-testing",null,"Effect-TS 4 property-based testing — Schema Arbitrary, fast-check, and generative test patterns","lambda-solver\u002Flambdabench-pro","lambda-solver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F279071046?v=4","01M71H55W2WK3PM6RRAY9JZWAJ","01M71H55WRT9XAFDAVACTCC2XP",0,"MIT","https:\u002F\u002Fgithub.com\u002Flambda-solver\u002Flambdabench-pro\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Feffect-ts\u002Ftesting\u002F03-property-testing\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33],"testing","03 property testing","effect","test","opencode","generative","test patterns","schema","fast","patterns","check","2026-11-10 10:12:30",false,"---\nname: 03-property-testing\ndescription: Effect-TS 4 property-based testing — Schema Arbitrary, fast-check, and generative test patterns\nlicense: MIT\ncompatibility: opencode\n---\n\n# Property-Based Testing\n\n## Schema Arbitrary — generate test data from schemas\n\nEffect Schema can derive `fast-check` arbitraries automatically.\n\n```typescript\nimport { Arbitrary, FastCheck, Schema } from \"effect\";\n\nconst User = Schema.Struct({\n  id: Schema.String,\n  age: Schema.Number.pipe(Schema.between(0, 120)),\n  active: Schema.Boolean,\n});\n\nconst arb = Arbitrary.make(User);\n\nFastCheck.assert(\n  FastCheck.property(arb, (user) => {\n    \u002F\u002F property must hold for all generated users\n    expect(user.age).toBeGreaterThanOrEqual(0);\n    expect(user.age).toBeLessThanOrEqual(120);\n  }),\n);\n```\n\n## it.effect.prop — built-in property test runner\n\n```typescript\nimport { it } from \"@effect\u002Fvitest\";\nimport { Schema } from \"effect\";\n\nit.effect.prop(\"encode then decode is identity\", [Schema.String, Schema.Number], ([str, num]) =>\n  Effect.gen(function* () {\n    const pair = { str, num };\n    const encoded = yield* Schema.encode(MySchema)(pair);\n    const decoded = yield* Schema.decode(MySchema)(encoded);\n    assert.deepStrictEqual(decoded, pair);\n  }),\n);\n```\n\n## Plain fast-check in Vitest\n\n```typescript\nimport { FastCheck } from \"effect\";\nimport { test } from \"vitest\";\n\ntest(\"sort is idempotent\", () => {\n  FastCheck.assert(\n    FastCheck.property(FastCheck.array(FastCheck.integer()), (arr) => {\n      const sorted = [...arr].sort();\n      expect([...sorted].sort()).toEqual(sorted);\n    }),\n  );\n});\n```\n\n## Custom arbitraries\n\n```typescript\nimport { Arbitrary, FastCheck } from \"effect\";\n\n\u002F\u002F Combine arbitraries\nconst nonEmptyString = FastCheck.string({ minLength: 1 });\nconst modelId = FastCheck.string({ minLength: 3 }).map((s) => `vendor\u002F${s}`);\n\n\u002F\u002F Use with property test\nFastCheck.assert(\n  FastCheck.property(modelId, (id) => {\n    expect(id).toContain(\"\u002F\");\n  }),\n);\n```\n\n## Schema constraints for tighter arbitraries\n\n```typescript\nconst BoundedAge = Schema.Number.pipe(Schema.int(), Schema.between(0, 120));\n\nconst NonEmptyTitle = Schema.String.pipe(Schema.minLength(1), Schema.maxLength(200));\n\nconst Task = Schema.Struct({\n  id: Schema.String.pipe(Schema.brand(\"TaskId\")),\n  title: NonEmptyTitle,\n  age: BoundedAge,\n});\n\n\u002F\u002F Arbitrary respects all constraints\nconst arb = Arbitrary.make(Task);\n```\n\n## Round-trip property (encode → decode)\n\nA fundamental property for any Schema with a transformation:\n\n```typescript\ntest(\"Schema round-trip\", () => {\n  FastCheck.assert(\n    FastCheck.property(Arbitrary.make(MySchema), (value) => {\n      const encoded = Schema.encodeSync(MySchema)(value);\n      const decoded = Schema.decodeSync(MySchema)(encoded);\n      expect(decoded).toEqual(value);\n    }),\n  );\n});\n```\n","# Property-Based Testing\n\n## Schema Arbitrary — generate test data from schemas\n\nEffect Schema can derive `fast-check` arbitraries automatically.\n\n```typescript\nimport { Arbitrary, FastCheck, Schema } from \"effect\";\n\nconst User = Schema.Struct({\n  id: Schema.String,\n  age: Schema.Number.pipe(Schema.between(0, 120)),\n  active: Schema.Boolean,\n});\n\nconst arb = Arbitrary.make(User);\n\nFastCheck.assert(\n  FastCheck.property(arb, (user) => {\n    \u002F\u002F property must hold for all generated users\n    expect(user.age).toBeGreaterThanOrEqual(0);\n    expect(user.age).toBeLessThanOrEqual(120);\n  }),\n);\n```\n\n## it.effect.prop — built-in property test runner\n\n```typescript\nimport { it } from \"@effect\u002Fvitest\";\nimport { Schema } from \"effect\";\n\nit.effect.prop(\"encode then decode is identity\", [Schema.String, Schema.Number], ([str, num]) =>\n  Effect.gen(function* () {\n    const pair = { str, num };\n    const encoded = yield* Schema.encode(MySchema)(pair);\n    const decoded = yield* Schema.decode(MySchema)(encoded);\n    assert.deepStrictEqual(decoded, pair);\n  }),\n);\n```\n\n## Plain fast-check in Vitest\n\n```typescript\nimport { FastCheck } from \"effect\";\nimport { test } from \"vitest\";\n\ntest(\"sort is idempotent\", () => {\n  FastCheck.assert(\n    FastCheck.property(FastCheck.array(FastCheck.integer()), (arr) => {\n      const sorted = [...arr].sort();\n      expect([...sorted].sort()).toEqual(sorted);\n    }),\n  );\n});\n```\n\n## Custom arbitraries\n\n```typescript\nimport { Arbitrary, FastCheck } from \"effect\";\n\n\u002F\u002F Combine arbitraries\nconst nonEmptyString = FastCheck.string({ minLength: 1 });\nconst modelId = FastCheck.string({ minLength: 3 }).map((s) => `vendor\u002F${s}`);\n\n\u002F\u002F Use with property test\nFastCheck.assert(\n  FastCheck.property(modelId, (id) => {\n    expect(id).toContain(\"\u002F\");\n  }),\n);\n```\n\n## Schema constraints for tighter arbitraries\n\n```typescript\nconst BoundedAge = Schema.Number.pipe(Schema.int(), Schema.between(0, 120));\n\nconst NonEmptyTitle = Schema.String.pipe(Schema.minLength(1), Schema.maxLength(200));\n\nconst Task = Schema.Struct({\n  id: Schema.String.pipe(Schema.brand(\"TaskId\")),\n  title: NonEmptyTitle,\n  age: BoundedAge,\n});\n\n\u002F\u002F Arbitrary respects all constraints\nconst arb = Arbitrary.make(Task);\n```\n\n## Round-trip property (encode → decode)\n\nA fundamental property for any Schema with a transformation:\n\n```typescript\ntest(\"Schema round-trip\", () => {\n  FastCheck.assert(\n    FastCheck.property(Arbitrary.make(MySchema), (value) => {\n      const encoded = Schema.encodeSync(MySchema)(value);\n      const decoded = Schema.decodeSync(MySchema)(encoded);\n      expect(decoded).toEqual(value);\n    }),\n  );\n});\n```\n",{"name":5,"license":14,"description":7,"compatibility":27},"main","816c073aaf171300af3605b06f7ec5aa7370ef0b",".opencode\u002Fskills\u002Feffect-ts\u002Ftesting\u002F03-property-testing","https:\u002F\u002Fgithub.com\u002Flambda-solver\u002Flambdabench-pro","https:\u002F\u002Fgithub.com\u002Flambda-solver","2026-05-31 17:08:46",{"source":8,"skillName":5,"commands":46,"prompt":56,"zipAvailable":57},[47,50,53],{"tool":48,"command":49},"npx","npx skills add lambda-solver\u002Flambdabench-pro --skill 03-property-testing",{"tool":51,"command":52},"bunx","bunx skills add lambda-solver\u002Flambdabench-pro --skill 03-property-testing",{"tool":54,"command":55},"pnpm","pnpm dlx skills add lambda-solver\u002Flambdabench-pro --skill 03-property-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Flambda-solver\u002Flambdabench-pro\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Feffect-ts\u002Ftesting\u002F03-property-testing\u002FSKILL.md",true,[],[60,89,110,129,150,168],{"skillNo":61,"name":62,"nameZh":6,"description":63,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":64,"categories":65,"keywords":69,"publishedAt":34},"01M71H9FNA5D6Y4ANXD18Z1Z3X","tmux-workflow","Development workflow with tmux — run dev servers, Storybook, and background processes in persistent sessions with live logs, while keeping OpenCode free for chat","https:\u002F\u002Fgithub.com\u002Flambda-solver\u002Flambdabench-pro\u002Fblob\u002Fmain\u002Freference\u002Fghui\u002F.opencode\u002Fskills\u002Ftmux\u002FSKILL.md",[66],{"categoryNo":67,"categoryName":68,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[70,71,72,73,74,75,76,77,78,79,80,27,81,82,83,84,85,86,87,88],"tmux","workflow","tmux workflow","chat","dev servers","background","processes","storybook","live","servers","run","with","logs","development workflow","free","dev","sessions","for","development",{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":98,"publishedAt":34},"01M71H9DQJDAJVZX37NDN99D3P","04-anti-patterns","React anti-patterns to avoid — manual JSX repetition, useEffect misuse, reference instability, prop drilling, conditional hooks, and common performance traps","https:\u002F\u002Fgithub.com\u002Flambda-solver\u002Flambdabench-pro\u002Fblob\u002Fmain\u002Freference\u002Fghui\u002F.opencode\u002Fskills\u002Freact\u002Fpatterns\u002F04-anti-patterns\u002FSKILL.md",[95],{"categoryNo":96,"categoryName":97,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000009","前端开发",[32,99,100,101,102,103,104,105,106,107,108,27,109],"anti patterns","04 anti patterns","common","jsx","reference","conditional","hooks","manual","performance","anti-patterns","react",{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":117,"publishedAt":34},"01M71H9BXF511W2R3B73S5P9ZN","03-state-management","React state management patterns — lifting state, colocation, URL state, server state with TanStack Query, local state with useState\u002FuseReducer","https:\u002F\u002Fgithub.com\u002Flambda-solver\u002Flambdabench-pro\u002Fblob\u002Fmain\u002Freference\u002Fghui\u002F.opencode\u002Fskills\u002Freact\u002Fpatterns\u002F03-state-management\u002FSKILL.md",[116],{"categoryNo":96,"categoryName":97,"taxonomyType":20,"taxonomyTypeDesc":21},[118,119,120,121,109,122,32,123,124,125,126,27,127,81,128],"management","state management","state","03 state management","query","URL","tanstack","react state management","local","server","tanstack query",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":136,"publishedAt":34},"01M71H9AAGVWMYQ4NG82QPYCTE","02-component-composition","React component composition patterns — render props, compound components, list rendering with map, slot patterns, and layout primitives","https:\u002F\u002Fgithub.com\u002Flambda-solver\u002Flambdabench-pro\u002Fblob\u002Fmain\u002Freference\u002Fghui\u002F.opencode\u002Fskills\u002Freact\u002Fpatterns\u002F02-component-composition\u002FSKILL.md",[135],{"categoryNo":96,"categoryName":97,"taxonomyType":20,"taxonomyTypeDesc":21},[137,138,139,27,81,140,141,109,142,32,143,144,145,146,147,148,149],"02 component composition","component","Composition","compound","components","primitives","composition patterns","list","map","rendering","render","react component","layout",{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":157,"publishedAt":34},"01M71H98RDXRQZDR496SRD906M","01-fp-style","React functional programming style — pure components, hooks conventions, Effect Atom integration, and Tailwind patterns","https:\u002F\u002Fgithub.com\u002Flambda-solver\u002Flambdabench-pro\u002Fblob\u002Fmain\u002Freference\u002Fghui\u002F.opencode\u002Fskills\u002Freact\u002Fpatterns\u002F01-fp-style\u002FSKILL.md",[156],{"categoryNo":96,"categoryName":97,"taxonomyType":20,"taxonomyTypeDesc":21},[158,159,160,32,161,162,27,163,109,164,141,105,165,166,167,25],"01 fp style","style","atom","conventions","integration","functional","programming","Tailwind","tailwind patterns","functional programming",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":175,"publishedAt":34},"01M71H95PYGAWBS5C8KN0C4WGT","react-animation","React animation with react\u002Fmotion (Framer Motion) — declarative animations, gestures, layout animations, and performance best practices","https:\u002F\u002Fgithub.com\u002Flambda-solver\u002Flambdabench-pro\u002Fblob\u002Fmain\u002Freference\u002Fghui\u002F.opencode\u002Fskills\u002Freact\u002Fanimation\u002FSKILL.md",[174],{"categoryNo":96,"categoryName":97,"taxonomyType":20,"taxonomyTypeDesc":21},[109,176,177,107,178,27,149,179,180,81,181,182,183,184],"react animation","Animation","framer motion","motion","best practices","framer","gestures","animations","declarative"]