[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-aptos-move-test":3,"mdc-2p4i9r-key":29,"related-org-aptos-move-test":2224,"related-repo-aptos-move-test":2389},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":20,"repoUrl":21,"updatedAt":22,"license":23,"forks":20,"topics":24,"repo":25,"sourceUrl":27,"mdContent":28},"move-test","generate unit tests for Move code","Generate unit tests for Move code. Use for test generation, writing tests, or improving coverage.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"aptos","Aptos Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Faptos.png","aptos-labs",[13,17],{"name":14,"slug":15,"type":16},"Web3","web3","tag",{"name":18,"slug":19,"type":16},"Testing","testing",0,"https:\u002F\u002Fgithub.com\u002Faptos-labs\u002Faptos-ai","2026-07-19T06:03:11.019744",null,[],{"repoUrl":21,"stars":20,"forks":20,"topics":26,"description":23},[],"https:\u002F\u002Fgithub.com\u002Faptos-labs\u002Faptos-ai\u002Ftree\u002FHEAD\u002Fplugins\u002Fmove-flow\u002Fskills\u002Fmove-test","---\nname: move-test\ndescription: Generate unit tests for Move code. Use for test generation, writing tests, or improving coverage.\n---\n\nBefore doing any work, use TaskCreate to create one task for each\n`**Task:**` entry listed below. Then execute them in order, marking\neach in_progress when you start it and completed when you finish.\n\n\n\n\n## Test Generation Tasks — Execute In Order\n\n**Task: Check package.** Build the package and establish a test coverage\nbaseline. Fix any compilation errors or failing tests before proceeding.\n\n**Task: Analyze target code.** Identify uncovered lines and testable behaviors\n(success paths, abort conditions, edge cases, potential bugs).\n\n**Task: Generate test module.** Create tests in `tests\u002Fmove_flow\u002F\u003Cmodule>_tests.move`.\n\n**Task: Validate tests.** Run tests. Fix compilation errors and wrong\nassertions. Move tests that expose real bugs to `bugs\u002F`.\n\n**Task: Check coverage improvement.** Verify new tests added coverage.\nGenerate additional tests for remaining gaps if feasible.\n\n**Task: Minimize tests.** Delete tests that add no new coverage. Keep distinct\nscenarios; prefer simpler setup and clearer naming.\n\n**Task: Report.** Summarize tests generated, coverage achieved, and any\npotential bugs found.\n\n\n\n\nThe reference material below supports the tasks above.\n\n\n\n\n\n## Move Language\n\nMove on Aptos is a safe, resource-oriented programming language for smart contracts on the\nAptos blockchain. It uses a linear type system to enforce ownership and prevent\ndouble-spending at compile time.\n\n## Move Language Basics\n\n- **Modules** are the unit of code organization, published at an address.\n- **Structs** define data types; abilities (`key`, `store`, `copy`, `drop`) control what\n  operations are permitted.\n- **Entry functions** (`entry fun`) are transaction entry points callable from outside Move.\n- **View functions** (`#[view]`) are read-only queries that do not modify state.\n- **Global storage** stores resources (structs with `key`) at addresses.\n- **Move 2 syntax** (required):\n    - Read resource: `&T[addr]` (not `borrow_global\u003CT>(addr)`)\n    - Mutate resource: `&mut T[addr]` (not `borrow_global_mut\u003CT>(addr)`)\n    - Access field: `T[addr].field` directly (the compiler inserts the ref op)\n    - `acquires` annotations are no longer needed — do not add them.\n- **Error codes**: Use named constants for abort codes (`const E_NOT_FOUND: u64 = 1;`) and\n  document them.\n- **Comments**: Use `\u002F\u002F` for regular comments. `\u002F\u002F\u002F` is a **doc comment** and is only valid\n  directly before a `module`, `struct`, `enum`, `fun`, or `const` declaration.\n- **Edit hook**: The edit hook auto-runs on `.move` files after edits. If it reports\n  compilation errors, fix them before proceeding with further changes.\n\n\n### Links\n\n- [The Move Book](https:\u002F\u002Faptos-labs.github.io\u002Fmove-book\u002F)\n- [Aptos Framework Book](https:\u002F\u002Faptos-labs.github.io\u002Fframework-book\u002F)\n\n\n\n## Move Packages\n\nA Move package is a directory with a `Move.toml` manifest and source files. The manifest defines the package name, dependencies, and named addresses.\n\n### Named Addresses\n\nModules are published at named addresses (e.g., `@my_package`). These must resolve to hex values for compilation.\n\n- **`[addresses]`** — production addresses (may use `_` placeholder for deploy-time assignment)\n- **`[dev-addresses]`** — development\u002Ftest values (used when compiling in dev or test mode)\n\n**Fixing \"Unresolved addresses\" errors:** For each `Named address 'X' in package 'Y'`, add `X = \"0x...\"` to `[dev-addresses]` in that package's `Move.toml`. Use `0x100` and up, avoiding reserved addresses (`0x0`=vm_reserved, `0x1`=std\u002Faptos_std\u002Faptos_framework, `0x3`=aptos_token, `0x4`=aptos_token_objects, `0x5`=aptos_trading, `0x7`=aptos_experimental, `0xA`=aptos_fungible_asset, `0xA550C18`=core_resources):\n\n```toml\n[dev-addresses]\nmy_package = \"0x100\"\nother_addr = \"0x101\"\n```\n\n\n\n## Unit Test Generation Rules\n\n\n\n\n## Move Unit Testing Reference\n\n### Test Attributes\n\n| Attribute | Usage |\n|-----------|-------|\n| `#[test]` | Marks a function as a test |\n| `#[test(name = @addr)]` | Test with signer parameters bound to addresses |\n| `#[test_only]` | Code only compiled for testing (modules, functions, structs, constants) |\n| `#[expected_failure]` | Test expected to abort (any code) |\n| `#[expected_failure(abort_code = N)]` | Expects abort with specific code |\n| `#[expected_failure(abort_code = N, location = mod)]` | Expects abort at specific location |\n\n### Signer Parameters\n\nSigners are bound via the test attribute, not passed as arguments:\n\n```move\n\u002F\u002F Single signer\n#[test(account = @0x1)]\nfun test_single(account: &signer) { }\n\n\u002F\u002F Multiple signers\n#[test(admin = @admin_addr, user = @0x42)]\nfun test_multi(admin: &signer, user: &signer) { }\n\n\u002F\u002F Framework signer for timestamp, account creation, etc.\n#[test(aptos_framework = @aptos_framework)]\nfun test_framework(aptos_framework: &signer) { }\n```\n\n### Expected Failure\n\nUse `#[expected_failure]` to test that code correctly aborts under certain conditions.\n\n**Basic usage** (any abort passes):\n```move\n#[test]\n#[expected_failure]\nfun test_will_abort() { abort 1 }\n```\n\n**With abort code** (must match exactly):\n```move\n#[test]\n#[expected_failure(abort_code = E_NOT_AUTHORIZED, location = Self)]\nfun test_unauthorized() { \u002F* should abort with E_NOT_AUTHORIZED *\u002F }\n```\n\n**With location** (when error originates in another module):\n```move\n#[test]\n#[expected_failure(abort_code = 26113, location = extensions::table)]\nfun test_table_error() { \u002F* should abort in table module *\u002F }\n```\n\n**Execution errors** (not abort, but runtime failures):\n```move\n\u002F\u002F Arithmetic error (overflow, divide by zero)\n#[test]\n#[expected_failure(arithmetic_error, location = Self)]\nfun test_overflow() { let _ = 255u8 + 1; }\n\n\u002F\u002F Vector out of bounds\n#[test]\n#[expected_failure(vector_error, minor_status = 1, location = Self)]\nfun test_out_of_bounds() { vector::borrow(&vector::empty\u003Cu8>(), 0); }\n```\n\n### Test-Only Code\n\n```move\n\u002F\u002F Test-only module (entire module only compiled for tests)\n#[test_only]\nmodule my_addr::test_helpers {\n    public fun setup(): u64 { 100 }\n}\n\n\u002F\u002F Test-only function in regular module\nmodule my_addr::my_module {\n    #[test_only]\n    public fun init_for_testing(account: &signer, value: u64) {\n        move_to(account, MyResource { value });\n    }\n}\n```\n\n### Useful Test Utilities\n\n```move\n\u002F\u002F Get address from signer\nuse std::signer;\nlet addr = signer::address_of(account);\n\n\u002F\u002F Create account (registers on-chain)\nuse aptos_framework::account;\naccount::create_account_for_test(addr);\n\n\u002F\u002F Create signer without registering (lightweight)\nlet signer = account::create_signer_for_test(@0x123);\n\n\u002F\u002F Check resource exists\nassert!(exists\u003CMyResource>(addr), E_NOT_FOUND);\n\n\u002F\u002F Initialize timestamp (required before time functions)\nuse aptos_framework::timestamp;\ntimestamp::set_time_has_started_for_testing(aptos_framework);\n\n\u002F\u002F Advance time\ntimestamp::update_global_time_for_test(1000000); \u002F\u002F microseconds\ntimestamp::update_global_time_for_test_secs(100); \u002F\u002F seconds\n```\n\n## Test Design Rules\n\n**Design rules:**\n- **One behavior per test.** Each test verifies exactly one scenario. Never combine success and failure cases.\n- **Minimal setup.** Only initialize what the specific test needs.\n- **Test the target function.** Every test must call the user-specified function.\n- **Document purpose.** Every test needs a comment explaining what behavior is tested.\n\n**Naming:** `test_\u003Cfunction>_\u003Cscenario>` (e.g., `test_transfer_insufficient_balance`), module: `\u003Cmodule>_tests`\n\n**Common Mistakes:**\n- `RESOURCE_ALREADY_EXISTS`: Don't initialize the same resource twice\n- `MISSING_DATA`: Ensure required resources exist before calling\n- Signer mismatch: Operations checking `signer::address_of()` require the correct signer. Match signers to expected addresses in test attributes.\n\n\n\n\n## Unit Test Generation — Detailed Instructions\n\n### Task: 1 — Check Package\n\n1. Call `move_package_manifest` to build the package and discover sources. **Fix any compilation errors before proceeding.**\n2. Call `move_package_test` with `establish_baseline` set to true. **Fix failing tests before proceeding.**\n\n### Task: 2 — Analyze Target Code\n\n**Specific function requested:**\n1. Call `move_package_coverage` with `function` set to `\"module_name::function_name\"` — get uncovered lines in that function\n2. Read the source and identify behaviors to test:\n   - Success path with valid inputs\n   - Each distinct abort condition\n   - Edge cases (empty, zero, boundaries)\n   - Potential bugs\n\n**Full module mode:**\n1. Call `move_package_coverage` — get uncovered lines per source file\n2. Read the source files that contain uncovered lines\n3. Identify testable functions: public, entry, public(friend) — skip `#[test_only]` and private\n4. For functions with uncovered lines, identify behaviors to test (same as above)\n\n### Task: 3 — Generate Test Module\n\nCreate `tests\u002Fmove_flow\u002F\u003Cmodule>_tests.move` (create directory if needed).\n\n```move\n\u002F\u002F =============================================================================\n\u002F\u002F AUTO-GENERATED TESTS - DO NOT EDIT MANUALLY\n\u002F\u002F Generated by: move-test agent\n\u002F\u002F Source module: \u003Cmodule>\n\u002F\u002F =============================================================================\n\n#[test_only]\nmodule \u003Cpackage_address>::\u003Cmodule>_tests {\n    use \u003Cpackage_address>::\u003Cmodule>;\n\n    #[test(account = @0x1)]\n    \u002F\u002F\u002F @ai-generated\n    \u002F\u002F\u002F Verifies that \u003Cfunction> \u003Cbehavior>.\n    fun test_\u003Cfunction>_\u003Cscenario>(account: &signer) { ... }\n}\n```\n\n**Full module mode:** Generate tests in batches, one module at a time.\n\n**Suspected bugs:** Assert the *correct* expected behavior — the test should fail against the buggy code.\n\n### Task: 4 — Validate Tests\n\nCall `move_package_test`. If `success` is false, classify each failure:\n\n- **Compilation error**: Fix the test\n- **Runtime failure**: Compare test expectation against expected behavior\n  - Test is wrong → Fix it\n  - Code is wrong → Move test to `bugs\u002F` (at package root, next to `sources\u002F` and `tests\u002F`) and document:\n    - Expected behavior\n    - Actual behavior\n    - Why this indicates a bug\n\nIterate until all tests in `tests\u002Fmove_flow\u002F` pass.\n\n### Task: 5 — Check Coverage Improvement\n\nCheck `newly_covered` from the validation step to confirm the generated tests added coverage. Use `move_package_coverage` to check remaining gaps (pass `function` as `\"module_name::function_name\"` when targeting a specific function) — generate additional tests if needed and feasible.\n\n### Task: 6 — Minimize Tests (do not skip)\n\nDelete tests that add no new coverage. Keep tests with distinct scenarios (different abort conditions, branches, edge cases). When duplicates exist, prefer simpler setup and clearer naming.\n\nOnly modify tests in `tests\u002Fmove_flow\u002F` — do not touch `sources\u002F` or `tests\u002F` root.\n\n### Task: 7 — Report\n\nSummarize:\n- Tests generated and coverage achieved\n- If any tests were moved to `bugs\u002F`, alert the user with a summary of potential bugs found\n\n\n\n\n\n## Task\n\nGenerate unit tests for the current Move package.\n",{"data":30,"body":31},{"name":4,"description":6},{"type":32,"children":33},"root",[34,51,58,69,79,97,114,124,134,144,149,155,160,166,456,463,488,494,507,513,526,565,677,717,723,729,735,865,871,876,981,987,999,1009,1040,1050,1080,1090,1120,1130,1206,1212,1323,1329,1507,1513,1521,1564,1596,1604,1642,1648,1654,1701,1707,1715,1773,1781,1817,1823,1835,1957,1966,1984,1990,2009,2086,2099,2105,2139,2145,2150,2176,2182,2187,2207,2213,2218],{"type":35,"tag":36,"props":37,"children":38},"element","p",{},[39,42,49],{"type":40,"value":41},"text","Before doing any work, use TaskCreate to create one task for each\n",{"type":35,"tag":43,"props":44,"children":46},"code",{"className":45},[],[47],{"type":40,"value":48},"**Task:**",{"type":40,"value":50}," entry listed below. Then execute them in order, marking\neach in_progress when you start it and completed when you finish.",{"type":35,"tag":52,"props":53,"children":55},"h2",{"id":54},"test-generation-tasks-execute-in-order",[56],{"type":40,"value":57},"Test Generation Tasks — Execute In Order",{"type":35,"tag":36,"props":59,"children":60},{},[61,67],{"type":35,"tag":62,"props":63,"children":64},"strong",{},[65],{"type":40,"value":66},"Task: Check package.",{"type":40,"value":68}," Build the package and establish a test coverage\nbaseline. Fix any compilation errors or failing tests before proceeding.",{"type":35,"tag":36,"props":70,"children":71},{},[72,77],{"type":35,"tag":62,"props":73,"children":74},{},[75],{"type":40,"value":76},"Task: Analyze target code.",{"type":40,"value":78}," Identify uncovered lines and testable behaviors\n(success paths, abort conditions, edge cases, potential bugs).",{"type":35,"tag":36,"props":80,"children":81},{},[82,87,89,95],{"type":35,"tag":62,"props":83,"children":84},{},[85],{"type":40,"value":86},"Task: Generate test module.",{"type":40,"value":88}," Create tests in ",{"type":35,"tag":43,"props":90,"children":92},{"className":91},[],[93],{"type":40,"value":94},"tests\u002Fmove_flow\u002F\u003Cmodule>_tests.move",{"type":40,"value":96},".",{"type":35,"tag":36,"props":98,"children":99},{},[100,105,107,113],{"type":35,"tag":62,"props":101,"children":102},{},[103],{"type":40,"value":104},"Task: Validate tests.",{"type":40,"value":106}," Run tests. Fix compilation errors and wrong\nassertions. Move tests that expose real bugs to ",{"type":35,"tag":43,"props":108,"children":110},{"className":109},[],[111],{"type":40,"value":112},"bugs\u002F",{"type":40,"value":96},{"type":35,"tag":36,"props":115,"children":116},{},[117,122],{"type":35,"tag":62,"props":118,"children":119},{},[120],{"type":40,"value":121},"Task: Check coverage improvement.",{"type":40,"value":123}," Verify new tests added coverage.\nGenerate additional tests for remaining gaps if feasible.",{"type":35,"tag":36,"props":125,"children":126},{},[127,132],{"type":35,"tag":62,"props":128,"children":129},{},[130],{"type":40,"value":131},"Task: Minimize tests.",{"type":40,"value":133}," Delete tests that add no new coverage. Keep distinct\nscenarios; prefer simpler setup and clearer naming.",{"type":35,"tag":36,"props":135,"children":136},{},[137,142],{"type":35,"tag":62,"props":138,"children":139},{},[140],{"type":40,"value":141},"Task: Report.",{"type":40,"value":143}," Summarize tests generated, coverage achieved, and any\npotential bugs found.",{"type":35,"tag":36,"props":145,"children":146},{},[147],{"type":40,"value":148},"The reference material below supports the tasks above.",{"type":35,"tag":52,"props":150,"children":152},{"id":151},"move-language",[153],{"type":40,"value":154},"Move Language",{"type":35,"tag":36,"props":156,"children":157},{},[158],{"type":40,"value":159},"Move on Aptos is a safe, resource-oriented programming language for smart contracts on the\nAptos blockchain. It uses a linear type system to enforce ownership and prevent\ndouble-spending at compile time.",{"type":35,"tag":52,"props":161,"children":163},{"id":162},"move-language-basics",[164],{"type":40,"value":165},"Move Language Basics",{"type":35,"tag":167,"props":168,"children":169},"ul",{},[170,181,221,239,256,273,350,368,438],{"type":35,"tag":171,"props":172,"children":173},"li",{},[174,179],{"type":35,"tag":62,"props":175,"children":176},{},[177],{"type":40,"value":178},"Modules",{"type":40,"value":180}," are the unit of code organization, published at an address.",{"type":35,"tag":171,"props":182,"children":183},{},[184,189,191,197,199,205,206,212,213,219],{"type":35,"tag":62,"props":185,"children":186},{},[187],{"type":40,"value":188},"Structs",{"type":40,"value":190}," define data types; abilities (",{"type":35,"tag":43,"props":192,"children":194},{"className":193},[],[195],{"type":40,"value":196},"key",{"type":40,"value":198},", ",{"type":35,"tag":43,"props":200,"children":202},{"className":201},[],[203],{"type":40,"value":204},"store",{"type":40,"value":198},{"type":35,"tag":43,"props":207,"children":209},{"className":208},[],[210],{"type":40,"value":211},"copy",{"type":40,"value":198},{"type":35,"tag":43,"props":214,"children":216},{"className":215},[],[217],{"type":40,"value":218},"drop",{"type":40,"value":220},") control what\noperations are permitted.",{"type":35,"tag":171,"props":222,"children":223},{},[224,229,231,237],{"type":35,"tag":62,"props":225,"children":226},{},[227],{"type":40,"value":228},"Entry functions",{"type":40,"value":230}," (",{"type":35,"tag":43,"props":232,"children":234},{"className":233},[],[235],{"type":40,"value":236},"entry fun",{"type":40,"value":238},") are transaction entry points callable from outside Move.",{"type":35,"tag":171,"props":240,"children":241},{},[242,247,248,254],{"type":35,"tag":62,"props":243,"children":244},{},[245],{"type":40,"value":246},"View functions",{"type":40,"value":230},{"type":35,"tag":43,"props":249,"children":251},{"className":250},[],[252],{"type":40,"value":253},"#[view]",{"type":40,"value":255},") are read-only queries that do not modify state.",{"type":35,"tag":171,"props":257,"children":258},{},[259,264,266,271],{"type":35,"tag":62,"props":260,"children":261},{},[262],{"type":40,"value":263},"Global storage",{"type":40,"value":265}," stores resources (structs with ",{"type":35,"tag":43,"props":267,"children":269},{"className":268},[],[270],{"type":40,"value":196},{"type":40,"value":272},") at addresses.",{"type":35,"tag":171,"props":274,"children":275},{},[276,281,283],{"type":35,"tag":62,"props":277,"children":278},{},[279],{"type":40,"value":280},"Move 2 syntax",{"type":40,"value":282}," (required):\n",{"type":35,"tag":167,"props":284,"children":285},{},[286,307,326,339],{"type":35,"tag":171,"props":287,"children":288},{},[289,291,297,299,305],{"type":40,"value":290},"Read resource: ",{"type":35,"tag":43,"props":292,"children":294},{"className":293},[],[295],{"type":40,"value":296},"&T[addr]",{"type":40,"value":298}," (not ",{"type":35,"tag":43,"props":300,"children":302},{"className":301},[],[303],{"type":40,"value":304},"borrow_global\u003CT>(addr)",{"type":40,"value":306},")",{"type":35,"tag":171,"props":308,"children":309},{},[310,312,318,319,325],{"type":40,"value":311},"Mutate resource: ",{"type":35,"tag":43,"props":313,"children":315},{"className":314},[],[316],{"type":40,"value":317},"&mut T[addr]",{"type":40,"value":298},{"type":35,"tag":43,"props":320,"children":322},{"className":321},[],[323],{"type":40,"value":324},"borrow_global_mut\u003CT>(addr)",{"type":40,"value":306},{"type":35,"tag":171,"props":327,"children":328},{},[329,331,337],{"type":40,"value":330},"Access field: ",{"type":35,"tag":43,"props":332,"children":334},{"className":333},[],[335],{"type":40,"value":336},"T[addr].field",{"type":40,"value":338}," directly (the compiler inserts the ref op)",{"type":35,"tag":171,"props":340,"children":341},{},[342,348],{"type":35,"tag":43,"props":343,"children":345},{"className":344},[],[346],{"type":40,"value":347},"acquires",{"type":40,"value":349}," annotations are no longer needed — do not add them.",{"type":35,"tag":171,"props":351,"children":352},{},[353,358,360,366],{"type":35,"tag":62,"props":354,"children":355},{},[356],{"type":40,"value":357},"Error codes",{"type":40,"value":359},": Use named constants for abort codes (",{"type":35,"tag":43,"props":361,"children":363},{"className":362},[],[364],{"type":40,"value":365},"const E_NOT_FOUND: u64 = 1;",{"type":40,"value":367},") and\ndocument them.",{"type":35,"tag":171,"props":369,"children":370},{},[371,376,378,384,386,392,394,399,401,407,408,414,415,421,422,428,430,436],{"type":35,"tag":62,"props":372,"children":373},{},[374],{"type":40,"value":375},"Comments",{"type":40,"value":377},": Use ",{"type":35,"tag":43,"props":379,"children":381},{"className":380},[],[382],{"type":40,"value":383},"\u002F\u002F",{"type":40,"value":385}," for regular comments. ",{"type":35,"tag":43,"props":387,"children":389},{"className":388},[],[390],{"type":40,"value":391},"\u002F\u002F\u002F",{"type":40,"value":393}," is a ",{"type":35,"tag":62,"props":395,"children":396},{},[397],{"type":40,"value":398},"doc comment",{"type":40,"value":400}," and is only valid\ndirectly before a ",{"type":35,"tag":43,"props":402,"children":404},{"className":403},[],[405],{"type":40,"value":406},"module",{"type":40,"value":198},{"type":35,"tag":43,"props":409,"children":411},{"className":410},[],[412],{"type":40,"value":413},"struct",{"type":40,"value":198},{"type":35,"tag":43,"props":416,"children":418},{"className":417},[],[419],{"type":40,"value":420},"enum",{"type":40,"value":198},{"type":35,"tag":43,"props":423,"children":425},{"className":424},[],[426],{"type":40,"value":427},"fun",{"type":40,"value":429},", or ",{"type":35,"tag":43,"props":431,"children":433},{"className":432},[],[434],{"type":40,"value":435},"const",{"type":40,"value":437}," declaration.",{"type":35,"tag":171,"props":439,"children":440},{},[441,446,448,454],{"type":35,"tag":62,"props":442,"children":443},{},[444],{"type":40,"value":445},"Edit hook",{"type":40,"value":447},": The edit hook auto-runs on ",{"type":35,"tag":43,"props":449,"children":451},{"className":450},[],[452],{"type":40,"value":453},".move",{"type":40,"value":455}," files after edits. If it reports\ncompilation errors, fix them before proceeding with further changes.",{"type":35,"tag":457,"props":458,"children":460},"h3",{"id":459},"links",[461],{"type":40,"value":462},"Links",{"type":35,"tag":167,"props":464,"children":465},{},[466,478],{"type":35,"tag":171,"props":467,"children":468},{},[469],{"type":35,"tag":470,"props":471,"children":475},"a",{"href":472,"rel":473},"https:\u002F\u002Faptos-labs.github.io\u002Fmove-book\u002F",[474],"nofollow",[476],{"type":40,"value":477},"The Move Book",{"type":35,"tag":171,"props":479,"children":480},{},[481],{"type":35,"tag":470,"props":482,"children":485},{"href":483,"rel":484},"https:\u002F\u002Faptos-labs.github.io\u002Fframework-book\u002F",[474],[486],{"type":40,"value":487},"Aptos Framework Book",{"type":35,"tag":52,"props":489,"children":491},{"id":490},"move-packages",[492],{"type":40,"value":493},"Move Packages",{"type":35,"tag":36,"props":495,"children":496},{},[497,499,505],{"type":40,"value":498},"A Move package is a directory with a ",{"type":35,"tag":43,"props":500,"children":502},{"className":501},[],[503],{"type":40,"value":504},"Move.toml",{"type":40,"value":506}," manifest and source files. The manifest defines the package name, dependencies, and named addresses.",{"type":35,"tag":457,"props":508,"children":510},{"id":509},"named-addresses",[511],{"type":40,"value":512},"Named Addresses",{"type":35,"tag":36,"props":514,"children":515},{},[516,518,524],{"type":40,"value":517},"Modules are published at named addresses (e.g., ",{"type":35,"tag":43,"props":519,"children":521},{"className":520},[],[522],{"type":40,"value":523},"@my_package",{"type":40,"value":525},"). These must resolve to hex values for compilation.",{"type":35,"tag":167,"props":527,"children":528},{},[529,551],{"type":35,"tag":171,"props":530,"children":531},{},[532,541,543,549],{"type":35,"tag":62,"props":533,"children":534},{},[535],{"type":35,"tag":43,"props":536,"children":538},{"className":537},[],[539],{"type":40,"value":540},"[addresses]",{"type":40,"value":542}," — production addresses (may use ",{"type":35,"tag":43,"props":544,"children":546},{"className":545},[],[547],{"type":40,"value":548},"_",{"type":40,"value":550}," placeholder for deploy-time assignment)",{"type":35,"tag":171,"props":552,"children":553},{},[554,563],{"type":35,"tag":62,"props":555,"children":556},{},[557],{"type":35,"tag":43,"props":558,"children":560},{"className":559},[],[561],{"type":40,"value":562},"[dev-addresses]",{"type":40,"value":564}," — development\u002Ftest values (used when compiling in dev or test mode)",{"type":35,"tag":36,"props":566,"children":567},{},[568,573,575,581,583,589,591,596,598,603,605,611,613,619,621,627,629,635,637,643,645,651,653,659,661,667,669,675],{"type":35,"tag":62,"props":569,"children":570},{},[571],{"type":40,"value":572},"Fixing \"Unresolved addresses\" errors:",{"type":40,"value":574}," For each ",{"type":35,"tag":43,"props":576,"children":578},{"className":577},[],[579],{"type":40,"value":580},"Named address 'X' in package 'Y'",{"type":40,"value":582},", add ",{"type":35,"tag":43,"props":584,"children":586},{"className":585},[],[587],{"type":40,"value":588},"X = \"0x...\"",{"type":40,"value":590}," to ",{"type":35,"tag":43,"props":592,"children":594},{"className":593},[],[595],{"type":40,"value":562},{"type":40,"value":597}," in that package's ",{"type":35,"tag":43,"props":599,"children":601},{"className":600},[],[602],{"type":40,"value":504},{"type":40,"value":604},". Use ",{"type":35,"tag":43,"props":606,"children":608},{"className":607},[],[609],{"type":40,"value":610},"0x100",{"type":40,"value":612}," and up, avoiding reserved addresses (",{"type":35,"tag":43,"props":614,"children":616},{"className":615},[],[617],{"type":40,"value":618},"0x0",{"type":40,"value":620},"=vm_reserved, ",{"type":35,"tag":43,"props":622,"children":624},{"className":623},[],[625],{"type":40,"value":626},"0x1",{"type":40,"value":628},"=std\u002Faptos_std\u002Faptos_framework, ",{"type":35,"tag":43,"props":630,"children":632},{"className":631},[],[633],{"type":40,"value":634},"0x3",{"type":40,"value":636},"=aptos_token, ",{"type":35,"tag":43,"props":638,"children":640},{"className":639},[],[641],{"type":40,"value":642},"0x4",{"type":40,"value":644},"=aptos_token_objects, ",{"type":35,"tag":43,"props":646,"children":648},{"className":647},[],[649],{"type":40,"value":650},"0x5",{"type":40,"value":652},"=aptos_trading, ",{"type":35,"tag":43,"props":654,"children":656},{"className":655},[],[657],{"type":40,"value":658},"0x7",{"type":40,"value":660},"=aptos_experimental, ",{"type":35,"tag":43,"props":662,"children":664},{"className":663},[],[665],{"type":40,"value":666},"0xA",{"type":40,"value":668},"=aptos_fungible_asset, ",{"type":35,"tag":43,"props":670,"children":672},{"className":671},[],[673],{"type":40,"value":674},"0xA550C18",{"type":40,"value":676},"=core_resources):",{"type":35,"tag":678,"props":679,"children":684},"pre",{"className":680,"code":681,"language":682,"meta":683,"style":683},"language-toml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[dev-addresses]\nmy_package = \"0x100\"\nother_addr = \"0x101\"\n","toml","",[685],{"type":35,"tag":43,"props":686,"children":687},{"__ignoreMap":683},[688,699,708],{"type":35,"tag":689,"props":690,"children":693},"span",{"class":691,"line":692},"line",1,[694],{"type":35,"tag":689,"props":695,"children":696},{},[697],{"type":40,"value":698},"[dev-addresses]\n",{"type":35,"tag":689,"props":700,"children":702},{"class":691,"line":701},2,[703],{"type":35,"tag":689,"props":704,"children":705},{},[706],{"type":40,"value":707},"my_package = \"0x100\"\n",{"type":35,"tag":689,"props":709,"children":711},{"class":691,"line":710},3,[712],{"type":35,"tag":689,"props":713,"children":714},{},[715],{"type":40,"value":716},"other_addr = \"0x101\"\n",{"type":35,"tag":52,"props":718,"children":720},{"id":719},"unit-test-generation-rules",[721],{"type":40,"value":722},"Unit Test Generation Rules",{"type":35,"tag":52,"props":724,"children":726},{"id":725},"move-unit-testing-reference",[727],{"type":40,"value":728},"Move Unit Testing Reference",{"type":35,"tag":457,"props":730,"children":732},{"id":731},"test-attributes",[733],{"type":40,"value":734},"Test Attributes",{"type":35,"tag":736,"props":737,"children":738},"table",{},[739,758],{"type":35,"tag":740,"props":741,"children":742},"thead",{},[743],{"type":35,"tag":744,"props":745,"children":746},"tr",{},[747,753],{"type":35,"tag":748,"props":749,"children":750},"th",{},[751],{"type":40,"value":752},"Attribute",{"type":35,"tag":748,"props":754,"children":755},{},[756],{"type":40,"value":757},"Usage",{"type":35,"tag":759,"props":760,"children":761},"tbody",{},[762,780,797,814,831,848],{"type":35,"tag":744,"props":763,"children":764},{},[765,775],{"type":35,"tag":766,"props":767,"children":768},"td",{},[769],{"type":35,"tag":43,"props":770,"children":772},{"className":771},[],[773],{"type":40,"value":774},"#[test]",{"type":35,"tag":766,"props":776,"children":777},{},[778],{"type":40,"value":779},"Marks a function as a test",{"type":35,"tag":744,"props":781,"children":782},{},[783,792],{"type":35,"tag":766,"props":784,"children":785},{},[786],{"type":35,"tag":43,"props":787,"children":789},{"className":788},[],[790],{"type":40,"value":791},"#[test(name = @addr)]",{"type":35,"tag":766,"props":793,"children":794},{},[795],{"type":40,"value":796},"Test with signer parameters bound to addresses",{"type":35,"tag":744,"props":798,"children":799},{},[800,809],{"type":35,"tag":766,"props":801,"children":802},{},[803],{"type":35,"tag":43,"props":804,"children":806},{"className":805},[],[807],{"type":40,"value":808},"#[test_only]",{"type":35,"tag":766,"props":810,"children":811},{},[812],{"type":40,"value":813},"Code only compiled for testing (modules, functions, structs, constants)",{"type":35,"tag":744,"props":815,"children":816},{},[817,826],{"type":35,"tag":766,"props":818,"children":819},{},[820],{"type":35,"tag":43,"props":821,"children":823},{"className":822},[],[824],{"type":40,"value":825},"#[expected_failure]",{"type":35,"tag":766,"props":827,"children":828},{},[829],{"type":40,"value":830},"Test expected to abort (any code)",{"type":35,"tag":744,"props":832,"children":833},{},[834,843],{"type":35,"tag":766,"props":835,"children":836},{},[837],{"type":35,"tag":43,"props":838,"children":840},{"className":839},[],[841],{"type":40,"value":842},"#[expected_failure(abort_code = N)]",{"type":35,"tag":766,"props":844,"children":845},{},[846],{"type":40,"value":847},"Expects abort with specific code",{"type":35,"tag":744,"props":849,"children":850},{},[851,860],{"type":35,"tag":766,"props":852,"children":853},{},[854],{"type":35,"tag":43,"props":855,"children":857},{"className":856},[],[858],{"type":40,"value":859},"#[expected_failure(abort_code = N, location = mod)]",{"type":35,"tag":766,"props":861,"children":862},{},[863],{"type":40,"value":864},"Expects abort at specific location",{"type":35,"tag":457,"props":866,"children":868},{"id":867},"signer-parameters",[869],{"type":40,"value":870},"Signer Parameters",{"type":35,"tag":36,"props":872,"children":873},{},[874],{"type":40,"value":875},"Signers are bound via the test attribute, not passed as arguments:",{"type":35,"tag":678,"props":877,"children":881},{"className":878,"code":879,"language":880,"meta":683,"style":683},"language-move shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Single signer\n#[test(account = @0x1)]\nfun test_single(account: &signer) { }\n\n\u002F\u002F Multiple signers\n#[test(admin = @admin_addr, user = @0x42)]\nfun test_multi(admin: &signer, user: &signer) { }\n\n\u002F\u002F Framework signer for timestamp, account creation, etc.\n#[test(aptos_framework = @aptos_framework)]\nfun test_framework(aptos_framework: &signer) { }\n","move",[882],{"type":35,"tag":43,"props":883,"children":884},{"__ignoreMap":683},[885,893,901,909,919,928,937,946,954,963,972],{"type":35,"tag":689,"props":886,"children":887},{"class":691,"line":692},[888],{"type":35,"tag":689,"props":889,"children":890},{},[891],{"type":40,"value":892},"\u002F\u002F Single signer\n",{"type":35,"tag":689,"props":894,"children":895},{"class":691,"line":701},[896],{"type":35,"tag":689,"props":897,"children":898},{},[899],{"type":40,"value":900},"#[test(account = @0x1)]\n",{"type":35,"tag":689,"props":902,"children":903},{"class":691,"line":710},[904],{"type":35,"tag":689,"props":905,"children":906},{},[907],{"type":40,"value":908},"fun test_single(account: &signer) { }\n",{"type":35,"tag":689,"props":910,"children":912},{"class":691,"line":911},4,[913],{"type":35,"tag":689,"props":914,"children":916},{"emptyLinePlaceholder":915},true,[917],{"type":40,"value":918},"\n",{"type":35,"tag":689,"props":920,"children":922},{"class":691,"line":921},5,[923],{"type":35,"tag":689,"props":924,"children":925},{},[926],{"type":40,"value":927},"\u002F\u002F Multiple signers\n",{"type":35,"tag":689,"props":929,"children":931},{"class":691,"line":930},6,[932],{"type":35,"tag":689,"props":933,"children":934},{},[935],{"type":40,"value":936},"#[test(admin = @admin_addr, user = @0x42)]\n",{"type":35,"tag":689,"props":938,"children":940},{"class":691,"line":939},7,[941],{"type":35,"tag":689,"props":942,"children":943},{},[944],{"type":40,"value":945},"fun test_multi(admin: &signer, user: &signer) { }\n",{"type":35,"tag":689,"props":947,"children":949},{"class":691,"line":948},8,[950],{"type":35,"tag":689,"props":951,"children":952},{"emptyLinePlaceholder":915},[953],{"type":40,"value":918},{"type":35,"tag":689,"props":955,"children":957},{"class":691,"line":956},9,[958],{"type":35,"tag":689,"props":959,"children":960},{},[961],{"type":40,"value":962},"\u002F\u002F Framework signer for timestamp, account creation, etc.\n",{"type":35,"tag":689,"props":964,"children":966},{"class":691,"line":965},10,[967],{"type":35,"tag":689,"props":968,"children":969},{},[970],{"type":40,"value":971},"#[test(aptos_framework = @aptos_framework)]\n",{"type":35,"tag":689,"props":973,"children":975},{"class":691,"line":974},11,[976],{"type":35,"tag":689,"props":977,"children":978},{},[979],{"type":40,"value":980},"fun test_framework(aptos_framework: &signer) { }\n",{"type":35,"tag":457,"props":982,"children":984},{"id":983},"expected-failure",[985],{"type":40,"value":986},"Expected Failure",{"type":35,"tag":36,"props":988,"children":989},{},[990,992,997],{"type":40,"value":991},"Use ",{"type":35,"tag":43,"props":993,"children":995},{"className":994},[],[996],{"type":40,"value":825},{"type":40,"value":998}," to test that code correctly aborts under certain conditions.",{"type":35,"tag":36,"props":1000,"children":1001},{},[1002,1007],{"type":35,"tag":62,"props":1003,"children":1004},{},[1005],{"type":40,"value":1006},"Basic usage",{"type":40,"value":1008}," (any abort passes):",{"type":35,"tag":678,"props":1010,"children":1012},{"className":878,"code":1011,"language":880,"meta":683,"style":683},"#[test]\n#[expected_failure]\nfun test_will_abort() { abort 1 }\n",[1013],{"type":35,"tag":43,"props":1014,"children":1015},{"__ignoreMap":683},[1016,1024,1032],{"type":35,"tag":689,"props":1017,"children":1018},{"class":691,"line":692},[1019],{"type":35,"tag":689,"props":1020,"children":1021},{},[1022],{"type":40,"value":1023},"#[test]\n",{"type":35,"tag":689,"props":1025,"children":1026},{"class":691,"line":701},[1027],{"type":35,"tag":689,"props":1028,"children":1029},{},[1030],{"type":40,"value":1031},"#[expected_failure]\n",{"type":35,"tag":689,"props":1033,"children":1034},{"class":691,"line":710},[1035],{"type":35,"tag":689,"props":1036,"children":1037},{},[1038],{"type":40,"value":1039},"fun test_will_abort() { abort 1 }\n",{"type":35,"tag":36,"props":1041,"children":1042},{},[1043,1048],{"type":35,"tag":62,"props":1044,"children":1045},{},[1046],{"type":40,"value":1047},"With abort code",{"type":40,"value":1049}," (must match exactly):",{"type":35,"tag":678,"props":1051,"children":1053},{"className":878,"code":1052,"language":880,"meta":683,"style":683},"#[test]\n#[expected_failure(abort_code = E_NOT_AUTHORIZED, location = Self)]\nfun test_unauthorized() { \u002F* should abort with E_NOT_AUTHORIZED *\u002F }\n",[1054],{"type":35,"tag":43,"props":1055,"children":1056},{"__ignoreMap":683},[1057,1064,1072],{"type":35,"tag":689,"props":1058,"children":1059},{"class":691,"line":692},[1060],{"type":35,"tag":689,"props":1061,"children":1062},{},[1063],{"type":40,"value":1023},{"type":35,"tag":689,"props":1065,"children":1066},{"class":691,"line":701},[1067],{"type":35,"tag":689,"props":1068,"children":1069},{},[1070],{"type":40,"value":1071},"#[expected_failure(abort_code = E_NOT_AUTHORIZED, location = Self)]\n",{"type":35,"tag":689,"props":1073,"children":1074},{"class":691,"line":710},[1075],{"type":35,"tag":689,"props":1076,"children":1077},{},[1078],{"type":40,"value":1079},"fun test_unauthorized() { \u002F* should abort with E_NOT_AUTHORIZED *\u002F }\n",{"type":35,"tag":36,"props":1081,"children":1082},{},[1083,1088],{"type":35,"tag":62,"props":1084,"children":1085},{},[1086],{"type":40,"value":1087},"With location",{"type":40,"value":1089}," (when error originates in another module):",{"type":35,"tag":678,"props":1091,"children":1093},{"className":878,"code":1092,"language":880,"meta":683,"style":683},"#[test]\n#[expected_failure(abort_code = 26113, location = extensions::table)]\nfun test_table_error() { \u002F* should abort in table module *\u002F }\n",[1094],{"type":35,"tag":43,"props":1095,"children":1096},{"__ignoreMap":683},[1097,1104,1112],{"type":35,"tag":689,"props":1098,"children":1099},{"class":691,"line":692},[1100],{"type":35,"tag":689,"props":1101,"children":1102},{},[1103],{"type":40,"value":1023},{"type":35,"tag":689,"props":1105,"children":1106},{"class":691,"line":701},[1107],{"type":35,"tag":689,"props":1108,"children":1109},{},[1110],{"type":40,"value":1111},"#[expected_failure(abort_code = 26113, location = extensions::table)]\n",{"type":35,"tag":689,"props":1113,"children":1114},{"class":691,"line":710},[1115],{"type":35,"tag":689,"props":1116,"children":1117},{},[1118],{"type":40,"value":1119},"fun test_table_error() { \u002F* should abort in table module *\u002F }\n",{"type":35,"tag":36,"props":1121,"children":1122},{},[1123,1128],{"type":35,"tag":62,"props":1124,"children":1125},{},[1126],{"type":40,"value":1127},"Execution errors",{"type":40,"value":1129}," (not abort, but runtime failures):",{"type":35,"tag":678,"props":1131,"children":1133},{"className":878,"code":1132,"language":880,"meta":683,"style":683},"\u002F\u002F Arithmetic error (overflow, divide by zero)\n#[test]\n#[expected_failure(arithmetic_error, location = Self)]\nfun test_overflow() { let _ = 255u8 + 1; }\n\n\u002F\u002F Vector out of bounds\n#[test]\n#[expected_failure(vector_error, minor_status = 1, location = Self)]\nfun test_out_of_bounds() { vector::borrow(&vector::empty\u003Cu8>(), 0); }\n",[1134],{"type":35,"tag":43,"props":1135,"children":1136},{"__ignoreMap":683},[1137,1145,1152,1160,1168,1175,1183,1190,1198],{"type":35,"tag":689,"props":1138,"children":1139},{"class":691,"line":692},[1140],{"type":35,"tag":689,"props":1141,"children":1142},{},[1143],{"type":40,"value":1144},"\u002F\u002F Arithmetic error (overflow, divide by zero)\n",{"type":35,"tag":689,"props":1146,"children":1147},{"class":691,"line":701},[1148],{"type":35,"tag":689,"props":1149,"children":1150},{},[1151],{"type":40,"value":1023},{"type":35,"tag":689,"props":1153,"children":1154},{"class":691,"line":710},[1155],{"type":35,"tag":689,"props":1156,"children":1157},{},[1158],{"type":40,"value":1159},"#[expected_failure(arithmetic_error, location = Self)]\n",{"type":35,"tag":689,"props":1161,"children":1162},{"class":691,"line":911},[1163],{"type":35,"tag":689,"props":1164,"children":1165},{},[1166],{"type":40,"value":1167},"fun test_overflow() { let _ = 255u8 + 1; }\n",{"type":35,"tag":689,"props":1169,"children":1170},{"class":691,"line":921},[1171],{"type":35,"tag":689,"props":1172,"children":1173},{"emptyLinePlaceholder":915},[1174],{"type":40,"value":918},{"type":35,"tag":689,"props":1176,"children":1177},{"class":691,"line":930},[1178],{"type":35,"tag":689,"props":1179,"children":1180},{},[1181],{"type":40,"value":1182},"\u002F\u002F Vector out of bounds\n",{"type":35,"tag":689,"props":1184,"children":1185},{"class":691,"line":939},[1186],{"type":35,"tag":689,"props":1187,"children":1188},{},[1189],{"type":40,"value":1023},{"type":35,"tag":689,"props":1191,"children":1192},{"class":691,"line":948},[1193],{"type":35,"tag":689,"props":1194,"children":1195},{},[1196],{"type":40,"value":1197},"#[expected_failure(vector_error, minor_status = 1, location = Self)]\n",{"type":35,"tag":689,"props":1199,"children":1200},{"class":691,"line":956},[1201],{"type":35,"tag":689,"props":1202,"children":1203},{},[1204],{"type":40,"value":1205},"fun test_out_of_bounds() { vector::borrow(&vector::empty\u003Cu8>(), 0); }\n",{"type":35,"tag":457,"props":1207,"children":1209},{"id":1208},"test-only-code",[1210],{"type":40,"value":1211},"Test-Only Code",{"type":35,"tag":678,"props":1213,"children":1215},{"className":878,"code":1214,"language":880,"meta":683,"style":683},"\u002F\u002F Test-only module (entire module only compiled for tests)\n#[test_only]\nmodule my_addr::test_helpers {\n    public fun setup(): u64 { 100 }\n}\n\n\u002F\u002F Test-only function in regular module\nmodule my_addr::my_module {\n    #[test_only]\n    public fun init_for_testing(account: &signer, value: u64) {\n        move_to(account, MyResource { value });\n    }\n}\n",[1216],{"type":35,"tag":43,"props":1217,"children":1218},{"__ignoreMap":683},[1219,1227,1235,1243,1251,1259,1266,1274,1282,1290,1298,1306,1315],{"type":35,"tag":689,"props":1220,"children":1221},{"class":691,"line":692},[1222],{"type":35,"tag":689,"props":1223,"children":1224},{},[1225],{"type":40,"value":1226},"\u002F\u002F Test-only module (entire module only compiled for tests)\n",{"type":35,"tag":689,"props":1228,"children":1229},{"class":691,"line":701},[1230],{"type":35,"tag":689,"props":1231,"children":1232},{},[1233],{"type":40,"value":1234},"#[test_only]\n",{"type":35,"tag":689,"props":1236,"children":1237},{"class":691,"line":710},[1238],{"type":35,"tag":689,"props":1239,"children":1240},{},[1241],{"type":40,"value":1242},"module my_addr::test_helpers {\n",{"type":35,"tag":689,"props":1244,"children":1245},{"class":691,"line":911},[1246],{"type":35,"tag":689,"props":1247,"children":1248},{},[1249],{"type":40,"value":1250},"    public fun setup(): u64 { 100 }\n",{"type":35,"tag":689,"props":1252,"children":1253},{"class":691,"line":921},[1254],{"type":35,"tag":689,"props":1255,"children":1256},{},[1257],{"type":40,"value":1258},"}\n",{"type":35,"tag":689,"props":1260,"children":1261},{"class":691,"line":930},[1262],{"type":35,"tag":689,"props":1263,"children":1264},{"emptyLinePlaceholder":915},[1265],{"type":40,"value":918},{"type":35,"tag":689,"props":1267,"children":1268},{"class":691,"line":939},[1269],{"type":35,"tag":689,"props":1270,"children":1271},{},[1272],{"type":40,"value":1273},"\u002F\u002F Test-only function in regular module\n",{"type":35,"tag":689,"props":1275,"children":1276},{"class":691,"line":948},[1277],{"type":35,"tag":689,"props":1278,"children":1279},{},[1280],{"type":40,"value":1281},"module my_addr::my_module {\n",{"type":35,"tag":689,"props":1283,"children":1284},{"class":691,"line":956},[1285],{"type":35,"tag":689,"props":1286,"children":1287},{},[1288],{"type":40,"value":1289},"    #[test_only]\n",{"type":35,"tag":689,"props":1291,"children":1292},{"class":691,"line":965},[1293],{"type":35,"tag":689,"props":1294,"children":1295},{},[1296],{"type":40,"value":1297},"    public fun init_for_testing(account: &signer, value: u64) {\n",{"type":35,"tag":689,"props":1299,"children":1300},{"class":691,"line":974},[1301],{"type":35,"tag":689,"props":1302,"children":1303},{},[1304],{"type":40,"value":1305},"        move_to(account, MyResource { value });\n",{"type":35,"tag":689,"props":1307,"children":1309},{"class":691,"line":1308},12,[1310],{"type":35,"tag":689,"props":1311,"children":1312},{},[1313],{"type":40,"value":1314},"    }\n",{"type":35,"tag":689,"props":1316,"children":1318},{"class":691,"line":1317},13,[1319],{"type":35,"tag":689,"props":1320,"children":1321},{},[1322],{"type":40,"value":1258},{"type":35,"tag":457,"props":1324,"children":1326},{"id":1325},"useful-test-utilities",[1327],{"type":40,"value":1328},"Useful Test Utilities",{"type":35,"tag":678,"props":1330,"children":1332},{"className":878,"code":1331,"language":880,"meta":683,"style":683},"\u002F\u002F Get address from signer\nuse std::signer;\nlet addr = signer::address_of(account);\n\n\u002F\u002F Create account (registers on-chain)\nuse aptos_framework::account;\naccount::create_account_for_test(addr);\n\n\u002F\u002F Create signer without registering (lightweight)\nlet signer = account::create_signer_for_test(@0x123);\n\n\u002F\u002F Check resource exists\nassert!(exists\u003CMyResource>(addr), E_NOT_FOUND);\n\n\u002F\u002F Initialize timestamp (required before time functions)\nuse aptos_framework::timestamp;\ntimestamp::set_time_has_started_for_testing(aptos_framework);\n\n\u002F\u002F Advance time\ntimestamp::update_global_time_for_test(1000000); \u002F\u002F microseconds\ntimestamp::update_global_time_for_test_secs(100); \u002F\u002F seconds\n",[1333],{"type":35,"tag":43,"props":1334,"children":1335},{"__ignoreMap":683},[1336,1344,1352,1360,1367,1375,1383,1391,1398,1406,1414,1421,1429,1437,1445,1454,1463,1472,1480,1489,1498],{"type":35,"tag":689,"props":1337,"children":1338},{"class":691,"line":692},[1339],{"type":35,"tag":689,"props":1340,"children":1341},{},[1342],{"type":40,"value":1343},"\u002F\u002F Get address from signer\n",{"type":35,"tag":689,"props":1345,"children":1346},{"class":691,"line":701},[1347],{"type":35,"tag":689,"props":1348,"children":1349},{},[1350],{"type":40,"value":1351},"use std::signer;\n",{"type":35,"tag":689,"props":1353,"children":1354},{"class":691,"line":710},[1355],{"type":35,"tag":689,"props":1356,"children":1357},{},[1358],{"type":40,"value":1359},"let addr = signer::address_of(account);\n",{"type":35,"tag":689,"props":1361,"children":1362},{"class":691,"line":911},[1363],{"type":35,"tag":689,"props":1364,"children":1365},{"emptyLinePlaceholder":915},[1366],{"type":40,"value":918},{"type":35,"tag":689,"props":1368,"children":1369},{"class":691,"line":921},[1370],{"type":35,"tag":689,"props":1371,"children":1372},{},[1373],{"type":40,"value":1374},"\u002F\u002F Create account (registers on-chain)\n",{"type":35,"tag":689,"props":1376,"children":1377},{"class":691,"line":930},[1378],{"type":35,"tag":689,"props":1379,"children":1380},{},[1381],{"type":40,"value":1382},"use aptos_framework::account;\n",{"type":35,"tag":689,"props":1384,"children":1385},{"class":691,"line":939},[1386],{"type":35,"tag":689,"props":1387,"children":1388},{},[1389],{"type":40,"value":1390},"account::create_account_for_test(addr);\n",{"type":35,"tag":689,"props":1392,"children":1393},{"class":691,"line":948},[1394],{"type":35,"tag":689,"props":1395,"children":1396},{"emptyLinePlaceholder":915},[1397],{"type":40,"value":918},{"type":35,"tag":689,"props":1399,"children":1400},{"class":691,"line":956},[1401],{"type":35,"tag":689,"props":1402,"children":1403},{},[1404],{"type":40,"value":1405},"\u002F\u002F Create signer without registering (lightweight)\n",{"type":35,"tag":689,"props":1407,"children":1408},{"class":691,"line":965},[1409],{"type":35,"tag":689,"props":1410,"children":1411},{},[1412],{"type":40,"value":1413},"let signer = account::create_signer_for_test(@0x123);\n",{"type":35,"tag":689,"props":1415,"children":1416},{"class":691,"line":974},[1417],{"type":35,"tag":689,"props":1418,"children":1419},{"emptyLinePlaceholder":915},[1420],{"type":40,"value":918},{"type":35,"tag":689,"props":1422,"children":1423},{"class":691,"line":1308},[1424],{"type":35,"tag":689,"props":1425,"children":1426},{},[1427],{"type":40,"value":1428},"\u002F\u002F Check resource exists\n",{"type":35,"tag":689,"props":1430,"children":1431},{"class":691,"line":1317},[1432],{"type":35,"tag":689,"props":1433,"children":1434},{},[1435],{"type":40,"value":1436},"assert!(exists\u003CMyResource>(addr), E_NOT_FOUND);\n",{"type":35,"tag":689,"props":1438,"children":1440},{"class":691,"line":1439},14,[1441],{"type":35,"tag":689,"props":1442,"children":1443},{"emptyLinePlaceholder":915},[1444],{"type":40,"value":918},{"type":35,"tag":689,"props":1446,"children":1448},{"class":691,"line":1447},15,[1449],{"type":35,"tag":689,"props":1450,"children":1451},{},[1452],{"type":40,"value":1453},"\u002F\u002F Initialize timestamp (required before time functions)\n",{"type":35,"tag":689,"props":1455,"children":1457},{"class":691,"line":1456},16,[1458],{"type":35,"tag":689,"props":1459,"children":1460},{},[1461],{"type":40,"value":1462},"use aptos_framework::timestamp;\n",{"type":35,"tag":689,"props":1464,"children":1466},{"class":691,"line":1465},17,[1467],{"type":35,"tag":689,"props":1468,"children":1469},{},[1470],{"type":40,"value":1471},"timestamp::set_time_has_started_for_testing(aptos_framework);\n",{"type":35,"tag":689,"props":1473,"children":1475},{"class":691,"line":1474},18,[1476],{"type":35,"tag":689,"props":1477,"children":1478},{"emptyLinePlaceholder":915},[1479],{"type":40,"value":918},{"type":35,"tag":689,"props":1481,"children":1483},{"class":691,"line":1482},19,[1484],{"type":35,"tag":689,"props":1485,"children":1486},{},[1487],{"type":40,"value":1488},"\u002F\u002F Advance time\n",{"type":35,"tag":689,"props":1490,"children":1492},{"class":691,"line":1491},20,[1493],{"type":35,"tag":689,"props":1494,"children":1495},{},[1496],{"type":40,"value":1497},"timestamp::update_global_time_for_test(1000000); \u002F\u002F microseconds\n",{"type":35,"tag":689,"props":1499,"children":1501},{"class":691,"line":1500},21,[1502],{"type":35,"tag":689,"props":1503,"children":1504},{},[1505],{"type":40,"value":1506},"timestamp::update_global_time_for_test_secs(100); \u002F\u002F seconds\n",{"type":35,"tag":52,"props":1508,"children":1510},{"id":1509},"test-design-rules",[1511],{"type":40,"value":1512},"Test Design Rules",{"type":35,"tag":36,"props":1514,"children":1515},{},[1516],{"type":35,"tag":62,"props":1517,"children":1518},{},[1519],{"type":40,"value":1520},"Design rules:",{"type":35,"tag":167,"props":1522,"children":1523},{},[1524,1534,1544,1554],{"type":35,"tag":171,"props":1525,"children":1526},{},[1527,1532],{"type":35,"tag":62,"props":1528,"children":1529},{},[1530],{"type":40,"value":1531},"One behavior per test.",{"type":40,"value":1533}," Each test verifies exactly one scenario. Never combine success and failure cases.",{"type":35,"tag":171,"props":1535,"children":1536},{},[1537,1542],{"type":35,"tag":62,"props":1538,"children":1539},{},[1540],{"type":40,"value":1541},"Minimal setup.",{"type":40,"value":1543}," Only initialize what the specific test needs.",{"type":35,"tag":171,"props":1545,"children":1546},{},[1547,1552],{"type":35,"tag":62,"props":1548,"children":1549},{},[1550],{"type":40,"value":1551},"Test the target function.",{"type":40,"value":1553}," Every test must call the user-specified function.",{"type":35,"tag":171,"props":1555,"children":1556},{},[1557,1562],{"type":35,"tag":62,"props":1558,"children":1559},{},[1560],{"type":40,"value":1561},"Document purpose.",{"type":40,"value":1563}," Every test needs a comment explaining what behavior is tested.",{"type":35,"tag":36,"props":1565,"children":1566},{},[1567,1572,1574,1580,1582,1588,1590],{"type":35,"tag":62,"props":1568,"children":1569},{},[1570],{"type":40,"value":1571},"Naming:",{"type":40,"value":1573}," ",{"type":35,"tag":43,"props":1575,"children":1577},{"className":1576},[],[1578],{"type":40,"value":1579},"test_\u003Cfunction>_\u003Cscenario>",{"type":40,"value":1581}," (e.g., ",{"type":35,"tag":43,"props":1583,"children":1585},{"className":1584},[],[1586],{"type":40,"value":1587},"test_transfer_insufficient_balance",{"type":40,"value":1589},"), module: ",{"type":35,"tag":43,"props":1591,"children":1593},{"className":1592},[],[1594],{"type":40,"value":1595},"\u003Cmodule>_tests",{"type":35,"tag":36,"props":1597,"children":1598},{},[1599],{"type":35,"tag":62,"props":1600,"children":1601},{},[1602],{"type":40,"value":1603},"Common Mistakes:",{"type":35,"tag":167,"props":1605,"children":1606},{},[1607,1618,1629],{"type":35,"tag":171,"props":1608,"children":1609},{},[1610,1616],{"type":35,"tag":43,"props":1611,"children":1613},{"className":1612},[],[1614],{"type":40,"value":1615},"RESOURCE_ALREADY_EXISTS",{"type":40,"value":1617},": Don't initialize the same resource twice",{"type":35,"tag":171,"props":1619,"children":1620},{},[1621,1627],{"type":35,"tag":43,"props":1622,"children":1624},{"className":1623},[],[1625],{"type":40,"value":1626},"MISSING_DATA",{"type":40,"value":1628},": Ensure required resources exist before calling",{"type":35,"tag":171,"props":1630,"children":1631},{},[1632,1634,1640],{"type":40,"value":1633},"Signer mismatch: Operations checking ",{"type":35,"tag":43,"props":1635,"children":1637},{"className":1636},[],[1638],{"type":40,"value":1639},"signer::address_of()",{"type":40,"value":1641}," require the correct signer. Match signers to expected addresses in test attributes.",{"type":35,"tag":52,"props":1643,"children":1645},{"id":1644},"unit-test-generation-detailed-instructions",[1646],{"type":40,"value":1647},"Unit Test Generation — Detailed Instructions",{"type":35,"tag":457,"props":1649,"children":1651},{"id":1650},"task-1-check-package",[1652],{"type":40,"value":1653},"Task: 1 — Check Package",{"type":35,"tag":1655,"props":1656,"children":1657},"ol",{},[1658,1676],{"type":35,"tag":171,"props":1659,"children":1660},{},[1661,1663,1669,1671],{"type":40,"value":1662},"Call ",{"type":35,"tag":43,"props":1664,"children":1666},{"className":1665},[],[1667],{"type":40,"value":1668},"move_package_manifest",{"type":40,"value":1670}," to build the package and discover sources. ",{"type":35,"tag":62,"props":1672,"children":1673},{},[1674],{"type":40,"value":1675},"Fix any compilation errors before proceeding.",{"type":35,"tag":171,"props":1677,"children":1678},{},[1679,1680,1686,1688,1694,1696],{"type":40,"value":1662},{"type":35,"tag":43,"props":1681,"children":1683},{"className":1682},[],[1684],{"type":40,"value":1685},"move_package_test",{"type":40,"value":1687}," with ",{"type":35,"tag":43,"props":1689,"children":1691},{"className":1690},[],[1692],{"type":40,"value":1693},"establish_baseline",{"type":40,"value":1695}," set to true. ",{"type":35,"tag":62,"props":1697,"children":1698},{},[1699],{"type":40,"value":1700},"Fix failing tests before proceeding.",{"type":35,"tag":457,"props":1702,"children":1704},{"id":1703},"task-2-analyze-target-code",[1705],{"type":40,"value":1706},"Task: 2 — Analyze Target Code",{"type":35,"tag":36,"props":1708,"children":1709},{},[1710],{"type":35,"tag":62,"props":1711,"children":1712},{},[1713],{"type":40,"value":1714},"Specific function requested:",{"type":35,"tag":1655,"props":1716,"children":1717},{},[1718,1745],{"type":35,"tag":171,"props":1719,"children":1720},{},[1721,1722,1728,1729,1735,1737,1743],{"type":40,"value":1662},{"type":35,"tag":43,"props":1723,"children":1725},{"className":1724},[],[1726],{"type":40,"value":1727},"move_package_coverage",{"type":40,"value":1687},{"type":35,"tag":43,"props":1730,"children":1732},{"className":1731},[],[1733],{"type":40,"value":1734},"function",{"type":40,"value":1736}," set to ",{"type":35,"tag":43,"props":1738,"children":1740},{"className":1739},[],[1741],{"type":40,"value":1742},"\"module_name::function_name\"",{"type":40,"value":1744}," — get uncovered lines in that function",{"type":35,"tag":171,"props":1746,"children":1747},{},[1748,1750],{"type":40,"value":1749},"Read the source and identify behaviors to test:\n",{"type":35,"tag":167,"props":1751,"children":1752},{},[1753,1758,1763,1768],{"type":35,"tag":171,"props":1754,"children":1755},{},[1756],{"type":40,"value":1757},"Success path with valid inputs",{"type":35,"tag":171,"props":1759,"children":1760},{},[1761],{"type":40,"value":1762},"Each distinct abort condition",{"type":35,"tag":171,"props":1764,"children":1765},{},[1766],{"type":40,"value":1767},"Edge cases (empty, zero, boundaries)",{"type":35,"tag":171,"props":1769,"children":1770},{},[1771],{"type":40,"value":1772},"Potential bugs",{"type":35,"tag":36,"props":1774,"children":1775},{},[1776],{"type":35,"tag":62,"props":1777,"children":1778},{},[1779],{"type":40,"value":1780},"Full module mode:",{"type":35,"tag":1655,"props":1782,"children":1783},{},[1784,1795,1800,1812],{"type":35,"tag":171,"props":1785,"children":1786},{},[1787,1788,1793],{"type":40,"value":1662},{"type":35,"tag":43,"props":1789,"children":1791},{"className":1790},[],[1792],{"type":40,"value":1727},{"type":40,"value":1794}," — get uncovered lines per source file",{"type":35,"tag":171,"props":1796,"children":1797},{},[1798],{"type":40,"value":1799},"Read the source files that contain uncovered lines",{"type":35,"tag":171,"props":1801,"children":1802},{},[1803,1805,1810],{"type":40,"value":1804},"Identify testable functions: public, entry, public(friend) — skip ",{"type":35,"tag":43,"props":1806,"children":1808},{"className":1807},[],[1809],{"type":40,"value":808},{"type":40,"value":1811}," and private",{"type":35,"tag":171,"props":1813,"children":1814},{},[1815],{"type":40,"value":1816},"For functions with uncovered lines, identify behaviors to test (same as above)",{"type":35,"tag":457,"props":1818,"children":1820},{"id":1819},"task-3-generate-test-module",[1821],{"type":40,"value":1822},"Task: 3 — Generate Test Module",{"type":35,"tag":36,"props":1824,"children":1825},{},[1826,1828,1833],{"type":40,"value":1827},"Create ",{"type":35,"tag":43,"props":1829,"children":1831},{"className":1830},[],[1832],{"type":40,"value":94},{"type":40,"value":1834}," (create directory if needed).",{"type":35,"tag":678,"props":1836,"children":1838},{"className":878,"code":1837,"language":880,"meta":683,"style":683},"\u002F\u002F =============================================================================\n\u002F\u002F AUTO-GENERATED TESTS - DO NOT EDIT MANUALLY\n\u002F\u002F Generated by: move-test agent\n\u002F\u002F Source module: \u003Cmodule>\n\u002F\u002F =============================================================================\n\n#[test_only]\nmodule \u003Cpackage_address>::\u003Cmodule>_tests {\n    use \u003Cpackage_address>::\u003Cmodule>;\n\n    #[test(account = @0x1)]\n    \u002F\u002F\u002F @ai-generated\n    \u002F\u002F\u002F Verifies that \u003Cfunction> \u003Cbehavior>.\n    fun test_\u003Cfunction>_\u003Cscenario>(account: &signer) { ... }\n}\n",[1839],{"type":35,"tag":43,"props":1840,"children":1841},{"__ignoreMap":683},[1842,1850,1858,1866,1874,1881,1888,1895,1903,1911,1918,1926,1934,1942,1950],{"type":35,"tag":689,"props":1843,"children":1844},{"class":691,"line":692},[1845],{"type":35,"tag":689,"props":1846,"children":1847},{},[1848],{"type":40,"value":1849},"\u002F\u002F =============================================================================\n",{"type":35,"tag":689,"props":1851,"children":1852},{"class":691,"line":701},[1853],{"type":35,"tag":689,"props":1854,"children":1855},{},[1856],{"type":40,"value":1857},"\u002F\u002F AUTO-GENERATED TESTS - DO NOT EDIT MANUALLY\n",{"type":35,"tag":689,"props":1859,"children":1860},{"class":691,"line":710},[1861],{"type":35,"tag":689,"props":1862,"children":1863},{},[1864],{"type":40,"value":1865},"\u002F\u002F Generated by: move-test agent\n",{"type":35,"tag":689,"props":1867,"children":1868},{"class":691,"line":911},[1869],{"type":35,"tag":689,"props":1870,"children":1871},{},[1872],{"type":40,"value":1873},"\u002F\u002F Source module: \u003Cmodule>\n",{"type":35,"tag":689,"props":1875,"children":1876},{"class":691,"line":921},[1877],{"type":35,"tag":689,"props":1878,"children":1879},{},[1880],{"type":40,"value":1849},{"type":35,"tag":689,"props":1882,"children":1883},{"class":691,"line":930},[1884],{"type":35,"tag":689,"props":1885,"children":1886},{"emptyLinePlaceholder":915},[1887],{"type":40,"value":918},{"type":35,"tag":689,"props":1889,"children":1890},{"class":691,"line":939},[1891],{"type":35,"tag":689,"props":1892,"children":1893},{},[1894],{"type":40,"value":1234},{"type":35,"tag":689,"props":1896,"children":1897},{"class":691,"line":948},[1898],{"type":35,"tag":689,"props":1899,"children":1900},{},[1901],{"type":40,"value":1902},"module \u003Cpackage_address>::\u003Cmodule>_tests {\n",{"type":35,"tag":689,"props":1904,"children":1905},{"class":691,"line":956},[1906],{"type":35,"tag":689,"props":1907,"children":1908},{},[1909],{"type":40,"value":1910},"    use \u003Cpackage_address>::\u003Cmodule>;\n",{"type":35,"tag":689,"props":1912,"children":1913},{"class":691,"line":965},[1914],{"type":35,"tag":689,"props":1915,"children":1916},{"emptyLinePlaceholder":915},[1917],{"type":40,"value":918},{"type":35,"tag":689,"props":1919,"children":1920},{"class":691,"line":974},[1921],{"type":35,"tag":689,"props":1922,"children":1923},{},[1924],{"type":40,"value":1925},"    #[test(account = @0x1)]\n",{"type":35,"tag":689,"props":1927,"children":1928},{"class":691,"line":1308},[1929],{"type":35,"tag":689,"props":1930,"children":1931},{},[1932],{"type":40,"value":1933},"    \u002F\u002F\u002F @ai-generated\n",{"type":35,"tag":689,"props":1935,"children":1936},{"class":691,"line":1317},[1937],{"type":35,"tag":689,"props":1938,"children":1939},{},[1940],{"type":40,"value":1941},"    \u002F\u002F\u002F Verifies that \u003Cfunction> \u003Cbehavior>.\n",{"type":35,"tag":689,"props":1943,"children":1944},{"class":691,"line":1439},[1945],{"type":35,"tag":689,"props":1946,"children":1947},{},[1948],{"type":40,"value":1949},"    fun test_\u003Cfunction>_\u003Cscenario>(account: &signer) { ... }\n",{"type":35,"tag":689,"props":1951,"children":1952},{"class":691,"line":1447},[1953],{"type":35,"tag":689,"props":1954,"children":1955},{},[1956],{"type":40,"value":1258},{"type":35,"tag":36,"props":1958,"children":1959},{},[1960,1964],{"type":35,"tag":62,"props":1961,"children":1962},{},[1963],{"type":40,"value":1780},{"type":40,"value":1965}," Generate tests in batches, one module at a time.",{"type":35,"tag":36,"props":1967,"children":1968},{},[1969,1974,1976,1982],{"type":35,"tag":62,"props":1970,"children":1971},{},[1972],{"type":40,"value":1973},"Suspected bugs:",{"type":40,"value":1975}," Assert the ",{"type":35,"tag":1977,"props":1978,"children":1979},"em",{},[1980],{"type":40,"value":1981},"correct",{"type":40,"value":1983}," expected behavior — the test should fail against the buggy code.",{"type":35,"tag":457,"props":1985,"children":1987},{"id":1986},"task-4-validate-tests",[1988],{"type":40,"value":1989},"Task: 4 — Validate Tests",{"type":35,"tag":36,"props":1991,"children":1992},{},[1993,1994,1999,2001,2007],{"type":40,"value":1662},{"type":35,"tag":43,"props":1995,"children":1997},{"className":1996},[],[1998],{"type":40,"value":1685},{"type":40,"value":2000},". If ",{"type":35,"tag":43,"props":2002,"children":2004},{"className":2003},[],[2005],{"type":40,"value":2006},"success",{"type":40,"value":2008}," is false, classify each failure:",{"type":35,"tag":167,"props":2010,"children":2011},{},[2012,2022],{"type":35,"tag":171,"props":2013,"children":2014},{},[2015,2020],{"type":35,"tag":62,"props":2016,"children":2017},{},[2018],{"type":40,"value":2019},"Compilation error",{"type":40,"value":2021},": Fix the test",{"type":35,"tag":171,"props":2023,"children":2024},{},[2025,2030,2032],{"type":35,"tag":62,"props":2026,"children":2027},{},[2028],{"type":40,"value":2029},"Runtime failure",{"type":40,"value":2031},": Compare test expectation against expected behavior\n",{"type":35,"tag":167,"props":2033,"children":2034},{},[2035,2040],{"type":35,"tag":171,"props":2036,"children":2037},{},[2038],{"type":40,"value":2039},"Test is wrong → Fix it",{"type":35,"tag":171,"props":2041,"children":2042},{},[2043,2045,2050,2052,2058,2060,2066,2068],{"type":40,"value":2044},"Code is wrong → Move test to ",{"type":35,"tag":43,"props":2046,"children":2048},{"className":2047},[],[2049],{"type":40,"value":112},{"type":40,"value":2051}," (at package root, next to ",{"type":35,"tag":43,"props":2053,"children":2055},{"className":2054},[],[2056],{"type":40,"value":2057},"sources\u002F",{"type":40,"value":2059}," and ",{"type":35,"tag":43,"props":2061,"children":2063},{"className":2062},[],[2064],{"type":40,"value":2065},"tests\u002F",{"type":40,"value":2067},") and document:\n",{"type":35,"tag":167,"props":2069,"children":2070},{},[2071,2076,2081],{"type":35,"tag":171,"props":2072,"children":2073},{},[2074],{"type":40,"value":2075},"Expected behavior",{"type":35,"tag":171,"props":2077,"children":2078},{},[2079],{"type":40,"value":2080},"Actual behavior",{"type":35,"tag":171,"props":2082,"children":2083},{},[2084],{"type":40,"value":2085},"Why this indicates a bug",{"type":35,"tag":36,"props":2087,"children":2088},{},[2089,2091,2097],{"type":40,"value":2090},"Iterate until all tests in ",{"type":35,"tag":43,"props":2092,"children":2094},{"className":2093},[],[2095],{"type":40,"value":2096},"tests\u002Fmove_flow\u002F",{"type":40,"value":2098}," pass.",{"type":35,"tag":457,"props":2100,"children":2102},{"id":2101},"task-5-check-coverage-improvement",[2103],{"type":40,"value":2104},"Task: 5 — Check Coverage Improvement",{"type":35,"tag":36,"props":2106,"children":2107},{},[2108,2110,2116,2118,2123,2125,2130,2132,2137],{"type":40,"value":2109},"Check ",{"type":35,"tag":43,"props":2111,"children":2113},{"className":2112},[],[2114],{"type":40,"value":2115},"newly_covered",{"type":40,"value":2117}," from the validation step to confirm the generated tests added coverage. Use ",{"type":35,"tag":43,"props":2119,"children":2121},{"className":2120},[],[2122],{"type":40,"value":1727},{"type":40,"value":2124}," to check remaining gaps (pass ",{"type":35,"tag":43,"props":2126,"children":2128},{"className":2127},[],[2129],{"type":40,"value":1734},{"type":40,"value":2131}," as ",{"type":35,"tag":43,"props":2133,"children":2135},{"className":2134},[],[2136],{"type":40,"value":1742},{"type":40,"value":2138}," when targeting a specific function) — generate additional tests if needed and feasible.",{"type":35,"tag":457,"props":2140,"children":2142},{"id":2141},"task-6-minimize-tests-do-not-skip",[2143],{"type":40,"value":2144},"Task: 6 — Minimize Tests (do not skip)",{"type":35,"tag":36,"props":2146,"children":2147},{},[2148],{"type":40,"value":2149},"Delete tests that add no new coverage. Keep tests with distinct scenarios (different abort conditions, branches, edge cases). When duplicates exist, prefer simpler setup and clearer naming.",{"type":35,"tag":36,"props":2151,"children":2152},{},[2153,2155,2160,2162,2167,2169,2174],{"type":40,"value":2154},"Only modify tests in ",{"type":35,"tag":43,"props":2156,"children":2158},{"className":2157},[],[2159],{"type":40,"value":2096},{"type":40,"value":2161}," — do not touch ",{"type":35,"tag":43,"props":2163,"children":2165},{"className":2164},[],[2166],{"type":40,"value":2057},{"type":40,"value":2168}," or ",{"type":35,"tag":43,"props":2170,"children":2172},{"className":2171},[],[2173],{"type":40,"value":2065},{"type":40,"value":2175}," root.",{"type":35,"tag":457,"props":2177,"children":2179},{"id":2178},"task-7-report",[2180],{"type":40,"value":2181},"Task: 7 — Report",{"type":35,"tag":36,"props":2183,"children":2184},{},[2185],{"type":40,"value":2186},"Summarize:",{"type":35,"tag":167,"props":2188,"children":2189},{},[2190,2195],{"type":35,"tag":171,"props":2191,"children":2192},{},[2193],{"type":40,"value":2194},"Tests generated and coverage achieved",{"type":35,"tag":171,"props":2196,"children":2197},{},[2198,2200,2205],{"type":40,"value":2199},"If any tests were moved to ",{"type":35,"tag":43,"props":2201,"children":2203},{"className":2202},[],[2204],{"type":40,"value":112},{"type":40,"value":2206},", alert the user with a summary of potential bugs found",{"type":35,"tag":52,"props":2208,"children":2210},{"id":2209},"task",[2211],{"type":40,"value":2212},"Task",{"type":35,"tag":36,"props":2214,"children":2215},{},[2216],{"type":40,"value":2217},"Generate unit tests for the current Move package.",{"type":35,"tag":2219,"props":2220,"children":2221},"style",{},[2222],{"type":40,"value":2223},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2225,"total":2388},[2226,2243,2260,2274,2286,2300,2314,2329,2343,2358,2368,2378],{"slug":2227,"name":2227,"fn":2228,"description":2229,"org":2230,"tags":2231,"stars":1474,"repoUrl":2241,"updatedAt":2242},"analyze-gas-optimization","optimize Aptos Move contracts for gas","Analyze and optimize Aptos Move contracts for gas efficiency, identifying expensive operations and suggesting optimizations. Triggers on: 'optimize gas', 'reduce gas costs', 'gas analysis', 'make contract cheaper', 'gas efficiency', 'analyze gas usage', 'reduce transaction costs'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2232,2235,2238],{"name":2233,"slug":2234,"type":16},"Blockchain","blockchain",{"name":2236,"slug":2237,"type":16},"Performance","performance",{"name":2239,"slug":2240,"type":16},"Smart Contracts","smart-contracts","https:\u002F\u002Fgithub.com\u002Faptos-labs\u002Faptos-agent-skills","2026-07-12T08:07:14.117466",{"slug":2244,"name":2244,"fn":2245,"description":2246,"org":2247,"tags":2248,"stars":1474,"repoUrl":2241,"updatedAt":2259},"create-aptos-project","scaffold new Aptos dApp projects","Scaffolds new Aptos projects using npx create-aptos-dapp. Supports fullstack (Vite or Next.js) and contract-only templates with network selection and optional API key. Triggers on: 'build app', 'create app', 'make app', 'new app', 'build dApp', 'create dApp', 'new dApp', 'build project', 'new project', 'create project', 'scaffold', 'start project', 'set up project', 'build me a', 'I want to build', 'make me a', 'help me build'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2249,2252,2255,2258],{"name":2250,"slug":2251,"type":16},"Next.js","next-js",{"name":2253,"slug":2254,"type":16},"TypeScript","typescript",{"name":2256,"slug":2257,"type":16},"Vite","vite",{"name":14,"slug":15,"type":16},"2026-07-12T08:07:30.595111",{"slug":2261,"name":2261,"fn":2262,"description":2263,"org":2264,"tags":2265,"stars":1474,"repoUrl":2241,"updatedAt":2273},"deploy-contracts","deploy Move contracts to Aptos networks","Safely deploys Move contracts to Aptos networks (devnet, testnet, mainnet) with pre-deployment verification. Triggers on: 'deploy contract', 'publish to testnet', 'deploy to mainnet', 'how to deploy', 'publish module', 'deployment checklist', 'deploy to devnet'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2266,2269,2272],{"name":2267,"slug":2268,"type":16},"Deployment","deployment",{"name":2270,"slug":2271,"type":16},"Engineering","engineering",{"name":2239,"slug":2240,"type":16},"2026-07-12T08:07:16.798352",{"slug":2275,"name":2275,"fn":2276,"description":2277,"org":2278,"tags":2279,"stars":1474,"repoUrl":2241,"updatedAt":2285},"generate-tests","generate test suites for Move contracts","Creates comprehensive test suites for Move contracts with 100% coverage requirement. Triggers on: 'generate tests', 'create tests', 'write test suite', 'test this contract', 'how to test', 'add test coverage', 'write unit tests'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2280,2281,2284],{"name":2270,"slug":2271,"type":16},{"name":2282,"slug":2283,"type":16},"QA","qa",{"name":18,"slug":19,"type":16},"2026-07-12T08:07:18.0205",{"slug":2287,"name":2287,"fn":2288,"description":2289,"org":2290,"tags":2291,"stars":1474,"repoUrl":2241,"updatedAt":2299},"modernize-move","modernize Move V1 contracts to V2","Detects and modernizes outdated Move V1 syntax, patterns, and APIs to Move V2+. Use when upgrading legacy contracts, migrating to modern syntax, or converting old patterns to current best practices. NOT for writing new contracts (use write-contracts) or fixing bugs.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2292,2295,2296],{"name":2293,"slug":2294,"type":16},"Code Analysis","code-analysis",{"name":2270,"slug":2271,"type":16},{"name":2297,"slug":2298,"type":16},"Migration","migration","2026-07-12T08:07:10.226223",{"slug":2301,"name":2301,"fn":2302,"description":2303,"org":2304,"tags":2305,"stars":1474,"repoUrl":2241,"updatedAt":2313},"search-aptos-examples","search Aptos reference implementations","Searches aptos-core and daily-move for reference implementations before writing contracts. Triggers on: 'search examples', 'find example', 'check aptos-core', 'is there an example', 'reference implementation', 'how does aptos implement', 'similar contract', 'daily-move'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2306,2307,2310],{"name":2233,"slug":2234,"type":16},{"name":2308,"slug":2309,"type":16},"Documentation","documentation",{"name":2311,"slug":2312,"type":16},"Search","search","2026-07-12T08:07:15.382039",{"slug":2315,"name":2315,"fn":2316,"description":2317,"org":2318,"tags":2319,"stars":1474,"repoUrl":2241,"updatedAt":2328},"security-audit","audit Move smart contracts for security","Audits Move contracts for security vulnerabilities before deployment using 7-category checklist. Triggers on: 'audit contract', 'security check', 'review security', 'check for vulnerabilities', 'security audit', 'is this secure', 'find security issues'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2320,2323,2324,2327],{"name":2321,"slug":2322,"type":16},"Audit","audit",{"name":2293,"slug":2294,"type":16},{"name":2325,"slug":2326,"type":16},"Security","security",{"name":2239,"slug":2240,"type":16},"2026-07-12T08:07:11.680215",{"slug":2330,"name":2330,"fn":2331,"description":2332,"org":2333,"tags":2334,"stars":1474,"repoUrl":2241,"updatedAt":2342},"smoothsend-gasless","sponsor gas fees for Aptos dApps","How to sponsor gas fees for Aptos dApp users using SmoothSend. Paid commercial service: free on testnet, credit-based on mainnet. Covers 3-line wallet adapter integration (transactionSubmitter), Script Composer for fee-in-token stablecoin transfers. Triggers on: 'gasless', 'sponsor gas', 'users pay no APT', 'transactionSubmitter', 'SmoothSend', 'fee payer', 'pay gas for users', 'no gas required'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2335,2338,2341],{"name":2336,"slug":2337,"type":16},"API Development","api-development",{"name":2339,"slug":2340,"type":16},"Payments","payments",{"name":14,"slug":15,"type":16},"2026-07-12T08:07:31.843242",{"slug":2344,"name":2344,"fn":2345,"description":2346,"org":2347,"tags":2348,"stars":1474,"repoUrl":2241,"updatedAt":2357},"ts-sdk-account","manage Aptos accounts with TS SDK","How to create and use Account (signer) in @aptos-labs\u002Fts-sdk. Covers Account.generate(), fromPrivateKey(), fromDerivationPath(), Ed25519 vs SingleKey vs MultiKey vs Keyless, serialization (fromHex\u002FtoHex). Triggers on: 'Account.generate', 'Account.fromPrivateKey', 'Ed25519PrivateKey', 'SDK account', 'mnemonic', 'SingleKeyAccount', 'KeylessAccount'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2349,2352,2353,2356],{"name":2350,"slug":2351,"type":16},"Auth","auth",{"name":2233,"slug":2234,"type":16},{"name":2354,"slug":2355,"type":16},"SDK","sdk",{"name":2253,"slug":2254,"type":16},"2026-07-12T08:07:29.297415",{"slug":2359,"name":2359,"fn":2360,"description":2361,"org":2362,"tags":2363,"stars":1474,"repoUrl":2241,"updatedAt":2367},"ts-sdk-address","manage AccountAddress in Aptos TypeScript SDK","How to create and use AccountAddress in @aptos-labs\u002Fts-sdk. Covers address format (AIP-40), from\u002FfromString\u002FfromStrict, special addresses, LONG vs SHORT form, and derived addresses (object, resource, token, user-derived). Triggers on: 'AccountAddress', 'AccountAddress.from', 'AIP-40', 'derived address', 'createObjectAddress', 'createResourceAddress', 'createTokenAddress'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2364,2365,2366],{"name":2233,"slug":2234,"type":16},{"name":2354,"slug":2355,"type":16},{"name":2253,"slug":2254,"type":16},"2026-07-12T08:07:26.430378",{"slug":2369,"name":2369,"fn":2370,"description":2371,"org":2372,"tags":2373,"stars":1474,"repoUrl":2241,"updatedAt":2377},"ts-sdk-client","configure Aptos SDK clients","How to create and configure the Aptos client (Aptos, AptosConfig) in @aptos-labs\u002Fts-sdk. Covers Network, fullnode\u002Findexer\u002Ffaucet URLs, singleton pattern, and Bun compatibility. Triggers on: 'Aptos client', 'AptosConfig', 'SDK client', 'client setup', 'new Aptos(', 'Network.TESTNET', 'Network.MAINNET'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2374,2375,2376],{"name":2336,"slug":2337,"type":16},{"name":2354,"slug":2355,"type":16},{"name":2253,"slug":2254,"type":16},"2026-07-12T08:07:21.933342",{"slug":2379,"name":2379,"fn":2380,"description":2381,"org":2382,"tags":2383,"stars":1474,"repoUrl":2241,"updatedAt":2387},"ts-sdk-transactions","manage Aptos blockchain transactions","How to build, sign, submit, and simulate transactions in @aptos-labs\u002Fts-sdk. Covers build.simple(), signAndSubmitTransaction(), waitForTransaction(), simulate, sponsored (fee payer), and multi-agent. Triggers on: 'build.simple', 'signAndSubmitTransaction', 'transaction.build', 'waitForTransaction', 'signAsFeePayer', 'SDK transaction', 'sponsored transaction', 'multi-agent transaction'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2384,2385,2386],{"name":2336,"slug":2337,"type":16},{"name":2253,"slug":2254,"type":16},{"name":14,"slug":15,"type":16},"2026-07-12T08:07:23.774257",24,{"items":2390,"total":939},[2391,2399,2410,2421,2432,2441,2450],{"slug":880,"name":880,"fn":2392,"description":2393,"org":2394,"tags":2395,"stars":20,"repoUrl":21,"updatedAt":2398},"develop applications on Aptos","Move development on Aptos",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2396,2397],{"name":2233,"slug":2234,"type":16},{"name":14,"slug":15,"type":16},"2026-07-19T06:03:46.40898",{"slug":2400,"name":2400,"fn":2401,"description":2402,"org":2403,"tags":2404,"stars":20,"repoUrl":21,"updatedAt":2409},"move-check","check Move packages for compilation errors","Check a Move package for compilation errors",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2405,2408],{"name":2406,"slug":2407,"type":16},"Debugging","debugging",{"name":14,"slug":15,"type":16},"2026-07-19T06:03:09.843322",{"slug":2411,"name":2411,"fn":2412,"description":2413,"org":2414,"tags":2415,"stars":20,"repoUrl":21,"updatedAt":2420},"move-inf","infer specifications for Move packages","Infer specifications for a Move package",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2416,2419],{"name":2417,"slug":2418,"type":16},"Data Modeling","data-modeling",{"name":14,"slug":15,"type":16},"2026-07-19T06:03:10.203983",{"slug":2422,"name":2422,"fn":2423,"description":2424,"org":2425,"tags":2426,"stars":20,"repoUrl":21,"updatedAt":2431},"move-init","initialize Move workflow routing","Initialize Move workflow routing in the project CLAUDE.md",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2427,2430],{"name":2428,"slug":2429,"type":16},"Configuration","configuration",{"name":14,"slug":15,"type":16},"2026-07-19T06:03:48.382736",{"slug":2433,"name":2433,"fn":2434,"description":2435,"org":2436,"tags":2437,"stars":20,"repoUrl":21,"updatedAt":2440},"move-prove","verify Move specifications with Move Prover","Run the Move Prover to formally verify specifications",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2438,2439],{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},"2026-07-19T06:03:10.663492",{"slug":2442,"name":2442,"fn":2443,"description":2444,"org":2445,"tags":2446,"stars":20,"repoUrl":21,"updatedAt":2449},"move-replay","replay and debug Aptos transactions","Replay a committed on-chain Aptos transaction locally to debug its outcome. Use when investigating a failed or unexpected transaction, reproducing an abort, or testing a local Move patch against a historical transaction.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2447,2448],{"name":2406,"slug":2407,"type":16},{"name":14,"slug":15,"type":16},"2026-07-19T06:03:11.562048",{"slug":4,"name":4,"fn":5,"description":6,"org":2451,"tags":2452,"stars":20,"repoUrl":21,"updatedAt":22},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2453,2454],{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16}]