using concurrent::AtomicBoolusing concurrent::AtomicRefusing afIoc::Registryusing afIoc::RegistryBuilderusing wisp::MemWispSessionStoreusing wisp::WispSessionStore** For testing 'BedSheet' apps: Run tests against 'BedSheet' without starting a 'wisp' web server.** Testing your web app is as simple as:** ** Void testMywebApp() {** server := BedServer(AppModule#).startup** client := server.makeClient** response := client.get(`/hello`)** ** verifyEq(response.statusCode, 200)** verifyEq(response.asStr, "Hello!")** ** server.shutdown** }** ** @since 1.0.4constclass BedServer {privateconststatic Log log := Utils.getLog(BedServer#)privateconst AtomicRef reg := AtomicRef()privateconst AtomicBool started := AtomicBool()privateconst AtomicRef modules := AtomicRef(Type#.emptyList)privateconst AtomicRef moduleDeps := AtomicRef(Pod#.emptyList)privateconst AtomicRef bsMeta := AtomicRef()** The 'afIoc' registry - read only. Registry registry { get { checkHasStarted; return reg.val }private set { reg.val = it}}** Create a instance of 'afBedSheet' with the given afIoc module (usually your web app)new makeWithModule(Type? iocModule := null){ addModulesFromDependencies(BedSheetModule#.pod)if(iocModule != null) addModule(iocModule) bsMeta.val = BedSheetMetaDataImpl(iocModule?.pod, iocModule, [:])}** Create a instance of 'afBedSheet' with afIoc dependencies from the given pod (usually your web app)new makeWithPod(Pod webApp){ addModulesFromDependencies(webApp) addModule(BedSheetModule#) mod := BedSheetWebMod.findModFromPod(webApp) bsMeta.val = BedSheetMetaDataImpl(webApp, mod, [:])}** Add extra (test) modules should you wish to override behaviour in your tests BedServer addModule(Type iocModule){ checkHasNotStarted mods := (Type[]) modules.val modules.val = mods.rw.add(iocModule).toImmutablereturnthis} BedServer addModulesFromDependencies(Pod dependency){ checkHasNotStarted deps := (Pod[]) moduleDeps.val moduleDeps.val = deps.rw.add(dependency).toImmutablereturnthis}** Startup 'afBedSheet' BedServer startup(){ checkHasNotStarted bannerText := "Alien-Factory BedServer v${typeof.pod.version}, IoC v${Registry#.pod.version}" bob := RegistryBuilder()((Pod[]) moduleDeps.val).each |pod| { bob.addModulesFromDependencies(pod)} mods := (Type[]) modules.val bob.addModules(mods) bedSheetMetaData := bsMeta.val registry = bob.build(["bannerText":bannerText, "bedSheetMetaData":bedSheetMetaData, "appName":"BedServer"]).startup started.val = truereturnthis}** Shutdown 'afBedSheet' BedServer shutdown(){ checkHasStarted registry.shutdown reg.val = null started.val = false modules.val = Type#.emptyListreturnthis}** Create a `BedClient` that makes requests against this server BedClient makeClient(){ checkHasStartedreturn BedClient(this)}// ---- Registry Methods ----** Helper method - tap into BedSheet's afIoc registry Obj serviceById(Str serviceId){ checkHasStartedreturn registry.serviceById(serviceId)}** Helper method - tap into BedSheet's afIoc registry Obj dependencyByType(Type dependencyType){ checkHasStartedreturn registry.dependencyByType(dependencyType)}** Helper method - tap into BedSheet's afIoc registry Obj autobuild(Type type, Obj?[] ctorArgs := Obj#.emptyList){ checkHasStartedreturn registry.autobuild(type, ctorArgs)}** Helper method - tap into BedSheet's afIoc registry Obj injectIntoFields(Obj service){ checkHasStartedreturn registry.injectIntoFields(service)}// ---- helper methods ----** as called by BedClients - if no reg then we must have been shutdowninternal Void checkHasNotShutdown(){if(reg.val == null)throw Err("${BedServer#.name} has been shutdown!")}private Void checkHasStarted(){if(!started.val)throw Err("${BedServer#.name} has not yet started!")}private Void checkHasNotStarted(){if(started.val)throw Err("${BedServer#.name} has not already been started!")}}