Changes
1 changed files (+203/-3)
-
-
@@ -123,23 +123,223 @@ private enum MockError: Error {case notImplementedInMock } private actor MockServer {} private struct MockPage { let browse: String let load: String func browseMsg() throws -> Moo { let bytes = browse.data(using: .utf8)! return Moo( verb: "COMPLETE", service: "Success", headers: [ "Content-Type": "application/json", "Content-Length": String(bytes.count, radix: 10), ], body: bytes, ) } func loadMsg() throws -> Moo { let bytes = load.data(using: .utf8)! return Moo( verb: "COMPLETE", service: "Success", headers: [ "Content-Type": "application/json", "Content-Length": String(bytes.count, radix: 10), ], body: bytes, ) } } private actor MockServer { var stack: [MockPage] = [] } extension MockServer: Communicatable { var root: MockPage { .init( browse: """ { "action": "list", "list": { "title": "Mock Page", "subtitle": "Various responses" } } """, load: """ { "list": { "title": "Mock Page", "subtitle": "Various responses", "level": 0 }, "items": [ { "title": "List", "item_key": "mock-list", "hint": "list" }, { "title": "Slow List", "item_key": "mock-slow-list", "hint": "list" }, { "title": "Action List", "item_key": "mock-action_list", "hint": "action_list" }, { "title": "Action", "item_key": "mock-action", "hint": "action" }, { "title": "Header", "item_key": "mock-header", "hint": "header" }, { "title": "Unknown", "item_key": "mock-unknown" } ] } """ ) } var list: MockPage { .init( browse: """ { "action": "list", "list": { "title": "List" } } """, load: """ { "list": { "title": "List", "subtitle": "Various responses", "level": 1 }, "items": [ { "title": "Action", "item_key": "mock-list-action", "hint": "action" }, { "title": "Item 1", "item_key": "mock-list-item1", "hint": "action_list" }, { "title": "Item 2", "item_key": "mock-list-item2", "hint": "action_list" }, { "title": "Item 3", "item_key": "mock-list-item3", "hint": "action_list" }, { "title": "Item 4", "item_key": "mock-list-item4", "hint": "action_list" } ] } """ ) } var messages: AsyncStream<Moo> { AsyncStream { stream in stream.finish() } } enum RequestError: Error { case noBody case notImplemented } func request(_ msg: consuming Moo) async throws -> Moo { throw MockError.notImplementedInMock switch msg.service { case "\(BrowseService.id)/browse": guard let body = msg.body, let data = body.data(using: .utf8) else { throw RequestError.noBody } let req = try JSONDecoder().decode( BrowseService.BrowseRequest.self, from: data ) guard req.hierarchy == .browse else { return Moo(verb: "COMPLETE", service: "MockNotImplemented") } if req.popAll == .some(true) { stack = [] } else if let pop = req.popLevels { stack = Array(stack[0...(stack.count - Int(pop))]) } else if let itemKey = req.itemKey { switch itemKey { case "mock-list": stack.append(list) case "mock-slow-list": try await Task.sleep(for: .milliseconds(500)) stack.append(list) case "mock-action": break case "mock-list-action": break default: return Moo(verb: "COMPLETE", service: "UnknownItemKey") } } let page = stack.last ?? root return try page.browseMsg() case "\(BrowseService.id)/load": guard let body = msg.body, let data = body.data(using: .utf8) else { throw RequestError.noBody } let req = try JSONDecoder().decode( BrowseService.LoadRequest.self, from: data ) guard req.hierarchy == .browse else { return Moo(verb: "COMPLETE", service: "MockNotImplemented") } let page = stack.last ?? root return try page.loadMsg() default: throw RequestError.notImplemented } } func request(_ msg: consuming Moo, timeout: ContinuousClock.Instant.Duration) async throws -> Moo { throw MockError.notImplementedInMock try await request(msg) } func send(_ msg: consuming Moo) async throws {}
-