[{"data":1,"prerenderedAt":1803},["ShallowReactive",2],{"navigation":3,"\u002Fguides\u002Fseeds-and-testbiome":170,"\u002Fguides\u002Fseeds-and-testbiome-surround":1798},[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":31,"body":172,"description":1791,"extension":1792,"links":1793,"meta":1794,"navigation":1795,"path":32,"seo":1796,"stem":33,"__hash__":1797},"docs\u002F2.guides\u002F01.seeds-and-testbiome.md",{"type":173,"value":174,"toc":1783},"minimark",[175,180,194,495,502,514,518,525,620,635,642,649,1310,1328,1339,1343,1346,1402,1415,1709,1719,1723,1739,1742,1779],[176,177,179],"h2",{"id":178},"the-seed","The seed",[181,182,183,184,188,189,193],"p",{},"Many scenarios share a small starting point: an owner, an organization, or a tenant ID. A ",[185,186,187],"strong",{},"seed"," (",[190,191,192],"code",{},"TSeed",") carries that baseline into the blueprints so each test does not have to pass it around. Biome never inspects its shape, so it can be a record, a string, or an existing fixture object.",[195,196,202],"pre",{"className":197,"code":198,"filename":199,"language":200,"meta":201,"style":201},"language-csharp shiki shiki-themes material-theme-lighter github-light github-dark","public sealed record ZeeqSeed(User Owner, Organization Organization)\n{\n    public static ZeeqSeed Generate()\n    {\n        var owner = new User\n        {\n            Id = $\"user_{Guid.CreateVersion7():N}\",\n            DisplayName = \"Owner\",\n        };\n        var organization = new Organization\n        {\n            Id = $\"org_{Guid.CreateVersion7():N}\",\n            DisplayName = \"Test Organization\",\n            CreatedByUserId = owner.Id,\n        };\n        return new(owner, organization);\n    }\n}\n","ZeeqSeed.cs","csharp","",[190,203,204,245,251,269,275,294,300,348,366,372,387,392,424,440,457,462,483,489],{"__ignoreMap":201},[205,206,209,213,216,220,224,228,231,234,237,240,242],"span",{"class":207,"line":208},"line",1,[205,210,212],{"class":211},"sbsja","public",[205,214,215],{"class":211}," sealed",[205,217,219],{"class":218},"sG8yY"," record",[205,221,223],{"class":222},"sbgvK"," ZeeqSeed",[205,225,227],{"class":226},"sP7_E","(",[205,229,230],{"class":222},"User",[205,232,233],{"class":222}," Owner",[205,235,236],{"class":226},",",[205,238,239],{"class":222}," Organization",[205,241,239],{"class":222},[205,243,244],{"class":226},")\n",[205,246,248],{"class":207,"line":247},2,[205,249,250],{"class":226},"{\n",[205,252,254,257,260,262,266],{"class":207,"line":253},3,[205,255,256],{"class":211},"    public",[205,258,259],{"class":211}," static",[205,261,223],{"class":222},[205,263,265],{"class":264},"sGLFI"," Generate",[205,267,268],{"class":226},"()\n",[205,270,272],{"class":207,"line":271},4,[205,273,274],{"class":226},"    {\n",[205,276,278,281,284,288,291],{"class":207,"line":277},5,[205,279,280],{"class":218},"        var",[205,282,283],{"class":222}," owner",[205,285,287],{"class":286},"smGrS"," =",[205,289,290],{"class":286}," new",[205,292,293],{"class":222}," User\n",[205,295,297],{"class":207,"line":296},6,[205,298,299],{"class":226},"        {\n",[205,301,303,307,310,314,318,321,324,327,330,333,336,339,342,345],{"class":207,"line":302},7,[205,304,306],{"class":305},"su5hD","            Id ",[205,308,309],{"class":286},"=",[205,311,313],{"class":312},"sjJ54"," $\"",[205,315,317],{"class":316},"s_sjI","user_",[205,319,320],{"class":312},"{",[205,322,323],{"class":305},"Guid",[205,325,326],{"class":312},".",[205,328,329],{"class":264},"CreateVersion7",[205,331,332],{"class":312},"()",[205,334,335],{"class":286},":",[205,337,338],{"class":305},"N",[205,340,341],{"class":312},"}",[205,343,344],{"class":312},"\"",[205,346,347],{"class":226},",\n",[205,349,351,354,356,359,362,364],{"class":207,"line":350},8,[205,352,353],{"class":305},"            DisplayName ",[205,355,309],{"class":286},[205,357,358],{"class":312}," \"",[205,360,361],{"class":316},"Owner",[205,363,344],{"class":312},[205,365,347],{"class":226},[205,367,369],{"class":207,"line":368},9,[205,370,371],{"class":226},"        };\n",[205,373,375,377,380,382,384],{"class":207,"line":374},10,[205,376,280],{"class":218},[205,378,379],{"class":222}," organization",[205,381,287],{"class":286},[205,383,290],{"class":286},[205,385,386],{"class":222}," Organization\n",[205,388,390],{"class":207,"line":389},11,[205,391,299],{"class":226},[205,393,395,397,399,401,404,406,408,410,412,414,416,418,420,422],{"class":207,"line":394},12,[205,396,306],{"class":305},[205,398,309],{"class":286},[205,400,313],{"class":312},[205,402,403],{"class":316},"org_",[205,405,320],{"class":312},[205,407,323],{"class":305},[205,409,326],{"class":312},[205,411,329],{"class":264},[205,413,332],{"class":312},[205,415,335],{"class":286},[205,417,338],{"class":305},[205,419,341],{"class":312},[205,421,344],{"class":312},[205,423,347],{"class":226},[205,425,427,429,431,433,436,438],{"class":207,"line":426},13,[205,428,353],{"class":305},[205,430,309],{"class":286},[205,432,358],{"class":312},[205,434,435],{"class":316},"Test Organization",[205,437,344],{"class":312},[205,439,347],{"class":226},[205,441,443,446,448,450,452,455],{"class":207,"line":442},14,[205,444,445],{"class":305},"            CreatedByUserId ",[205,447,309],{"class":286},[205,449,283],{"class":305},[205,451,326],{"class":226},[205,453,454],{"class":305},"Id",[205,456,347],{"class":226},[205,458,460],{"class":207,"line":459},15,[205,461,371],{"class":226},[205,463,465,469,471,473,476,478,480],{"class":207,"line":464},16,[205,466,468],{"class":467},"sVHd0","        return",[205,470,290],{"class":286},[205,472,227],{"class":226},[205,474,475],{"class":305},"owner",[205,477,236],{"class":226},[205,479,379],{"class":305},[205,481,482],{"class":226},");\n",[205,484,486],{"class":207,"line":485},17,[205,487,488],{"class":226},"    }\n",[205,490,492],{"class":207,"line":491},18,[205,493,494],{"class":226},"}\n",[181,496,497,498,501],{},"The seed is ",[185,499,500],{},"created outside the session"," for each test, so a new test never shares rows with another.",[503,504,505],"tip",{},[181,506,507,508,510,511,326],{},"Entities and parents must be reference types. The ",[185,509,187],{}," is the one thing that may have any shape, such as ",[190,512,513],{},"public sealed record TenantSeed(string Actor, int Tenant);",[176,515,517],{"id":516},"seed-rows","Seed rows",[181,519,520,521,524],{},"A seed can contain configuration as well as entities, so Biome cannot assume which objects belong in the database. Select those rows with ",[190,522,523],{},"SeedEntities",". They are saved before the created entities, in the order you list them.",[195,526,530],{"className":197,"code":527,"filename":528,"highlights":529,"language":200,"meta":201,"style":201},"private static readonly BiomeOptions\u003CZeeqSeed> Options =\n    new BiomeOptions\u003CZeeqSeed>().SeedEntities(seed =>\n        [seed.Owner, seed.Organization]\n    ); \u002F\u002F foreign-key-safe order\n","TestBiome.cs",[247,253,271],[190,531,532,560,585,610],{"__ignoreMap":201},[205,533,534,537,539,542,545,548,551,554,557],{"class":207,"line":208},[205,535,536],{"class":211},"private",[205,538,259],{"class":211},[205,540,541],{"class":211}," readonly",[205,543,544],{"class":222}," BiomeOptions",[205,546,547],{"class":226},"\u003C",[205,549,550],{"class":222},"ZeeqSeed",[205,552,553],{"class":226},">",[205,555,556],{"class":222}," Options",[205,558,559],{"class":286}," =\n",[205,561,564,567,569,571,573,576,578,580,582],{"class":562,"line":247},[207,563],"highlight",[205,565,566],{"class":286},"    new",[205,568,544],{"class":222},[205,570,547],{"class":226},[205,572,550],{"class":222},[205,574,575],{"class":226},">().",[205,577,523],{"class":264},[205,579,227],{"class":226},[205,581,187],{"class":222},[205,583,584],{"class":286}," =>\n",[205,586,588,591,593,595,597,599,602,604,607],{"class":587,"line":253},[207,563],[205,589,590],{"class":226},"        [",[205,592,187],{"class":305},[205,594,326],{"class":226},[205,596,361],{"class":305},[205,598,236],{"class":226},[205,600,601],{"class":305}," seed",[205,603,326],{"class":226},[205,605,606],{"class":305},"Organization",[205,608,609],{"class":226},"]\n",[205,611,613,616],{"class":612,"line":271},[207,563],[205,614,615],{"class":226},"    );",[205,617,619],{"class":618},"sutJx"," \u002F\u002F foreign-key-safe order\n",[181,621,622,623,626,627,630,631,634],{},"Seed rows also count as ",[185,624,625],{},"owned by the session",", so a test can anchor children to one with ",[190,628,629],{},".Under(seed.Owner)",". A ",[190,632,633],{},"null"," entry in the list throws immediately.",[176,636,638,641],{"id":637},"testbiome-one-call-to-start",[190,639,640],{},"TestBiome",": one call to start",[181,643,644,645,648],{},"Most tests use the same seed factory and options. Wrapping ",[190,646,647],{},"Biome.Start"," once keeps that wiring in one place and gives each test a short entry point.",[650,651,652,998],"code-group",{},[195,653,657],{"className":197,"code":654,"filename":528,"highlights":655,"language":200,"meta":201,"style":201},"public static partial class TestBiome\n{\n    private static readonly BiomeOptions\u003CZeeqSeed> Options =\n        new BiomeOptions\u003CZeeqSeed>().SeedEntities(seed =>\n            [seed.Owner, seed.Organization]\n        );\n\n    \u002F\u002F No database: NullStore, entities still exist after each Add.\n    public static BiomeBuilder\u003CZeeqSeed, ZeeqSeed> Start(\n        out ZeeqSeed seed,\n        IBiomeStore? store = null,\n        TimeProvider? time = null\n    )\n    {\n        seed = ZeeqSeed.Generate();\n        return Biome.Start(seed, Options, store, time);\n    }\n\n    \u002F\u002F With EF Core: same session, saved through a DbContext.\n    public static BiomeBuilder\u003CZeeqSeed, ZeeqSeed> Start(\n        DbContext db,\n        out ZeeqSeed seed,\n        TimeProvider? time = null\n    ) => Start(out seed, db.AsBiomeStore(), time);\n}\n",[271,277,296,464,656],24,[190,658,659,674,678,699,721,743,749,755,760,785,796,815,830,835,839,856,887,891,895,901,924,935,946,959,993],{"__ignoreMap":201},[205,660,661,663,665,668,671],{"class":207,"line":208},[205,662,212],{"class":211},[205,664,259],{"class":211},[205,666,667],{"class":211}," partial",[205,669,670],{"class":218}," class",[205,672,673],{"class":222}," TestBiome\n",[205,675,676],{"class":207,"line":247},[205,677,250],{"class":226},[205,679,680,683,685,687,689,691,693,695,697],{"class":207,"line":253},[205,681,682],{"class":211},"    private",[205,684,259],{"class":211},[205,686,541],{"class":211},[205,688,544],{"class":222},[205,690,547],{"class":226},[205,692,550],{"class":222},[205,694,553],{"class":226},[205,696,556],{"class":222},[205,698,559],{"class":286},[205,700,702,705,707,709,711,713,715,717,719],{"class":701,"line":271},[207,563],[205,703,704],{"class":286},"        new",[205,706,544],{"class":222},[205,708,547],{"class":226},[205,710,550],{"class":222},[205,712,575],{"class":226},[205,714,523],{"class":264},[205,716,227],{"class":226},[205,718,187],{"class":222},[205,720,584],{"class":286},[205,722,724,727,729,731,733,735,737,739,741],{"class":723,"line":277},[207,563],[205,725,726],{"class":226},"            [",[205,728,187],{"class":305},[205,730,326],{"class":226},[205,732,361],{"class":305},[205,734,236],{"class":226},[205,736,601],{"class":305},[205,738,326],{"class":226},[205,740,606],{"class":305},[205,742,609],{"class":226},[205,744,746],{"class":745,"line":296},[207,563],[205,747,748],{"class":226},"        );\n",[205,750,751],{"class":207,"line":302},[205,752,754],{"emptyLinePlaceholder":753},true,"\n",[205,756,757],{"class":207,"line":350},[205,758,759],{"class":618},"    \u002F\u002F No database: NullStore, entities still exist after each Add.\n",[205,761,762,764,766,769,771,773,775,777,779,782],{"class":207,"line":368},[205,763,256],{"class":211},[205,765,259],{"class":211},[205,767,768],{"class":222}," BiomeBuilder",[205,770,547],{"class":226},[205,772,550],{"class":222},[205,774,236],{"class":226},[205,776,223],{"class":222},[205,778,553],{"class":226},[205,780,781],{"class":264}," Start",[205,783,784],{"class":226},"(\n",[205,786,787,790,792,794],{"class":207,"line":374},[205,788,789],{"class":211},"        out",[205,791,223],{"class":222},[205,793,601],{"class":222},[205,795,347],{"class":226},[205,797,798,801,804,807,809,813],{"class":207,"line":389},[205,799,800],{"class":222},"        IBiomeStore",[205,802,803],{"class":226},"?",[205,805,806],{"class":222}," store",[205,808,287],{"class":286},[205,810,812],{"class":811},"s39Yj"," null",[205,814,347],{"class":226},[205,816,817,820,822,825,827],{"class":207,"line":394},[205,818,819],{"class":222},"        TimeProvider",[205,821,803],{"class":226},[205,823,824],{"class":222}," time",[205,826,287],{"class":286},[205,828,829],{"class":811}," null\n",[205,831,832],{"class":207,"line":426},[205,833,834],{"class":226},"    )\n",[205,836,837],{"class":207,"line":442},[205,838,274],{"class":226},[205,840,841,844,846,848,850,853],{"class":207,"line":459},[205,842,843],{"class":305},"        seed ",[205,845,309],{"class":286},[205,847,223],{"class":305},[205,849,326],{"class":226},[205,851,852],{"class":264},"Generate",[205,854,855],{"class":226},"();\n",[205,857,859,861,864,866,869,871,873,875,877,879,881,883,885],{"class":858,"line":464},[207,563],[205,860,468],{"class":467},[205,862,863],{"class":305}," Biome",[205,865,326],{"class":226},[205,867,868],{"class":264},"Start",[205,870,227],{"class":226},[205,872,187],{"class":305},[205,874,236],{"class":226},[205,876,556],{"class":305},[205,878,236],{"class":226},[205,880,806],{"class":305},[205,882,236],{"class":226},[205,884,824],{"class":305},[205,886,482],{"class":226},[205,888,889],{"class":207,"line":485},[205,890,488],{"class":226},[205,892,893],{"class":207,"line":491},[205,894,754],{"emptyLinePlaceholder":753},[205,896,898],{"class":207,"line":897},19,[205,899,900],{"class":618},"    \u002F\u002F With EF Core: same session, saved through a DbContext.\n",[205,902,904,906,908,910,912,914,916,918,920,922],{"class":207,"line":903},20,[205,905,256],{"class":211},[205,907,259],{"class":211},[205,909,768],{"class":222},[205,911,547],{"class":226},[205,913,550],{"class":222},[205,915,236],{"class":226},[205,917,223],{"class":222},[205,919,553],{"class":226},[205,921,781],{"class":264},[205,923,784],{"class":226},[205,925,927,930,933],{"class":207,"line":926},21,[205,928,929],{"class":222},"        DbContext",[205,931,932],{"class":222}," db",[205,934,347],{"class":226},[205,936,938,940,942,944],{"class":207,"line":937},22,[205,939,789],{"class":211},[205,941,223],{"class":222},[205,943,601],{"class":222},[205,945,347],{"class":226},[205,947,949,951,953,955,957],{"class":207,"line":948},23,[205,950,819],{"class":222},[205,952,803],{"class":226},[205,954,824],{"class":222},[205,956,287],{"class":286},[205,958,829],{"class":811},[205,960,962,965,968,970,972,975,977,979,981,983,986,989,991],{"class":961,"line":656},[207,563],[205,963,964],{"class":226},"    )",[205,966,967],{"class":286}," =>",[205,969,781],{"class":264},[205,971,227],{"class":226},[205,973,974],{"class":211},"out",[205,976,601],{"class":305},[205,978,236],{"class":226},[205,980,932],{"class":305},[205,982,326],{"class":226},[205,984,985],{"class":264},"AsBiomeStore",[205,987,988],{"class":226},"(),",[205,990,824],{"class":305},[205,992,482],{"class":226},[205,994,996],{"class":207,"line":995},25,[205,997,494],{"class":226},[999,1000,1003],"code-collapse",{"label":1001,"name":1002},"Without Biome","setup",[195,1004,1006],{"className":197,"code":1005,"language":200,"meta":201,"style":201},"\u002F\u002F Every test class repeats this fixture code, or inherits it from a base class.\npublic abstract class DatabaseTestBase\n{\n    protected AppDb Db = null!;\n    protected User Owner = null!;\n    protected Organization Organization = null!;\n\n    [Before(Test)]\n    public async Task SeedAsync()\n    {\n        Owner = new User\n        {\n            Id = $\"user_{Guid.CreateVersion7():N}\",\n            DisplayName = \"Owner\",\n        };\n        Organization = new Organization\n        {\n            Id = $\"org_{Guid.CreateVersion7():N}\",\n            DisplayName = \"Test Organization\",\n            CreatedByUserId = Owner.Id,\n        };\n        Db.AddRange(Owner, Organization);\n        \u002F\u002F every test pays for the baseline, needed or not\n        await Db.SaveChangesAsync();\n    }\n}\n",[190,1007,1008,1013,1025,1029,1050,1067,1083,1087,1103,1118,1122,1133,1137,1167,1181,1185,1196,1200,1230,1244,1258,1262,1282,1287,1301,1305],{"__ignoreMap":201},[205,1009,1010],{"class":207,"line":208},[205,1011,1012],{"class":618},"\u002F\u002F Every test class repeats this fixture code, or inherits it from a base class.\n",[205,1014,1015,1017,1020,1022],{"class":207,"line":247},[205,1016,212],{"class":211},[205,1018,1019],{"class":211}," abstract",[205,1021,670],{"class":218},[205,1023,1024],{"class":222}," DatabaseTestBase\n",[205,1026,1027],{"class":207,"line":253},[205,1028,250],{"class":226},[205,1030,1031,1034,1037,1040,1042,1044,1047],{"class":207,"line":271},[205,1032,1033],{"class":211},"    protected",[205,1035,1036],{"class":222}," AppDb",[205,1038,1039],{"class":222}," Db",[205,1041,287],{"class":286},[205,1043,812],{"class":811},[205,1045,1046],{"class":286},"!",[205,1048,1049],{"class":226},";\n",[205,1051,1052,1054,1057,1059,1061,1063,1065],{"class":207,"line":277},[205,1053,1033],{"class":211},[205,1055,1056],{"class":222}," User",[205,1058,233],{"class":222},[205,1060,287],{"class":286},[205,1062,812],{"class":811},[205,1064,1046],{"class":286},[205,1066,1049],{"class":226},[205,1068,1069,1071,1073,1075,1077,1079,1081],{"class":207,"line":296},[205,1070,1033],{"class":211},[205,1072,239],{"class":222},[205,1074,239],{"class":222},[205,1076,287],{"class":286},[205,1078,812],{"class":811},[205,1080,1046],{"class":286},[205,1082,1049],{"class":226},[205,1084,1085],{"class":207,"line":302},[205,1086,754],{"emptyLinePlaceholder":753},[205,1088,1089,1092,1095,1097,1100],{"class":207,"line":350},[205,1090,1091],{"class":226},"    [",[205,1093,1094],{"class":222},"Before",[205,1096,227],{"class":226},[205,1098,1099],{"class":305},"Test",[205,1101,1102],{"class":226},")]\n",[205,1104,1105,1107,1110,1113,1116],{"class":207,"line":368},[205,1106,256],{"class":211},[205,1108,1109],{"class":211}," async",[205,1111,1112],{"class":222}," Task",[205,1114,1115],{"class":264}," SeedAsync",[205,1117,268],{"class":226},[205,1119,1120],{"class":207,"line":374},[205,1121,274],{"class":226},[205,1123,1124,1127,1129,1131],{"class":207,"line":389},[205,1125,1126],{"class":305},"        Owner ",[205,1128,309],{"class":286},[205,1130,290],{"class":286},[205,1132,293],{"class":222},[205,1134,1135],{"class":207,"line":394},[205,1136,299],{"class":226},[205,1138,1139,1141,1143,1145,1147,1149,1151,1153,1155,1157,1159,1161,1163,1165],{"class":207,"line":426},[205,1140,306],{"class":305},[205,1142,309],{"class":286},[205,1144,313],{"class":312},[205,1146,317],{"class":316},[205,1148,320],{"class":312},[205,1150,323],{"class":305},[205,1152,326],{"class":312},[205,1154,329],{"class":264},[205,1156,332],{"class":312},[205,1158,335],{"class":286},[205,1160,338],{"class":305},[205,1162,341],{"class":312},[205,1164,344],{"class":312},[205,1166,347],{"class":226},[205,1168,1169,1171,1173,1175,1177,1179],{"class":207,"line":442},[205,1170,353],{"class":305},[205,1172,309],{"class":286},[205,1174,358],{"class":312},[205,1176,361],{"class":316},[205,1178,344],{"class":312},[205,1180,347],{"class":226},[205,1182,1183],{"class":207,"line":459},[205,1184,371],{"class":226},[205,1186,1187,1190,1192,1194],{"class":207,"line":464},[205,1188,1189],{"class":305},"        Organization ",[205,1191,309],{"class":286},[205,1193,290],{"class":286},[205,1195,386],{"class":222},[205,1197,1198],{"class":207,"line":485},[205,1199,299],{"class":226},[205,1201,1202,1204,1206,1208,1210,1212,1214,1216,1218,1220,1222,1224,1226,1228],{"class":207,"line":491},[205,1203,306],{"class":305},[205,1205,309],{"class":286},[205,1207,313],{"class":312},[205,1209,403],{"class":316},[205,1211,320],{"class":312},[205,1213,323],{"class":305},[205,1215,326],{"class":312},[205,1217,329],{"class":264},[205,1219,332],{"class":312},[205,1221,335],{"class":286},[205,1223,338],{"class":305},[205,1225,341],{"class":312},[205,1227,344],{"class":312},[205,1229,347],{"class":226},[205,1231,1232,1234,1236,1238,1240,1242],{"class":207,"line":897},[205,1233,353],{"class":305},[205,1235,309],{"class":286},[205,1237,358],{"class":312},[205,1239,435],{"class":316},[205,1241,344],{"class":312},[205,1243,347],{"class":226},[205,1245,1246,1248,1250,1252,1254,1256],{"class":207,"line":903},[205,1247,445],{"class":305},[205,1249,309],{"class":286},[205,1251,233],{"class":305},[205,1253,326],{"class":226},[205,1255,454],{"class":305},[205,1257,347],{"class":226},[205,1259,1260],{"class":207,"line":926},[205,1261,371],{"class":226},[205,1263,1264,1267,1269,1272,1274,1276,1278,1280],{"class":207,"line":937},[205,1265,1266],{"class":305},"        Db",[205,1268,326],{"class":226},[205,1270,1271],{"class":264},"AddRange",[205,1273,227],{"class":226},[205,1275,361],{"class":305},[205,1277,236],{"class":226},[205,1279,239],{"class":305},[205,1281,482],{"class":226},[205,1283,1284],{"class":207,"line":948},[205,1285,1286],{"class":618},"        \u002F\u002F every test pays for the baseline, needed or not\n",[205,1288,1289,1292,1294,1296,1299],{"class":207,"line":656},[205,1290,1291],{"class":286},"        await",[205,1293,1039],{"class":305},[205,1295,326],{"class":226},[205,1297,1298],{"class":264},"SaveChangesAsync",[205,1300,855],{"class":226},[205,1302,1303],{"class":207,"line":995},[205,1304,488],{"class":226},[205,1306,1308],{"class":207,"line":1307},26,[205,1309,494],{"class":226},[181,1311,1312,1315,1316,630,1319,1321,1322,630,1325,1327],{},[190,1313,1314],{},"Biome.Start(seed, options, store, time)"," returns a ",[190,1317,1318],{},"BiomeBuilder\u003CTSeed, TSeed>",[190,1320,633],{}," store means ",[190,1323,1324],{},"NullStore",[190,1326,633],{}," time means a frozen clock.",[181,1329,1330,1331,1334,1335,1338],{},"When several methods need the same starting graph, call ",[190,1332,1333],{},"TestBiome.Start"," in the test class's instance constructor and keep the baseline builder in an instance field. Each test instance gets a fresh session and extends it for its own scenario. See ",[1336,1337,100],"a",{"href":101}," for TUnit and xUnit examples.",[176,1340,1342],{"id":1341},"options-are-shared-and-frozen","Options are shared and frozen",[181,1344,1345],{},"Sharing configuration is useful until one test changes it for another. Biome freezes options on first use and keeps each scenario's mutable state in its own session:",[1347,1348,1349,1361,1392],"ul",{},[1350,1351,1352,1353,1356,1357,1360],"li",{},"Options are configured ",[185,1354,1355],{},"once",", as a ",[190,1358,1359],{},"static readonly"," field.",[1350,1362,1363,1364,1369,1370,1372,1373,1372,1376,1372,1379,1372,1382,1372,1385,1388,1389,326],{},"They ",[185,1365,1366,1367],{},"freeze on the first ",[190,1368,868],{},". Every later change (",[190,1371,523],{},", ",[190,1374,1375],{},"Default",[190,1377,1378],{},"BeforeSave",[190,1380,1381],{},"AfterSave",[190,1383,1384],{},"TimePrecision",[190,1386,1387],{},"Ids",") throws ",[190,1390,1391],{},"InvalidOperationException",[1350,1393,1394,1395,1397,1398,1401],{},"Each ",[190,1396,868],{}," creates a ",[185,1399,1400],{},"new session",", so each test gets its own entities, sequences and clock. Parallel tests are safe.",[1403,1404,1405],"warning",{},[181,1406,1407,1408,1410,1411,1414],{},"Never change shared options inside a test. If one test needs different options, give ",[190,1409,640],{}," a factory and build a fresh instance, as the library's own ",[190,1412,1413],{},"CustomSeed"," tests do:",[195,1416,1420],{"className":197,"code":1417,"filename":1418,"highlights":1419,"language":200,"meta":201,"style":201},"internal static class TestBiome\n{\n    internal static BiomeOptions\u003CCustomSeed> NewOptions() =>\n        new BiomeOptions\u003CCustomSeed>().Default\u003CIHasCreatedBy, string?>(\n            n => n.CreatedBy,\n            (_, ctx) => ctx.Seed.Actor\n        );\n\n    private static readonly BiomeOptions\u003CCustomSeed> Options = NewOptions();\n\n    internal static BiomeBuilder\u003CCustomSeed, CustomSeed> Start(\n        out CustomSeed seed,\n        IBiomeStore? store = null,\n        BiomeOptions\u003CCustomSeed>? options = null\n    )\n    {\n        seed = new(\"actor\", 42);\n        return Biome.Start(seed, options ?? Options, store);\n    }\n}\n","CustomSeed\u002FDomain.cs",[253,442,491],[190,1421,1422,1433,1437,1460,1487,1504,1534,1538,1542,1566,1570,1593,1603,1617,1637,1641,1645,1670,1701,1705],{"__ignoreMap":201},[205,1423,1424,1427,1429,1431],{"class":207,"line":208},[205,1425,1426],{"class":211},"internal",[205,1428,259],{"class":211},[205,1430,670],{"class":218},[205,1432,673],{"class":222},[205,1434,1435],{"class":207,"line":247},[205,1436,250],{"class":226},[205,1438,1440,1443,1445,1447,1449,1451,1453,1456,1458],{"class":1439,"line":253},[207,563],[205,1441,1442],{"class":211},"    internal",[205,1444,259],{"class":211},[205,1446,544],{"class":222},[205,1448,547],{"class":226},[205,1450,1413],{"class":222},[205,1452,553],{"class":226},[205,1454,1455],{"class":264}," NewOptions",[205,1457,332],{"class":226},[205,1459,584],{"class":286},[205,1461,1462,1464,1466,1468,1470,1472,1474,1476,1479,1481,1484],{"class":207,"line":271},[205,1463,704],{"class":286},[205,1465,544],{"class":222},[205,1467,547],{"class":226},[205,1469,1413],{"class":222},[205,1471,575],{"class":226},[205,1473,1375],{"class":264},[205,1475,547],{"class":226},[205,1477,1478],{"class":222},"IHasCreatedBy",[205,1480,236],{"class":226},[205,1482,1483],{"class":286}," string",[205,1485,1486],{"class":226},"?>(\n",[205,1488,1489,1492,1494,1497,1499,1502],{"class":207,"line":277},[205,1490,1491],{"class":222},"            n",[205,1493,967],{"class":286},[205,1495,1496],{"class":305}," n",[205,1498,326],{"class":226},[205,1500,1501],{"class":305},"CreatedBy",[205,1503,347],{"class":226},[205,1505,1506,1509,1512,1514,1517,1520,1522,1524,1526,1529,1531],{"class":207,"line":296},[205,1507,1508],{"class":226},"            (",[205,1510,1511],{"class":222},"_",[205,1513,236],{"class":226},[205,1515,1516],{"class":222}," ctx",[205,1518,1519],{"class":226},")",[205,1521,967],{"class":286},[205,1523,1516],{"class":305},[205,1525,326],{"class":226},[205,1527,1528],{"class":305},"Seed",[205,1530,326],{"class":226},[205,1532,1533],{"class":305},"Actor\n",[205,1535,1536],{"class":207,"line":302},[205,1537,748],{"class":226},[205,1539,1540],{"class":207,"line":350},[205,1541,754],{"emptyLinePlaceholder":753},[205,1543,1544,1546,1548,1550,1552,1554,1556,1558,1560,1562,1564],{"class":207,"line":368},[205,1545,682],{"class":211},[205,1547,259],{"class":211},[205,1549,541],{"class":211},[205,1551,544],{"class":222},[205,1553,547],{"class":226},[205,1555,1413],{"class":222},[205,1557,553],{"class":226},[205,1559,556],{"class":222},[205,1561,287],{"class":286},[205,1563,1455],{"class":264},[205,1565,855],{"class":226},[205,1567,1568],{"class":207,"line":374},[205,1569,754],{"emptyLinePlaceholder":753},[205,1571,1572,1574,1576,1578,1580,1582,1584,1587,1589,1591],{"class":207,"line":389},[205,1573,1442],{"class":211},[205,1575,259],{"class":211},[205,1577,768],{"class":222},[205,1579,547],{"class":226},[205,1581,1413],{"class":222},[205,1583,236],{"class":226},[205,1585,1586],{"class":222}," CustomSeed",[205,1588,553],{"class":226},[205,1590,781],{"class":264},[205,1592,784],{"class":226},[205,1594,1595,1597,1599,1601],{"class":207,"line":394},[205,1596,789],{"class":211},[205,1598,1586],{"class":222},[205,1600,601],{"class":222},[205,1602,347],{"class":226},[205,1604,1605,1607,1609,1611,1613,1615],{"class":207,"line":426},[205,1606,800],{"class":222},[205,1608,803],{"class":226},[205,1610,806],{"class":222},[205,1612,287],{"class":286},[205,1614,812],{"class":811},[205,1616,347],{"class":226},[205,1618,1620,1623,1625,1627,1630,1633,1635],{"class":1619,"line":442},[207,563],[205,1621,1622],{"class":222},"        BiomeOptions",[205,1624,547],{"class":226},[205,1626,1413],{"class":222},[205,1628,1629],{"class":226},">?",[205,1631,1632],{"class":222}," options",[205,1634,287],{"class":286},[205,1636,829],{"class":811},[205,1638,1639],{"class":207,"line":459},[205,1640,834],{"class":226},[205,1642,1643],{"class":207,"line":464},[205,1644,274],{"class":226},[205,1646,1647,1649,1651,1653,1655,1657,1660,1662,1664,1668],{"class":207,"line":485},[205,1648,843],{"class":305},[205,1650,309],{"class":286},[205,1652,290],{"class":286},[205,1654,227],{"class":226},[205,1656,344],{"class":312},[205,1658,1659],{"class":316},"actor",[205,1661,344],{"class":312},[205,1663,236],{"class":226},[205,1665,1667],{"class":1666},"srdBf"," 42",[205,1669,482],{"class":226},[205,1671,1673,1675,1677,1679,1681,1683,1685,1687,1690,1693,1695,1697,1699],{"class":1672,"line":491},[207,563],[205,1674,468],{"class":467},[205,1676,863],{"class":305},[205,1678,326],{"class":226},[205,1680,868],{"class":264},[205,1682,227],{"class":226},[205,1684,187],{"class":305},[205,1686,236],{"class":226},[205,1688,1689],{"class":305}," options ",[205,1691,1692],{"class":286},"??",[205,1694,556],{"class":305},[205,1696,236],{"class":226},[205,1698,806],{"class":305},[205,1700,482],{"class":226},[205,1702,1703],{"class":207,"line":897},[205,1704,488],{"class":226},[205,1706,1707],{"class":207,"line":903},[205,1708,494],{"class":226},[181,1710,1711,1712,1715,1716,326],{},"A test then builds its own options, for example ",[190,1713,1714],{},"TestBiome.NewOptions().BeforeSave(...)",", and passes them in. See ",[1336,1717,1718],{"href":128},"Custom seed shapes",[176,1720,1722],{"id":1721},"a-seed-with-timestamps","A seed with timestamps",[1724,1725,1726],"note",{},[181,1727,1728,1729,1732,1733,1736,1737,326],{},"The seed is created before the session starts, so it cannot use ",[190,1730,1731],{},"ctx.Now",". If seed timestamps are compared with database values, round them yourself, or set them from the same ",[190,1734,1735],{},"TimeProvider"," you pass to ",[190,1738,868],{},[181,1740,1741],{},"An existing fixture can be the seed directly:",[195,1743,1745],{"className":197,"code":1744,"filename":528,"language":200,"meta":201,"style":201},"new BiomeOptions\u003CAppFixtureData>().SeedEntities(seed => seed.GetSeedEntities());\n",[190,1746,1747],{"__ignoreMap":201},[205,1748,1749,1752,1754,1756,1759,1761,1763,1765,1767,1769,1771,1773,1776],{"class":207,"line":208},[205,1750,1751],{"class":211},"new",[205,1753,544],{"class":264},[205,1755,547],{"class":226},[205,1757,1758],{"class":222},"AppFixtureData",[205,1760,575],{"class":226},[205,1762,523],{"class":264},[205,1764,227],{"class":226},[205,1766,187],{"class":222},[205,1768,967],{"class":286},[205,1770,601],{"class":305},[205,1772,326],{"class":226},[205,1774,1775],{"class":264},"GetSeedEntities",[205,1777,1778],{"class":226},"());\n",[1780,1781,1782],"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 .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}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 .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 .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 .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 .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 .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":201,"searchDepth":208,"depth":247,"links":1784},[1785,1786,1787,1789,1790],{"id":178,"depth":247,"text":179},{"id":516,"depth":247,"text":517},{"id":637,"depth":247,"text":1788},"TestBiome: one call to start",{"id":1341,"depth":247,"text":1342},{"id":1721,"depth":247,"text":1722},"The baseline every test starts from, and the one-call entry point your tests use.","md",null,{},{"icon":34},{"title":31,"description":1791},"gd2cZ7Zbo5MUqT16LJuBEO3Vi_lPVCXyTu5QucxlFrY",[1799,1801],{"title":21,"path":22,"stem":23,"description":1800,"icon":24,"children":-1},"Write a seed, a blueprint, a chain and a saved test in six steps.",{"title":36,"path":37,"stem":38,"description":1802,"icon":39,"children":-1},"One factory per entity type, as an immutable value.",1791831050382]