[{"data":1,"prerenderedAt":1402},["ShallowReactive",2],{"navigation":3,"\u002Fguides\u002Fblueprints":170,"\u002Fguides\u002Fblueprints-surround":1397},[4,25,104,150,160],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-rocket",{"title":26,"icon":6,"path":27,"stem":28,"children":29,"page":6},"Guides","\u002Fguides","2.guides",[30,35,40,45,50,55,60,65,70,75,79,84,89,94,99],{"title":31,"path":32,"stem":33,"icon":34},"Seeds and TestBiome","\u002Fguides\u002Fseeds-and-testbiome","2.guides\u002F01.seeds-and-testbiome","i-lucide-sprout",{"title":36,"path":37,"stem":38,"icon":39},"Blueprints","\u002Fguides\u002Fblueprints","2.guides\u002F02.blueprints","i-lucide-drafting-compass",{"title":41,"path":42,"stem":43,"icon":44},"Customizing","\u002Fguides\u002Fcustomizing","2.guides\u002F03.customizing","i-lucide-sliders-horizontal",{"title":46,"path":47,"stem":48,"icon":49},"Parent\u002Fchild chains and .Under","\u002Fguides\u002Fparents-and-children","2.guides\u002F04.parents-and-children","i-lucide-git-fork",{"title":51,"path":52,"stem":53,"icon":54},"Fan-out","\u002Fguides\u002Ffan-out","2.guides\u002F05.fan-out","i-lucide-split",{"title":56,"path":57,"stem":58,"icon":59},"Sequences","\u002Fguides\u002Fsequences","2.guides\u002F06.sequences","i-lucide-list-ordered",{"title":61,"path":62,"stem":63,"icon":64},"Time and precision","\u002Fguides\u002Ftime-and-precision","2.guides\u002F07.time-and-precision","i-lucide-clock",{"title":66,"path":67,"stem":68,"icon":69},"Transients","\u002Fguides\u002Ftransients","2.guides\u002F08.transients","i-lucide-ghost",{"title":71,"path":72,"stem":73,"icon":74},"Aggregates","\u002Fguides\u002Faggregates","2.guides\u002F09.aggregates","i-lucide-boxes",{"title":76,"path":77,"stem":78,"icon":74},"Input blueprints","\u002Fguides\u002Finput-blueprints","2.guides\u002F09.input-blueprints",{"title":80,"path":81,"stem":82,"icon":83},"Save hooks and global defaults","\u002Fguides\u002Fsave-hooks-and-defaults","2.guides\u002F10.save-hooks-and-defaults","i-lucide-webhook",{"title":85,"path":86,"stem":87,"icon":88},"EF Core store","\u002Fguides\u002Fef-core-store","2.guides\u002F11.ef-core-store","i-lucide-database",{"title":90,"path":91,"stem":92,"icon":93},"No-DB unit tests","\u002Fguides\u002Fno-db-unit-tests","2.guides\u002F12.no-db-unit-tests","i-lucide-flask-conical",{"title":95,"path":96,"stem":97,"icon":98},"Generated grafts and scenario helpers","\u002Fguides\u002Fscenario-helpers-and-sugar","2.guides\u002F13.scenario-helpers-and-sugar","i-lucide-wand-sparkles",{"title":100,"path":101,"stem":102,"icon":103},"Constructor setup","\u002Fguides\u002Fconstructor-setup","2.guides\u002F14.constructor-setup","i-lucide-blocks",{"title":105,"path":106,"stem":107,"children":108,"icon":6},"Examples","\u002Fexamples","3.examples\u002F1.index",[109,111,116,121,126,130,135,140,145],{"title":105,"path":106,"stem":107,"icon":110},"i-lucide-library",{"title":112,"path":113,"stem":114,"icon":115},"Code reviews","\u002Fexamples\u002Fcode-reviews","3.examples\u002F2.code-reviews","i-lucide-git-pull-request",{"title":117,"path":118,"stem":119,"icon":120},"Membership","\u002Fexamples\u002Fmembership","3.examples\u002F3.membership","i-lucide-users",{"title":122,"path":123,"stem":124,"icon":125},"Board","\u002Fexamples\u002Fboard","3.examples\u002F4.board","i-lucide-kanban",{"title":127,"path":128,"stem":129,"icon":44},"Custom seed","\u002Fexamples\u002Fcustom-seed","3.examples\u002F5.custom-seed",{"title":131,"path":132,"stem":133,"icon":134},"Commerce","\u002Fexamples\u002Fcommerce","3.examples\u002F6.commerce","i-lucide-shopping-cart",{"title":136,"path":137,"stem":138,"icon":139},"Project management","\u002Fexamples\u002Fproject-management","3.examples\u002F7.project-management","i-lucide-folder-kanban",{"title":141,"path":142,"stem":143,"icon":144},"Learning","\u002Fexamples\u002Flearning","3.examples\u002F8.learning","i-lucide-graduation-cap",{"title":146,"path":147,"stem":148,"icon":149},"Docs ingest","\u002Fexamples\u002Fdocs-ingest","3.examples\u002F9.docs-ingest","i-lucide-file-search",{"title":151,"icon":6,"path":152,"stem":153,"children":154,"page":6},"Reference","\u002Freference","4.reference",[155],{"title":156,"path":157,"stem":158,"icon":159},"API cheat sheet","\u002Freference\u002Fapi-cheat-sheet","4.reference\u002F1.api-cheat-sheet","i-lucide-list-checks",{"title":161,"icon":6,"path":162,"stem":163,"children":164,"page":6},"Agent Skills","\u002Fagents","5.agents",[165],{"title":166,"path":167,"stem":168,"icon":169},"Agent skills","\u002Fagents\u002Fagent-skills","5.agents\u002F1.agent-skills","i-lucide-bot",{"id":171,"title":36,"body":172,"description":1390,"extension":1391,"links":1392,"meta":1393,"navigation":1394,"path":37,"seo":1395,"stem":38,"__hash__":1396},"docs\u002F2.guides\u002F02.blueprints.md",{"type":173,"value":174,"toc":1384},"minimark",[175,189,278,284,289,881,887,1007,1011,1014,1071,1087,1112,1116,1119,1215,1274,1284,1288,1364,1380],[176,177,178,179,183,184,188],"p",{},"Writing a valid entity often takes more properties than the test actually cares about. A ",[180,181,182],"strong",{},"blueprint"," keeps those routine choices in one factory, leaving the test free to describe its scenario. Declare it as a ",[185,186,187],"code",{},"static readonly"," value with valid defaults. Choose among these forms based on the relationship you need:",[190,191,192,208],"table",{},[193,194,195],"thead",{},[196,197,198,202,205],"tr",{},[199,200,201],"th",{},"Kind",[199,203,204],{},"Factory",[199,206,207],{},"Use for",[209,210,211,227,242,263],"tbody",{},[196,212,213,219,224],{},[214,215,216],"td",{},[185,217,218],{},"Blueprint\u003CTSeed, T>",[214,220,221],{},[185,222,223],{},"Blueprint.For\u003CTSeed, T>(ctx => new() { … })",[214,225,226],{},"A root entity",[196,228,229,234,239],{},[214,230,231],{},[185,232,233],{},"ChildBlueprint\u003CTSeed, TParent, T>",[214,235,236],{},[185,237,238],{},"Blueprint.ChildOf\u003CTSeed, TParent, T>((parent, ctx) => new() { … })",[214,240,241],{},"An entity that belongs to a parent",[196,243,244,249,254],{},[214,245,246],{},[185,247,248],{},"InputBlueprint\u003CTSeed, TInput, T>",[214,250,251],{},[185,252,253],{},"Blueprint.FromInput\u003CTSeed, TInput, T>(() => new(), (input, ctx) => …)",[214,255,256,257,262],{},"A root entity (or ",[258,259,261],"a",{"href":260},"\u002Fguides\u002Finput-blueprints#aggregates-one-input-several-rows","group of rows",") built from a customizable input",[196,264,265,270,275],{},[214,266,267],{},[185,268,269],{},"ChildInputBlueprint\u003CTSeed, TParent, TInput, T>",[214,271,272],{},[185,273,274],{},"Blueprint.ChildFromInput\u003CTSeed, TParent, TInput, T>(() => new(), (parent, input, ctx) => …)",[214,276,277],{},"A child built from a customizable input",[176,279,280,281,283],{},"The two input forms are for rows that tests cannot edit after construction, such as init-only properties. See ",[258,282,76],{"href":77}," and check that the package referenced by your project exposes the form you use.",[285,286,288],"h2",{"id":287},"a-root-blueprint","A root blueprint",[290,291,292,554],"code-group",{},[293,294,304],"pre",{"className":295,"code":296,"filename":297,"highlights":298,"language":302,"meta":303,"style":303},"language-csharp shiki shiki-themes material-theme-lighter github-light github-dark","public static partial class Blueprints\n{\n    public static readonly Blueprint\u003CZeeqSeed, CodeRepository> Repository =\n        Blueprint.For\u003CZeeqSeed, CodeRepository>(ctx =>\n            new()\n            {\n                Id = ctx.NewId(\"repo\"), \u002F\u002F \"repo_\u003Cuuidv7>\"\n                OrganizationId = ctx.Seed.Organization.Id,\n                OwnerQualifiedName = \"zeeq-ai\u002Fexample\",\n                Enabled = true,\n                CreatedAtUtc = ctx.Now, \u002F\u002F never DateTimeOffset.UtcNow\n            }\n        );\n}\n","Blueprints.cs",[299,300,301],7,8,11,"csharp","",[185,305,306,329,336,372,403,412,418,456,484,502,516,536,542,548],{"__ignoreMap":303},[307,308,311,315,318,321,325],"span",{"class":309,"line":310},"line",1,[307,312,314],{"class":313},"sbsja","public",[307,316,317],{"class":313}," static",[307,319,320],{"class":313}," partial",[307,322,324],{"class":323},"sG8yY"," class",[307,326,328],{"class":327},"sbgvK"," Blueprints\n",[307,330,332],{"class":309,"line":331},2,[307,333,335],{"class":334},"sP7_E","{\n",[307,337,339,342,344,347,350,353,356,359,362,365,368],{"class":309,"line":338},3,[307,340,341],{"class":313},"    public",[307,343,317],{"class":313},[307,345,346],{"class":313}," readonly",[307,348,349],{"class":327}," Blueprint",[307,351,352],{"class":334},"\u003C",[307,354,355],{"class":327},"ZeeqSeed",[307,357,358],{"class":334},",",[307,360,361],{"class":327}," CodeRepository",[307,363,364],{"class":334},">",[307,366,367],{"class":327}," Repository",[307,369,371],{"class":370},"smGrS"," =\n",[307,373,375,379,382,386,388,390,392,394,397,400],{"class":309,"line":374},4,[307,376,378],{"class":377},"su5hD","        Blueprint",[307,380,381],{"class":334},".",[307,383,385],{"class":384},"sGLFI","For",[307,387,352],{"class":334},[307,389,355],{"class":327},[307,391,358],{"class":334},[307,393,361],{"class":327},[307,395,396],{"class":334},">(",[307,398,399],{"class":327},"ctx",[307,401,402],{"class":370}," =>\n",[307,404,406,409],{"class":309,"line":405},5,[307,407,408],{"class":370},"            new",[307,410,411],{"class":334},"()\n",[307,413,415],{"class":309,"line":414},6,[307,416,417],{"class":334},"            {\n",[307,419,422,425,428,431,433,436,439,443,447,449,452],{"class":420,"line":299},[309,421],"highlight",[307,423,424],{"class":377},"                Id ",[307,426,427],{"class":370},"=",[307,429,430],{"class":377}," ctx",[307,432,381],{"class":334},[307,434,435],{"class":384},"NewId",[307,437,438],{"class":334},"(",[307,440,442],{"class":441},"sjJ54","\"",[307,444,446],{"class":445},"s_sjI","repo",[307,448,442],{"class":441},[307,450,451],{"class":334},"),",[307,453,455],{"class":454},"sutJx"," \u002F\u002F \"repo_\u003Cuuidv7>\"\n",[307,457,459,462,464,466,468,471,473,476,478,481],{"class":458,"line":300},[309,421],[307,460,461],{"class":377},"                OrganizationId ",[307,463,427],{"class":370},[307,465,430],{"class":377},[307,467,381],{"class":334},[307,469,470],{"class":377},"Seed",[307,472,381],{"class":334},[307,474,475],{"class":377},"Organization",[307,477,381],{"class":334},[307,479,480],{"class":377},"Id",[307,482,483],{"class":334},",\n",[307,485,487,490,492,495,498,500],{"class":309,"line":486},9,[307,488,489],{"class":377},"                OwnerQualifiedName ",[307,491,427],{"class":370},[307,493,494],{"class":441}," \"",[307,496,497],{"class":445},"zeeq-ai\u002Fexample",[307,499,442],{"class":441},[307,501,483],{"class":334},[307,503,505,508,510,514],{"class":309,"line":504},10,[307,506,507],{"class":377},"                Enabled ",[307,509,427],{"class":370},[307,511,513],{"class":512},"syTEX"," true",[307,515,483],{"class":334},[307,517,519,522,524,526,528,531,533],{"class":518,"line":301},[309,421],[307,520,521],{"class":377},"                CreatedAtUtc ",[307,523,427],{"class":370},[307,525,430],{"class":377},[307,527,381],{"class":334},[307,529,530],{"class":377},"Now",[307,532,358],{"class":334},[307,534,535],{"class":454}," \u002F\u002F never DateTimeOffset.UtcNow\n",[307,537,539],{"class":309,"line":538},12,[307,540,541],{"class":334},"            }\n",[307,543,545],{"class":309,"line":544},13,[307,546,547],{"class":334},"        );\n",[307,549,551],{"class":309,"line":550},14,[307,552,553],{"class":334},"}\n",[555,556,559],"code-collapse",{"label":557,"name":558},"Without Biome","setup",[293,560,562],{"className":295,"code":561,"language":302,"meta":303,"style":303},"\u002F\u002F A factory method in a helper class: no sequences, no clock, no parent wiring,\n\u002F\u002F and every test must remember to pass the right organization.\npublic static class TestData\n{\n    public static CodeRepository Repository(\n        Organization organization,\n        string? ownerQualifiedName = null,\n        bool enabled = true,\n        DateTimeOffset? createdAtUtc = null\n    )\n    {\n        var now = DateTimeOffset.UtcNow;\n        return new CodeRepository\n        {\n            Id = $\"repo_{Guid.CreateVersion7():N}\",\n            OrganizationId = organization.Id,\n            OwnerQualifiedName = ownerQualifiedName ?? \"zeeq-ai\u002Fexample\",\n            Enabled = enabled,\n            CreatedAtUtc =\n                createdAtUtc\n                ?? new DateTimeOffset(now.Ticks - now.Ticks % 10, TimeSpan.Zero),\n        };\n    }\n}\n",[185,563,564,569,574,585,589,602,612,632,646,661,666,671,692,704,709,750,766,788,800,809,815,864,870,876],{"__ignoreMap":303},[307,565,566],{"class":309,"line":310},[307,567,568],{"class":454},"\u002F\u002F A factory method in a helper class: no sequences, no clock, no parent wiring,\n",[307,570,571],{"class":309,"line":331},[307,572,573],{"class":454},"\u002F\u002F and every test must remember to pass the right organization.\n",[307,575,576,578,580,582],{"class":309,"line":338},[307,577,314],{"class":313},[307,579,317],{"class":313},[307,581,324],{"class":323},[307,583,584],{"class":327}," TestData\n",[307,586,587],{"class":309,"line":374},[307,588,335],{"class":334},[307,590,591,593,595,597,599],{"class":309,"line":405},[307,592,341],{"class":313},[307,594,317],{"class":313},[307,596,361],{"class":327},[307,598,367],{"class":384},[307,600,601],{"class":334},"(\n",[307,603,604,607,610],{"class":309,"line":414},[307,605,606],{"class":327},"        Organization",[307,608,609],{"class":327}," organization",[307,611,483],{"class":334},[307,613,614,617,620,623,626,630],{"class":309,"line":299},[307,615,616],{"class":370},"        string",[307,618,619],{"class":334},"?",[307,621,622],{"class":327}," ownerQualifiedName",[307,624,625],{"class":370}," =",[307,627,629],{"class":628},"s39Yj"," null",[307,631,483],{"class":334},[307,633,634,637,640,642,644],{"class":309,"line":300},[307,635,636],{"class":370},"        bool",[307,638,639],{"class":327}," enabled",[307,641,625],{"class":370},[307,643,513],{"class":512},[307,645,483],{"class":334},[307,647,648,651,653,656,658],{"class":309,"line":486},[307,649,650],{"class":327},"        DateTimeOffset",[307,652,619],{"class":334},[307,654,655],{"class":327}," createdAtUtc",[307,657,625],{"class":370},[307,659,660],{"class":628}," null\n",[307,662,663],{"class":309,"line":504},[307,664,665],{"class":334},"    )\n",[307,667,668],{"class":309,"line":301},[307,669,670],{"class":334},"    {\n",[307,672,673,676,679,681,684,686,689],{"class":309,"line":538},[307,674,675],{"class":323},"        var",[307,677,678],{"class":327}," now",[307,680,625],{"class":370},[307,682,683],{"class":377}," DateTimeOffset",[307,685,381],{"class":334},[307,687,688],{"class":377},"UtcNow",[307,690,691],{"class":334},";\n",[307,693,694,698,701],{"class":309,"line":544},[307,695,697],{"class":696},"sVHd0","        return",[307,699,700],{"class":370}," new",[307,702,703],{"class":327}," CodeRepository\n",[307,705,706],{"class":309,"line":550},[307,707,708],{"class":334},"        {\n",[307,710,712,715,717,720,723,726,729,731,734,737,740,743,746,748],{"class":309,"line":711},15,[307,713,714],{"class":377},"            Id ",[307,716,427],{"class":370},[307,718,719],{"class":441}," $\"",[307,721,722],{"class":445},"repo_",[307,724,725],{"class":441},"{",[307,727,728],{"class":377},"Guid",[307,730,381],{"class":441},[307,732,733],{"class":384},"CreateVersion7",[307,735,736],{"class":441},"()",[307,738,739],{"class":370},":",[307,741,742],{"class":377},"N",[307,744,745],{"class":441},"}",[307,747,442],{"class":441},[307,749,483],{"class":334},[307,751,753,756,758,760,762,764],{"class":309,"line":752},16,[307,754,755],{"class":377},"            OrganizationId ",[307,757,427],{"class":370},[307,759,609],{"class":377},[307,761,381],{"class":334},[307,763,480],{"class":377},[307,765,483],{"class":334},[307,767,769,772,774,777,780,782,784,786],{"class":309,"line":768},17,[307,770,771],{"class":377},"            OwnerQualifiedName ",[307,773,427],{"class":370},[307,775,776],{"class":377}," ownerQualifiedName ",[307,778,779],{"class":370},"??",[307,781,494],{"class":441},[307,783,497],{"class":445},[307,785,442],{"class":441},[307,787,483],{"class":334},[307,789,791,794,796,798],{"class":309,"line":790},18,[307,792,793],{"class":377},"            Enabled ",[307,795,427],{"class":370},[307,797,639],{"class":377},[307,799,483],{"class":334},[307,801,803,806],{"class":309,"line":802},19,[307,804,805],{"class":377},"            CreatedAtUtc ",[307,807,808],{"class":370},"=\n",[307,810,812],{"class":309,"line":811},20,[307,813,814],{"class":377},"                createdAtUtc\n",[307,816,818,821,823,825,827,830,832,835,838,840,842,844,847,851,853,856,858,861],{"class":309,"line":817},21,[307,819,820],{"class":370},"                ??",[307,822,700],{"class":370},[307,824,683],{"class":327},[307,826,438],{"class":334},[307,828,829],{"class":377},"now",[307,831,381],{"class":334},[307,833,834],{"class":377},"Ticks ",[307,836,837],{"class":370},"-",[307,839,678],{"class":377},[307,841,381],{"class":334},[307,843,834],{"class":377},[307,845,846],{"class":370},"%",[307,848,850],{"class":849},"srdBf"," 10",[307,852,358],{"class":334},[307,854,855],{"class":377}," TimeSpan",[307,857,381],{"class":334},[307,859,860],{"class":377},"Zero",[307,862,863],{"class":334},"),\n",[307,865,867],{"class":309,"line":866},22,[307,868,869],{"class":334},"        };\n",[307,871,873],{"class":309,"line":872},23,[307,874,875],{"class":334},"    }\n",[307,877,879],{"class":309,"line":878},24,[307,880,553],{"class":334},[176,882,883,884,886],{},"The factory receives a context (",[185,885,399],{},"):",[190,888,889,899],{},[193,890,891],{},[196,892,893,896],{},[199,894,895],{},"Member",[199,897,898],{},"Use",[209,900,901,911,928,941,954,967,981,994],{},[196,902,903,908],{},[214,904,905],{},[185,906,907],{},"ctx.Seed",[214,909,910],{},"The baseline rows (organization, owner).",[196,912,913,925],{},[214,914,915,918,919,918,922],{},[185,916,917],{},"ctx.Now",", ",[185,920,921],{},"ctx.Ago(t)",[185,923,924],{},"ctx.FromNow(t)",[214,926,927],{},"The session clock, already rounded.",[196,929,930,935],{},[214,931,932],{},[185,933,934],{},"ctx.NewId(\"prefix\")",[214,936,937,940],{},[185,938,939],{},"prefix_\u003Cuuidv7>"," unless options override it.",[196,942,943,948],{},[214,944,945],{},[185,946,947],{},"ctx.Index",[214,949,950,951],{},"Position in this Add. ",[180,952,953],{},"Cosmetic values only.",[196,955,956,961],{},[214,957,958],{},[185,959,960],{},"ctx.Next(seq)",[214,962,963,964,381],{},"Advance a sequence manually. Prefer ",[185,965,966],{},"Derive(prop, seq)",[196,968,969,974],{},[214,970,971],{},[185,972,973],{},"ctx.Ancestor\u003CT>()",[214,975,976,977,980],{},"Nearest ancestor of type ",[185,978,979],{},"T",". Throws a clear error if none.",[196,982,983,991],{},[214,984,985,918,988],{},[185,986,987],{},"ctx.All\u003CT>()",[185,989,990],{},"ctx.Last\u003CT>()",[214,992,993],{},"Inspection only. Never for wiring relationships.",[196,995,996,1004],{},[214,997,998,918,1001],{},[185,999,1000],{},"ctx.Parent",[185,1002,1003],{},"ctx.ParentIndex",[214,1005,1006],{},"Child context only.",[285,1008,1010],{"id":1009},"factory-rules","Factory rules",[176,1012,1013],{},"A useful factory makes ordinary entities easy to build without choosing the behavior under test. These conventions keep defaults predictable as the test suite grows:",[1015,1016,1017,1027,1042,1047,1060],"ol",{},[1018,1019,1020,1026],"li",{},[1021,1022,1023],"em",{},[180,1024,1025],{},"Valid and uninteresting."," Every required column gets a default no test should care about.",[1018,1028,1029,1030,1032,1033,1035,1036,1035,1039,381],{},"IDs come from ",[185,1031,934],{},". Time comes from ",[185,1034,917],{}," \u002F ",[185,1037,1038],{},"ctx.Ago",[185,1040,1041],{},"ctx.FromNow",[1018,1043,1044,1045,381],{},"Take the parent from the typed argument, and grandparents from ",[185,1046,973],{},[1018,1048,1049,1052,1053,1059],{},[180,1050,1051],{},"Leave derived properties unset",", so a ",[258,1054,1056],{"href":1055},"\u002Fguides\u002Fcustomizing#derived-defaults-are-fill-only",[185,1057,1058],{},"Derive"," can fill them.",[1018,1061,1062,1063,1066,1067,1070],{},"A property that tests vary must be ",[180,1064,1065],{},"settable",", or come from an ",[258,1068,1069],{"href":77},"input"," that the factory reads.",[1072,1073,1074],"warning",{},[176,1075,1076,1077,1080,1081,1083,1084,1086],{},"The most recently created entity is not necessarily the intended parent. Siblings and ",[185,1078,1079],{},".Under"," make that assumption unreliable. Use the typed parent for relationships, and keep ",[185,1082,990],{}," and ",[185,1085,987],{}," for inspection.",[1088,1089,1090],"caution",{},[176,1091,1092,1093,1096,1097,1100,1101,1103,1104,1107,1108,1111],{},"Customizers assign properties, so a property a test varies needs a setter. With ",[185,1094,1095],{},"{ get; init; }"," the compiler rejects the assignment (",[185,1098,1099],{},"CS8852","). ",[185,1102,1058],{}," can still fill ",[185,1105,1106],{},"init"," properties. If the model must stay immutable, let tests customize an ",[258,1109,1110],{"href":77},"input blueprint"," instead of changing the model.",[285,1113,1115],{"id":1114},"blueprints-are-immutable-values","Blueprints are immutable values",[176,1117,1118],{},"Tests often need a recurring variation, such as a disabled repository. A variant lets you name that choice without changing the defaults other tests use. Every modifier returns a new blueprint:",[293,1120,1123],{"className":295,"code":1121,"filename":297,"highlights":1122,"language":302,"meta":303,"style":303},"public static readonly Blueprint\u003CZeeqSeed, CodeRepository> Repository = \u002F* … *\u002F;\n\n\u002F\u002F A variant: Repository itself is unchanged.\npublic static readonly Blueprint\u003CZeeqSeed, CodeRepository> DisabledRepository =\n    Repository.With(Repositories.Disabled);\n",[374,405],[185,1124,1125,1154,1160,1165,1191],{"__ignoreMap":303},[307,1126,1127,1129,1131,1133,1135,1137,1139,1141,1143,1145,1147,1149,1152],{"class":309,"line":310},[307,1128,314],{"class":313},[307,1130,317],{"class":313},[307,1132,346],{"class":313},[307,1134,349],{"class":327},[307,1136,352],{"class":334},[307,1138,355],{"class":327},[307,1140,358],{"class":334},[307,1142,361],{"class":327},[307,1144,364],{"class":334},[307,1146,367],{"class":327},[307,1148,625],{"class":370},[307,1150,1151],{"class":454}," \u002F* … *\u002F",[307,1153,691],{"class":334},[307,1155,1156],{"class":309,"line":331},[307,1157,1159],{"emptyLinePlaceholder":1158},true,"\n",[307,1161,1162],{"class":309,"line":338},[307,1163,1164],{"class":454},"\u002F\u002F A variant: Repository itself is unchanged.\n",[307,1166,1168,1170,1172,1174,1176,1178,1180,1182,1184,1186,1189],{"class":1167,"line":374},[309,421],[307,1169,314],{"class":313},[307,1171,317],{"class":313},[307,1173,346],{"class":313},[307,1175,349],{"class":327},[307,1177,352],{"class":334},[307,1179,355],{"class":327},[307,1181,358],{"class":334},[307,1183,361],{"class":327},[307,1185,364],{"class":334},[307,1187,1188],{"class":327}," DisabledRepository",[307,1190,371],{"class":370},[307,1192,1194,1197,1199,1202,1204,1207,1209,1212],{"class":1193,"line":405},[309,421],[307,1195,1196],{"class":377},"    Repository",[307,1198,381],{"class":334},[307,1200,1201],{"class":384},"With",[307,1203,438],{"class":334},[307,1205,1206],{"class":377},"Repositories",[307,1208,381],{"class":334},[307,1210,1211],{"class":377},"Disabled",[307,1213,1214],{"class":334},");\n",[190,1216,1217,1227],{},[193,1218,1219],{},[196,1220,1221,1224],{},[199,1222,1223],{},"Modifier",[199,1225,1226],{},"Effect",[209,1228,1229,1239,1249,1262],{},[196,1230,1231,1236],{},[214,1232,1233],{},[185,1234,1235],{},".With(trait)",[214,1237,1238],{},"Adds a trait. Runs before call-site customizers, so the call site still wins.",[196,1240,1241,1246],{},[214,1242,1243],{},[185,1244,1245],{},".Derive(e => e.Prop, (e, ctx) => value)",[214,1247,1248],{},"Fill-only assignment after customizers.",[196,1250,1251,1256],{},[214,1252,1253],{},[185,1254,1255],{},".Derive(e => e.Prop, sequence)",[214,1257,1258,1259,381],{},"Fill-only assignment from a ",[258,1260,1261],{"href":57},"sequence",[196,1263,1264,1269],{},[214,1265,1266],{},[185,1267,1268],{},".AsTransient()",[214,1270,1271,1272,381],{},"The output is built and returned, but never saved. See ",[258,1273,66],{"href":67},[1275,1276,1277],"note",{},[176,1278,1279,1280,1283],{},"Static fields initialize top to bottom, so a variant needs its base to be initialized first. Declare them in that order in the same file; ordering across ",[185,1281,1282],{},"partial"," files is unspecified. Put a sequence above the blueprint that uses it for the same reason.",[285,1285,1287],{"id":1286},"adding-blueprints-to-a-chain","Adding blueprints to a chain",[293,1289,1293],{"className":295,"code":1290,"filename":1291,"highlights":1292,"language":302,"meta":303,"style":303},"await TestBiome\n    .Start(out var seed)\n    .AddOne(Blueprints.Repository, out var repo)\n    .BuildAsync();\n","CodeRepositoryTests.cs",[338],[185,1294,1295,1303,1325,1354],{"__ignoreMap":303},[307,1296,1297,1300],{"class":309,"line":310},[307,1298,1299],{"class":370},"await",[307,1301,1302],{"class":377}," TestBiome\n",[307,1304,1305,1308,1311,1313,1316,1319,1322],{"class":309,"line":331},[307,1306,1307],{"class":334},"    .",[307,1309,1310],{"class":384},"Start",[307,1312,438],{"class":334},[307,1314,1315],{"class":313},"out",[307,1317,1318],{"class":323}," var",[307,1320,1321],{"class":327}," seed",[307,1323,1324],{"class":334},")\n",[307,1326,1328,1330,1333,1335,1337,1339,1342,1344,1347,1349,1352],{"class":1327,"line":338},[309,421],[307,1329,1307],{"class":334},[307,1331,1332],{"class":384},"AddOne",[307,1334,438],{"class":334},[307,1336,36],{"class":377},[307,1338,381],{"class":334},[307,1340,1341],{"class":377},"Repository",[307,1343,358],{"class":334},[307,1345,1346],{"class":313}," out",[307,1348,1318],{"class":323},[307,1350,1351],{"class":327}," repo",[307,1353,1324],{"class":334},[307,1355,1356,1358,1361],{"class":309,"line":374},[307,1357,1307],{"class":334},[307,1359,1360],{"class":384},"BuildAsync",[307,1362,1363],{"class":334},"();\n",[176,1365,1366,1367,1369,1370,1373,1374,1377,1378,381],{},"In real tests you rarely call ",[185,1368,1332],{}," directly. Mark the blueprint catalog ",[185,1371,1372],{},"[BiomeGraft]"," and the generator supplies methods such as ",[185,1375,1376],{},".AddCodeRepository(out var repo)",". See ",[258,1379,95],{"href":96},[1381,1382,1383],"style",{},"html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sG8yY, html code.shiki .sG8yY{--shiki-light:#E2931D;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}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);}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":303,"searchDepth":310,"depth":331,"links":1385},[1386,1387,1388,1389],{"id":287,"depth":331,"text":288},{"id":1009,"depth":331,"text":1010},{"id":1114,"depth":331,"text":1115},{"id":1286,"depth":331,"text":1287},"One factory per entity type, as an immutable value.","md",null,{},{"icon":39},{"title":36,"description":1390},"FuPOg806B1SeWwUnkwWjnyTmZWtYQ0cofnj599_iNDw",[1398,1400],{"title":31,"path":32,"stem":33,"description":1399,"icon":34,"children":-1},"The baseline every test starts from, and the one-call entry point your tests use.",{"title":41,"path":42,"stem":43,"description":1401,"icon":44,"children":-1},"How customizers and defaults work together, and why their order matters.",1791831051052]