Skip to content

Commit

Permalink
Add Jest imports everywhere, remove global availability (#6911)
Browse files Browse the repository at this point in the history
In ESM mode, the `jest` globals are technically no longer available. For
some reason, we're still getting away with it, but this issue surfaces
in the v29 upgrade PR so I'm going to address it separately.

https://jestjs.io/docs/ecmascript-modules#differences-between-esm-and-commonjs

Ref:
#6850 (comment)

<!--
First, 🌠 thank you 🌠 for taking the time to consider a contribution to
Apollo!

Here are some important details to follow:

* ⏰ Your time is important
To save your precious time, if the contribution you are making will take
more
than an hour, please make sure it has been discussed in an issue first.
          This is especially true for feature requests!
* 💡 Features
Feature requests can be created and discussed within a GitHub Issue. Be
sure to search for existing feature requests (and related issues!) prior
to
opening a new request. If an existing issue covers the need, please
upvote
that issue by using the 👍 emote, rather than opening a new issue.
* 🔌 Integrations
Apollo Server has many web-framework integrations including Express,
Koa,
Hapi and more. When adding a new feature, or fixing a bug, please take a
peak and see if other integrations are also affected. In most cases, the
fix can be applied to the other frameworks as well. Please note that,
since new web-frameworks have a high maintenance cost, pull-requests for
new web-frameworks should be discussed with a project maintainer first.
* 🕷 Bug fixes
These can be created and discussed in this repository. When fixing a
bug,
please _try_ to add a test which verifies the fix. If you cannot, you
should
still submit the PR but we may still ask you (and help you!) to create a
test.
* 📖 Contribution guidelines
Follow
https://github.com/apollographql/apollo-server/blob/main/CONTRIBUTING.md
when submitting a pull request. Make sure existing tests still pass, and
add
          tests for all new behavior.
* ✏️ Explain your pull request
Describe the big picture of your changes here to communicate to what
your
pull request is meant to accomplish. Provide 🔗 links 🔗 to associated
issues!

We hope you will find this to be a positive experience! Open source
contribution can be intimidating and we hope to alleviate that pain as
much as possible. Without following these guidelines, you may be missing
context that can help you succeed with your contribution, which is why
we encourage discussion first. Ultimately, there is no guarantee that we
will be able to merge your pull-request, but by following these
guidelines we can try to avoid disappointment.
-->
  • Loading branch information
trevor-scheer committed Sep 15, 2022
1 parent 6541f92 commit 793de3e
Show file tree
Hide file tree
Showing 32 changed files with 57 additions and 30 deletions.
2 changes: 2 additions & 0 deletions .changeset/eleven-drinks-mix.md
@@ -0,0 +1,2 @@
---
---
@@ -1,4 +1,5 @@
import plugin from '../ApolloServerPluginResponseCache';
import { describe, it, expect } from '@jest/globals';

describe('Response cache plugin', () => {
it('will instantiate when not called with options', () => {
Expand Down
Expand Up @@ -6,6 +6,7 @@ import {
import { startStandaloneServer } from '@apollo/server/standalone';
import ApolloServerPluginResponseCache from '../index.js';
import request, { type Response } from 'supertest';
import { jest, describe, it, expect, beforeAll, afterAll } from '@jest/globals';

describe('Response caching', () => {
beforeAll(() => {
Expand Down
1 change: 1 addition & 0 deletions packages/plugin-response-cache/src/__tests__/tsconfig.json
Expand Up @@ -3,5 +3,6 @@
"include": ["**/*"],
"references": [
{ "path": "../../" },
{ "path": "../../../server" }
]
}
3 changes: 2 additions & 1 deletion packages/server/src/__tests__/ApolloServer.test.ts
Expand Up @@ -9,6 +9,7 @@ import { HeaderMap } from '../runHttpQuery.js';
import { mockLogger } from './mockLogger.js';
import gql from 'graphql-tag';
import type { GatewayInterface } from '@apollo/server-gateway-interface';
import { jest, describe, it, expect } from '@jest/globals';

const typeDefs = gql`
type Query {
Expand Down Expand Up @@ -132,7 +133,7 @@ const failToStartPlugin: ApolloServerPlugin<BaseContext> = {

describe('ApolloServer start', () => {
it('start throws on startup error and startupDidFail hook is called with error', async () => {
const startupDidFail = jest.fn();
const startupDidFail = jest.fn(async () => {});
const server = new ApolloServer({
typeDefs,
resolvers,
Expand Down
1 change: 1 addition & 0 deletions packages/server/src/__tests__/cachePolicy.test.ts
@@ -1,5 +1,6 @@
import type { CachePolicy } from '@apollo/cache-control-types';
import { newCachePolicy } from '../cachePolicy.js';
import { describe, it, expect, beforeEach } from '@jest/globals';

describe('newCachePolicy', () => {
let cachePolicy: CachePolicy;
Expand Down
1 change: 1 addition & 0 deletions packages/server/src/__tests__/documentStore.test.ts
Expand Up @@ -3,6 +3,7 @@ import type { DocumentNode } from 'graphql';
import gql from 'graphql-tag';
import { InMemoryLRUCache } from '@apollo/utils.keyvaluecache';
import { ApolloServer } from '..';
import { jest, describe, it, expect } from '@jest/globals';

const typeDefs = gql`
type Query {
Expand Down
3 changes: 2 additions & 1 deletion packages/server/src/__tests__/errors.test.ts
Expand Up @@ -2,6 +2,7 @@ import { GraphQLError, GraphQLFormattedError } from 'graphql';
import { unwrapResolverError } from '@apollo/server/errors';

import { normalizeAndFormatErrors } from '../errorNormalize.js';
import { jest, describe, it, expect } from '@jest/globals';

describe('Errors', () => {
describe('normalizeAndFormatErrors', () => {
Expand Down Expand Up @@ -55,7 +56,7 @@ describe('Errors', () => {
const error = new GraphQLError(message, {
extensions: { code, key },
});
const formatError = jest.fn();
const formatError = jest.fn((fErr, _err) => fErr);
normalizeAndFormatErrors([error], {
formatError,
includeStacktraceInErrorResponses: true,
Expand Down
Expand Up @@ -2,6 +2,7 @@ import express from 'express';
import request from 'supertest';
import { ApolloServer } from '../../index.js';
import { expressMiddleware } from '../../express4/index.js';
import { it, expect } from '@jest/globals';

it('gives helpful error if body-parser middleware is not installed', async () => {
const server = new ApolloServer({ typeDefs: 'type Query {f: ID}' });
Expand Down
Expand Up @@ -3,6 +3,7 @@ import { ApolloServer } from '..';
import { ApolloGateway as AG0OldestSupported } from 'apollo-gateway-0-oldest-supported';
import { ApolloGateway as AG0BeforeASGI } from 'apollo-gateway-0-before-asgi';
import { ApolloGateway as AG0Latest } from 'apollo-gateway-0-latest';
import { it } from '@jest/globals';

// This is the oldest version which prints no peer dep warnings when installed
// with graphql-js@16; it's possible that some older versions could work as
Expand Down
Expand Up @@ -3,6 +3,7 @@ import { ApolloServer } from '..';
import { ApolloGateway as AG2OldestSupported } from 'apollo-gateway-2-oldest-supported';
import { ApolloGateway as AG2BeforeASGI } from 'apollo-gateway-2-before-asgi';
import { ApolloGateway as AG2Latest } from 'apollo-gateway-2-latest';
import { it } from '@jest/globals';

it('can construct an ApolloServer with oldest supported @apollo/gateway 2.x', () => {
new ApolloServer({ gateway: new AG2OldestSupported() });
Expand Down
1 change: 1 addition & 0 deletions packages/server/src/__tests__/logger.test.ts
Expand Up @@ -2,6 +2,7 @@ import { ApolloServer } from '..';
import gql from 'graphql-tag';
import loglevel from 'loglevel';
import { mockLogger } from './mockLogger';
import { jest, describe, it, expect } from '@jest/globals';

const KNOWN_DEBUG_MESSAGE = 'The server is starting.';

Expand Down
2 changes: 2 additions & 0 deletions packages/server/src/__tests__/mockLogger.ts
@@ -1,3 +1,5 @@
import { jest } from '@jest/globals';

export function mockLogger() {
return {
debug: jest.fn(),
Expand Down
Expand Up @@ -7,6 +7,7 @@ import {
collectCacheControlHints,
collectCacheControlHintsAndPolicyIfCacheable,
} from './collectCacheControlHints';
import { describe, it, expect } from '@jest/globals';

describe('@cacheControl directives', () => {
it('should set maxAge: 0 and no scope for a field without cache hints', async () => {
Expand Down
Expand Up @@ -5,6 +5,7 @@ import {
} from '../../../plugin/cacheControl';
import { ApolloServer, HTTPGraphQLResponse } from '../../..';
import type { CacheHint } from '@apollo/cache-control-types';
import { describe, it, expect } from '@jest/globals';

describe('plugin', () => {
describe('willSendResponse', () => {
Expand Down
Expand Up @@ -5,6 +5,7 @@ import {
ApolloServerPluginCacheControl,
ApolloServerPluginCacheControlOptions,
} from '../../../plugin/cacheControl';
import { expect } from '@jest/globals';

export async function collectCacheControlHintsAndPolicyIfCacheable(
schema: GraphQLSchema,
Expand Down
Expand Up @@ -8,6 +8,7 @@ import type {
import { makeExecutableSchemaWithCacheControlSupport } from './cacheControlSupport';

import { collectCacheControlHints } from './collectCacheControlHints';
import { describe, it, expect } from '@jest/globals';

export interface GraphQLResolvers {
[fieldName: string]: (() => any) | GraphQLResolverObject | GraphQLScalarType;
Expand Down
Expand Up @@ -38,6 +38,7 @@ import { Stopper } from '../../../plugin/drainHttpServer/stoppable';
import child from 'child_process';
import path from 'path';
import type { AddressInfo } from 'net';
import { describe, it, expect, afterEach, beforeEach } from '@jest/globals';

function port(s: http.Server) {
return (s.address() as AddressInfo).port;
Expand Down
@@ -1,5 +1,6 @@
import { getEmbeddedExplorerHTML } from '../../../plugin/landingPage/default/getEmbeddedHTML';
import type { ApolloServerPluginEmbeddedLandingPageProductionDefaultOptions } from '../../../plugin/landingPage/default/types';
import { describe, it, expect } from '@jest/globals';

const version = '_latest';
expect.addSnapshotSerializer(require('jest-serializer-html'));
Expand Down
@@ -1,5 +1,6 @@
import { getEmbeddedSandboxHTML } from '../../../plugin/landingPage/default/getEmbeddedHTML';
import type { LandingPageConfig } from '../../../plugin/landingPage/default/types';
import { describe, it, expect } from '@jest/globals';

const version = '_latest';
expect.addSnapshotSerializer(require('jest-serializer-html'));
Expand Down
@@ -1,6 +1,7 @@
import { ApolloServer } from '../../..';
import { ApolloServerPluginUsageReportingDisabled } from '../../../plugin/disabled';
import { ApolloServerPluginSchemaReporting } from '../../../plugin/schemaReporting';
import { describe, it, expect } from '@jest/globals';

describe('end-to-end', () => {
it('fails for unparsable overrideReportedSchema', async () => {
Expand Down
Expand Up @@ -5,9 +5,9 @@ import {
} from '../../../plugin/schemaReporting/schemaReporter';
import type {
SchemaReportMutation,
ReportSchemaResponse,
SchemaReportMutationVariables,
} from '../../../plugin/schemaReporting/generated/operations';
import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';

function mockReporterRequest(
url: any,
Expand Down Expand Up @@ -64,9 +64,7 @@ describe('Schema reporter', () => {
withCoreSchema: false,
});

expect(
await schemaReporter.reportSchema(false),
).toEqual<ReportSchemaResponse>({
expect(await schemaReporter.reportSchema(false)).toEqual({
__typename: 'ReportSchemaResponse',
inSeconds: 30,
withCoreSchema: false,
Expand All @@ -78,9 +76,7 @@ describe('Schema reporter', () => {
withCoreSchema: true,
});

expect(
await schemaReporter.reportSchema(false),
).toEqual<ReportSchemaResponse>({
expect(await schemaReporter.reportSchema(false)).toEqual({
__typename: 'ReportSchemaResponse',
inSeconds: 60,
withCoreSchema: true,
Expand Down
@@ -1,4 +1,5 @@
import { DurationHistogram } from '../../../plugin/usageReporting/durationHistogram';
import { describe, it, expect } from '@jest/globals';

describe('Duration histogram tests', () => {
it('generateEmptyHistogram', () => {
Expand Down
@@ -1,4 +1,5 @@
import { operationDerivedDataCacheKey } from '../../../plugin/usageReporting/operationDerivedDataCache';
import { describe, it, expect } from '@jest/globals';

describe('operation-derived data cache key', () => {
it('generates without the operationName', () => {
Expand Down
Expand Up @@ -25,6 +25,7 @@ import {
ApolloServerPluginUsageReporting,
} from '../../../plugin/usageReporting';
import { ApolloServerPluginCacheControlDisabled } from '../../../plugin/disabled';
import { describe, it, expect, afterEach } from '@jest/globals';

const quietLogger = loglevel.getLogger('quiet');
quietLogger.setLevel(loglevel.levels.WARN);
Expand Down
Expand Up @@ -5,6 +5,7 @@ import {
SizeEstimator,
} from '../../../plugin/usageReporting/stats';
import { DurationHistogram } from '../../../plugin/usageReporting/durationHistogram';
import { describe, it, expect } from '@jest/globals';

const statsContext = {
clientVersion: 'version',
Expand Down
@@ -1,6 +1,7 @@
import { makeTraceDetails } from '../../../plugin/usageReporting/traceDetails';
import { Trace } from '@apollo/usage-reporting-protobuf';
import { GraphQLError } from 'graphql';
import { describe, it, expect } from '@jest/globals';

const variables: Record<string, any> = {
testing: 'testing',
Expand Down
7 changes: 4 additions & 3 deletions packages/server/src/__tests__/rollupCommonJs.test.ts
@@ -1,15 +1,16 @@
const rollup = require('rollup');
import { describe, expect, it } from '@jest/globals';
import commonjs from '@rollup/plugin-commonjs';
import path from 'path';
import { rollup, OutputOptions } from 'rollup';

describe('@rollup/plugin-commonjs', () => {
it('bundles into es6 without circular dependencies issues', async () => {
const outputOptions = {
const outputOptions: OutputOptions = {
exports: 'named',
name: 'apollo',
format: 'umd',
};
const bundle = await rollup.rollup({
const bundle = await rollup({
input: path.resolve(__dirname, '..', '..', 'dist', 'cjs', 'index.js'),
plugins: [commonjs()],
onwarn: () => {
Expand Down
33 changes: 17 additions & 16 deletions packages/server/src/__tests__/runQuery.test.ts
Expand Up @@ -23,6 +23,7 @@ import {
GraphQLRequestListenerValidationDidEnd,
} from '..';
import { mockLogger } from './mockLogger';
import { jest, describe, it, expect } from '@jest/globals';

async function runQuery(
config: ApolloServerOptions<BaseContext>,
Expand Down Expand Up @@ -291,7 +292,7 @@ it('uses custom field resolver', async () => {

describe('request pipeline life-cycle hooks', () => {
it('requestDidStart called for each request', async () => {
const requestDidStart = jest.fn();
const requestDidStart = jest.fn(async (_rc) => {});
const runOnce = () =>
runQuery(
{
Expand All @@ -318,7 +319,7 @@ describe('request pipeline life-cycle hooks', () => {
* within the "Persisted Queries" tests. (Search for "didResolveSource").
*/
it('didResolveSource called with the source', async () => {
const didResolveSource = jest.fn();
const didResolveSource = jest.fn(async (_rc) => {});
await runQuery(
{
schema,
Expand All @@ -343,7 +344,7 @@ describe('request pipeline life-cycle hooks', () => {
});

describe('parsingDidStart', () => {
const parsingDidStart = jest.fn();
const parsingDidStart = jest.fn(async (_rc) => {});
const plugin = {
async requestDidStart() {
return {
Expand Down Expand Up @@ -378,7 +379,7 @@ describe('request pipeline life-cycle hooks', () => {

describe('executionDidStart', () => {
it('called when execution starts', async () => {
const executionDidStart = jest.fn();
const executionDidStart = jest.fn(async (_rc) => {});
await runQuery(
{
schema,
Expand All @@ -400,7 +401,7 @@ describe('request pipeline life-cycle hooks', () => {

describe('executionDidEnd', () => {
it('works as a listener on an object returned from "executionDidStart"', async () => {
const executionDidEnd = jest.fn();
const executionDidEnd = jest.fn(async (_rc) => {});
const executionDidStart = jest.fn(
async (): Promise<GraphQLRequestExecutionListener<BaseContext>> => ({
executionDidEnd,
Expand Down Expand Up @@ -468,8 +469,8 @@ describe('request pipeline life-cycle hooks', () => {

describe('willResolveField', () => {
it('called when resolving a field starts', async () => {
const willResolveField = jest.fn();
const executionDidEnd = jest.fn();
const willResolveField = jest.fn((_frp) => {});
const executionDidEnd = jest.fn(async (_rc) => {});
const executionDidStart = jest.fn(
async (): Promise<GraphQLRequestExecutionListener<BaseContext>> => ({
willResolveField,
Expand Down Expand Up @@ -499,8 +500,8 @@ describe('request pipeline life-cycle hooks', () => {
});

it('called once for each field being resolved', async () => {
const willResolveField = jest.fn();
const executionDidEnd = jest.fn();
const willResolveField = jest.fn((_frp) => {});
const executionDidEnd = jest.fn(async (_rc) => {});
const executionDidStart = jest.fn(
async (): Promise<GraphQLRequestExecutionListener<BaseContext>> => ({
willResolveField,
Expand Down Expand Up @@ -531,7 +532,7 @@ describe('request pipeline life-cycle hooks', () => {

describe('receives correct resolver parameter object', () => {
it('receives undefined parent when there is no parent', async () => {
const willResolveField = jest.fn();
const willResolveField = jest.fn((_frp) => {});

await runQuery(
{
Expand Down Expand Up @@ -560,7 +561,7 @@ describe('request pipeline life-cycle hooks', () => {
});

it('receives the parent when there is one', async () => {
const willResolveField = jest.fn();
const willResolveField = jest.fn((_frp) => {});

await runQuery(
{
Expand Down Expand Up @@ -599,7 +600,7 @@ describe('request pipeline life-cycle hooks', () => {
});

it('receives context', async () => {
const willResolveField = jest.fn();
const willResolveField = jest.fn((_frp) => {});

await runQuery(
{
Expand Down Expand Up @@ -630,7 +631,7 @@ describe('request pipeline life-cycle hooks', () => {
});

it('receives arguments', async () => {
const willResolveField = jest.fn();
const willResolveField = jest.fn((_frp) => {});

await runQuery(
{
Expand Down Expand Up @@ -662,7 +663,7 @@ describe('request pipeline life-cycle hooks', () => {
const didResolveField: GraphQLRequestListenerDidResolveField =
jest.fn();
const willResolveField = jest.fn(() => didResolveField);
const executionDidEnd = jest.fn();
const executionDidEnd = jest.fn(async () => {});
const executionDidStart = jest.fn(
async (): Promise<GraphQLRequestExecutionListener<BaseContext>> => ({
willResolveField,
Expand Down Expand Up @@ -696,7 +697,7 @@ describe('request pipeline life-cycle hooks', () => {
const didResolveField: GraphQLRequestListenerDidResolveField =
jest.fn();
const willResolveField = jest.fn(() => didResolveField);
const executionDidEnd = jest.fn();
const executionDidEnd = jest.fn(async () => {});
const executionDidStart = jest.fn(
async (): Promise<GraphQLRequestExecutionListener<BaseContext>> => ({
willResolveField,
Expand Down Expand Up @@ -807,7 +808,7 @@ describe('request pipeline life-cycle hooks', () => {
});

describe('didEncounterErrors', () => {
const didEncounterErrors = jest.fn();
const didEncounterErrors = jest.fn(async () => {});
const plugins: ApolloServerPlugin<BaseContext>[] = [
{
async requestDidStart() {
Expand Down

0 comments on commit 793de3e

Please sign in to comment.