Skip to content

Commit 08d4f3d

Browse files
committed
rename test files
also combine execute/subscribe
1 parent 0a44105 commit 08d4f3d

4 files changed

Lines changed: 102 additions & 142 deletions

File tree

src/execution/__tests__/subscribe-diagnostics-test.ts

Lines changed: 0 additions & 123 deletions
This file was deleted.

src/execution/__tests__/execute-diagnostics-test.ts renamed to src/execution/__tests__/tracing-test.ts

Lines changed: 102 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from '../../__testUtils__/diagnosticsTestUtils.js';
88

99
import { isAsyncIterable } from '../../jsutils/isAsyncIterable.js';
10+
import { isPromise } from '../../jsutils/isPromise.js';
1011

1112
import { parse } from '../../language/parser.js';
1213

@@ -23,18 +24,22 @@ const schema = buildSchema(`
2324
type Query {
2425
sync: String
2526
async: String
27+
dummy: String
2628
}
27-
`);
28-
29-
const rootValue = {
30-
sync: () => 'hello',
31-
async: () => Promise.resolve('hello-async'),
32-
};
3329
34-
const executeChannel = getTracingChannel('graphql:execute');
30+
type Subscription {
31+
tick: String
32+
}
33+
`);
3534

3635
describe('execute diagnostics channel', () => {
3736
let active: ReturnType<typeof collectEvents> | undefined;
37+
const executeChannel = getTracingChannel('graphql:execute');
38+
39+
const rootValue = {
40+
sync: () => 'hello',
41+
async: () => Promise.resolve('hello-async'),
42+
};
3843

3944
afterEach(() => {
4045
active?.unsubscribe();
@@ -110,16 +115,6 @@ describe('execute diagnostics channel', () => {
110115
});
111116

112117
it('emits for each subscription event with resolved operation ctx', async () => {
113-
const subscriptionSchema = buildSchema(`
114-
type Query {
115-
dummy: String
116-
}
117-
118-
type Subscription {
119-
tick: String
120-
}
121-
`);
122-
123118
async function* tickGenerator() {
124119
await Promise.resolve();
125120
yield { tick: 'one' };
@@ -131,7 +126,7 @@ describe('execute diagnostics channel', () => {
131126
active = collectEvents(executeChannel);
132127

133128
const subscription = await subscribe({
134-
schema: subscriptionSchema,
129+
schema,
135130
document,
136131
rootValue: { tick: tickGenerator },
137132
});
@@ -152,7 +147,7 @@ describe('execute diagnostics channel', () => {
152147
expect(ev.ctx.operationType).to.equal('subscription');
153148
expect(ev.ctx.operationName).to.equal('S');
154149
expect(ev.ctx.operation).to.equal(document.definitions[0]);
155-
expect(ev.ctx.schema).to.equal(subscriptionSchema);
150+
expect(ev.ctx.schema).to.equal(schema);
156151
}
157152
});
158153

@@ -162,3 +157,91 @@ describe('execute diagnostics channel', () => {
162157
expect(result).to.deep.equal({ data: { sync: 'hello' } });
163158
});
164159
});
160+
161+
describe('subscribe diagnostics channel', () => {
162+
let active: ReturnType<typeof collectEvents> | undefined;
163+
const subscribeChannel = getTracingChannel('graphql:subscribe');
164+
165+
async function* twoTicks(): AsyncIterable<{ tick: string }> {
166+
await Promise.resolve();
167+
yield { tick: 'one' };
168+
yield { tick: 'two' };
169+
}
170+
171+
afterEach(() => {
172+
active?.unsubscribe();
173+
active = undefined;
174+
});
175+
176+
it('emits start and end for a synchronous subscription setup', async () => {
177+
active = collectEvents(subscribeChannel);
178+
179+
const document = parse('subscription S { tick }');
180+
181+
const result = subscribe({
182+
schema,
183+
document,
184+
rootValue: { tick: twoTicks },
185+
});
186+
const resolved = isPromise(result) ? await result : result;
187+
assert(isAsyncIterable(resolved));
188+
await resolved.return?.();
189+
190+
expect(active.events.map((e) => e.kind)).to.deep.equal(['start', 'end']);
191+
expect(active.events[0].ctx.operationType).to.equal('subscription');
192+
expect(active.events[0].ctx.operationName).to.equal('S');
193+
expect(active.events[0].ctx.document).to.equal(document);
194+
expect(active.events[0].ctx.schema).to.equal(schema);
195+
});
196+
197+
it('emits the full async lifecycle when subscribe resolver returns a promise', async () => {
198+
active = collectEvents(subscribeChannel);
199+
200+
const document = parse('subscription { tick }');
201+
202+
const result = subscribe({
203+
schema,
204+
document,
205+
rootValue: {
206+
tick: (): Promise<AsyncIterable<{ tick: string }>> =>
207+
Promise.resolve(twoTicks()),
208+
},
209+
});
210+
const resolved = isPromise(result) ? await result : result;
211+
assert(isAsyncIterable(resolved));
212+
await resolved.return?.();
213+
214+
expect(active.events.map((e) => e.kind)).to.deep.equal([
215+
'start',
216+
'end',
217+
'asyncStart',
218+
'asyncEnd',
219+
]);
220+
});
221+
222+
it('emits only start and end for a synchronous validation failure', () => {
223+
active = collectEvents(subscribeChannel);
224+
225+
// Invalid: no operation.
226+
const document = parse('fragment F on Subscription { tick }');
227+
228+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
229+
subscribe({ schema, document, rootValue: { tick: twoTicks } });
230+
231+
expect(active.events.map((e) => e.kind)).to.deep.equal(['start', 'end']);
232+
});
233+
234+
it('does nothing when no subscribers are attached', async () => {
235+
const document = parse('subscription { tick }');
236+
237+
const result = subscribe({
238+
schema,
239+
document,
240+
rootValue: { tick: twoTicks },
241+
});
242+
const resolved = isPromise(result) ? await result : result;
243+
if (isAsyncIterable(resolved)) {
244+
await resolved.return?.();
245+
}
246+
});
247+
});
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)