Skip to content

Commit a52bed8

Browse files
author
Jay Herron
committed
Fixes Observable<Any> type issues with testing
1 parent 220713b commit a52bed8

2 files changed

Lines changed: 46 additions & 72 deletions

File tree

Sources/GraphQL/Subscription/Subscribe.swift

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,11 @@ func createSourceEventStream(
135135
) -> EventLoopFuture<SourceEventStreamResult> {
136136

137137
let executeStarted = instrumentation.now
138-
let exeContext: ExecutionContext
139138

140139
do {
141140
// If a valid context cannot be created due to incorrect arguments,
142141
// this will throw an error.
143-
exeContext = try buildExecutionContext(
142+
let exeContext = try buildExecutionContext(
144143
queryStrategy: queryStrategy,
145144
mutationStrategy: mutationStrategy,
146145
subscriptionStrategy: subscriptionStrategy,
@@ -154,6 +153,7 @@ func createSourceEventStream(
154153
operationName: operationName
155154
// TODO shouldn't we be including the subscribeFieldResolver??
156155
)
156+
return try executeSubscription(context: exeContext, eventLoopGroup: eventLoopGroup)
157157
} catch let error as GraphQLError {
158158
instrumentation.operationExecution(
159159
processId: processId(),
@@ -174,8 +174,6 @@ func createSourceEventStream(
174174
} catch {
175175
return eventLoopGroup.next().makeSucceededFuture(SourceEventStreamResult.failure(GraphQLError(error)))
176176
}
177-
178-
return try! executeSubscription(context: exeContext, eventLoopGroup: eventLoopGroup)
179177
}
180178

181179
func executeSubscription(
@@ -233,45 +231,32 @@ func executeSubscription(
233231

234232
// Get the resolve func, regardless of if its result is normal
235233
// or abrupt (error).
236-
let result = resolveOrError(
234+
let resolvedFutureOrError = resolveOrError(
237235
resolve: resolve,
238236
source: context.rootValue,
239237
args: args,
240238
context: contextValue,
241239
eventLoopGroup: eventLoopGroup,
242240
info: info
243241
)
244-
return try completeValueCatchingError(
245-
exeContext: context,
246-
returnType: fieldDef.type,
247-
fieldASTs: fieldNodes,
248-
info: info,
249-
path: path,
250-
result: result
251-
)
252-
// TODO do we need to create this data map?
253-
// .flatMapThrowing { data -> Any in
254-
// // Translate from raw value completion map into a GraphQLResult
255-
// var dataMap: Map = [:]
256-
// dataMap[fieldDef.name] = try map(from: data)
257-
// var result: GraphQLResult = GraphQLResult(data: dataMap)
258-
//
259-
// if !context.errors.isEmpty {
260-
// result.errors = context.errors
261-
// }
262-
// return result
263-
// }
264-
.map { value -> SourceEventStreamResult in
242+
243+
let resolvedFuture:Future<Any?>
244+
switch resolvedFutureOrError {
245+
case let .failure(error):
246+
throw error
247+
case let .success(success):
248+
resolvedFuture = success
249+
}
250+
return resolvedFuture.map { resolved -> SourceEventStreamResult in
265251
if !context.errors.isEmpty {
266252
// TODO improve this to return multiple errors if we have them.
267253
return SourceEventStreamResult.failure(context.errors.first!)
268-
} else if value is Observable<Any?> {
269-
let observable = value as! Observable<Any>
270-
return SourceEventStreamResult.success(observable)
271-
} else if let error = value as? GraphQLError {
254+
} else if let error = resolved as? GraphQLError {
272255
return SourceEventStreamResult.failure(error)
256+
} else if let observable = resolved as? Observable<Any> {
257+
return SourceEventStreamResult.success(observable)
273258
} else {
274-
return SourceEventStreamResult.failure(GraphQLError(message: "Subscription field resolver must return Observable of GraphQLResults."))
259+
return SourceEventStreamResult.failure(GraphQLError(message: "Subscription field resolver must return an Observable<Any>"))
275260
}
276261
}
277262
}

Tests/GraphQLTests/Subscription/SubscriptionTests.swift

Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import RxSwift
66
class SubscriptionTests : XCTestCase {
77

88
private func createSubscription(
9-
pubsub:Observable<Email>,
9+
pubsub:Observable<Any>,
1010
schema:GraphQLSchema = emailSchemaWithResolvers(subscribe: nil, resolve: nil),
1111
document:Document = defaultSubscriptionAST
1212
) -> EventLoopFuture<SubscriptionResult> {
@@ -54,12 +54,40 @@ class SubscriptionTests : XCTestCase {
5454
)
5555
}
5656

57+
58+
59+
// TODO Delete me - this just goes thru the entire pipeline
60+
func testDELETEME() throws {
61+
let pubsub = PublishSubject<Any>()
62+
let testSchema = emailSchemaWithResolvers(
63+
subscribe: {_, _, _, eventLoopGroup, _ throws -> EventLoopFuture<Any?> in
64+
return eventLoopGroup.next().makeSucceededFuture(pubsub)
65+
},
66+
resolve: nil
67+
)
68+
let subscriptionResult = try createSubscription(pubsub: pubsub, schema: testSchema).wait()
69+
switch subscriptionResult {
70+
case .success(let subscription):
71+
let subscriber = subscription.subscribe {
72+
print("Event: \($0)")
73+
}
74+
pubsub.onNext(Email(
75+
from: "yuzhi@graphql.org",
76+
subject: "Alright",
77+
message: "Tests are good",
78+
unread: true
79+
))
80+
case .failure(let error):
81+
throw error
82+
}
83+
}
84+
5785
// MARK: Subscription Initialization Phase
5886

5987
/// accepts multiple subscription fields defined in schema
6088
// TODO Finish up this test
6189
func testAcceptsMultipleSubscriptionFields() throws {
62-
let pubsub = PublishSubject<Email>()
90+
let pubsub = PublishSubject<Any>()
6391
let subscriptionTypeMultiple = try GraphQLObjectType(
6492
name: "Subscription",
6593
fields: [
@@ -121,45 +149,6 @@ class SubscriptionTests : XCTestCase {
121149
}
122150
}
123151

124-
// TODO Delete me - this is a test to ensure that we are returning the correct thing.
125-
func testDELETEME() throws {
126-
let pubsub = PublishSubject<Email>()
127-
let subscriptionType = try GraphQLObjectType(
128-
name: "Subscription",
129-
fields: [
130-
"importantEmail": GraphQLField(
131-
type: EmailEventType,
132-
args: [
133-
"priority": GraphQLArgument(
134-
type: GraphQLInt
135-
)
136-
],
137-
subscribe: {_, _, _, eventLoopGroup, _ throws -> EventLoopFuture<Any?> in
138-
return eventLoopGroup.next().makeSucceededFuture(pubsub)
139-
}
140-
)
141-
]
142-
)
143-
let testSchema = emailSchemaWithResolvers(
144-
subscribe: {_, _, _, eventLoopGroup, _ throws -> EventLoopFuture<Any?> in
145-
return eventLoopGroup.next().makeSucceededFuture(pubsub)
146-
},
147-
resolve: nil
148-
)
149-
let subscriptionResult = try createSubscription(pubsub: pubsub, schema: testSchema).wait()
150-
switch subscriptionResult {
151-
case .success:
152-
pubsub.onNext(Email(
153-
from: "yuzhi@graphql.org",
154-
subject: "Alright",
155-
message: "Tests are good",
156-
unread: true
157-
))
158-
case .failure(let error):
159-
throw error
160-
}
161-
}
162-
163152
// Working!!!
164153
func testResolverThrowingErrorSchema() throws {
165154
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)

0 commit comments

Comments
 (0)