[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-aptos-generate-tests":3,"mdc--lwk4r5-key":36,"related-org-aptos-generate-tests":2991,"related-repo-aptos-generate-tests":3146},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":31,"sourceUrl":34,"mdContent":35},"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},"aptos","Aptos Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Faptos.png","aptos-labs",[13,17,20],{"name":14,"slug":15,"type":16},"QA","qa","tag",{"name":18,"slug":19,"type":16},"Engineering","engineering",{"name":21,"slug":22,"type":16},"Testing","testing",18,"https:\u002F\u002Fgithub.com\u002Faptos-labs\u002Faptos-agent-skills","2026-07-12T08:07:18.0205","MIT",8,[29,30],"agent-skills","blockchain",{"repoUrl":24,"stars":23,"forks":27,"topics":32,"description":33},[29,30],"AI skills for building secure, modern Aptos dApps — Move contracts, TypeScript SDK, and frontend integration for Claude Code, Cursor, and Copilot.","https:\u002F\u002Fgithub.com\u002Faptos-labs\u002Faptos-agent-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fmove\u002Fgenerate-tests","---\nname: generate-tests\ndescription:\n  \"Creates comprehensive test suites for Move contracts with 100% coverage requirement. Triggers on: 'generate tests',\n  'create tests', 'write test suite', 'test this contract', 'how to test', 'add test coverage', 'write unit tests'.\"\nlicense: MIT\nmetadata:\n  author: aptos-labs\n  version: \"1.0\"\n  category: move\n  tags: [\"testing\", \"unit-tests\", \"coverage\", \"quality\"]\n  priority: critical\n---\n\n# Generate Tests Skill\n\n## Overview\n\nThis skill generates comprehensive test suites for Move contracts with **100% line coverage** requirement. Tests verify:\n\n- ✅ Happy paths (functionality works)\n- ✅ Access control (unauthorized users blocked)\n- ✅ Input validation (invalid inputs rejected)\n- ✅ Edge cases (boundaries, limits, empty states)\n\n**Critical Rule:** NEVER deploy without 100% test coverage.\n\n## Core Workflow\n\n### Step 1: Create Test Module\n\n```move\n#[test_only]\nmodule my_addr::my_module_tests {\n    use my_addr::my_module::{Self, MyObject};\n    use aptos_framework::object::{Self, Object};\n    use std::string;\n    use std::signer;\n\n    \u002F\u002F Test constants\n    const ADMIN_ADDR: address = @0x100;\n    const USER_ADDR: address = @0x200;\n    const ATTACKER_ADDR: address = @0x300;\n\n    \u002F\u002F ========== Setup Helpers ==========\n    \u002F\u002F (Reusable setup functions)\n\n    \u002F\u002F ========== Happy Path Tests ==========\n    \u002F\u002F (Basic functionality)\n\n    \u002F\u002F ========== Access Control Tests ==========\n    \u002F\u002F (Unauthorized access blocked)\n\n    \u002F\u002F ========== Input Validation Tests ==========\n    \u002F\u002F (Invalid inputs rejected)\n\n    \u002F\u002F ========== Edge Case Tests ==========\n    \u002F\u002F (Boundaries and limits)\n}\n```\n\n### Step 2: Write Happy Path Tests\n\n**Test basic functionality works correctly:**\n\n```move\n#[test(creator = @0x1)]\npublic fun test_create_object_succeeds(creator: &signer) {\n    \u002F\u002F Execute\n    let obj = my_module::create_my_object(\n        creator,\n        string::utf8(b\"Test Object\")\n    );\n\n    \u002F\u002F Verify\n    assert!(object::owner(obj) == signer::address_of(creator), 0);\n}\n\n#[test(owner = @0x1)]\npublic fun test_update_object_succeeds(owner: &signer) {\n    \u002F\u002F Setup\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Old Name\"));\n\n    \u002F\u002F Execute\n    let new_name = string::utf8(b\"New Name\");\n    my_module::update_object(owner, obj, new_name);\n\n    \u002F\u002F Verify (if you have view functions)\n    \u002F\u002F assert!(my_module::get_object_name(obj) == new_name, 0);\n}\n\n#[test(owner = @0x1, recipient = @0x2)]\npublic fun test_transfer_object_succeeds(\n    owner: &signer,\n    recipient: &signer\n) {\n    let recipient_addr = signer::address_of(recipient);\n\n    \u002F\u002F Setup\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Object\"));\n    assert!(object::owner(obj) == signer::address_of(owner), 0);\n\n    \u002F\u002F Execute\n    my_module::transfer_object(owner, obj, recipient_addr);\n\n    \u002F\u002F Verify\n    assert!(object::owner(obj) == recipient_addr, 1);\n}\n```\n\n### Step 3: Write Access Control Tests\n\n**Test unauthorized access is blocked:**\n\n```move\n#[test(owner = @0x1, attacker = @0x2)]\n#[expected_failure(abort_code = my_module::E_NOT_OWNER)]\npublic fun test_non_owner_cannot_update(\n    owner: &signer,\n    attacker: &signer\n) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Object\"));\n\n    \u002F\u002F Attacker tries to update (should abort)\n    my_module::update_object(attacker, obj, string::utf8(b\"Hacked\"));\n}\n\n#[test(owner = @0x1, attacker = @0x2)]\n#[expected_failure(abort_code = my_module::E_NOT_OWNER)]\npublic fun test_non_owner_cannot_transfer(\n    owner: &signer,\n    attacker: &signer\n) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Object\"));\n\n    \u002F\u002F Attacker tries to transfer (should abort)\n    my_module::transfer_object(attacker, obj, @0x3);\n}\n\n#[test(admin = @0x1, user = @0x2)]\n#[expected_failure(abort_code = my_module::E_NOT_ADMIN)]\npublic fun test_non_admin_cannot_configure(\n    admin: &signer,\n    user: &signer\n) {\n    my_module::init_module(admin);\n\n    \u002F\u002F Regular user tries admin function (should abort)\n    my_module::update_config(user, 100);\n}\n```\n\n### Step 4: Write Input Validation Tests\n\n**Test invalid inputs are rejected:**\n\n```move\n#[test(user = @0x1)]\n#[expected_failure(abort_code = my_module::E_ZERO_AMOUNT)]\npublic fun test_zero_amount_rejected(user: &signer) {\n    my_module::deposit(user, 0); \u002F\u002F Should abort\n}\n\n#[test(user = @0x1)]\n#[expected_failure(abort_code = my_module::E_AMOUNT_TOO_HIGH)]\npublic fun test_excessive_amount_rejected(user: &signer) {\n    my_module::deposit(user, my_module::MAX_DEPOSIT_AMOUNT + 1); \u002F\u002F Should abort\n}\n\n#[test(owner = @0x1)]\n#[expected_failure(abort_code = my_module::E_EMPTY_NAME)]\npublic fun test_empty_string_rejected(owner: &signer) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Initial\"));\n    my_module::update_object(owner, obj, string::utf8(b\"\")); \u002F\u002F Empty - should abort\n}\n\n#[test(owner = @0x1)]\n#[expected_failure(abort_code = my_module::E_NAME_TOO_LONG)]\npublic fun test_string_too_long_rejected(owner: &signer) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Initial\"));\n\n    \u002F\u002F String exceeding MAX_NAME_LENGTH\n    let long_name = string::utf8(b\"This is an extremely long name that exceeds the maximum allowed length\");\n\n    my_module::update_object(owner, obj, long_name); \u002F\u002F Should abort\n}\n\n#[test(owner = @0x1)]\n#[expected_failure(abort_code = my_module::E_ZERO_ADDRESS)]\npublic fun test_zero_address_rejected(owner: &signer) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Object\"));\n    my_module::transfer_object(owner, obj, @0x0); \u002F\u002F Should abort\n}\n```\n\n### Step 5: Write Edge Case Tests\n\n**Test boundary conditions:**\n\n```move\n#[test(user = @0x1)]\npublic fun test_max_amount_allowed(user: &signer) {\n    my_module::init_account(user);\n\n    \u002F\u002F Exactly MAX_DEPOSIT_AMOUNT should work\n    my_module::deposit(user, my_module::MAX_DEPOSIT_AMOUNT);\n\n    \u002F\u002F Verify\n    assert!(my_module::get_balance(signer::address_of(user)) == my_module::MAX_DEPOSIT_AMOUNT, 0);\n}\n\n#[test(user = @0x1)]\npublic fun test_max_name_length_allowed(user: &signer) {\n    \u002F\u002F Create string exactly MAX_NAME_LENGTH long\n    let max_name = string::utf8(b\"12345678901234567890123456789012\"); \u002F\u002F 32 chars if MAX = 32\n\n    \u002F\u002F Should succeed\n    let obj = my_module::create_my_object(user, max_name);\n}\n\n#[test(user = @0x1)]\npublic fun test_empty_collection_operations(user: &signer) {\n    let collection = my_module::create_collection(user, string::utf8(b\"Collection\"));\n\n    \u002F\u002F Should handle empty collection gracefully\n    assert!(my_module::get_collection_size(collection) == 0, 0);\n}\n```\n\n### Step 6: Verify Coverage\n\n**Run tests with coverage:**\n\n```bash\n# Run all tests\naptos move test\n\n# Run with coverage\naptos move test --coverage\n\n# Generate detailed coverage report\naptos move coverage source --module \u003Cmodule_name>\n\n# Verify 100% coverage\naptos move coverage summary\n```\n\n**Coverage report example:**\n\n```\nmodule: my_module\ncoverage: 100.0% (150\u002F150 lines covered)\n```\n\n**If coverage \u003C 100%:**\n\n1. Check uncovered lines in report\n2. Write tests for missing paths\n3. Repeat until 100%\n\n## Test Template Structure\n\n```move\n#[test_only]\nmodule my_addr::module_tests {\n    use my_addr::module::{Self, Type};\n\n    \u002F\u002F ========== Setup Helpers ==========\n\n    fun setup_default(): Object\u003CType> {\n        \u002F\u002F Common setup code\n    }\n\n    \u002F\u002F ========== Happy Path Tests ==========\n\n    #[test(user = @0x1)]\n    public fun test_basic_operation_succeeds(user: &signer) {\n        \u002F\u002F Test happy path\n    }\n\n    \u002F\u002F ========== Access Control Tests ==========\n\n    #[test(owner = @0x1, attacker = @0x2)]\n    #[expected_failure(abort_code = E_NOT_OWNER)]\n    public fun test_unauthorized_access_fails(\n        owner: &signer,\n        attacker: &signer\n    ) {\n        \u002F\u002F Test access control\n    }\n\n    \u002F\u002F ========== Input Validation Tests ==========\n\n    #[test(user = @0x1)]\n    #[expected_failure(abort_code = E_INVALID_INPUT)]\n    public fun test_invalid_input_rejected(user: &signer) {\n        \u002F\u002F Test input validation\n    }\n\n    \u002F\u002F ========== Edge Case Tests ==========\n\n    #[test(user = @0x1)]\n    public fun test_boundary_condition(user: &signer) {\n        \u002F\u002F Test edge cases\n    }\n}\n```\n\n## Testing Checklist\n\nFor each contract, verify you have tests for:\n\n**Happy Paths:**\n\n- [ ] Object creation works\n- [ ] State updates work\n- [ ] Transfers work\n- [ ] All main features work\n\n**Access Control:**\n\n- [ ] Non-owners cannot modify objects\n- [ ] Non-admins cannot call admin functions\n- [ ] Unauthorized users blocked\n\n**Input Validation:**\n\n- [ ] Zero amounts rejected\n- [ ] Excessive amounts rejected\n- [ ] Empty strings rejected\n- [ ] Strings too long rejected\n- [ ] Zero addresses rejected\n\n**Edge Cases:**\n\n- [ ] Maximum values work\n- [ ] Minimum values work\n- [ ] Empty states handled\n\n**Coverage:**\n\n- [ ] 100% line coverage achieved\n- [ ] All error codes tested\n- [ ] All functions tested\n\n## ALWAYS Rules\n\n- ✅ ALWAYS achieve 100% test coverage\n- ✅ ALWAYS test error paths with `#[expected_failure(abort_code = E_CODE)]`\n- ✅ ALWAYS test access control with multiple signers\n- ✅ ALWAYS test input validation with invalid inputs\n- ✅ ALWAYS test edge cases (boundaries, limits, empty states)\n- ✅ ALWAYS use clear test names: `test_feature_scenario`\n- ✅ ALWAYS verify all state changes in tests\n- ✅ ALWAYS run `aptos move test --coverage` before deployment\n\n## NEVER Rules\n\n- ❌ NEVER deploy without 100% coverage\n- ❌ NEVER skip testing error paths\n- ❌ NEVER skip access control tests\n- ❌ NEVER use unclear test names\n- ❌ NEVER batch tests without verifying each case\n- ❌ NEVER hardcode real private keys or account addresses in test code — use test addresses like `@0x1`, `@0x100`,\n  `@0xCAFE`\n- ❌ NEVER read `.env` or `~\u002F.aptos\u002Fconfig.yaml` to get test addresses\n\n## Common Pitfalls\n\n### Struct Field Access Across Modules\n\n**Problem:** Test modules cannot access struct fields from other modules directly.\n\n```move\n\u002F\u002F ❌ WRONG - Will NOT compile\nlet listing = marketplace::get_listing(nft_addr);\nassert!(listing.price == 1000, 0);  \u002F\u002F ERROR: field access not allowed\n```\n\n**Solution:** Use public view accessor functions from the main module.\n\n```move\n\u002F\u002F ✅ CORRECT - Use accessor function\nlet (seller, price, timestamp) = marketplace::get_listing_details(nft_addr);\nassert!(price == 1000, 0);\n```\n\nIf the module doesn't have accessors, add them:\n\n```move\n\u002F\u002F In main module\n#[view]\npublic fun get_listing_details(nft_addr: address): (address, u64, u64) acquires Listings {\n    let listing = table::borrow(&listings.items, nft_addr);\n    (listing.seller, listing.price, listing.listed_at)\n}\n```\n\n### Escrow Pattern Error Expectations\n\n**Problem:** After listing an NFT to escrow, the seller no longer owns it.\n\n```move\n\u002F\u002F ❌ WRONG expectation\n#[expected_failure(abort_code = marketplace::E_ALREADY_LISTED)]\npublic fun test_cannot_list_twice(seller: &signer) {\n    list_nft(seller, nft, 1000);  \u002F\u002F NFT transfers to marketplace\n    list_nft(seller, nft, 2000);  \u002F\u002F Fails with E_NOT_OWNER, not E_ALREADY_LISTED!\n}\n```\n\n**Solution:** Understand validation order - ownership is checked before listing status.\n\n```move\n\u002F\u002F ✅ CORRECT expectation\n#[expected_failure(abort_code = marketplace::E_NOT_OWNER)]\npublic fun test_cannot_list_twice(seller: &signer) {\n    list_nft(seller, nft, 1000);  \u002F\u002F NFT transfers to marketplace\n    list_nft(seller, nft, 2000);  \u002F\u002F Seller doesn't own it -> E_NOT_OWNER\n}\n```\n\n### Acquires Annotation Errors\n\n**Problem:** Adding acquires for resources borrowed by framework functions causes errors.\n\n```move\n\u002F\u002F ❌ WRONG - framework handles its own acquires\npublic entry fun stake(...) acquires VaultConfig, Stakes, StakeTokenRefs {\n    primary_fungible_store::transfer(...);  \u002F\u002F Don't list what framework borrows\n}\n```\n\n**Solution:** Only list resources YOUR code borrows.\n\n```move\n\u002F\u002F ✅ CORRECT\npublic entry fun stake(...) acquires VaultConfig, Stakes {\n    let config = borrow_global\u003CVaultConfig>(...);  \u002F\u002F You borrow this\n    primary_fungible_store::transfer(...);          \u002F\u002F Framework handles its own\n}\n```\n\n## References\n\n**Pattern Documentation:**\n\n- `..\u002F..\u002F..\u002Fpatterns\u002Fmove\u002FTESTING.md` - Comprehensive testing guide (see Pattern 8 for cross-module issues)\n- `..\u002F..\u002F..\u002Fpatterns\u002Fmove\u002FSECURITY.md` - Security testing requirements\n\n**Official Documentation:**\n\n- https:\u002F\u002Faptos.dev\u002Fbuild\u002Fsmart-contracts\u002Fbook\u002Funit-testing\n\n**Related Skills:**\n\n- `write-contracts` - Generate code to test\n- `security-audit` - Verify security after testing\n\n---\n\n**Remember:** 100% coverage is mandatory. Test happy paths, error paths, access control, and edge cases.\n",{"data":37,"body":46},{"name":4,"description":6,"license":26,"metadata":38},{"author":11,"version":39,"category":40,"tags":41,"priority":45},"1.0","move",[22,42,43,44],"unit-tests","coverage","quality","critical",{"type":47,"children":48},"root",[49,58,65,79,104,114,120,127,377,383,391,734,740,748,1017,1023,1031,1309,1315,1323,1533,1539,1547,1718,1726,1736,1744,1763,1769,2098,2104,2109,2117,2161,2169,2200,2208,2257,2265,2296,2304,2335,2341,2404,2410,2486,2492,2498,2508,2539,2549,2580,2585,2639,2645,2654,2708,2717,2769,2775,2784,2822,2831,2877,2883,2891,2916,2924,2938,2946,2971,2975,2985],{"type":50,"tag":51,"props":52,"children":54},"element","h1",{"id":53},"generate-tests-skill",[55],{"type":56,"value":57},"text","Generate Tests Skill",{"type":50,"tag":59,"props":60,"children":62},"h2",{"id":61},"overview",[63],{"type":56,"value":64},"Overview",{"type":50,"tag":66,"props":67,"children":68},"p",{},[69,71,77],{"type":56,"value":70},"This skill generates comprehensive test suites for Move contracts with ",{"type":50,"tag":72,"props":73,"children":74},"strong",{},[75],{"type":56,"value":76},"100% line coverage",{"type":56,"value":78}," requirement. Tests verify:",{"type":50,"tag":80,"props":81,"children":82},"ul",{},[83,89,94,99],{"type":50,"tag":84,"props":85,"children":86},"li",{},[87],{"type":56,"value":88},"✅ Happy paths (functionality works)",{"type":50,"tag":84,"props":90,"children":91},{},[92],{"type":56,"value":93},"✅ Access control (unauthorized users blocked)",{"type":50,"tag":84,"props":95,"children":96},{},[97],{"type":56,"value":98},"✅ Input validation (invalid inputs rejected)",{"type":50,"tag":84,"props":100,"children":101},{},[102],{"type":56,"value":103},"✅ Edge cases (boundaries, limits, empty states)",{"type":50,"tag":66,"props":105,"children":106},{},[107,112],{"type":50,"tag":72,"props":108,"children":109},{},[110],{"type":56,"value":111},"Critical Rule:",{"type":56,"value":113}," NEVER deploy without 100% test coverage.",{"type":50,"tag":59,"props":115,"children":117},{"id":116},"core-workflow",[118],{"type":56,"value":119},"Core Workflow",{"type":50,"tag":121,"props":122,"children":124},"h3",{"id":123},"step-1-create-test-module",[125],{"type":56,"value":126},"Step 1: Create Test Module",{"type":50,"tag":128,"props":129,"children":133},"pre",{"className":130,"code":131,"language":40,"meta":132,"style":132},"language-move shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","#[test_only]\nmodule my_addr::my_module_tests {\n    use my_addr::my_module::{Self, MyObject};\n    use aptos_framework::object::{Self, Object};\n    use std::string;\n    use std::signer;\n\n    \u002F\u002F Test constants\n    const ADMIN_ADDR: address = @0x100;\n    const USER_ADDR: address = @0x200;\n    const ATTACKER_ADDR: address = @0x300;\n\n    \u002F\u002F ========== Setup Helpers ==========\n    \u002F\u002F (Reusable setup functions)\n\n    \u002F\u002F ========== Happy Path Tests ==========\n    \u002F\u002F (Basic functionality)\n\n    \u002F\u002F ========== Access Control Tests ==========\n    \u002F\u002F (Unauthorized access blocked)\n\n    \u002F\u002F ========== Input Validation Tests ==========\n    \u002F\u002F (Invalid inputs rejected)\n\n    \u002F\u002F ========== Edge Case Tests ==========\n    \u002F\u002F (Boundaries and limits)\n}\n","",[134],{"type":50,"tag":135,"props":136,"children":137},"code",{"__ignoreMap":132},[138,149,158,167,176,185,194,204,212,221,230,239,247,256,265,273,282,291,298,307,316,324,333,342,350,359,368],{"type":50,"tag":139,"props":140,"children":143},"span",{"class":141,"line":142},"line",1,[144],{"type":50,"tag":139,"props":145,"children":146},{},[147],{"type":56,"value":148},"#[test_only]\n",{"type":50,"tag":139,"props":150,"children":152},{"class":141,"line":151},2,[153],{"type":50,"tag":139,"props":154,"children":155},{},[156],{"type":56,"value":157},"module my_addr::my_module_tests {\n",{"type":50,"tag":139,"props":159,"children":161},{"class":141,"line":160},3,[162],{"type":50,"tag":139,"props":163,"children":164},{},[165],{"type":56,"value":166},"    use my_addr::my_module::{Self, MyObject};\n",{"type":50,"tag":139,"props":168,"children":170},{"class":141,"line":169},4,[171],{"type":50,"tag":139,"props":172,"children":173},{},[174],{"type":56,"value":175},"    use aptos_framework::object::{Self, Object};\n",{"type":50,"tag":139,"props":177,"children":179},{"class":141,"line":178},5,[180],{"type":50,"tag":139,"props":181,"children":182},{},[183],{"type":56,"value":184},"    use std::string;\n",{"type":50,"tag":139,"props":186,"children":188},{"class":141,"line":187},6,[189],{"type":50,"tag":139,"props":190,"children":191},{},[192],{"type":56,"value":193},"    use std::signer;\n",{"type":50,"tag":139,"props":195,"children":197},{"class":141,"line":196},7,[198],{"type":50,"tag":139,"props":199,"children":201},{"emptyLinePlaceholder":200},true,[202],{"type":56,"value":203},"\n",{"type":50,"tag":139,"props":205,"children":206},{"class":141,"line":27},[207],{"type":50,"tag":139,"props":208,"children":209},{},[210],{"type":56,"value":211},"    \u002F\u002F Test constants\n",{"type":50,"tag":139,"props":213,"children":215},{"class":141,"line":214},9,[216],{"type":50,"tag":139,"props":217,"children":218},{},[219],{"type":56,"value":220},"    const ADMIN_ADDR: address = @0x100;\n",{"type":50,"tag":139,"props":222,"children":224},{"class":141,"line":223},10,[225],{"type":50,"tag":139,"props":226,"children":227},{},[228],{"type":56,"value":229},"    const USER_ADDR: address = @0x200;\n",{"type":50,"tag":139,"props":231,"children":233},{"class":141,"line":232},11,[234],{"type":50,"tag":139,"props":235,"children":236},{},[237],{"type":56,"value":238},"    const ATTACKER_ADDR: address = @0x300;\n",{"type":50,"tag":139,"props":240,"children":242},{"class":141,"line":241},12,[243],{"type":50,"tag":139,"props":244,"children":245},{"emptyLinePlaceholder":200},[246],{"type":56,"value":203},{"type":50,"tag":139,"props":248,"children":250},{"class":141,"line":249},13,[251],{"type":50,"tag":139,"props":252,"children":253},{},[254],{"type":56,"value":255},"    \u002F\u002F ========== Setup Helpers ==========\n",{"type":50,"tag":139,"props":257,"children":259},{"class":141,"line":258},14,[260],{"type":50,"tag":139,"props":261,"children":262},{},[263],{"type":56,"value":264},"    \u002F\u002F (Reusable setup functions)\n",{"type":50,"tag":139,"props":266,"children":268},{"class":141,"line":267},15,[269],{"type":50,"tag":139,"props":270,"children":271},{"emptyLinePlaceholder":200},[272],{"type":56,"value":203},{"type":50,"tag":139,"props":274,"children":276},{"class":141,"line":275},16,[277],{"type":50,"tag":139,"props":278,"children":279},{},[280],{"type":56,"value":281},"    \u002F\u002F ========== Happy Path Tests ==========\n",{"type":50,"tag":139,"props":283,"children":285},{"class":141,"line":284},17,[286],{"type":50,"tag":139,"props":287,"children":288},{},[289],{"type":56,"value":290},"    \u002F\u002F (Basic functionality)\n",{"type":50,"tag":139,"props":292,"children":293},{"class":141,"line":23},[294],{"type":50,"tag":139,"props":295,"children":296},{"emptyLinePlaceholder":200},[297],{"type":56,"value":203},{"type":50,"tag":139,"props":299,"children":301},{"class":141,"line":300},19,[302],{"type":50,"tag":139,"props":303,"children":304},{},[305],{"type":56,"value":306},"    \u002F\u002F ========== Access Control Tests ==========\n",{"type":50,"tag":139,"props":308,"children":310},{"class":141,"line":309},20,[311],{"type":50,"tag":139,"props":312,"children":313},{},[314],{"type":56,"value":315},"    \u002F\u002F (Unauthorized access blocked)\n",{"type":50,"tag":139,"props":317,"children":319},{"class":141,"line":318},21,[320],{"type":50,"tag":139,"props":321,"children":322},{"emptyLinePlaceholder":200},[323],{"type":56,"value":203},{"type":50,"tag":139,"props":325,"children":327},{"class":141,"line":326},22,[328],{"type":50,"tag":139,"props":329,"children":330},{},[331],{"type":56,"value":332},"    \u002F\u002F ========== Input Validation Tests ==========\n",{"type":50,"tag":139,"props":334,"children":336},{"class":141,"line":335},23,[337],{"type":50,"tag":139,"props":338,"children":339},{},[340],{"type":56,"value":341},"    \u002F\u002F (Invalid inputs rejected)\n",{"type":50,"tag":139,"props":343,"children":345},{"class":141,"line":344},24,[346],{"type":50,"tag":139,"props":347,"children":348},{"emptyLinePlaceholder":200},[349],{"type":56,"value":203},{"type":50,"tag":139,"props":351,"children":353},{"class":141,"line":352},25,[354],{"type":50,"tag":139,"props":355,"children":356},{},[357],{"type":56,"value":358},"    \u002F\u002F ========== Edge Case Tests ==========\n",{"type":50,"tag":139,"props":360,"children":362},{"class":141,"line":361},26,[363],{"type":50,"tag":139,"props":364,"children":365},{},[366],{"type":56,"value":367},"    \u002F\u002F (Boundaries and limits)\n",{"type":50,"tag":139,"props":369,"children":371},{"class":141,"line":370},27,[372],{"type":50,"tag":139,"props":373,"children":374},{},[375],{"type":56,"value":376},"}\n",{"type":50,"tag":121,"props":378,"children":380},{"id":379},"step-2-write-happy-path-tests",[381],{"type":56,"value":382},"Step 2: Write Happy Path Tests",{"type":50,"tag":66,"props":384,"children":385},{},[386],{"type":50,"tag":72,"props":387,"children":388},{},[389],{"type":56,"value":390},"Test basic functionality works correctly:",{"type":50,"tag":128,"props":392,"children":394},{"className":130,"code":393,"language":40,"meta":132,"style":132},"#[test(creator = @0x1)]\npublic fun test_create_object_succeeds(creator: &signer) {\n    \u002F\u002F Execute\n    let obj = my_module::create_my_object(\n        creator,\n        string::utf8(b\"Test Object\")\n    );\n\n    \u002F\u002F Verify\n    assert!(object::owner(obj) == signer::address_of(creator), 0);\n}\n\n#[test(owner = @0x1)]\npublic fun test_update_object_succeeds(owner: &signer) {\n    \u002F\u002F Setup\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Old Name\"));\n\n    \u002F\u002F Execute\n    let new_name = string::utf8(b\"New Name\");\n    my_module::update_object(owner, obj, new_name);\n\n    \u002F\u002F Verify (if you have view functions)\n    \u002F\u002F assert!(my_module::get_object_name(obj) == new_name, 0);\n}\n\n#[test(owner = @0x1, recipient = @0x2)]\npublic fun test_transfer_object_succeeds(\n    owner: &signer,\n    recipient: &signer\n) {\n    let recipient_addr = signer::address_of(recipient);\n\n    \u002F\u002F Setup\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Object\"));\n    assert!(object::owner(obj) == signer::address_of(owner), 0);\n\n    \u002F\u002F Execute\n    my_module::transfer_object(owner, obj, recipient_addr);\n\n    \u002F\u002F Verify\n    assert!(object::owner(obj) == recipient_addr, 1);\n}\n",[395],{"type":50,"tag":135,"props":396,"children":397},{"__ignoreMap":132},[398,406,414,422,430,438,446,454,461,469,477,484,491,499,507,515,523,530,537,545,553,560,568,576,583,590,598,606,615,624,633,642,650,658,667,676,684,692,701,709,717,726],{"type":50,"tag":139,"props":399,"children":400},{"class":141,"line":142},[401],{"type":50,"tag":139,"props":402,"children":403},{},[404],{"type":56,"value":405},"#[test(creator = @0x1)]\n",{"type":50,"tag":139,"props":407,"children":408},{"class":141,"line":151},[409],{"type":50,"tag":139,"props":410,"children":411},{},[412],{"type":56,"value":413},"public fun test_create_object_succeeds(creator: &signer) {\n",{"type":50,"tag":139,"props":415,"children":416},{"class":141,"line":160},[417],{"type":50,"tag":139,"props":418,"children":419},{},[420],{"type":56,"value":421},"    \u002F\u002F Execute\n",{"type":50,"tag":139,"props":423,"children":424},{"class":141,"line":169},[425],{"type":50,"tag":139,"props":426,"children":427},{},[428],{"type":56,"value":429},"    let obj = my_module::create_my_object(\n",{"type":50,"tag":139,"props":431,"children":432},{"class":141,"line":178},[433],{"type":50,"tag":139,"props":434,"children":435},{},[436],{"type":56,"value":437},"        creator,\n",{"type":50,"tag":139,"props":439,"children":440},{"class":141,"line":187},[441],{"type":50,"tag":139,"props":442,"children":443},{},[444],{"type":56,"value":445},"        string::utf8(b\"Test Object\")\n",{"type":50,"tag":139,"props":447,"children":448},{"class":141,"line":196},[449],{"type":50,"tag":139,"props":450,"children":451},{},[452],{"type":56,"value":453},"    );\n",{"type":50,"tag":139,"props":455,"children":456},{"class":141,"line":27},[457],{"type":50,"tag":139,"props":458,"children":459},{"emptyLinePlaceholder":200},[460],{"type":56,"value":203},{"type":50,"tag":139,"props":462,"children":463},{"class":141,"line":214},[464],{"type":50,"tag":139,"props":465,"children":466},{},[467],{"type":56,"value":468},"    \u002F\u002F Verify\n",{"type":50,"tag":139,"props":470,"children":471},{"class":141,"line":223},[472],{"type":50,"tag":139,"props":473,"children":474},{},[475],{"type":56,"value":476},"    assert!(object::owner(obj) == signer::address_of(creator), 0);\n",{"type":50,"tag":139,"props":478,"children":479},{"class":141,"line":232},[480],{"type":50,"tag":139,"props":481,"children":482},{},[483],{"type":56,"value":376},{"type":50,"tag":139,"props":485,"children":486},{"class":141,"line":241},[487],{"type":50,"tag":139,"props":488,"children":489},{"emptyLinePlaceholder":200},[490],{"type":56,"value":203},{"type":50,"tag":139,"props":492,"children":493},{"class":141,"line":249},[494],{"type":50,"tag":139,"props":495,"children":496},{},[497],{"type":56,"value":498},"#[test(owner = @0x1)]\n",{"type":50,"tag":139,"props":500,"children":501},{"class":141,"line":258},[502],{"type":50,"tag":139,"props":503,"children":504},{},[505],{"type":56,"value":506},"public fun test_update_object_succeeds(owner: &signer) {\n",{"type":50,"tag":139,"props":508,"children":509},{"class":141,"line":267},[510],{"type":50,"tag":139,"props":511,"children":512},{},[513],{"type":56,"value":514},"    \u002F\u002F Setup\n",{"type":50,"tag":139,"props":516,"children":517},{"class":141,"line":275},[518],{"type":50,"tag":139,"props":519,"children":520},{},[521],{"type":56,"value":522},"    let obj = my_module::create_my_object(owner, string::utf8(b\"Old Name\"));\n",{"type":50,"tag":139,"props":524,"children":525},{"class":141,"line":284},[526],{"type":50,"tag":139,"props":527,"children":528},{"emptyLinePlaceholder":200},[529],{"type":56,"value":203},{"type":50,"tag":139,"props":531,"children":532},{"class":141,"line":23},[533],{"type":50,"tag":139,"props":534,"children":535},{},[536],{"type":56,"value":421},{"type":50,"tag":139,"props":538,"children":539},{"class":141,"line":300},[540],{"type":50,"tag":139,"props":541,"children":542},{},[543],{"type":56,"value":544},"    let new_name = string::utf8(b\"New Name\");\n",{"type":50,"tag":139,"props":546,"children":547},{"class":141,"line":309},[548],{"type":50,"tag":139,"props":549,"children":550},{},[551],{"type":56,"value":552},"    my_module::update_object(owner, obj, new_name);\n",{"type":50,"tag":139,"props":554,"children":555},{"class":141,"line":318},[556],{"type":50,"tag":139,"props":557,"children":558},{"emptyLinePlaceholder":200},[559],{"type":56,"value":203},{"type":50,"tag":139,"props":561,"children":562},{"class":141,"line":326},[563],{"type":50,"tag":139,"props":564,"children":565},{},[566],{"type":56,"value":567},"    \u002F\u002F Verify (if you have view functions)\n",{"type":50,"tag":139,"props":569,"children":570},{"class":141,"line":335},[571],{"type":50,"tag":139,"props":572,"children":573},{},[574],{"type":56,"value":575},"    \u002F\u002F assert!(my_module::get_object_name(obj) == new_name, 0);\n",{"type":50,"tag":139,"props":577,"children":578},{"class":141,"line":344},[579],{"type":50,"tag":139,"props":580,"children":581},{},[582],{"type":56,"value":376},{"type":50,"tag":139,"props":584,"children":585},{"class":141,"line":352},[586],{"type":50,"tag":139,"props":587,"children":588},{"emptyLinePlaceholder":200},[589],{"type":56,"value":203},{"type":50,"tag":139,"props":591,"children":592},{"class":141,"line":361},[593],{"type":50,"tag":139,"props":594,"children":595},{},[596],{"type":56,"value":597},"#[test(owner = @0x1, recipient = @0x2)]\n",{"type":50,"tag":139,"props":599,"children":600},{"class":141,"line":370},[601],{"type":50,"tag":139,"props":602,"children":603},{},[604],{"type":56,"value":605},"public fun test_transfer_object_succeeds(\n",{"type":50,"tag":139,"props":607,"children":609},{"class":141,"line":608},28,[610],{"type":50,"tag":139,"props":611,"children":612},{},[613],{"type":56,"value":614},"    owner: &signer,\n",{"type":50,"tag":139,"props":616,"children":618},{"class":141,"line":617},29,[619],{"type":50,"tag":139,"props":620,"children":621},{},[622],{"type":56,"value":623},"    recipient: &signer\n",{"type":50,"tag":139,"props":625,"children":627},{"class":141,"line":626},30,[628],{"type":50,"tag":139,"props":629,"children":630},{},[631],{"type":56,"value":632},") {\n",{"type":50,"tag":139,"props":634,"children":636},{"class":141,"line":635},31,[637],{"type":50,"tag":139,"props":638,"children":639},{},[640],{"type":56,"value":641},"    let recipient_addr = signer::address_of(recipient);\n",{"type":50,"tag":139,"props":643,"children":645},{"class":141,"line":644},32,[646],{"type":50,"tag":139,"props":647,"children":648},{"emptyLinePlaceholder":200},[649],{"type":56,"value":203},{"type":50,"tag":139,"props":651,"children":653},{"class":141,"line":652},33,[654],{"type":50,"tag":139,"props":655,"children":656},{},[657],{"type":56,"value":514},{"type":50,"tag":139,"props":659,"children":661},{"class":141,"line":660},34,[662],{"type":50,"tag":139,"props":663,"children":664},{},[665],{"type":56,"value":666},"    let obj = my_module::create_my_object(owner, string::utf8(b\"Object\"));\n",{"type":50,"tag":139,"props":668,"children":670},{"class":141,"line":669},35,[671],{"type":50,"tag":139,"props":672,"children":673},{},[674],{"type":56,"value":675},"    assert!(object::owner(obj) == signer::address_of(owner), 0);\n",{"type":50,"tag":139,"props":677,"children":679},{"class":141,"line":678},36,[680],{"type":50,"tag":139,"props":681,"children":682},{"emptyLinePlaceholder":200},[683],{"type":56,"value":203},{"type":50,"tag":139,"props":685,"children":687},{"class":141,"line":686},37,[688],{"type":50,"tag":139,"props":689,"children":690},{},[691],{"type":56,"value":421},{"type":50,"tag":139,"props":693,"children":695},{"class":141,"line":694},38,[696],{"type":50,"tag":139,"props":697,"children":698},{},[699],{"type":56,"value":700},"    my_module::transfer_object(owner, obj, recipient_addr);\n",{"type":50,"tag":139,"props":702,"children":704},{"class":141,"line":703},39,[705],{"type":50,"tag":139,"props":706,"children":707},{"emptyLinePlaceholder":200},[708],{"type":56,"value":203},{"type":50,"tag":139,"props":710,"children":712},{"class":141,"line":711},40,[713],{"type":50,"tag":139,"props":714,"children":715},{},[716],{"type":56,"value":468},{"type":50,"tag":139,"props":718,"children":720},{"class":141,"line":719},41,[721],{"type":50,"tag":139,"props":722,"children":723},{},[724],{"type":56,"value":725},"    assert!(object::owner(obj) == recipient_addr, 1);\n",{"type":50,"tag":139,"props":727,"children":729},{"class":141,"line":728},42,[730],{"type":50,"tag":139,"props":731,"children":732},{},[733],{"type":56,"value":376},{"type":50,"tag":121,"props":735,"children":737},{"id":736},"step-3-write-access-control-tests",[738],{"type":56,"value":739},"Step 3: Write Access Control Tests",{"type":50,"tag":66,"props":741,"children":742},{},[743],{"type":50,"tag":72,"props":744,"children":745},{},[746],{"type":56,"value":747},"Test unauthorized access is blocked:",{"type":50,"tag":128,"props":749,"children":751},{"className":130,"code":750,"language":40,"meta":132,"style":132},"#[test(owner = @0x1, attacker = @0x2)]\n#[expected_failure(abort_code = my_module::E_NOT_OWNER)]\npublic fun test_non_owner_cannot_update(\n    owner: &signer,\n    attacker: &signer\n) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Object\"));\n\n    \u002F\u002F Attacker tries to update (should abort)\n    my_module::update_object(attacker, obj, string::utf8(b\"Hacked\"));\n}\n\n#[test(owner = @0x1, attacker = @0x2)]\n#[expected_failure(abort_code = my_module::E_NOT_OWNER)]\npublic fun test_non_owner_cannot_transfer(\n    owner: &signer,\n    attacker: &signer\n) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Object\"));\n\n    \u002F\u002F Attacker tries to transfer (should abort)\n    my_module::transfer_object(attacker, obj, @0x3);\n}\n\n#[test(admin = @0x1, user = @0x2)]\n#[expected_failure(abort_code = my_module::E_NOT_ADMIN)]\npublic fun test_non_admin_cannot_configure(\n    admin: &signer,\n    user: &signer\n) {\n    my_module::init_module(admin);\n\n    \u002F\u002F Regular user tries admin function (should abort)\n    my_module::update_config(user, 100);\n}\n",[752],{"type":50,"tag":135,"props":753,"children":754},{"__ignoreMap":132},[755,763,771,779,786,794,801,808,815,823,831,838,845,852,859,867,874,881,888,895,902,910,918,925,932,940,948,956,964,972,979,987,994,1002,1010],{"type":50,"tag":139,"props":756,"children":757},{"class":141,"line":142},[758],{"type":50,"tag":139,"props":759,"children":760},{},[761],{"type":56,"value":762},"#[test(owner = @0x1, attacker = @0x2)]\n",{"type":50,"tag":139,"props":764,"children":765},{"class":141,"line":151},[766],{"type":50,"tag":139,"props":767,"children":768},{},[769],{"type":56,"value":770},"#[expected_failure(abort_code = my_module::E_NOT_OWNER)]\n",{"type":50,"tag":139,"props":772,"children":773},{"class":141,"line":160},[774],{"type":50,"tag":139,"props":775,"children":776},{},[777],{"type":56,"value":778},"public fun test_non_owner_cannot_update(\n",{"type":50,"tag":139,"props":780,"children":781},{"class":141,"line":169},[782],{"type":50,"tag":139,"props":783,"children":784},{},[785],{"type":56,"value":614},{"type":50,"tag":139,"props":787,"children":788},{"class":141,"line":178},[789],{"type":50,"tag":139,"props":790,"children":791},{},[792],{"type":56,"value":793},"    attacker: &signer\n",{"type":50,"tag":139,"props":795,"children":796},{"class":141,"line":187},[797],{"type":50,"tag":139,"props":798,"children":799},{},[800],{"type":56,"value":632},{"type":50,"tag":139,"props":802,"children":803},{"class":141,"line":196},[804],{"type":50,"tag":139,"props":805,"children":806},{},[807],{"type":56,"value":666},{"type":50,"tag":139,"props":809,"children":810},{"class":141,"line":27},[811],{"type":50,"tag":139,"props":812,"children":813},{"emptyLinePlaceholder":200},[814],{"type":56,"value":203},{"type":50,"tag":139,"props":816,"children":817},{"class":141,"line":214},[818],{"type":50,"tag":139,"props":819,"children":820},{},[821],{"type":56,"value":822},"    \u002F\u002F Attacker tries to update (should abort)\n",{"type":50,"tag":139,"props":824,"children":825},{"class":141,"line":223},[826],{"type":50,"tag":139,"props":827,"children":828},{},[829],{"type":56,"value":830},"    my_module::update_object(attacker, obj, string::utf8(b\"Hacked\"));\n",{"type":50,"tag":139,"props":832,"children":833},{"class":141,"line":232},[834],{"type":50,"tag":139,"props":835,"children":836},{},[837],{"type":56,"value":376},{"type":50,"tag":139,"props":839,"children":840},{"class":141,"line":241},[841],{"type":50,"tag":139,"props":842,"children":843},{"emptyLinePlaceholder":200},[844],{"type":56,"value":203},{"type":50,"tag":139,"props":846,"children":847},{"class":141,"line":249},[848],{"type":50,"tag":139,"props":849,"children":850},{},[851],{"type":56,"value":762},{"type":50,"tag":139,"props":853,"children":854},{"class":141,"line":258},[855],{"type":50,"tag":139,"props":856,"children":857},{},[858],{"type":56,"value":770},{"type":50,"tag":139,"props":860,"children":861},{"class":141,"line":267},[862],{"type":50,"tag":139,"props":863,"children":864},{},[865],{"type":56,"value":866},"public fun test_non_owner_cannot_transfer(\n",{"type":50,"tag":139,"props":868,"children":869},{"class":141,"line":275},[870],{"type":50,"tag":139,"props":871,"children":872},{},[873],{"type":56,"value":614},{"type":50,"tag":139,"props":875,"children":876},{"class":141,"line":284},[877],{"type":50,"tag":139,"props":878,"children":879},{},[880],{"type":56,"value":793},{"type":50,"tag":139,"props":882,"children":883},{"class":141,"line":23},[884],{"type":50,"tag":139,"props":885,"children":886},{},[887],{"type":56,"value":632},{"type":50,"tag":139,"props":889,"children":890},{"class":141,"line":300},[891],{"type":50,"tag":139,"props":892,"children":893},{},[894],{"type":56,"value":666},{"type":50,"tag":139,"props":896,"children":897},{"class":141,"line":309},[898],{"type":50,"tag":139,"props":899,"children":900},{"emptyLinePlaceholder":200},[901],{"type":56,"value":203},{"type":50,"tag":139,"props":903,"children":904},{"class":141,"line":318},[905],{"type":50,"tag":139,"props":906,"children":907},{},[908],{"type":56,"value":909},"    \u002F\u002F Attacker tries to transfer (should abort)\n",{"type":50,"tag":139,"props":911,"children":912},{"class":141,"line":326},[913],{"type":50,"tag":139,"props":914,"children":915},{},[916],{"type":56,"value":917},"    my_module::transfer_object(attacker, obj, @0x3);\n",{"type":50,"tag":139,"props":919,"children":920},{"class":141,"line":335},[921],{"type":50,"tag":139,"props":922,"children":923},{},[924],{"type":56,"value":376},{"type":50,"tag":139,"props":926,"children":927},{"class":141,"line":344},[928],{"type":50,"tag":139,"props":929,"children":930},{"emptyLinePlaceholder":200},[931],{"type":56,"value":203},{"type":50,"tag":139,"props":933,"children":934},{"class":141,"line":352},[935],{"type":50,"tag":139,"props":936,"children":937},{},[938],{"type":56,"value":939},"#[test(admin = @0x1, user = @0x2)]\n",{"type":50,"tag":139,"props":941,"children":942},{"class":141,"line":361},[943],{"type":50,"tag":139,"props":944,"children":945},{},[946],{"type":56,"value":947},"#[expected_failure(abort_code = my_module::E_NOT_ADMIN)]\n",{"type":50,"tag":139,"props":949,"children":950},{"class":141,"line":370},[951],{"type":50,"tag":139,"props":952,"children":953},{},[954],{"type":56,"value":955},"public fun test_non_admin_cannot_configure(\n",{"type":50,"tag":139,"props":957,"children":958},{"class":141,"line":608},[959],{"type":50,"tag":139,"props":960,"children":961},{},[962],{"type":56,"value":963},"    admin: &signer,\n",{"type":50,"tag":139,"props":965,"children":966},{"class":141,"line":617},[967],{"type":50,"tag":139,"props":968,"children":969},{},[970],{"type":56,"value":971},"    user: &signer\n",{"type":50,"tag":139,"props":973,"children":974},{"class":141,"line":626},[975],{"type":50,"tag":139,"props":976,"children":977},{},[978],{"type":56,"value":632},{"type":50,"tag":139,"props":980,"children":981},{"class":141,"line":635},[982],{"type":50,"tag":139,"props":983,"children":984},{},[985],{"type":56,"value":986},"    my_module::init_module(admin);\n",{"type":50,"tag":139,"props":988,"children":989},{"class":141,"line":644},[990],{"type":50,"tag":139,"props":991,"children":992},{"emptyLinePlaceholder":200},[993],{"type":56,"value":203},{"type":50,"tag":139,"props":995,"children":996},{"class":141,"line":652},[997],{"type":50,"tag":139,"props":998,"children":999},{},[1000],{"type":56,"value":1001},"    \u002F\u002F Regular user tries admin function (should abort)\n",{"type":50,"tag":139,"props":1003,"children":1004},{"class":141,"line":660},[1005],{"type":50,"tag":139,"props":1006,"children":1007},{},[1008],{"type":56,"value":1009},"    my_module::update_config(user, 100);\n",{"type":50,"tag":139,"props":1011,"children":1012},{"class":141,"line":669},[1013],{"type":50,"tag":139,"props":1014,"children":1015},{},[1016],{"type":56,"value":376},{"type":50,"tag":121,"props":1018,"children":1020},{"id":1019},"step-4-write-input-validation-tests",[1021],{"type":56,"value":1022},"Step 4: Write Input Validation Tests",{"type":50,"tag":66,"props":1024,"children":1025},{},[1026],{"type":50,"tag":72,"props":1027,"children":1028},{},[1029],{"type":56,"value":1030},"Test invalid inputs are rejected:",{"type":50,"tag":128,"props":1032,"children":1034},{"className":130,"code":1033,"language":40,"meta":132,"style":132},"#[test(user = @0x1)]\n#[expected_failure(abort_code = my_module::E_ZERO_AMOUNT)]\npublic fun test_zero_amount_rejected(user: &signer) {\n    my_module::deposit(user, 0); \u002F\u002F Should abort\n}\n\n#[test(user = @0x1)]\n#[expected_failure(abort_code = my_module::E_AMOUNT_TOO_HIGH)]\npublic fun test_excessive_amount_rejected(user: &signer) {\n    my_module::deposit(user, my_module::MAX_DEPOSIT_AMOUNT + 1); \u002F\u002F Should abort\n}\n\n#[test(owner = @0x1)]\n#[expected_failure(abort_code = my_module::E_EMPTY_NAME)]\npublic fun test_empty_string_rejected(owner: &signer) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Initial\"));\n    my_module::update_object(owner, obj, string::utf8(b\"\")); \u002F\u002F Empty - should abort\n}\n\n#[test(owner = @0x1)]\n#[expected_failure(abort_code = my_module::E_NAME_TOO_LONG)]\npublic fun test_string_too_long_rejected(owner: &signer) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Initial\"));\n\n    \u002F\u002F String exceeding MAX_NAME_LENGTH\n    let long_name = string::utf8(b\"This is an extremely long name that exceeds the maximum allowed length\");\n\n    my_module::update_object(owner, obj, long_name); \u002F\u002F Should abort\n}\n\n#[test(owner = @0x1)]\n#[expected_failure(abort_code = my_module::E_ZERO_ADDRESS)]\npublic fun test_zero_address_rejected(owner: &signer) {\n    let obj = my_module::create_my_object(owner, string::utf8(b\"Object\"));\n    my_module::transfer_object(owner, obj, @0x0); \u002F\u002F Should abort\n}\n",[1035],{"type":50,"tag":135,"props":1036,"children":1037},{"__ignoreMap":132},[1038,1046,1054,1062,1070,1077,1084,1091,1099,1107,1115,1122,1129,1136,1144,1152,1160,1168,1175,1182,1189,1197,1205,1212,1219,1227,1235,1242,1250,1257,1264,1271,1279,1287,1294,1302],{"type":50,"tag":139,"props":1039,"children":1040},{"class":141,"line":142},[1041],{"type":50,"tag":139,"props":1042,"children":1043},{},[1044],{"type":56,"value":1045},"#[test(user = @0x1)]\n",{"type":50,"tag":139,"props":1047,"children":1048},{"class":141,"line":151},[1049],{"type":50,"tag":139,"props":1050,"children":1051},{},[1052],{"type":56,"value":1053},"#[expected_failure(abort_code = my_module::E_ZERO_AMOUNT)]\n",{"type":50,"tag":139,"props":1055,"children":1056},{"class":141,"line":160},[1057],{"type":50,"tag":139,"props":1058,"children":1059},{},[1060],{"type":56,"value":1061},"public fun test_zero_amount_rejected(user: &signer) {\n",{"type":50,"tag":139,"props":1063,"children":1064},{"class":141,"line":169},[1065],{"type":50,"tag":139,"props":1066,"children":1067},{},[1068],{"type":56,"value":1069},"    my_module::deposit(user, 0); \u002F\u002F Should abort\n",{"type":50,"tag":139,"props":1071,"children":1072},{"class":141,"line":178},[1073],{"type":50,"tag":139,"props":1074,"children":1075},{},[1076],{"type":56,"value":376},{"type":50,"tag":139,"props":1078,"children":1079},{"class":141,"line":187},[1080],{"type":50,"tag":139,"props":1081,"children":1082},{"emptyLinePlaceholder":200},[1083],{"type":56,"value":203},{"type":50,"tag":139,"props":1085,"children":1086},{"class":141,"line":196},[1087],{"type":50,"tag":139,"props":1088,"children":1089},{},[1090],{"type":56,"value":1045},{"type":50,"tag":139,"props":1092,"children":1093},{"class":141,"line":27},[1094],{"type":50,"tag":139,"props":1095,"children":1096},{},[1097],{"type":56,"value":1098},"#[expected_failure(abort_code = my_module::E_AMOUNT_TOO_HIGH)]\n",{"type":50,"tag":139,"props":1100,"children":1101},{"class":141,"line":214},[1102],{"type":50,"tag":139,"props":1103,"children":1104},{},[1105],{"type":56,"value":1106},"public fun test_excessive_amount_rejected(user: &signer) {\n",{"type":50,"tag":139,"props":1108,"children":1109},{"class":141,"line":223},[1110],{"type":50,"tag":139,"props":1111,"children":1112},{},[1113],{"type":56,"value":1114},"    my_module::deposit(user, my_module::MAX_DEPOSIT_AMOUNT + 1); \u002F\u002F Should abort\n",{"type":50,"tag":139,"props":1116,"children":1117},{"class":141,"line":232},[1118],{"type":50,"tag":139,"props":1119,"children":1120},{},[1121],{"type":56,"value":376},{"type":50,"tag":139,"props":1123,"children":1124},{"class":141,"line":241},[1125],{"type":50,"tag":139,"props":1126,"children":1127},{"emptyLinePlaceholder":200},[1128],{"type":56,"value":203},{"type":50,"tag":139,"props":1130,"children":1131},{"class":141,"line":249},[1132],{"type":50,"tag":139,"props":1133,"children":1134},{},[1135],{"type":56,"value":498},{"type":50,"tag":139,"props":1137,"children":1138},{"class":141,"line":258},[1139],{"type":50,"tag":139,"props":1140,"children":1141},{},[1142],{"type":56,"value":1143},"#[expected_failure(abort_code = my_module::E_EMPTY_NAME)]\n",{"type":50,"tag":139,"props":1145,"children":1146},{"class":141,"line":267},[1147],{"type":50,"tag":139,"props":1148,"children":1149},{},[1150],{"type":56,"value":1151},"public fun test_empty_string_rejected(owner: &signer) {\n",{"type":50,"tag":139,"props":1153,"children":1154},{"class":141,"line":275},[1155],{"type":50,"tag":139,"props":1156,"children":1157},{},[1158],{"type":56,"value":1159},"    let obj = my_module::create_my_object(owner, string::utf8(b\"Initial\"));\n",{"type":50,"tag":139,"props":1161,"children":1162},{"class":141,"line":284},[1163],{"type":50,"tag":139,"props":1164,"children":1165},{},[1166],{"type":56,"value":1167},"    my_module::update_object(owner, obj, string::utf8(b\"\")); \u002F\u002F Empty - should abort\n",{"type":50,"tag":139,"props":1169,"children":1170},{"class":141,"line":23},[1171],{"type":50,"tag":139,"props":1172,"children":1173},{},[1174],{"type":56,"value":376},{"type":50,"tag":139,"props":1176,"children":1177},{"class":141,"line":300},[1178],{"type":50,"tag":139,"props":1179,"children":1180},{"emptyLinePlaceholder":200},[1181],{"type":56,"value":203},{"type":50,"tag":139,"props":1183,"children":1184},{"class":141,"line":309},[1185],{"type":50,"tag":139,"props":1186,"children":1187},{},[1188],{"type":56,"value":498},{"type":50,"tag":139,"props":1190,"children":1191},{"class":141,"line":318},[1192],{"type":50,"tag":139,"props":1193,"children":1194},{},[1195],{"type":56,"value":1196},"#[expected_failure(abort_code = my_module::E_NAME_TOO_LONG)]\n",{"type":50,"tag":139,"props":1198,"children":1199},{"class":141,"line":326},[1200],{"type":50,"tag":139,"props":1201,"children":1202},{},[1203],{"type":56,"value":1204},"public fun test_string_too_long_rejected(owner: &signer) {\n",{"type":50,"tag":139,"props":1206,"children":1207},{"class":141,"line":335},[1208],{"type":50,"tag":139,"props":1209,"children":1210},{},[1211],{"type":56,"value":1159},{"type":50,"tag":139,"props":1213,"children":1214},{"class":141,"line":344},[1215],{"type":50,"tag":139,"props":1216,"children":1217},{"emptyLinePlaceholder":200},[1218],{"type":56,"value":203},{"type":50,"tag":139,"props":1220,"children":1221},{"class":141,"line":352},[1222],{"type":50,"tag":139,"props":1223,"children":1224},{},[1225],{"type":56,"value":1226},"    \u002F\u002F String exceeding MAX_NAME_LENGTH\n",{"type":50,"tag":139,"props":1228,"children":1229},{"class":141,"line":361},[1230],{"type":50,"tag":139,"props":1231,"children":1232},{},[1233],{"type":56,"value":1234},"    let long_name = string::utf8(b\"This is an extremely long name that exceeds the maximum allowed length\");\n",{"type":50,"tag":139,"props":1236,"children":1237},{"class":141,"line":370},[1238],{"type":50,"tag":139,"props":1239,"children":1240},{"emptyLinePlaceholder":200},[1241],{"type":56,"value":203},{"type":50,"tag":139,"props":1243,"children":1244},{"class":141,"line":608},[1245],{"type":50,"tag":139,"props":1246,"children":1247},{},[1248],{"type":56,"value":1249},"    my_module::update_object(owner, obj, long_name); \u002F\u002F Should abort\n",{"type":50,"tag":139,"props":1251,"children":1252},{"class":141,"line":617},[1253],{"type":50,"tag":139,"props":1254,"children":1255},{},[1256],{"type":56,"value":376},{"type":50,"tag":139,"props":1258,"children":1259},{"class":141,"line":626},[1260],{"type":50,"tag":139,"props":1261,"children":1262},{"emptyLinePlaceholder":200},[1263],{"type":56,"value":203},{"type":50,"tag":139,"props":1265,"children":1266},{"class":141,"line":635},[1267],{"type":50,"tag":139,"props":1268,"children":1269},{},[1270],{"type":56,"value":498},{"type":50,"tag":139,"props":1272,"children":1273},{"class":141,"line":644},[1274],{"type":50,"tag":139,"props":1275,"children":1276},{},[1277],{"type":56,"value":1278},"#[expected_failure(abort_code = my_module::E_ZERO_ADDRESS)]\n",{"type":50,"tag":139,"props":1280,"children":1281},{"class":141,"line":652},[1282],{"type":50,"tag":139,"props":1283,"children":1284},{},[1285],{"type":56,"value":1286},"public fun test_zero_address_rejected(owner: &signer) {\n",{"type":50,"tag":139,"props":1288,"children":1289},{"class":141,"line":660},[1290],{"type":50,"tag":139,"props":1291,"children":1292},{},[1293],{"type":56,"value":666},{"type":50,"tag":139,"props":1295,"children":1296},{"class":141,"line":669},[1297],{"type":50,"tag":139,"props":1298,"children":1299},{},[1300],{"type":56,"value":1301},"    my_module::transfer_object(owner, obj, @0x0); \u002F\u002F Should abort\n",{"type":50,"tag":139,"props":1303,"children":1304},{"class":141,"line":678},[1305],{"type":50,"tag":139,"props":1306,"children":1307},{},[1308],{"type":56,"value":376},{"type":50,"tag":121,"props":1310,"children":1312},{"id":1311},"step-5-write-edge-case-tests",[1313],{"type":56,"value":1314},"Step 5: Write Edge Case Tests",{"type":50,"tag":66,"props":1316,"children":1317},{},[1318],{"type":50,"tag":72,"props":1319,"children":1320},{},[1321],{"type":56,"value":1322},"Test boundary conditions:",{"type":50,"tag":128,"props":1324,"children":1326},{"className":130,"code":1325,"language":40,"meta":132,"style":132},"#[test(user = @0x1)]\npublic fun test_max_amount_allowed(user: &signer) {\n    my_module::init_account(user);\n\n    \u002F\u002F Exactly MAX_DEPOSIT_AMOUNT should work\n    my_module::deposit(user, my_module::MAX_DEPOSIT_AMOUNT);\n\n    \u002F\u002F Verify\n    assert!(my_module::get_balance(signer::address_of(user)) == my_module::MAX_DEPOSIT_AMOUNT, 0);\n}\n\n#[test(user = @0x1)]\npublic fun test_max_name_length_allowed(user: &signer) {\n    \u002F\u002F Create string exactly MAX_NAME_LENGTH long\n    let max_name = string::utf8(b\"12345678901234567890123456789012\"); \u002F\u002F 32 chars if MAX = 32\n\n    \u002F\u002F Should succeed\n    let obj = my_module::create_my_object(user, max_name);\n}\n\n#[test(user = @0x1)]\npublic fun test_empty_collection_operations(user: &signer) {\n    let collection = my_module::create_collection(user, string::utf8(b\"Collection\"));\n\n    \u002F\u002F Should handle empty collection gracefully\n    assert!(my_module::get_collection_size(collection) == 0, 0);\n}\n",[1327],{"type":50,"tag":135,"props":1328,"children":1329},{"__ignoreMap":132},[1330,1337,1345,1353,1360,1368,1376,1383,1390,1398,1405,1412,1419,1427,1435,1443,1450,1458,1466,1473,1480,1487,1495,1503,1510,1518,1526],{"type":50,"tag":139,"props":1331,"children":1332},{"class":141,"line":142},[1333],{"type":50,"tag":139,"props":1334,"children":1335},{},[1336],{"type":56,"value":1045},{"type":50,"tag":139,"props":1338,"children":1339},{"class":141,"line":151},[1340],{"type":50,"tag":139,"props":1341,"children":1342},{},[1343],{"type":56,"value":1344},"public fun test_max_amount_allowed(user: &signer) {\n",{"type":50,"tag":139,"props":1346,"children":1347},{"class":141,"line":160},[1348],{"type":50,"tag":139,"props":1349,"children":1350},{},[1351],{"type":56,"value":1352},"    my_module::init_account(user);\n",{"type":50,"tag":139,"props":1354,"children":1355},{"class":141,"line":169},[1356],{"type":50,"tag":139,"props":1357,"children":1358},{"emptyLinePlaceholder":200},[1359],{"type":56,"value":203},{"type":50,"tag":139,"props":1361,"children":1362},{"class":141,"line":178},[1363],{"type":50,"tag":139,"props":1364,"children":1365},{},[1366],{"type":56,"value":1367},"    \u002F\u002F Exactly MAX_DEPOSIT_AMOUNT should work\n",{"type":50,"tag":139,"props":1369,"children":1370},{"class":141,"line":187},[1371],{"type":50,"tag":139,"props":1372,"children":1373},{},[1374],{"type":56,"value":1375},"    my_module::deposit(user, my_module::MAX_DEPOSIT_AMOUNT);\n",{"type":50,"tag":139,"props":1377,"children":1378},{"class":141,"line":196},[1379],{"type":50,"tag":139,"props":1380,"children":1381},{"emptyLinePlaceholder":200},[1382],{"type":56,"value":203},{"type":50,"tag":139,"props":1384,"children":1385},{"class":141,"line":27},[1386],{"type":50,"tag":139,"props":1387,"children":1388},{},[1389],{"type":56,"value":468},{"type":50,"tag":139,"props":1391,"children":1392},{"class":141,"line":214},[1393],{"type":50,"tag":139,"props":1394,"children":1395},{},[1396],{"type":56,"value":1397},"    assert!(my_module::get_balance(signer::address_of(user)) == my_module::MAX_DEPOSIT_AMOUNT, 0);\n",{"type":50,"tag":139,"props":1399,"children":1400},{"class":141,"line":223},[1401],{"type":50,"tag":139,"props":1402,"children":1403},{},[1404],{"type":56,"value":376},{"type":50,"tag":139,"props":1406,"children":1407},{"class":141,"line":232},[1408],{"type":50,"tag":139,"props":1409,"children":1410},{"emptyLinePlaceholder":200},[1411],{"type":56,"value":203},{"type":50,"tag":139,"props":1413,"children":1414},{"class":141,"line":241},[1415],{"type":50,"tag":139,"props":1416,"children":1417},{},[1418],{"type":56,"value":1045},{"type":50,"tag":139,"props":1420,"children":1421},{"class":141,"line":249},[1422],{"type":50,"tag":139,"props":1423,"children":1424},{},[1425],{"type":56,"value":1426},"public fun test_max_name_length_allowed(user: &signer) {\n",{"type":50,"tag":139,"props":1428,"children":1429},{"class":141,"line":258},[1430],{"type":50,"tag":139,"props":1431,"children":1432},{},[1433],{"type":56,"value":1434},"    \u002F\u002F Create string exactly MAX_NAME_LENGTH long\n",{"type":50,"tag":139,"props":1436,"children":1437},{"class":141,"line":267},[1438],{"type":50,"tag":139,"props":1439,"children":1440},{},[1441],{"type":56,"value":1442},"    let max_name = string::utf8(b\"12345678901234567890123456789012\"); \u002F\u002F 32 chars if MAX = 32\n",{"type":50,"tag":139,"props":1444,"children":1445},{"class":141,"line":275},[1446],{"type":50,"tag":139,"props":1447,"children":1448},{"emptyLinePlaceholder":200},[1449],{"type":56,"value":203},{"type":50,"tag":139,"props":1451,"children":1452},{"class":141,"line":284},[1453],{"type":50,"tag":139,"props":1454,"children":1455},{},[1456],{"type":56,"value":1457},"    \u002F\u002F Should succeed\n",{"type":50,"tag":139,"props":1459,"children":1460},{"class":141,"line":23},[1461],{"type":50,"tag":139,"props":1462,"children":1463},{},[1464],{"type":56,"value":1465},"    let obj = my_module::create_my_object(user, max_name);\n",{"type":50,"tag":139,"props":1467,"children":1468},{"class":141,"line":300},[1469],{"type":50,"tag":139,"props":1470,"children":1471},{},[1472],{"type":56,"value":376},{"type":50,"tag":139,"props":1474,"children":1475},{"class":141,"line":309},[1476],{"type":50,"tag":139,"props":1477,"children":1478},{"emptyLinePlaceholder":200},[1479],{"type":56,"value":203},{"type":50,"tag":139,"props":1481,"children":1482},{"class":141,"line":318},[1483],{"type":50,"tag":139,"props":1484,"children":1485},{},[1486],{"type":56,"value":1045},{"type":50,"tag":139,"props":1488,"children":1489},{"class":141,"line":326},[1490],{"type":50,"tag":139,"props":1491,"children":1492},{},[1493],{"type":56,"value":1494},"public fun test_empty_collection_operations(user: &signer) {\n",{"type":50,"tag":139,"props":1496,"children":1497},{"class":141,"line":335},[1498],{"type":50,"tag":139,"props":1499,"children":1500},{},[1501],{"type":56,"value":1502},"    let collection = my_module::create_collection(user, string::utf8(b\"Collection\"));\n",{"type":50,"tag":139,"props":1504,"children":1505},{"class":141,"line":344},[1506],{"type":50,"tag":139,"props":1507,"children":1508},{"emptyLinePlaceholder":200},[1509],{"type":56,"value":203},{"type":50,"tag":139,"props":1511,"children":1512},{"class":141,"line":352},[1513],{"type":50,"tag":139,"props":1514,"children":1515},{},[1516],{"type":56,"value":1517},"    \u002F\u002F Should handle empty collection gracefully\n",{"type":50,"tag":139,"props":1519,"children":1520},{"class":141,"line":361},[1521],{"type":50,"tag":139,"props":1522,"children":1523},{},[1524],{"type":56,"value":1525},"    assert!(my_module::get_collection_size(collection) == 0, 0);\n",{"type":50,"tag":139,"props":1527,"children":1528},{"class":141,"line":370},[1529],{"type":50,"tag":139,"props":1530,"children":1531},{},[1532],{"type":56,"value":376},{"type":50,"tag":121,"props":1534,"children":1536},{"id":1535},"step-6-verify-coverage",[1537],{"type":56,"value":1538},"Step 6: Verify Coverage",{"type":50,"tag":66,"props":1540,"children":1541},{},[1542],{"type":50,"tag":72,"props":1543,"children":1544},{},[1545],{"type":56,"value":1546},"Run tests with coverage:",{"type":50,"tag":128,"props":1548,"children":1552},{"className":1549,"code":1550,"language":1551,"meta":132,"style":132},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Run all tests\naptos move test\n\n# Run with coverage\naptos move test --coverage\n\n# Generate detailed coverage report\naptos move coverage source --module \u003Cmodule_name>\n\n# Verify 100% coverage\naptos move coverage summary\n","bash",[1553],{"type":50,"tag":135,"props":1554,"children":1555},{"__ignoreMap":132},[1556,1565,1584,1591,1599,1620,1627,1635,1683,1690,1698],{"type":50,"tag":139,"props":1557,"children":1558},{"class":141,"line":142},[1559],{"type":50,"tag":139,"props":1560,"children":1562},{"style":1561},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1563],{"type":56,"value":1564},"# Run all tests\n",{"type":50,"tag":139,"props":1566,"children":1567},{"class":141,"line":151},[1568,1573,1579],{"type":50,"tag":139,"props":1569,"children":1571},{"style":1570},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[1572],{"type":56,"value":8},{"type":50,"tag":139,"props":1574,"children":1576},{"style":1575},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[1577],{"type":56,"value":1578}," move",{"type":50,"tag":139,"props":1580,"children":1581},{"style":1575},[1582],{"type":56,"value":1583}," test\n",{"type":50,"tag":139,"props":1585,"children":1586},{"class":141,"line":160},[1587],{"type":50,"tag":139,"props":1588,"children":1589},{"emptyLinePlaceholder":200},[1590],{"type":56,"value":203},{"type":50,"tag":139,"props":1592,"children":1593},{"class":141,"line":169},[1594],{"type":50,"tag":139,"props":1595,"children":1596},{"style":1561},[1597],{"type":56,"value":1598},"# Run with coverage\n",{"type":50,"tag":139,"props":1600,"children":1601},{"class":141,"line":178},[1602,1606,1610,1615],{"type":50,"tag":139,"props":1603,"children":1604},{"style":1570},[1605],{"type":56,"value":8},{"type":50,"tag":139,"props":1607,"children":1608},{"style":1575},[1609],{"type":56,"value":1578},{"type":50,"tag":139,"props":1611,"children":1612},{"style":1575},[1613],{"type":56,"value":1614}," test",{"type":50,"tag":139,"props":1616,"children":1617},{"style":1575},[1618],{"type":56,"value":1619}," --coverage\n",{"type":50,"tag":139,"props":1621,"children":1622},{"class":141,"line":187},[1623],{"type":50,"tag":139,"props":1624,"children":1625},{"emptyLinePlaceholder":200},[1626],{"type":56,"value":203},{"type":50,"tag":139,"props":1628,"children":1629},{"class":141,"line":196},[1630],{"type":50,"tag":139,"props":1631,"children":1632},{"style":1561},[1633],{"type":56,"value":1634},"# Generate detailed coverage report\n",{"type":50,"tag":139,"props":1636,"children":1637},{"class":141,"line":27},[1638,1642,1646,1651,1656,1661,1667,1672,1678],{"type":50,"tag":139,"props":1639,"children":1640},{"style":1570},[1641],{"type":56,"value":8},{"type":50,"tag":139,"props":1643,"children":1644},{"style":1575},[1645],{"type":56,"value":1578},{"type":50,"tag":139,"props":1647,"children":1648},{"style":1575},[1649],{"type":56,"value":1650}," coverage",{"type":50,"tag":139,"props":1652,"children":1653},{"style":1575},[1654],{"type":56,"value":1655}," source",{"type":50,"tag":139,"props":1657,"children":1658},{"style":1575},[1659],{"type":56,"value":1660}," --module",{"type":50,"tag":139,"props":1662,"children":1664},{"style":1663},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[1665],{"type":56,"value":1666}," \u003C",{"type":50,"tag":139,"props":1668,"children":1669},{"style":1575},[1670],{"type":56,"value":1671},"module_nam",{"type":50,"tag":139,"props":1673,"children":1675},{"style":1674},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[1676],{"type":56,"value":1677},"e",{"type":50,"tag":139,"props":1679,"children":1680},{"style":1663},[1681],{"type":56,"value":1682},">\n",{"type":50,"tag":139,"props":1684,"children":1685},{"class":141,"line":214},[1686],{"type":50,"tag":139,"props":1687,"children":1688},{"emptyLinePlaceholder":200},[1689],{"type":56,"value":203},{"type":50,"tag":139,"props":1691,"children":1692},{"class":141,"line":223},[1693],{"type":50,"tag":139,"props":1694,"children":1695},{"style":1561},[1696],{"type":56,"value":1697},"# Verify 100% coverage\n",{"type":50,"tag":139,"props":1699,"children":1700},{"class":141,"line":232},[1701,1705,1709,1713],{"type":50,"tag":139,"props":1702,"children":1703},{"style":1570},[1704],{"type":56,"value":8},{"type":50,"tag":139,"props":1706,"children":1707},{"style":1575},[1708],{"type":56,"value":1578},{"type":50,"tag":139,"props":1710,"children":1711},{"style":1575},[1712],{"type":56,"value":1650},{"type":50,"tag":139,"props":1714,"children":1715},{"style":1575},[1716],{"type":56,"value":1717}," summary\n",{"type":50,"tag":66,"props":1719,"children":1720},{},[1721],{"type":50,"tag":72,"props":1722,"children":1723},{},[1724],{"type":56,"value":1725},"Coverage report example:",{"type":50,"tag":128,"props":1727,"children":1731},{"className":1728,"code":1730,"language":56},[1729],"language-text","module: my_module\ncoverage: 100.0% (150\u002F150 lines covered)\n",[1732],{"type":50,"tag":135,"props":1733,"children":1734},{"__ignoreMap":132},[1735],{"type":56,"value":1730},{"type":50,"tag":66,"props":1737,"children":1738},{},[1739],{"type":50,"tag":72,"props":1740,"children":1741},{},[1742],{"type":56,"value":1743},"If coverage \u003C 100%:",{"type":50,"tag":1745,"props":1746,"children":1747},"ol",{},[1748,1753,1758],{"type":50,"tag":84,"props":1749,"children":1750},{},[1751],{"type":56,"value":1752},"Check uncovered lines in report",{"type":50,"tag":84,"props":1754,"children":1755},{},[1756],{"type":56,"value":1757},"Write tests for missing paths",{"type":50,"tag":84,"props":1759,"children":1760},{},[1761],{"type":56,"value":1762},"Repeat until 100%",{"type":50,"tag":59,"props":1764,"children":1766},{"id":1765},"test-template-structure",[1767],{"type":56,"value":1768},"Test Template Structure",{"type":50,"tag":128,"props":1770,"children":1772},{"className":130,"code":1771,"language":40,"meta":132,"style":132},"#[test_only]\nmodule my_addr::module_tests {\n    use my_addr::module::{Self, Type};\n\n    \u002F\u002F ========== Setup Helpers ==========\n\n    fun setup_default(): Object\u003CType> {\n        \u002F\u002F Common setup code\n    }\n\n    \u002F\u002F ========== Happy Path Tests ==========\n\n    #[test(user = @0x1)]\n    public fun test_basic_operation_succeeds(user: &signer) {\n        \u002F\u002F Test happy path\n    }\n\n    \u002F\u002F ========== Access Control Tests ==========\n\n    #[test(owner = @0x1, attacker = @0x2)]\n    #[expected_failure(abort_code = E_NOT_OWNER)]\n    public fun test_unauthorized_access_fails(\n        owner: &signer,\n        attacker: &signer\n    ) {\n        \u002F\u002F Test access control\n    }\n\n    \u002F\u002F ========== Input Validation Tests ==========\n\n    #[test(user = @0x1)]\n    #[expected_failure(abort_code = E_INVALID_INPUT)]\n    public fun test_invalid_input_rejected(user: &signer) {\n        \u002F\u002F Test input validation\n    }\n\n    \u002F\u002F ========== Edge Case Tests ==========\n\n    #[test(user = @0x1)]\n    public fun test_boundary_condition(user: &signer) {\n        \u002F\u002F Test edge cases\n    }\n}\n",[1773],{"type":50,"tag":135,"props":1774,"children":1775},{"__ignoreMap":132},[1776,1783,1791,1799,1806,1813,1820,1828,1836,1844,1851,1858,1865,1873,1881,1889,1896,1903,1910,1917,1925,1933,1941,1949,1957,1965,1973,1980,1987,1994,2001,2008,2016,2024,2032,2039,2046,2053,2060,2067,2075,2083,2090],{"type":50,"tag":139,"props":1777,"children":1778},{"class":141,"line":142},[1779],{"type":50,"tag":139,"props":1780,"children":1781},{},[1782],{"type":56,"value":148},{"type":50,"tag":139,"props":1784,"children":1785},{"class":141,"line":151},[1786],{"type":50,"tag":139,"props":1787,"children":1788},{},[1789],{"type":56,"value":1790},"module my_addr::module_tests {\n",{"type":50,"tag":139,"props":1792,"children":1793},{"class":141,"line":160},[1794],{"type":50,"tag":139,"props":1795,"children":1796},{},[1797],{"type":56,"value":1798},"    use my_addr::module::{Self, Type};\n",{"type":50,"tag":139,"props":1800,"children":1801},{"class":141,"line":169},[1802],{"type":50,"tag":139,"props":1803,"children":1804},{"emptyLinePlaceholder":200},[1805],{"type":56,"value":203},{"type":50,"tag":139,"props":1807,"children":1808},{"class":141,"line":178},[1809],{"type":50,"tag":139,"props":1810,"children":1811},{},[1812],{"type":56,"value":255},{"type":50,"tag":139,"props":1814,"children":1815},{"class":141,"line":187},[1816],{"type":50,"tag":139,"props":1817,"children":1818},{"emptyLinePlaceholder":200},[1819],{"type":56,"value":203},{"type":50,"tag":139,"props":1821,"children":1822},{"class":141,"line":196},[1823],{"type":50,"tag":139,"props":1824,"children":1825},{},[1826],{"type":56,"value":1827},"    fun setup_default(): Object\u003CType> {\n",{"type":50,"tag":139,"props":1829,"children":1830},{"class":141,"line":27},[1831],{"type":50,"tag":139,"props":1832,"children":1833},{},[1834],{"type":56,"value":1835},"        \u002F\u002F Common setup code\n",{"type":50,"tag":139,"props":1837,"children":1838},{"class":141,"line":214},[1839],{"type":50,"tag":139,"props":1840,"children":1841},{},[1842],{"type":56,"value":1843},"    }\n",{"type":50,"tag":139,"props":1845,"children":1846},{"class":141,"line":223},[1847],{"type":50,"tag":139,"props":1848,"children":1849},{"emptyLinePlaceholder":200},[1850],{"type":56,"value":203},{"type":50,"tag":139,"props":1852,"children":1853},{"class":141,"line":232},[1854],{"type":50,"tag":139,"props":1855,"children":1856},{},[1857],{"type":56,"value":281},{"type":50,"tag":139,"props":1859,"children":1860},{"class":141,"line":241},[1861],{"type":50,"tag":139,"props":1862,"children":1863},{"emptyLinePlaceholder":200},[1864],{"type":56,"value":203},{"type":50,"tag":139,"props":1866,"children":1867},{"class":141,"line":249},[1868],{"type":50,"tag":139,"props":1869,"children":1870},{},[1871],{"type":56,"value":1872},"    #[test(user = @0x1)]\n",{"type":50,"tag":139,"props":1874,"children":1875},{"class":141,"line":258},[1876],{"type":50,"tag":139,"props":1877,"children":1878},{},[1879],{"type":56,"value":1880},"    public fun test_basic_operation_succeeds(user: &signer) {\n",{"type":50,"tag":139,"props":1882,"children":1883},{"class":141,"line":267},[1884],{"type":50,"tag":139,"props":1885,"children":1886},{},[1887],{"type":56,"value":1888},"        \u002F\u002F Test happy path\n",{"type":50,"tag":139,"props":1890,"children":1891},{"class":141,"line":275},[1892],{"type":50,"tag":139,"props":1893,"children":1894},{},[1895],{"type":56,"value":1843},{"type":50,"tag":139,"props":1897,"children":1898},{"class":141,"line":284},[1899],{"type":50,"tag":139,"props":1900,"children":1901},{"emptyLinePlaceholder":200},[1902],{"type":56,"value":203},{"type":50,"tag":139,"props":1904,"children":1905},{"class":141,"line":23},[1906],{"type":50,"tag":139,"props":1907,"children":1908},{},[1909],{"type":56,"value":306},{"type":50,"tag":139,"props":1911,"children":1912},{"class":141,"line":300},[1913],{"type":50,"tag":139,"props":1914,"children":1915},{"emptyLinePlaceholder":200},[1916],{"type":56,"value":203},{"type":50,"tag":139,"props":1918,"children":1919},{"class":141,"line":309},[1920],{"type":50,"tag":139,"props":1921,"children":1922},{},[1923],{"type":56,"value":1924},"    #[test(owner = @0x1, attacker = @0x2)]\n",{"type":50,"tag":139,"props":1926,"children":1927},{"class":141,"line":318},[1928],{"type":50,"tag":139,"props":1929,"children":1930},{},[1931],{"type":56,"value":1932},"    #[expected_failure(abort_code = E_NOT_OWNER)]\n",{"type":50,"tag":139,"props":1934,"children":1935},{"class":141,"line":326},[1936],{"type":50,"tag":139,"props":1937,"children":1938},{},[1939],{"type":56,"value":1940},"    public fun test_unauthorized_access_fails(\n",{"type":50,"tag":139,"props":1942,"children":1943},{"class":141,"line":335},[1944],{"type":50,"tag":139,"props":1945,"children":1946},{},[1947],{"type":56,"value":1948},"        owner: &signer,\n",{"type":50,"tag":139,"props":1950,"children":1951},{"class":141,"line":344},[1952],{"type":50,"tag":139,"props":1953,"children":1954},{},[1955],{"type":56,"value":1956},"        attacker: &signer\n",{"type":50,"tag":139,"props":1958,"children":1959},{"class":141,"line":352},[1960],{"type":50,"tag":139,"props":1961,"children":1962},{},[1963],{"type":56,"value":1964},"    ) {\n",{"type":50,"tag":139,"props":1966,"children":1967},{"class":141,"line":361},[1968],{"type":50,"tag":139,"props":1969,"children":1970},{},[1971],{"type":56,"value":1972},"        \u002F\u002F Test access control\n",{"type":50,"tag":139,"props":1974,"children":1975},{"class":141,"line":370},[1976],{"type":50,"tag":139,"props":1977,"children":1978},{},[1979],{"type":56,"value":1843},{"type":50,"tag":139,"props":1981,"children":1982},{"class":141,"line":608},[1983],{"type":50,"tag":139,"props":1984,"children":1985},{"emptyLinePlaceholder":200},[1986],{"type":56,"value":203},{"type":50,"tag":139,"props":1988,"children":1989},{"class":141,"line":617},[1990],{"type":50,"tag":139,"props":1991,"children":1992},{},[1993],{"type":56,"value":332},{"type":50,"tag":139,"props":1995,"children":1996},{"class":141,"line":626},[1997],{"type":50,"tag":139,"props":1998,"children":1999},{"emptyLinePlaceholder":200},[2000],{"type":56,"value":203},{"type":50,"tag":139,"props":2002,"children":2003},{"class":141,"line":635},[2004],{"type":50,"tag":139,"props":2005,"children":2006},{},[2007],{"type":56,"value":1872},{"type":50,"tag":139,"props":2009,"children":2010},{"class":141,"line":644},[2011],{"type":50,"tag":139,"props":2012,"children":2013},{},[2014],{"type":56,"value":2015},"    #[expected_failure(abort_code = E_INVALID_INPUT)]\n",{"type":50,"tag":139,"props":2017,"children":2018},{"class":141,"line":652},[2019],{"type":50,"tag":139,"props":2020,"children":2021},{},[2022],{"type":56,"value":2023},"    public fun test_invalid_input_rejected(user: &signer) {\n",{"type":50,"tag":139,"props":2025,"children":2026},{"class":141,"line":660},[2027],{"type":50,"tag":139,"props":2028,"children":2029},{},[2030],{"type":56,"value":2031},"        \u002F\u002F Test input validation\n",{"type":50,"tag":139,"props":2033,"children":2034},{"class":141,"line":669},[2035],{"type":50,"tag":139,"props":2036,"children":2037},{},[2038],{"type":56,"value":1843},{"type":50,"tag":139,"props":2040,"children":2041},{"class":141,"line":678},[2042],{"type":50,"tag":139,"props":2043,"children":2044},{"emptyLinePlaceholder":200},[2045],{"type":56,"value":203},{"type":50,"tag":139,"props":2047,"children":2048},{"class":141,"line":686},[2049],{"type":50,"tag":139,"props":2050,"children":2051},{},[2052],{"type":56,"value":358},{"type":50,"tag":139,"props":2054,"children":2055},{"class":141,"line":694},[2056],{"type":50,"tag":139,"props":2057,"children":2058},{"emptyLinePlaceholder":200},[2059],{"type":56,"value":203},{"type":50,"tag":139,"props":2061,"children":2062},{"class":141,"line":703},[2063],{"type":50,"tag":139,"props":2064,"children":2065},{},[2066],{"type":56,"value":1872},{"type":50,"tag":139,"props":2068,"children":2069},{"class":141,"line":711},[2070],{"type":50,"tag":139,"props":2071,"children":2072},{},[2073],{"type":56,"value":2074},"    public fun test_boundary_condition(user: &signer) {\n",{"type":50,"tag":139,"props":2076,"children":2077},{"class":141,"line":719},[2078],{"type":50,"tag":139,"props":2079,"children":2080},{},[2081],{"type":56,"value":2082},"        \u002F\u002F Test edge cases\n",{"type":50,"tag":139,"props":2084,"children":2085},{"class":141,"line":728},[2086],{"type":50,"tag":139,"props":2087,"children":2088},{},[2089],{"type":56,"value":1843},{"type":50,"tag":139,"props":2091,"children":2093},{"class":141,"line":2092},43,[2094],{"type":50,"tag":139,"props":2095,"children":2096},{},[2097],{"type":56,"value":376},{"type":50,"tag":59,"props":2099,"children":2101},{"id":2100},"testing-checklist",[2102],{"type":56,"value":2103},"Testing Checklist",{"type":50,"tag":66,"props":2105,"children":2106},{},[2107],{"type":56,"value":2108},"For each contract, verify you have tests for:",{"type":50,"tag":66,"props":2110,"children":2111},{},[2112],{"type":50,"tag":72,"props":2113,"children":2114},{},[2115],{"type":56,"value":2116},"Happy Paths:",{"type":50,"tag":80,"props":2118,"children":2121},{"className":2119},[2120],"contains-task-list",[2122,2134,2143,2152],{"type":50,"tag":84,"props":2123,"children":2126},{"className":2124},[2125],"task-list-item",[2127,2132],{"type":50,"tag":2128,"props":2129,"children":2131},"input",{"disabled":200,"type":2130},"checkbox",[],{"type":56,"value":2133}," Object creation works",{"type":50,"tag":84,"props":2135,"children":2137},{"className":2136},[2125],[2138,2141],{"type":50,"tag":2128,"props":2139,"children":2140},{"disabled":200,"type":2130},[],{"type":56,"value":2142}," State updates work",{"type":50,"tag":84,"props":2144,"children":2146},{"className":2145},[2125],[2147,2150],{"type":50,"tag":2128,"props":2148,"children":2149},{"disabled":200,"type":2130},[],{"type":56,"value":2151}," Transfers work",{"type":50,"tag":84,"props":2153,"children":2155},{"className":2154},[2125],[2156,2159],{"type":50,"tag":2128,"props":2157,"children":2158},{"disabled":200,"type":2130},[],{"type":56,"value":2160}," All main features work",{"type":50,"tag":66,"props":2162,"children":2163},{},[2164],{"type":50,"tag":72,"props":2165,"children":2166},{},[2167],{"type":56,"value":2168},"Access Control:",{"type":50,"tag":80,"props":2170,"children":2172},{"className":2171},[2120],[2173,2182,2191],{"type":50,"tag":84,"props":2174,"children":2176},{"className":2175},[2125],[2177,2180],{"type":50,"tag":2128,"props":2178,"children":2179},{"disabled":200,"type":2130},[],{"type":56,"value":2181}," Non-owners cannot modify objects",{"type":50,"tag":84,"props":2183,"children":2185},{"className":2184},[2125],[2186,2189],{"type":50,"tag":2128,"props":2187,"children":2188},{"disabled":200,"type":2130},[],{"type":56,"value":2190}," Non-admins cannot call admin functions",{"type":50,"tag":84,"props":2192,"children":2194},{"className":2193},[2125],[2195,2198],{"type":50,"tag":2128,"props":2196,"children":2197},{"disabled":200,"type":2130},[],{"type":56,"value":2199}," Unauthorized users blocked",{"type":50,"tag":66,"props":2201,"children":2202},{},[2203],{"type":50,"tag":72,"props":2204,"children":2205},{},[2206],{"type":56,"value":2207},"Input Validation:",{"type":50,"tag":80,"props":2209,"children":2211},{"className":2210},[2120],[2212,2221,2230,2239,2248],{"type":50,"tag":84,"props":2213,"children":2215},{"className":2214},[2125],[2216,2219],{"type":50,"tag":2128,"props":2217,"children":2218},{"disabled":200,"type":2130},[],{"type":56,"value":2220}," Zero amounts rejected",{"type":50,"tag":84,"props":2222,"children":2224},{"className":2223},[2125],[2225,2228],{"type":50,"tag":2128,"props":2226,"children":2227},{"disabled":200,"type":2130},[],{"type":56,"value":2229}," Excessive amounts rejected",{"type":50,"tag":84,"props":2231,"children":2233},{"className":2232},[2125],[2234,2237],{"type":50,"tag":2128,"props":2235,"children":2236},{"disabled":200,"type":2130},[],{"type":56,"value":2238}," Empty strings rejected",{"type":50,"tag":84,"props":2240,"children":2242},{"className":2241},[2125],[2243,2246],{"type":50,"tag":2128,"props":2244,"children":2245},{"disabled":200,"type":2130},[],{"type":56,"value":2247}," Strings too long rejected",{"type":50,"tag":84,"props":2249,"children":2251},{"className":2250},[2125],[2252,2255],{"type":50,"tag":2128,"props":2253,"children":2254},{"disabled":200,"type":2130},[],{"type":56,"value":2256}," Zero addresses rejected",{"type":50,"tag":66,"props":2258,"children":2259},{},[2260],{"type":50,"tag":72,"props":2261,"children":2262},{},[2263],{"type":56,"value":2264},"Edge Cases:",{"type":50,"tag":80,"props":2266,"children":2268},{"className":2267},[2120],[2269,2278,2287],{"type":50,"tag":84,"props":2270,"children":2272},{"className":2271},[2125],[2273,2276],{"type":50,"tag":2128,"props":2274,"children":2275},{"disabled":200,"type":2130},[],{"type":56,"value":2277}," Maximum values work",{"type":50,"tag":84,"props":2279,"children":2281},{"className":2280},[2125],[2282,2285],{"type":50,"tag":2128,"props":2283,"children":2284},{"disabled":200,"type":2130},[],{"type":56,"value":2286}," Minimum values work",{"type":50,"tag":84,"props":2288,"children":2290},{"className":2289},[2125],[2291,2294],{"type":50,"tag":2128,"props":2292,"children":2293},{"disabled":200,"type":2130},[],{"type":56,"value":2295}," Empty states handled",{"type":50,"tag":66,"props":2297,"children":2298},{},[2299],{"type":50,"tag":72,"props":2300,"children":2301},{},[2302],{"type":56,"value":2303},"Coverage:",{"type":50,"tag":80,"props":2305,"children":2307},{"className":2306},[2120],[2308,2317,2326],{"type":50,"tag":84,"props":2309,"children":2311},{"className":2310},[2125],[2312,2315],{"type":50,"tag":2128,"props":2313,"children":2314},{"disabled":200,"type":2130},[],{"type":56,"value":2316}," 100% line coverage achieved",{"type":50,"tag":84,"props":2318,"children":2320},{"className":2319},[2125],[2321,2324],{"type":50,"tag":2128,"props":2322,"children":2323},{"disabled":200,"type":2130},[],{"type":56,"value":2325}," All error codes tested",{"type":50,"tag":84,"props":2327,"children":2329},{"className":2328},[2125],[2330,2333],{"type":50,"tag":2128,"props":2331,"children":2332},{"disabled":200,"type":2130},[],{"type":56,"value":2334}," All functions tested",{"type":50,"tag":59,"props":2336,"children":2338},{"id":2337},"always-rules",[2339],{"type":56,"value":2340},"ALWAYS Rules",{"type":50,"tag":80,"props":2342,"children":2343},{},[2344,2349,2360,2365,2370,2375,2386,2391],{"type":50,"tag":84,"props":2345,"children":2346},{},[2347],{"type":56,"value":2348},"✅ ALWAYS achieve 100% test coverage",{"type":50,"tag":84,"props":2350,"children":2351},{},[2352,2354],{"type":56,"value":2353},"✅ ALWAYS test error paths with ",{"type":50,"tag":135,"props":2355,"children":2357},{"className":2356},[],[2358],{"type":56,"value":2359},"#[expected_failure(abort_code = E_CODE)]",{"type":50,"tag":84,"props":2361,"children":2362},{},[2363],{"type":56,"value":2364},"✅ ALWAYS test access control with multiple signers",{"type":50,"tag":84,"props":2366,"children":2367},{},[2368],{"type":56,"value":2369},"✅ ALWAYS test input validation with invalid inputs",{"type":50,"tag":84,"props":2371,"children":2372},{},[2373],{"type":56,"value":2374},"✅ ALWAYS test edge cases (boundaries, limits, empty states)",{"type":50,"tag":84,"props":2376,"children":2377},{},[2378,2380],{"type":56,"value":2379},"✅ ALWAYS use clear test names: ",{"type":50,"tag":135,"props":2381,"children":2383},{"className":2382},[],[2384],{"type":56,"value":2385},"test_feature_scenario",{"type":50,"tag":84,"props":2387,"children":2388},{},[2389],{"type":56,"value":2390},"✅ ALWAYS verify all state changes in tests",{"type":50,"tag":84,"props":2392,"children":2393},{},[2394,2396,2402],{"type":56,"value":2395},"✅ ALWAYS run ",{"type":50,"tag":135,"props":2397,"children":2399},{"className":2398},[],[2400],{"type":56,"value":2401},"aptos move test --coverage",{"type":56,"value":2403}," before deployment",{"type":50,"tag":59,"props":2405,"children":2407},{"id":2406},"never-rules",[2408],{"type":56,"value":2409},"NEVER Rules",{"type":50,"tag":80,"props":2411,"children":2412},{},[2413,2418,2423,2428,2433,2438,2465],{"type":50,"tag":84,"props":2414,"children":2415},{},[2416],{"type":56,"value":2417},"❌ NEVER deploy without 100% coverage",{"type":50,"tag":84,"props":2419,"children":2420},{},[2421],{"type":56,"value":2422},"❌ NEVER skip testing error paths",{"type":50,"tag":84,"props":2424,"children":2425},{},[2426],{"type":56,"value":2427},"❌ NEVER skip access control tests",{"type":50,"tag":84,"props":2429,"children":2430},{},[2431],{"type":56,"value":2432},"❌ NEVER use unclear test names",{"type":50,"tag":84,"props":2434,"children":2435},{},[2436],{"type":56,"value":2437},"❌ NEVER batch tests without verifying each case",{"type":50,"tag":84,"props":2439,"children":2440},{},[2441,2443,2449,2451,2457,2459],{"type":56,"value":2442},"❌ NEVER hardcode real private keys or account addresses in test code — use test addresses like ",{"type":50,"tag":135,"props":2444,"children":2446},{"className":2445},[],[2447],{"type":56,"value":2448},"@0x1",{"type":56,"value":2450},", ",{"type":50,"tag":135,"props":2452,"children":2454},{"className":2453},[],[2455],{"type":56,"value":2456},"@0x100",{"type":56,"value":2458},",\n",{"type":50,"tag":135,"props":2460,"children":2462},{"className":2461},[],[2463],{"type":56,"value":2464},"@0xCAFE",{"type":50,"tag":84,"props":2466,"children":2467},{},[2468,2470,2476,2478,2484],{"type":56,"value":2469},"❌ NEVER read ",{"type":50,"tag":135,"props":2471,"children":2473},{"className":2472},[],[2474],{"type":56,"value":2475},".env",{"type":56,"value":2477}," or ",{"type":50,"tag":135,"props":2479,"children":2481},{"className":2480},[],[2482],{"type":56,"value":2483},"~\u002F.aptos\u002Fconfig.yaml",{"type":56,"value":2485}," to get test addresses",{"type":50,"tag":59,"props":2487,"children":2489},{"id":2488},"common-pitfalls",[2490],{"type":56,"value":2491},"Common Pitfalls",{"type":50,"tag":121,"props":2493,"children":2495},{"id":2494},"struct-field-access-across-modules",[2496],{"type":56,"value":2497},"Struct Field Access Across Modules",{"type":50,"tag":66,"props":2499,"children":2500},{},[2501,2506],{"type":50,"tag":72,"props":2502,"children":2503},{},[2504],{"type":56,"value":2505},"Problem:",{"type":56,"value":2507}," Test modules cannot access struct fields from other modules directly.",{"type":50,"tag":128,"props":2509,"children":2511},{"className":130,"code":2510,"language":40,"meta":132,"style":132},"\u002F\u002F ❌ WRONG - Will NOT compile\nlet listing = marketplace::get_listing(nft_addr);\nassert!(listing.price == 1000, 0);  \u002F\u002F ERROR: field access not allowed\n",[2512],{"type":50,"tag":135,"props":2513,"children":2514},{"__ignoreMap":132},[2515,2523,2531],{"type":50,"tag":139,"props":2516,"children":2517},{"class":141,"line":142},[2518],{"type":50,"tag":139,"props":2519,"children":2520},{},[2521],{"type":56,"value":2522},"\u002F\u002F ❌ WRONG - Will NOT compile\n",{"type":50,"tag":139,"props":2524,"children":2525},{"class":141,"line":151},[2526],{"type":50,"tag":139,"props":2527,"children":2528},{},[2529],{"type":56,"value":2530},"let listing = marketplace::get_listing(nft_addr);\n",{"type":50,"tag":139,"props":2532,"children":2533},{"class":141,"line":160},[2534],{"type":50,"tag":139,"props":2535,"children":2536},{},[2537],{"type":56,"value":2538},"assert!(listing.price == 1000, 0);  \u002F\u002F ERROR: field access not allowed\n",{"type":50,"tag":66,"props":2540,"children":2541},{},[2542,2547],{"type":50,"tag":72,"props":2543,"children":2544},{},[2545],{"type":56,"value":2546},"Solution:",{"type":56,"value":2548}," Use public view accessor functions from the main module.",{"type":50,"tag":128,"props":2550,"children":2552},{"className":130,"code":2551,"language":40,"meta":132,"style":132},"\u002F\u002F ✅ CORRECT - Use accessor function\nlet (seller, price, timestamp) = marketplace::get_listing_details(nft_addr);\nassert!(price == 1000, 0);\n",[2553],{"type":50,"tag":135,"props":2554,"children":2555},{"__ignoreMap":132},[2556,2564,2572],{"type":50,"tag":139,"props":2557,"children":2558},{"class":141,"line":142},[2559],{"type":50,"tag":139,"props":2560,"children":2561},{},[2562],{"type":56,"value":2563},"\u002F\u002F ✅ CORRECT - Use accessor function\n",{"type":50,"tag":139,"props":2565,"children":2566},{"class":141,"line":151},[2567],{"type":50,"tag":139,"props":2568,"children":2569},{},[2570],{"type":56,"value":2571},"let (seller, price, timestamp) = marketplace::get_listing_details(nft_addr);\n",{"type":50,"tag":139,"props":2573,"children":2574},{"class":141,"line":160},[2575],{"type":50,"tag":139,"props":2576,"children":2577},{},[2578],{"type":56,"value":2579},"assert!(price == 1000, 0);\n",{"type":50,"tag":66,"props":2581,"children":2582},{},[2583],{"type":56,"value":2584},"If the module doesn't have accessors, add them:",{"type":50,"tag":128,"props":2586,"children":2588},{"className":130,"code":2587,"language":40,"meta":132,"style":132},"\u002F\u002F In main module\n#[view]\npublic fun get_listing_details(nft_addr: address): (address, u64, u64) acquires Listings {\n    let listing = table::borrow(&listings.items, nft_addr);\n    (listing.seller, listing.price, listing.listed_at)\n}\n",[2589],{"type":50,"tag":135,"props":2590,"children":2591},{"__ignoreMap":132},[2592,2600,2608,2616,2624,2632],{"type":50,"tag":139,"props":2593,"children":2594},{"class":141,"line":142},[2595],{"type":50,"tag":139,"props":2596,"children":2597},{},[2598],{"type":56,"value":2599},"\u002F\u002F In main module\n",{"type":50,"tag":139,"props":2601,"children":2602},{"class":141,"line":151},[2603],{"type":50,"tag":139,"props":2604,"children":2605},{},[2606],{"type":56,"value":2607},"#[view]\n",{"type":50,"tag":139,"props":2609,"children":2610},{"class":141,"line":160},[2611],{"type":50,"tag":139,"props":2612,"children":2613},{},[2614],{"type":56,"value":2615},"public fun get_listing_details(nft_addr: address): (address, u64, u64) acquires Listings {\n",{"type":50,"tag":139,"props":2617,"children":2618},{"class":141,"line":169},[2619],{"type":50,"tag":139,"props":2620,"children":2621},{},[2622],{"type":56,"value":2623},"    let listing = table::borrow(&listings.items, nft_addr);\n",{"type":50,"tag":139,"props":2625,"children":2626},{"class":141,"line":178},[2627],{"type":50,"tag":139,"props":2628,"children":2629},{},[2630],{"type":56,"value":2631},"    (listing.seller, listing.price, listing.listed_at)\n",{"type":50,"tag":139,"props":2633,"children":2634},{"class":141,"line":187},[2635],{"type":50,"tag":139,"props":2636,"children":2637},{},[2638],{"type":56,"value":376},{"type":50,"tag":121,"props":2640,"children":2642},{"id":2641},"escrow-pattern-error-expectations",[2643],{"type":56,"value":2644},"Escrow Pattern Error Expectations",{"type":50,"tag":66,"props":2646,"children":2647},{},[2648,2652],{"type":50,"tag":72,"props":2649,"children":2650},{},[2651],{"type":56,"value":2505},{"type":56,"value":2653}," After listing an NFT to escrow, the seller no longer owns it.",{"type":50,"tag":128,"props":2655,"children":2657},{"className":130,"code":2656,"language":40,"meta":132,"style":132},"\u002F\u002F ❌ WRONG expectation\n#[expected_failure(abort_code = marketplace::E_ALREADY_LISTED)]\npublic fun test_cannot_list_twice(seller: &signer) {\n    list_nft(seller, nft, 1000);  \u002F\u002F NFT transfers to marketplace\n    list_nft(seller, nft, 2000);  \u002F\u002F Fails with E_NOT_OWNER, not E_ALREADY_LISTED!\n}\n",[2658],{"type":50,"tag":135,"props":2659,"children":2660},{"__ignoreMap":132},[2661,2669,2677,2685,2693,2701],{"type":50,"tag":139,"props":2662,"children":2663},{"class":141,"line":142},[2664],{"type":50,"tag":139,"props":2665,"children":2666},{},[2667],{"type":56,"value":2668},"\u002F\u002F ❌ WRONG expectation\n",{"type":50,"tag":139,"props":2670,"children":2671},{"class":141,"line":151},[2672],{"type":50,"tag":139,"props":2673,"children":2674},{},[2675],{"type":56,"value":2676},"#[expected_failure(abort_code = marketplace::E_ALREADY_LISTED)]\n",{"type":50,"tag":139,"props":2678,"children":2679},{"class":141,"line":160},[2680],{"type":50,"tag":139,"props":2681,"children":2682},{},[2683],{"type":56,"value":2684},"public fun test_cannot_list_twice(seller: &signer) {\n",{"type":50,"tag":139,"props":2686,"children":2687},{"class":141,"line":169},[2688],{"type":50,"tag":139,"props":2689,"children":2690},{},[2691],{"type":56,"value":2692},"    list_nft(seller, nft, 1000);  \u002F\u002F NFT transfers to marketplace\n",{"type":50,"tag":139,"props":2694,"children":2695},{"class":141,"line":178},[2696],{"type":50,"tag":139,"props":2697,"children":2698},{},[2699],{"type":56,"value":2700},"    list_nft(seller, nft, 2000);  \u002F\u002F Fails with E_NOT_OWNER, not E_ALREADY_LISTED!\n",{"type":50,"tag":139,"props":2702,"children":2703},{"class":141,"line":187},[2704],{"type":50,"tag":139,"props":2705,"children":2706},{},[2707],{"type":56,"value":376},{"type":50,"tag":66,"props":2709,"children":2710},{},[2711,2715],{"type":50,"tag":72,"props":2712,"children":2713},{},[2714],{"type":56,"value":2546},{"type":56,"value":2716}," Understand validation order - ownership is checked before listing status.",{"type":50,"tag":128,"props":2718,"children":2720},{"className":130,"code":2719,"language":40,"meta":132,"style":132},"\u002F\u002F ✅ CORRECT expectation\n#[expected_failure(abort_code = marketplace::E_NOT_OWNER)]\npublic fun test_cannot_list_twice(seller: &signer) {\n    list_nft(seller, nft, 1000);  \u002F\u002F NFT transfers to marketplace\n    list_nft(seller, nft, 2000);  \u002F\u002F Seller doesn't own it -> E_NOT_OWNER\n}\n",[2721],{"type":50,"tag":135,"props":2722,"children":2723},{"__ignoreMap":132},[2724,2732,2740,2747,2754,2762],{"type":50,"tag":139,"props":2725,"children":2726},{"class":141,"line":142},[2727],{"type":50,"tag":139,"props":2728,"children":2729},{},[2730],{"type":56,"value":2731},"\u002F\u002F ✅ CORRECT expectation\n",{"type":50,"tag":139,"props":2733,"children":2734},{"class":141,"line":151},[2735],{"type":50,"tag":139,"props":2736,"children":2737},{},[2738],{"type":56,"value":2739},"#[expected_failure(abort_code = marketplace::E_NOT_OWNER)]\n",{"type":50,"tag":139,"props":2741,"children":2742},{"class":141,"line":160},[2743],{"type":50,"tag":139,"props":2744,"children":2745},{},[2746],{"type":56,"value":2684},{"type":50,"tag":139,"props":2748,"children":2749},{"class":141,"line":169},[2750],{"type":50,"tag":139,"props":2751,"children":2752},{},[2753],{"type":56,"value":2692},{"type":50,"tag":139,"props":2755,"children":2756},{"class":141,"line":178},[2757],{"type":50,"tag":139,"props":2758,"children":2759},{},[2760],{"type":56,"value":2761},"    list_nft(seller, nft, 2000);  \u002F\u002F Seller doesn't own it -> E_NOT_OWNER\n",{"type":50,"tag":139,"props":2763,"children":2764},{"class":141,"line":187},[2765],{"type":50,"tag":139,"props":2766,"children":2767},{},[2768],{"type":56,"value":376},{"type":50,"tag":121,"props":2770,"children":2772},{"id":2771},"acquires-annotation-errors",[2773],{"type":56,"value":2774},"Acquires Annotation Errors",{"type":50,"tag":66,"props":2776,"children":2777},{},[2778,2782],{"type":50,"tag":72,"props":2779,"children":2780},{},[2781],{"type":56,"value":2505},{"type":56,"value":2783}," Adding acquires for resources borrowed by framework functions causes errors.",{"type":50,"tag":128,"props":2785,"children":2787},{"className":130,"code":2786,"language":40,"meta":132,"style":132},"\u002F\u002F ❌ WRONG - framework handles its own acquires\npublic entry fun stake(...) acquires VaultConfig, Stakes, StakeTokenRefs {\n    primary_fungible_store::transfer(...);  \u002F\u002F Don't list what framework borrows\n}\n",[2788],{"type":50,"tag":135,"props":2789,"children":2790},{"__ignoreMap":132},[2791,2799,2807,2815],{"type":50,"tag":139,"props":2792,"children":2793},{"class":141,"line":142},[2794],{"type":50,"tag":139,"props":2795,"children":2796},{},[2797],{"type":56,"value":2798},"\u002F\u002F ❌ WRONG - framework handles its own acquires\n",{"type":50,"tag":139,"props":2800,"children":2801},{"class":141,"line":151},[2802],{"type":50,"tag":139,"props":2803,"children":2804},{},[2805],{"type":56,"value":2806},"public entry fun stake(...) acquires VaultConfig, Stakes, StakeTokenRefs {\n",{"type":50,"tag":139,"props":2808,"children":2809},{"class":141,"line":160},[2810],{"type":50,"tag":139,"props":2811,"children":2812},{},[2813],{"type":56,"value":2814},"    primary_fungible_store::transfer(...);  \u002F\u002F Don't list what framework borrows\n",{"type":50,"tag":139,"props":2816,"children":2817},{"class":141,"line":169},[2818],{"type":50,"tag":139,"props":2819,"children":2820},{},[2821],{"type":56,"value":376},{"type":50,"tag":66,"props":2823,"children":2824},{},[2825,2829],{"type":50,"tag":72,"props":2826,"children":2827},{},[2828],{"type":56,"value":2546},{"type":56,"value":2830}," Only list resources YOUR code borrows.",{"type":50,"tag":128,"props":2832,"children":2834},{"className":130,"code":2833,"language":40,"meta":132,"style":132},"\u002F\u002F ✅ CORRECT\npublic entry fun stake(...) acquires VaultConfig, Stakes {\n    let config = borrow_global\u003CVaultConfig>(...);  \u002F\u002F You borrow this\n    primary_fungible_store::transfer(...);          \u002F\u002F Framework handles its own\n}\n",[2835],{"type":50,"tag":135,"props":2836,"children":2837},{"__ignoreMap":132},[2838,2846,2854,2862,2870],{"type":50,"tag":139,"props":2839,"children":2840},{"class":141,"line":142},[2841],{"type":50,"tag":139,"props":2842,"children":2843},{},[2844],{"type":56,"value":2845},"\u002F\u002F ✅ CORRECT\n",{"type":50,"tag":139,"props":2847,"children":2848},{"class":141,"line":151},[2849],{"type":50,"tag":139,"props":2850,"children":2851},{},[2852],{"type":56,"value":2853},"public entry fun stake(...) acquires VaultConfig, Stakes {\n",{"type":50,"tag":139,"props":2855,"children":2856},{"class":141,"line":160},[2857],{"type":50,"tag":139,"props":2858,"children":2859},{},[2860],{"type":56,"value":2861},"    let config = borrow_global\u003CVaultConfig>(...);  \u002F\u002F You borrow this\n",{"type":50,"tag":139,"props":2863,"children":2864},{"class":141,"line":169},[2865],{"type":50,"tag":139,"props":2866,"children":2867},{},[2868],{"type":56,"value":2869},"    primary_fungible_store::transfer(...);          \u002F\u002F Framework handles its own\n",{"type":50,"tag":139,"props":2871,"children":2872},{"class":141,"line":178},[2873],{"type":50,"tag":139,"props":2874,"children":2875},{},[2876],{"type":56,"value":376},{"type":50,"tag":59,"props":2878,"children":2880},{"id":2879},"references",[2881],{"type":56,"value":2882},"References",{"type":50,"tag":66,"props":2884,"children":2885},{},[2886],{"type":50,"tag":72,"props":2887,"children":2888},{},[2889],{"type":56,"value":2890},"Pattern Documentation:",{"type":50,"tag":80,"props":2892,"children":2893},{},[2894,2905],{"type":50,"tag":84,"props":2895,"children":2896},{},[2897,2903],{"type":50,"tag":135,"props":2898,"children":2900},{"className":2899},[],[2901],{"type":56,"value":2902},"..\u002F..\u002F..\u002Fpatterns\u002Fmove\u002FTESTING.md",{"type":56,"value":2904}," - Comprehensive testing guide (see Pattern 8 for cross-module issues)",{"type":50,"tag":84,"props":2906,"children":2907},{},[2908,2914],{"type":50,"tag":135,"props":2909,"children":2911},{"className":2910},[],[2912],{"type":56,"value":2913},"..\u002F..\u002F..\u002Fpatterns\u002Fmove\u002FSECURITY.md",{"type":56,"value":2915}," - Security testing requirements",{"type":50,"tag":66,"props":2917,"children":2918},{},[2919],{"type":50,"tag":72,"props":2920,"children":2921},{},[2922],{"type":56,"value":2923},"Official Documentation:",{"type":50,"tag":80,"props":2925,"children":2926},{},[2927],{"type":50,"tag":84,"props":2928,"children":2929},{},[2930],{"type":50,"tag":2931,"props":2932,"children":2936},"a",{"href":2933,"rel":2934},"https:\u002F\u002Faptos.dev\u002Fbuild\u002Fsmart-contracts\u002Fbook\u002Funit-testing",[2935],"nofollow",[2937],{"type":56,"value":2933},{"type":50,"tag":66,"props":2939,"children":2940},{},[2941],{"type":50,"tag":72,"props":2942,"children":2943},{},[2944],{"type":56,"value":2945},"Related Skills:",{"type":50,"tag":80,"props":2947,"children":2948},{},[2949,2960],{"type":50,"tag":84,"props":2950,"children":2951},{},[2952,2958],{"type":50,"tag":135,"props":2953,"children":2955},{"className":2954},[],[2956],{"type":56,"value":2957},"write-contracts",{"type":56,"value":2959}," - Generate code to test",{"type":50,"tag":84,"props":2961,"children":2962},{},[2963,2969],{"type":50,"tag":135,"props":2964,"children":2966},{"className":2965},[],[2967],{"type":56,"value":2968},"security-audit",{"type":56,"value":2970}," - Verify security after testing",{"type":50,"tag":2972,"props":2973,"children":2974},"hr",{},[],{"type":50,"tag":66,"props":2976,"children":2977},{},[2978,2983],{"type":50,"tag":72,"props":2979,"children":2980},{},[2981],{"type":56,"value":2982},"Remember:",{"type":56,"value":2984}," 100% coverage is mandatory. Test happy paths, error paths, access control, and edge cases.",{"type":50,"tag":2986,"props":2987,"children":2988},"style",{},[2989],{"type":56,"value":2990},"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":2992,"total":344},[2993,3008,3027,3039,3045,3059,3073,3087,3101,3116,3126,3136],{"slug":2994,"name":2994,"fn":2995,"description":2996,"org":2997,"tags":2998,"stars":23,"repoUrl":24,"updatedAt":3007},"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},[2999,3001,3004],{"name":3000,"slug":30,"type":16},"Blockchain",{"name":3002,"slug":3003,"type":16},"Performance","performance",{"name":3005,"slug":3006,"type":16},"Smart Contracts","smart-contracts","2026-07-12T08:07:14.117466",{"slug":3009,"name":3009,"fn":3010,"description":3011,"org":3012,"tags":3013,"stars":23,"repoUrl":24,"updatedAt":3026},"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},[3014,3017,3020,3023],{"name":3015,"slug":3016,"type":16},"Next.js","next-js",{"name":3018,"slug":3019,"type":16},"TypeScript","typescript",{"name":3021,"slug":3022,"type":16},"Vite","vite",{"name":3024,"slug":3025,"type":16},"Web3","web3","2026-07-12T08:07:30.595111",{"slug":3028,"name":3028,"fn":3029,"description":3030,"org":3031,"tags":3032,"stars":23,"repoUrl":24,"updatedAt":3038},"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},[3033,3036,3037],{"name":3034,"slug":3035,"type":16},"Deployment","deployment",{"name":18,"slug":19,"type":16},{"name":3005,"slug":3006,"type":16},"2026-07-12T08:07:16.798352",{"slug":4,"name":4,"fn":5,"description":6,"org":3040,"tags":3041,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3042,3043,3044],{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"slug":3046,"name":3046,"fn":3047,"description":3048,"org":3049,"tags":3050,"stars":23,"repoUrl":24,"updatedAt":3058},"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},[3051,3054,3055],{"name":3052,"slug":3053,"type":16},"Code Analysis","code-analysis",{"name":18,"slug":19,"type":16},{"name":3056,"slug":3057,"type":16},"Migration","migration","2026-07-12T08:07:10.226223",{"slug":3060,"name":3060,"fn":3061,"description":3062,"org":3063,"tags":3064,"stars":23,"repoUrl":24,"updatedAt":3072},"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},[3065,3066,3069],{"name":3000,"slug":30,"type":16},{"name":3067,"slug":3068,"type":16},"Documentation","documentation",{"name":3070,"slug":3071,"type":16},"Search","search","2026-07-12T08:07:15.382039",{"slug":2968,"name":2968,"fn":3074,"description":3075,"org":3076,"tags":3077,"stars":23,"repoUrl":24,"updatedAt":3086},"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},[3078,3081,3082,3085],{"name":3079,"slug":3080,"type":16},"Audit","audit",{"name":3052,"slug":3053,"type":16},{"name":3083,"slug":3084,"type":16},"Security","security",{"name":3005,"slug":3006,"type":16},"2026-07-12T08:07:11.680215",{"slug":3088,"name":3088,"fn":3089,"description":3090,"org":3091,"tags":3092,"stars":23,"repoUrl":24,"updatedAt":3100},"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},[3093,3096,3099],{"name":3094,"slug":3095,"type":16},"API Development","api-development",{"name":3097,"slug":3098,"type":16},"Payments","payments",{"name":3024,"slug":3025,"type":16},"2026-07-12T08:07:31.843242",{"slug":3102,"name":3102,"fn":3103,"description":3104,"org":3105,"tags":3106,"stars":23,"repoUrl":24,"updatedAt":3115},"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},[3107,3110,3111,3114],{"name":3108,"slug":3109,"type":16},"Auth","auth",{"name":3000,"slug":30,"type":16},{"name":3112,"slug":3113,"type":16},"SDK","sdk",{"name":3018,"slug":3019,"type":16},"2026-07-12T08:07:29.297415",{"slug":3117,"name":3117,"fn":3118,"description":3119,"org":3120,"tags":3121,"stars":23,"repoUrl":24,"updatedAt":3125},"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},[3122,3123,3124],{"name":3000,"slug":30,"type":16},{"name":3112,"slug":3113,"type":16},{"name":3018,"slug":3019,"type":16},"2026-07-12T08:07:26.430378",{"slug":3127,"name":3127,"fn":3128,"description":3129,"org":3130,"tags":3131,"stars":23,"repoUrl":24,"updatedAt":3135},"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},[3132,3133,3134],{"name":3094,"slug":3095,"type":16},{"name":3112,"slug":3113,"type":16},{"name":3018,"slug":3019,"type":16},"2026-07-12T08:07:21.933342",{"slug":3137,"name":3137,"fn":3138,"description":3139,"org":3140,"tags":3141,"stars":23,"repoUrl":24,"updatedAt":3145},"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},[3142,3143,3144],{"name":3094,"slug":3095,"type":16},{"name":3018,"slug":3019,"type":16},{"name":3024,"slug":3025,"type":16},"2026-07-12T08:07:23.774257",{"items":3147,"total":284},[3148,3154,3161,3167,3173,3179,3185],{"slug":2994,"name":2994,"fn":2995,"description":2996,"org":3149,"tags":3150,"stars":23,"repoUrl":24,"updatedAt":3007},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3151,3152,3153],{"name":3000,"slug":30,"type":16},{"name":3002,"slug":3003,"type":16},{"name":3005,"slug":3006,"type":16},{"slug":3009,"name":3009,"fn":3010,"description":3011,"org":3155,"tags":3156,"stars":23,"repoUrl":24,"updatedAt":3026},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3157,3158,3159,3160],{"name":3015,"slug":3016,"type":16},{"name":3018,"slug":3019,"type":16},{"name":3021,"slug":3022,"type":16},{"name":3024,"slug":3025,"type":16},{"slug":3028,"name":3028,"fn":3029,"description":3030,"org":3162,"tags":3163,"stars":23,"repoUrl":24,"updatedAt":3038},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3164,3165,3166],{"name":3034,"slug":3035,"type":16},{"name":18,"slug":19,"type":16},{"name":3005,"slug":3006,"type":16},{"slug":4,"name":4,"fn":5,"description":6,"org":3168,"tags":3169,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3170,3171,3172],{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"slug":3046,"name":3046,"fn":3047,"description":3048,"org":3174,"tags":3175,"stars":23,"repoUrl":24,"updatedAt":3058},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3176,3177,3178],{"name":3052,"slug":3053,"type":16},{"name":18,"slug":19,"type":16},{"name":3056,"slug":3057,"type":16},{"slug":3060,"name":3060,"fn":3061,"description":3062,"org":3180,"tags":3181,"stars":23,"repoUrl":24,"updatedAt":3072},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3182,3183,3184],{"name":3000,"slug":30,"type":16},{"name":3067,"slug":3068,"type":16},{"name":3070,"slug":3071,"type":16},{"slug":2968,"name":2968,"fn":3074,"description":3075,"org":3186,"tags":3187,"stars":23,"repoUrl":24,"updatedAt":3086},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[3188,3189,3190,3191],{"name":3079,"slug":3080,"type":16},{"name":3052,"slug":3053,"type":16},{"name":3083,"slug":3084,"type":16},{"name":3005,"slug":3006,"type":16}]