[{"data":1,"prerenderedAt":646},["ShallowReactive",2],{"navigation":3,"\u002Fcontributing\u002Fmutation-testing":252,"\u002Fcontributing\u002Fmutation-testing-surround":641},[4,89,128,171,213,217,248],{"title":5,"path":6,"stem":7,"children":8,"icon":88},"Guide","\u002Fguide","1.guide\u002F01.index",[9,10,14,18,22,26,30,34,38,42,73],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"Install","\u002Fguide\u002Finstall","1.guide\u002F02.install",{"title":15,"path":16,"stem":17},"First widget","\u002Fguide\u002Ffirst-widget","1.guide\u002F03.first-widget",{"title":19,"path":20,"stem":21},"Concepts","\u002Fguide\u002Fconcepts","1.guide\u002F05.concepts",{"title":23,"path":24,"stem":25},"Apple data transport","\u002Fguide\u002Ftransport","1.guide\u002F06.transport",{"title":27,"path":28,"stem":29},"Doctor","\u002Fguide\u002Fdoctor","1.guide\u002F07.doctor",{"title":31,"path":32,"stem":33},"CLI","\u002Fguide\u002Fcli","1.guide\u002F08.cli",{"title":35,"path":36,"stem":37},"Core vs extended","\u002Fguide\u002Ftiers","1.guide\u002F09.tiers",{"title":39,"path":40,"stem":41},"Troubleshooting","\u002Fguide\u002Ftroubleshooting","1.guide\u002F10.troubleshooting",{"title":43,"path":44,"stem":45,"children":46,"icon":72},"Platform setup","\u002Fguide\u002Fsetup","1.guide\u002F12.setup\u002F1.index",[47,48,52,56,60,64,68],{"title":43,"path":44,"stem":45},{"title":49,"path":50,"stem":51},"Android setup","\u002Fguide\u002Fsetup\u002Fandroid","1.guide\u002F12.setup\u002F2.android",{"title":53,"path":54,"stem":55},"iOS setup","\u002Fguide\u002Fsetup\u002Fios","1.guide\u002F12.setup\u002F3.ios",{"title":57,"path":58,"stem":59},"macOS setup","\u002Fguide\u002Fsetup\u002Fmacos","1.guide\u002F12.setup\u002F4.macos",{"title":61,"path":62,"stem":63},"Windows setup","\u002Fguide\u002Fsetup\u002Fwindows","1.guide\u002F12.setup\u002F5.windows",{"title":65,"path":66,"stem":67},"Linux setup","\u002Fguide\u002Fsetup\u002Flinux","1.guide\u002F12.setup\u002F6.linux",{"title":69,"path":70,"stem":71},"Desktop webview","\u002Fguide\u002Fsetup\u002Fdesktop","1.guide\u002F12.setup\u002F7.desktop","i-lucide-monitor-smartphone",{"title":74,"icon":75,"path":76,"stem":77,"children":78,"page":87},"Recipes","i-lucide-chef-hat","\u002Fguide\u002Frecipes","1.guide\u002F13.recipes",[79,83],{"title":80,"path":81,"stem":82},"Multi-widget","\u002Fguide\u002Frecipes\u002Fmulti-widget","1.guide\u002F13.recipes\u002F4.multi-widget",{"title":84,"path":85,"stem":86},"Testing your widget","\u002Fguide\u002Frecipes\u002Ftesting","1.guide\u002F13.recipes\u002F5.testing",false,"i-lucide-rocket",{"title":90,"path":91,"stem":92,"children":93,"icon":127},"Elements","\u002Felements","2.elements\u002F1.index",[94,95,99,103,107,111,115,119,123],{"title":90,"path":91,"stem":92},{"title":96,"path":97,"stem":98},"Layout elements","\u002Felements\u002Flayout","2.elements\u002F2.layout",{"title":100,"path":101,"stem":102},"Text elements","\u002Felements\u002Ftext","2.elements\u002F3.text",{"title":104,"path":105,"stem":106},"Media elements","\u002Felements\u002Fmedia","2.elements\u002F4.media",{"title":108,"path":109,"stem":110},"Data elements","\u002Felements\u002Fdata","2.elements\u002F5.data",{"title":112,"path":113,"stem":114},"Interactive elements","\u002Felements\u002Finteractive","2.elements\u002F6.interactive",{"title":116,"path":117,"stem":118},"Spacing elements","\u002Felements\u002Fspacing","2.elements\u002F7.spacing",{"title":120,"path":121,"stem":122},"Style","\u002Felements\u002Fstyle","2.elements\u002F8.style",{"title":124,"path":125,"stem":126},"Colors","\u002Felements\u002Fcolors","2.elements\u002F9.colors","i-lucide-blocks",{"title":129,"path":130,"stem":131,"children":132,"icon":170},"Features","\u002Ffeatures","2.features\u002F01.index",[133,134,138,142,146,150,154,158,162,166],{"title":129,"path":130,"stem":131},{"title":135,"path":136,"stem":137},"Dynamic Island","\u002Ffeatures\u002Fdynamic-island","2.features\u002F02.dynamic-island",{"title":139,"path":140,"stem":141},"Interactive widgets","\u002Ffeatures\u002Finteractive","2.features\u002F03.interactive",{"title":143,"path":144,"stem":145},"Live activities","\u002Ffeatures\u002Flive-activities","2.features\u002F04.live-activities",{"title":147,"path":148,"stem":149},"Timelines and transitions","\u002Ffeatures\u002Ftimelines","2.features\u002F05.timelines",{"title":151,"path":152,"stem":153},"Remote data","\u002Ffeatures\u002Fremote-data","2.features\u002F06.remote-data",{"title":155,"path":156,"stem":157},"Widget updater","\u002Ffeatures\u002Fwidget-updater","2.features\u002F07.widget-updater",{"title":159,"path":160,"stem":161},"Instances","\u002Ffeatures\u002Finstances","2.features\u002F08.instances",{"title":163,"path":164,"stem":165},"Conditions, lists and templates","\u002Ffeatures\u002Fdynamic-content","2.features\u002F09.dynamic-content",{"title":167,"path":168,"stem":169},"Images","\u002Ffeatures\u002Fimages","2.features\u002F10.images","i-lucide-sparkles",{"title":172,"icon":173,"path":174,"stem":175,"children":176,"page":87},"API","i-lucide-file-code","\u002Fapi","3.api",[177,181,185,189,193,197,201,205,209],{"title":178,"path":179,"stem":180},"JavaScript API","\u002Fapi\u002Fjs","3.api\u002F1.js",{"title":182,"path":183,"stem":184},"JS reference","\u002Fapi\u002Freference","3.api\u002F2.reference",{"title":186,"path":187,"stem":188},"Rust API","\u002Fapi\u002Frust","3.api\u002F3.rust",{"title":190,"path":191,"stem":192},"Tauri commands","\u002Fapi\u002Fcommands","3.api\u002F4.commands",{"title":194,"path":195,"stem":196},"Plugin config","\u002Fapi\u002Fplugin-config","3.api\u002F5.plugin-config",{"title":198,"path":199,"stem":200},"Cargo features","\u002Fapi\u002Fcargo-features","3.api\u002F6.cargo-features",{"title":202,"path":203,"stem":204},"Environment variables","\u002Fapi\u002Fenv","3.api\u002F7.env",{"title":206,"path":207,"stem":208},"Permissions","\u002Fapi\u002Fpermissions","3.api\u002F8.permissions",{"title":210,"path":211,"stem":212},"JSON Schema","\u002Fapi\u002Fjson-schema","3.api\u002F9.json-schema",{"title":214,"path":215,"stem":216},"Showcase","\u002Fshowcase","4.showcase",{"title":218,"path":219,"stem":220,"children":221,"icon":247},"Contributing","\u002Fcontributing","5.contributing\u002F1.index",[222,223,227,231,235,239,243],{"title":218,"path":219,"stem":220},{"title":224,"path":225,"stem":226},"Development guide","\u002Fcontributing\u002Fdevelopment","5.contributing\u002F2.development",{"title":228,"path":229,"stem":230},"Render testing (config → geometry \u002F pixels)","\u002Fcontributing\u002Frender-testing","5.contributing\u002F3.render-testing",{"title":232,"path":233,"stem":234},"Visual stand (Level-2 pixels)","\u002Fcontributing\u002Fvisual-stand","5.contributing\u002F4.visual-stand",{"title":236,"path":237,"stem":238},"Linux harness (Docker)","\u002Fcontributing\u002Flinux-harness","5.contributing\u002F5.linux-harness",{"title":240,"path":241,"stem":242},"Windows surface split","\u002Fcontributing\u002Fwindows-surfaces","5.contributing\u002F6.windows-surfaces",{"title":244,"path":245,"stem":246},"Mutation testing","\u002Fcontributing\u002Fmutation-testing","5.contributing\u002F7.mutation-testing","i-lucide-git-pull-request",{"title":249,"path":250,"stem":251},"Changelog","\u002Fchangelog","6.changelog",{"id":253,"title":244,"body":254,"description":634,"extension":635,"generated":87,"links":636,"meta":637,"navigation":638,"path":245,"seo":639,"stem":246,"__hash__":640},"docs\u002F5.contributing\u002F7.mutation-testing.md",{"type":255,"value":256,"toc":625},"minimark",[257,279,286,444,459,464,472,509,513,576,580,604,608],[258,259,260,261,265,266,269,270,273,274,278],"p",{},"Unit tests pass is not proof they check anything. Mutation testing changes the code (a ",[262,263,264],"code",{},"\u003C","\ninto ",[262,267,268],{},"\u003C=",", a branch into ",[262,271,272],{},"true",") and expects some test to fail; a mutant that ",[275,276,277],"strong",{},"survives","\nmarks code no test watches. Fix the test, not the config.",[258,280,281,282,285],{},"Run the tools ",[275,283,284],{},"one at a time"," — each compiles and runs the suite hundreds of times.",[287,288,289,311],"table",{},[290,291,292],"thead",{},[293,294,295,299,302,305,308],"tr",{},[296,297,298],"th",{},"Layer",[296,300,301],{},"Tool",[296,303,304],{},"Command",[296,306,307],{},"Scope \u002F config",[296,309,310],{},"Report",[312,313,314,344,377,413],"tbody",{},[293,315,316,320,329,334,339],{},[317,318,319],"td",{},"Rust",[317,321,322],{},[323,324,328],"a",{"href":325,"rel":326},"https:\u002F\u002Fmutants.rs",[327],"nofollow","cargo-mutants",[317,330,331],{},[262,332,333],{},"pnpm mutants:rust",[317,335,336],{},[262,337,338],{},".cargo\u002Fmutants.toml",[317,340,341],{},[262,342,343],{},"mutants.out\u002F",[293,345,346,349,357,362,372],{},[317,347,348],{},"TypeScript",[317,350,351,356],{},[323,352,355],{"href":353,"rel":354},"https:\u002F\u002Fstryker-mutator.io",[327],"Stryker"," + vitest",[317,358,359],{},[262,360,361],{},"pnpm mutants:js",[317,363,364,367,368,371],{},[262,365,366],{},"stryker.config.json"," (",[262,369,370],{},"mutate",")",[317,373,374],{},[262,375,376],{},"reports\u002Fmutation\u002Fmutation.html",[293,378,379,382,390,395,408],{},[317,380,381],{},"Kotlin",[317,383,384,389],{},[323,385,388],{"href":386,"rel":387},"https:\u002F\u002Fpitest.org",[327],"PIT"," (gradle-pitest-plugin)",[317,391,392],{},[262,393,394],{},"pnpm mutants:kotlin",[317,396,397,400,401,404,405],{},[262,398,399],{},"android\u002Fpitest.gradle",", applied from ",[262,402,403],{},"build.gradle.kts"," only with ",[262,406,407],{},"-Ppitest=true",[317,409,410],{},[262,411,412],{},"android\u002Fbuild\u002Freports\u002Fpitest\u002F",[293,414,415,418,425,430,439],{},[317,416,417],{},"Swift",[317,419,420],{},[323,421,424],{"href":422,"rel":423},"https:\u002F\u002Fgithub.com\u002Fmuter-mutation-testing\u002Fmuter",[327],"Muter",[317,426,427],{},[262,428,429],{},"pnpm mutants:swift",[317,431,432,435,436],{},[262,433,434],{},"swift\u002Fmuter.conf.yml"," + ",[262,437,438],{},"--files-to-mutate Resolve.swift",[317,440,441],{},[262,442,443],{},"swift\u002Fmuter_logs\u002F",[258,445,446,447,450,451,454,455,458],{},"Install once: ",[262,448,449],{},"cargo install --locked cargo-mutants",", ",[262,452,453],{},"brew install muter-mutation-testing\u002Fformulae\u002Fmuter",".\nStryker and vitest come with ",[262,456,457],{},"pnpm install","; PIT is fetched by Gradle.",[460,461,463],"h2",{"id":462},"speed-first","Speed first",[258,465,466,467,471],{},"A mutation run costs ",[468,469,470],"em",{},"mutants × (rebuild + tests)",", so slow tests multiply. Before a run:",[473,474,475,491],"ul",{},[476,477,478,479,482,483,486,487,490],"li",{},"Rust: ",[262,480,481],{},"[profile.dev.package.\"*\"] opt-level = 2"," optimizes dependencies only (the resvg\nraster tests went 4.1 s → 0.8 s), and ",[262,484,485],{},"[profile.mutants]"," drops debug info (rebuild per\nmutant 3.2 s → 2.4 s). Find slow tests with the loop in the commit that added this page\nor ",[262,488,489],{},"cargo test -- -Z unstable-options --report-time"," on nightly.",[476,492,493,494,497,498,501,502,367,505,508],{},"Keep each tool on code its unit tests reach: Stryker mutates ",[262,495,496],{},"widget-src\u002Fresolve.ts",",\nPIT the pure Kotlin classes (",[262,499,500],{},"Resolve",", store keys, scheduler math), Muter only\n",[262,503,504],{},"Resolve.swift",[262,506,507],{},"--files-to-mutate","). UI code is covered by the golden-image stands instead.",[460,510,512],{"id":511},"current-scores","Current scores",[287,514,515,524],{},[290,516,517],{},[293,518,519,521],{},[296,520,298],{},[296,522,523],{},"Result",[312,525,526,547,556,563],{},[293,527,528,530],{},[317,529,319],{},[317,531,532,533,535,536,538,539,542,543,546],{},"5 survivors left, all equivalent: TTL ",[262,534,264],{}," \u002F ",[262,537,268],{}," boundaries, and the ",[262,540,541],{},"image.url"," ",[262,544,545],{},"!"," where the cell is full on every platform",[293,548,549,551],{},[317,550,348],{},[317,552,553,554],{},"97.6% on ",[262,555,496],{},[293,557,558,560],{},[317,559,381],{},[317,561,562],{},"91% killed, 99% line coverage of the targeted classes",[293,564,565,567],{},[317,566,417],{},[317,568,569,570,542,572,575],{},"96%; the one reported survivor (the bool ternary in ",[262,571,504],{},[262,573,574],{},"text()",") is a Muter false positive — the test fails when that mutation is applied by hand",[460,577,579],{"id":578},"local-only","Local only",[258,581,582,583,450,585,450,588,591,592,595,596,599,600,603],{},"Mutation tools are not run in CI: run them locally, one tool at a time, after the feature\nwork and the scenario tests are done (",[262,584,333],{},[262,586,587],{},"mutants:js",[262,589,590],{},"mutants:kotlin",",\n",[262,593,594],{},"mutants:swift","). cargo-mutants without ",[262,597,598],{},"-j"," when other heavy work shares the machine.\nChanged lines only: ",[262,601,602],{},"git diff main -- '*.rs' > pr.diff && cargo mutants --in-diff pr.diff",".",[460,605,607],{"id":606},"shared-fixtures","Shared fixtures",[258,609,610,613,614,591,617,450,619,450,621,624],{},[262,611,612],{},"tests\u002Ffixtures\u002Fresolve\u002F*.json"," are run by all four ports (",[262,615,616],{},"src\u002Fresolve.rs",[262,618,496],{},[262,620,504],{},[262,622,623],{},"Resolve.kt","). Add a case there when the\ncontract changes; every platform then has to agree.",{"title":626,"searchDepth":627,"depth":628,"links":629},"",2,3,[630,631,632,633],{"id":462,"depth":627,"text":463},{"id":511,"depth":627,"text":512},{"id":578,"depth":627,"text":579},{"id":606,"depth":627,"text":607},"Unit tests pass is not proof they check anything. Mutation testing changes the code (a \u003C\ninto \u003C=, a branch into true) and expects some test to fail; a mutant that survives\nmarks code no test watches. Fix the test, not the config.","md",null,{},true,{"title":244,"description":634},"hJYbHlJ_6uPx9HBe1tQ7QtnW2TBxmLsH1u0ZEu11oIw",[642,644],{"title":240,"path":241,"stem":242,"description":643,"children":-1},"Two independent Windows integrations. Do not mix them in one code path.",{"title":249,"path":250,"stem":251,"description":645,"children":-1},"All notable changes to tauri-plugin-widgets and tauri-plugin-widgets-api.",1794660592225]