Skip to content

Instantly share code, notes, and snippets.

@ryan-roemer
Last active February 15, 2019 22:13
Show Gist options
  • Save ryan-roemer/fe19ca41709ad0df2a8f07155a6b4b69 to your computer and use it in GitHub Desktop.
Save ryan-roemer/fe19ca41709ad0df2a8f07155a6b4b69 to your computer and use it in GitHub Desktop.
urql - chore/publishing
$ publish-diff -o urql@1.0.0 -n .
Index: dist/types/client.test.d.ts
===================================================================
--- dist/types/client.test.d.ts urql@1.0.0
+++ dist/types/client.test.d.ts .
@@ -1,1 +1,0 @@
-export {};
\ No newline at end of file
Index: dist/types/context.test.d.ts
===================================================================
--- dist/types/context.test.d.ts urql@1.0.0
+++ dist/types/context.test.d.ts .
@@ -1,1 +1,0 @@
-export {};
\ No newline at end of file
Index: dist/types/test-utils/index.d.ts
===================================================================
--- dist/types/test-utils/index.d.ts urql@1.0.0
+++ dist/types/test-utils/index.d.ts .
@@ -1,0 +1,1 @@
\ No newline at end of file
+export * from './samples';
Index: dist/types/test-utils/samples.d.ts
===================================================================
--- dist/types/test-utils/samples.d.ts urql@1.0.0
+++ dist/types/test-utils/samples.d.ts .
@@ -1,0 +1,11 @@
\ No newline at end of file
+import { ExecutionResult, GraphqlMutation, GraphqlQuery, GraphqlSubscription, Operation, OperationResult } from '../types';
+export declare const queryGql: GraphqlQuery;
+export declare const mutationGql: GraphqlMutation;
+export declare const subscriptionGql: GraphqlSubscription;
+export declare const teardownOperation: Operation;
+export declare const queryOperation: Operation;
+export declare const mutationOperation: Operation;
+export declare const subscriptionOperation: Operation;
+export declare const queryResponse: OperationResult;
+export declare const mutationResponse: OperationResult;
+export declare const subscriptionResult: ExecutionResult;
Index: package.json
===================================================================
--- package.json urql@1.0.0
+++ package.json .
@@ -6,15 +6,8 @@
"module": "dist/urql.es.js",
"types": "dist/types/index.d.ts",
"source": "src/index.ts",
"sideEffects": false,
- "files": [
- "dist",
- "src",
- "README.md",
- "CHANGELOG.md",
- "LICENSE"
- ],
"scripts": {
"prebuild": "rimraf dist",
"build": "run-p build:types build:bundle",
"build:clean": "rimraf dist",
Index: src/.DS_Store
===================================================================
--- src/.DS_Store urql@1.0.0
+++ src/.DS_Store .
Binary files differ
Index: src/client.test.ts
===================================================================
--- src/client.test.ts urql@1.0.0
+++ src/client.test.ts .
@@ -1,170 +1,0 @@
-/** NOTE: Testing in this file is designed to test both the client and it's interaction with default Exchanges */
-jest.mock('./utils/hash', () => ({
- hashString: () => 'hash',
-}));
-import { map, pipe, subscribe, tap } from 'wonka';
-import { createClient } from './client';
-
-const url = 'https://hostname.com';
-
-describe('createClient', () => {
- it('passes snapshot', () => {
- const c = createClient({
- url,
- });
-
- expect(c).toMatchSnapshot();
- });
-
- describe('args', () => {
- describe('fetchOptions', () => {
- const fetchOptions = jest.fn(() => ({}));
-
- it('function is executed', () => {
- createClient({
- url,
- fetchOptions: fetchOptions as any,
- });
-
- expect(fetchOptions).toBeCalled();
- });
- });
- });
-});
-
-const query = { query: 'myquery', variables: { example: 1234 } };
-let receivedOps: any[] = [];
-let client = createClient({ url: '1234' });
-const receiveMock = jest.fn(s =>
- pipe(
- s,
- tap(op => (receivedOps = [...receivedOps, op])),
- map(op => ({ operation: op }))
- )
-);
-const exchangeMock = jest.fn(() => receiveMock);
-
-beforeEach(() => {
- receivedOps = [];
- exchangeMock.mockClear();
- receiveMock.mockClear();
- client = createClient({ url, exchanges: [exchangeMock] as any[] });
-});
-
-describe('exchange args', () => {
- it('receives forward function', () => {
- // @ts-ignore
- expect(typeof exchangeMock.mock.calls[0][0].forward).toBe('function');
- });
-
- it('recieves client', () => {
- // @ts-ignore
- expect(exchangeMock.mock.calls[0][0]).toHaveProperty('client', client);
- });
-});
-
-describe('executeQuery', () => {
- it('passes query string exchange', () => {
- pipe(
- client.executeQuery(query),
- subscribe(x => x)
- );
-
- // console.log(receivedOps);
- expect(receivedOps[0]).toHaveProperty('query', query.query);
- });
-
- it('passes variables type to exchange', () => {
- pipe(
- client.executeQuery(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('variables', query.variables);
- });
-
- it('passes operationName type to exchange', () => {
- pipe(
- client.executeQuery(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('operationName', 'query');
- });
-
- it('passes url (from context) to exchange', () => {
- pipe(
- client.executeQuery(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('context.url', url);
- });
-});
-
-describe('executeMutation', () => {
- it('passes query string exchange', async () => {
- pipe(
- client.executeMutation(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('query', query.query);
- });
-
- it('passes variables type to exchange', () => {
- pipe(
- client.executeMutation(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('variables', query.variables);
- });
-
- it('passes operationName type to exchange', () => {
- pipe(
- client.executeMutation(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('operationName', 'mutation');
- });
-
- it('passes url (from context) to exchange', () => {
- pipe(
- client.executeMutation(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('context.url', url);
- });
-});
-
-describe('executeSubscription', () => {
- it('passes query string exchange', async () => {
- pipe(
- client.executeSubscription(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('query', query.query);
- });
-
- it('passes variables type to exchange', () => {
- pipe(
- client.executeSubscription(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('variables', query.variables);
- });
-
- it('passes operationName type to exchange', () => {
- pipe(
- client.executeSubscription(query),
- subscribe(x => x)
- );
-
- expect(receivedOps[0]).toHaveProperty('operationName', 'subscription');
- });
-});
\ No newline at end of file
Index: src/components/Mutation.test.tsx
===================================================================
--- src/components/Mutation.test.tsx urql@1.0.0
+++ src/components/Mutation.test.tsx .
@@ -1,120 +1,0 @@
-jest.mock('../context', () => {
- const c = {
- executeMutation: jest.fn(),
- };
-
- return {
- client: c,
- Consumer: (p: any) => p.children(client),
- };
-});
-
-import { mount } from 'enzyme';
-import React from 'react';
-import { fromValue } from 'wonka';
-// @ts-ignore - client is exclusively from mock
-import { client } from '../context';
-import { Mutation } from './Mutation';
-
-const props = {
- query: 'examplequery',
-};
-let childProps: any;
-
-const childMock = (c: any) => {
- childProps = c;
- return null;
-};
-let activeWrapper: any;
-const mountWrapper = p => {
- activeWrapper = mount(<Mutation {...p} children={childMock} />);
- return activeWrapper;
-};
-
-beforeEach(() => {
- client.executeMutation.mockClear();
- childProps = undefined;
-});
-
-afterEach(() => {
- if (activeWrapper !== undefined) {
- activeWrapper.unmount();
- }
-});
-
-describe('on init', () => {
- it('default values match snapshot', () => {
- mountWrapper(props);
- expect(childProps).toMatchSnapshot();
- });
-});
-
-describe('execute mutation', () => {
- it('calls executeMutation', () => {
- mountWrapper(props);
- childProps.executeMutation();
- expect(client.executeMutation).toBeCalledTimes(1);
- });
-
- it('calls executeMutation with query', () => {
- mountWrapper(props);
- childProps.executeMutation();
- expect(client.executeMutation.mock.calls[0][0]).toHaveProperty(
- 'query',
- props.query
- );
- });
-
- it('calls executeMutation with variables', () => {
- const vars = { test: 1234 };
- mountWrapper(props);
- childProps.executeMutation(vars);
- expect(client.executeMutation.mock.calls[0][0]).toHaveProperty(
- 'variables',
- vars
- );
- });
-});
-
-describe('on execute', () => {
- it('sets fetching to true', () => {
- client.executeMutation.mockReturnValue(new Promise(() => undefined));
-
- mountWrapper(props);
- childProps.executeMutation();
-
- expect(childProps.fetching).toBe(true);
- });
-
- it('returns data from client', done => {
- const data = 1234;
- client.executeMutation.mockReturnValue(
- fromValue({ data, error: undefined })
- );
-
- mountWrapper(props);
- childProps.executeMutation();
-
- // This should be synchronous...
- setTimeout(() => {
- expect(childProps.data).toBe(data);
- done();
- }, 300);
- });
-
- it('returns error from client', done => {
- const error = Error('Error here');
- client.executeMutation.mockReturnValue(
- fromValue({ data: undefined, error })
- );
-
- mountWrapper(props);
- childProps.executeMutation();
-
- // This should be synchronous...
- setTimeout(() => {
- expect(childProps.error).toBe(error);
- done();
- }, 300);
- });
-});
\ No newline at end of file
Index: src/components/Query.test.tsx
===================================================================
--- src/components/Query.test.tsx urql@1.0.0
+++ src/components/Query.test.tsx .
@@ -1,112 +1,0 @@
-jest.mock('../context', () => {
- const c = {
- executeQuery: jest.fn(),
- };
-
- return {
- client: c,
- Consumer: (p: any) => p.children(client),
- };
-});
-
-import { mount, shallow } from 'enzyme';
-import React from 'react';
-import { delay, fromValue, pipe } from 'wonka';
-// @ts-ignore - client is exclusively from mock
-import { client } from '../context';
-import { Query } from './Query';
-
-const props = {
- query: 'examplequery',
-};
-let childProps: any;
-
-const childMock = (c: any) => {
- childProps = c;
- return <h1>mock</h1>;
-};
-const mountWrapper = (p, isShallow = false) => {
- if (isShallow) {
- return shallow(<Query {...p} children={childMock} />);
- }
-
- const w = mount(<Query {...p} children={childMock} />);
- return w;
-};
-
-beforeEach(() => {
- client.executeQuery.mockClear();
- childProps = undefined;
-});
-
-describe('on init', () => {
- beforeEach(() => {
- client.executeQuery.mockReturnValue(fromValue({ data: 1234 }));
- });
-
- it('default values match snapshot', () => {
- mountWrapper(props);
- expect(childProps).toMatchSnapshot();
- });
-
- it('calls executeQuery', () => {
- mountWrapper(props);
- expect(client.executeQuery).toBeCalledTimes(1);
- });
-});
-
-describe('on change', () => {
- beforeEach(() => {
- client.executeQuery.mockReturnValue(fromValue({ data: 1234 }));
- });
-
- it('executes new query', () => {
- const wrapper = mountWrapper(props);
-
- // @ts-ignore
- wrapper.setProps({ ...props, query: 'new query' });
- expect(client.executeQuery).toBeCalledTimes(2);
- });
-});
-
-describe('on fetch', () => {
- beforeAll(() => {
- client.executeQuery.mockReturnValue(
- pipe(
- fromValue({ data: 1234 }),
- delay(1234)
- )
- );
- });
-
- it('sets fetching to true', () => {
- mountWrapper(props);
- expect(childProps).toHaveProperty('fetching', true);
- });
-});
-
-describe('on data', () => {
- const data = 12345;
-
- beforeAll(() => {
- client.executeQuery.mockReturnValue(fromValue({ data }));
- });
-
- it('returns data', () => {
- mountWrapper(props);
- expect(childProps).toHaveProperty('data', data);
- });
-});
-
-describe('on error', () => {
- const error = Error('error here');
-
- beforeAll(() => {
- client.executeQuery.mockReturnValue(fromValue({ error }));
- });
-
- it('returns error', () => {
- mountWrapper(props);
- expect(childProps).toHaveProperty('error', error);
- });
-});
\ No newline at end of file
Index: src/context.test.ts
===================================================================
--- src/context.test.ts urql@1.0.0
+++ src/context.test.ts .
@@ -1,21 +1,0 @@
-import { Consumer, Provider } from './context';
-
-describe('ContextConsumer', () => {
- it('passes snapshot', () => {
- expect(Consumer).toMatchSnapshot();
- });
-
- it('is exported', () => {
- expect(typeof Consumer).toBe('object');
- });
-});
-
-describe('ContextProvider', () => {
- it('passes snapshot', () => {
- expect(Provider).toMatchSnapshot();
- });
-
- it('is exported', () => {
- expect(typeof Provider).toBe('object');
- });
-});
\ No newline at end of file
Index: src/exchanges/cache.test.ts
===================================================================
--- src/exchanges/cache.test.ts urql@1.0.0
+++ src/exchanges/cache.test.ts .
@@ -1,111 +1,0 @@
-import { makeSubject, map, pipe, publish, Source, Subject } from 'wonka';
-import { Client } from '../client';
-import {
- mutationOperation,
- mutationResponse,
- queryOperation,
- queryResponse,
- subscriptionOperation,
- subscriptionResult,
-} from '../test-utils';
-import { Operation } from '../types';
-import { afterMutation, cacheExchange } from './cache';
-
-let response;
-let exchangeArgs;
-let forwardedOperations: Operation[];
-let reexecuteOperation;
-let input: Subject<Operation>;
-
-beforeEach(() => {
- response = queryResponse;
- forwardedOperations = [];
- reexecuteOperation = jest.fn();
- input = makeSubject<Operation>();
-
- // Collect all forwarded operations
- const forward = (s: Source<Operation>) => {
- return pipe(
- s,
- map(op => {
- forwardedOperations.push(op);
- return response;
- })
- );
- };
-
- const client = {
- reexecuteOperation: reexecuteOperation as any,
- } as Client;
-
- exchangeArgs = { forward, client };
-});
-
-it('forwards to next exchange when no cache is found', () => {
- const [ops$, next, complete] = input;
- const exchange = cacheExchange(exchangeArgs)(ops$);
-
- publish(exchange);
- next(queryOperation);
- complete();
- expect(forwardedOperations.length).toBe(1);
- expect(reexecuteOperation).not.toBeCalled();
-});
-
-it('caches queries', () => {
- const [ops$, next, complete] = input;
- const exchange = cacheExchange(exchangeArgs)(ops$);
-
- publish(exchange);
- next(queryOperation);
- next(queryOperation);
- complete();
- expect(forwardedOperations.length).toBe(1);
- expect(reexecuteOperation).not.toBeCalled();
-});
-
-it("doesn't cache mutations", () => {
- response = mutationResponse;
- const [ops$, next, complete] = input;
- const exchange = cacheExchange(exchangeArgs)(ops$);
-
- publish(exchange);
- next(mutationOperation);
- next(mutationOperation);
- complete();
- expect(forwardedOperations.length).toBe(2);
- expect(reexecuteOperation).not.toBeCalled();
-});
-
-it('retriggers query operation when mutation occurs', () => {
- const typename = 'ExampleType';
- const resultCache = new Map([['test', queryResponse]]);
- const operationCache = { [typename]: new Set(['test']) };
-
- afterMutation(resultCache, operationCache, exchangeArgs.client)({
- ...mutationResponse,
- data: {
- todos: [
- {
- id: 1,
- __typename: typename,
- },
- ],
- },
- });
-
- expect(reexecuteOperation).toBeCalledTimes(1);
-});
-
-it('forwards subscriptions', () => {
- response = subscriptionResult;
- const [ops$, next, complete] = input;
- const exchange = cacheExchange(exchangeArgs)(ops$);
-
- publish(exchange);
- next(subscriptionOperation);
- next(subscriptionOperation);
- complete();
- expect(forwardedOperations.length).toBe(2);
- expect(reexecuteOperation).not.toBeCalled();
-});
\ No newline at end of file
Index: src/exchanges/compose.test.ts
===================================================================
--- src/exchanges/compose.test.ts urql@1.0.0
+++ src/exchanges/compose.test.ts .
@@ -1,42 +1,0 @@
-import { empty, Source } from 'wonka';
-import { Client } from '../client';
-import { Exchange } from '../types';
-import { composeExchanges } from './compose';
-
-const mockClient = {} as Client;
-const noopExchange: Exchange = ({ forward }) => ops$ => forward(ops$);
-
-it('returns the first exchange if it is the only input', () => {
- expect(composeExchanges([noopExchange])).toBe(noopExchange);
-});
-
-it('composes exchanges correctly', () => {
- let counter = 0;
-
- const firstExchange: Exchange = ({ client, forward }) => {
- expect(client).toBe(mockClient);
- expect(counter++).toBe(1);
-
- return ops$ => {
- expect(counter++).toBe(2);
- return forward(ops$);
- };
- };
-
- const secondExchange: Exchange = ({ client, forward }) => {
- expect(client).toBe(mockClient);
- expect(counter++).toBe(0);
-
- return ops$ => {
- expect(counter++).toBe(3);
- return forward(ops$);
- };
- };
-
- const exchange = composeExchanges([firstExchange, secondExchange]);
- const outerFw = jest.fn(() => noopExchange) as any;
-
- exchange({ client: mockClient, forward: outerFw })(empty as Source<any>);
- expect(outerFw).toHaveBeenCalled();
- expect(counter).toBe(4);
-});
\ No newline at end of file
Index: src/exchanges/dedup.test.ts
===================================================================
--- src/exchanges/dedup.test.ts urql@1.0.0
+++ src/exchanges/dedup.test.ts .
@@ -1,88 +1,0 @@
-import {
- filter,
- makeSubject,
- map,
- pipe,
- publish,
- Source,
- Subject,
-} from 'wonka';
-import { Client } from '../client';
-import {
- mutationOperation,
- queryOperation,
- queryResponse,
-} from '../test-utils';
-import { Operation } from '../types';
-import { dedupeExchange } from './dedup';
-
-let shouldRespond = false;
-let exchangeArgs;
-let forwardedOperations: Operation[];
-let input: Subject<Operation>;
-
-beforeEach(() => {
- shouldRespond = false;
- forwardedOperations = [];
- input = makeSubject<Operation>();
-
- // Collect all forwarded operations
- const forward = (s: Source<Operation>) => {
- return pipe(
- s,
- map(op => {
- forwardedOperations.push(op);
- return queryResponse;
- }),
- filter(() => !!shouldRespond)
- );
- };
-
- exchangeArgs = { forward, subject: {} as Client };
-});
-
-it('forwards query operations correctly', async () => {
- const [ops$, next, complete] = input;
- const exchange = dedupeExchange(exchangeArgs)(ops$);
-
- publish(exchange);
- next(queryOperation);
- complete();
- expect(forwardedOperations.length).toBe(1);
-});
-
-it('forwards only non-pending query operations', async () => {
- shouldRespond = false; // We filter out our mock responses
- const [ops$, next, complete] = input;
- const exchange = dedupeExchange(exchangeArgs)(ops$);
-
- publish(exchange);
- next(queryOperation);
- next(queryOperation);
- complete();
- expect(forwardedOperations.length).toBe(1);
-});
-
-it('forwards duplicate query operations as usual after they respond', async () => {
- shouldRespond = true; // Response will immediately resolve
- const [ops$, next, complete] = input;
- const exchange = dedupeExchange(exchangeArgs)(ops$);
-
- publish(exchange);
- next(queryOperation);
- next(queryOperation);
- complete();
- expect(forwardedOperations.length).toBe(2);
-});
-
-it('always forwards mutation operations without deduplicating them', async () => {
- shouldRespond = false; // We filter out our mock responses
- const [ops$, next, complete] = input;
- const exchange = dedupeExchange(exchangeArgs)(ops$);
-
- publish(exchange);
- next(mutationOperation);
- next(mutationOperation);
- complete();
- expect(forwardedOperations.length).toBe(2);
-});
\ No newline at end of file
Index: src/exchanges/fallback.test.ts
===================================================================
--- src/exchanges/fallback.test.ts urql@1.0.0
+++ src/exchanges/fallback.test.ts .
@@ -1,37 +1,0 @@
-import { forEach, fromValue, pipe } from 'wonka';
-import { queryOperation, teardownOperation } from '../test-utils';
-import { fallbackExchangeIO } from './fallback';
-
-const consoleWarn = console.warn;
-
-beforeEach(() => {
- console.warn = jest.fn();
-});
-
-afterAll(() => {
- console.warn = consoleWarn;
-});
-
-it('filters all results and warns about input', () => {
- const res: any[] = [];
-
- pipe(
- fallbackExchangeIO(fromValue(queryOperation)),
- forEach(x => res.push(x))
- );
-
- expect(res.length).toBe(0);
- expect(console.warn).toHaveBeenCalled();
-});
-
-it('filters all results and warns about input', () => {
- const res: any[] = [];
-
- pipe(
- fallbackExchangeIO(fromValue(teardownOperation)),
- forEach(x => res.push(x))
- );
-
- expect(res.length).toBe(0);
- expect(console.warn).not.toHaveBeenCalled();
-});
\ No newline at end of file
Index: src/exchanges/fetch.test.ts
===================================================================
--- src/exchanges/fetch.test.ts urql@1.0.0
+++ src/exchanges/fetch.test.ts .
@@ -1,85 +1,0 @@
-import { empty, fromValue, pipe, Source, subscribe, toPromise } from 'wonka';
-import { Client } from '../client';
-import { queryOperation } from '../test-utils';
-import { OperationResult } from '../types';
-import { fetchExchange } from './fetch';
-
-const fetch = (global as any).fetch as jest.Mock;
-const abort = jest.fn();
-
-const abortError = new Error();
-abortError.name = 'AbortError';
-
-beforeAll(() => {
- (global as any).AbortController = function AbortController() {
- this.signal = undefined;
- this.abort = abort;
- };
-});
-
-beforeEach(() => {
- fetch.mockClear();
- abort.mockClear();
-});
-
-afterAll(() => {
- (global as any).AbortController = undefined;
-});
-
-const response = {
- status: 200,
- data: {
- data: {
- user: 1200,
- },
- },
-};
-
-const exchangeArgs = {
- forward: () => empty as Source<OperationResult>,
- client: {} as Client,
-};
-
-it('returns response data from fetch', async () => {
- fetch.mockResolvedValue({
- status: 200,
- json: jest.fn().mockResolvedValue(response),
- });
-
- const data = await pipe(
- fromValue(queryOperation),
- fetchExchange(exchangeArgs),
- toPromise
- );
-
- expect(data).toMatchSnapshot();
-});
-
-it('returns error data from fetch', async () => {
- fetch.mockResolvedValue({
- status: 400,
- json: jest.fn().mockResolvedValue(response),
- });
-
- const data = await pipe(
- fromValue(queryOperation),
- fetchExchange(exchangeArgs),
- toPromise
- );
-
- expect(data).toMatchSnapshot();
-});
-
-it('calls cancel when the Observable is cancelled', () => {
- fetch.mockReturnValue(Promise.reject(abortError));
-
- const [unsubscribe] = pipe(
- fromValue(queryOperation),
- fetchExchange(exchangeArgs),
- subscribe(fail)
- );
-
- unsubscribe();
- expect(fetch).toHaveBeenCalledTimes(1);
- expect(abort).toHaveBeenCalledTimes(1);
-});
\ No newline at end of file
Index: src/exchanges/subscription.test.ts
===================================================================
--- src/exchanges/subscription.test.ts urql@1.0.0
+++ src/exchanges/subscription.test.ts .
@@ -1,40 +1,0 @@
-import { empty, fromValue, pipe, Source, take, toPromise } from 'wonka';
-import { Client } from '../client';
-import { subscriptionOperation, subscriptionResult } from '../test-utils';
-import { OperationResult } from '../types';
-import { subscriptionExchange, SubscriptionForwarder } from './subscription';
-
-const exchangeArgs = {
- forward: () => empty as Source<OperationResult>,
- client: {} as Client,
-};
-
-it('should return response data from forwardSubscription observable', async () => {
- const unsubscribe = jest.fn();
- const forwardSubscription: SubscriptionForwarder = operation => {
- expect(operation.key).toBe(subscriptionOperation.key);
- expect(operation.query).toBe(subscriptionOperation.query);
- expect(operation.variables).toBe(subscriptionOperation.variables);
- expect(operation.context).toEqual(subscriptionOperation.context);
-
- return {
- subscribe(observer) {
- Promise.resolve().then(() => {
- observer.next(subscriptionResult);
- });
-
- return { unsubscribe };
- },
- };
- };
-
- const data = await pipe(
- fromValue(subscriptionOperation),
- subscriptionExchange({ forwardSubscription })(exchangeArgs),
- take(1),
- toPromise
- );
-
- expect(data).toMatchSnapshot();
- expect(unsubscribe).toHaveBeenCalled();
-});
\ No newline at end of file
Index: src/hooks/useMutation.test.tsx
===================================================================
--- src/hooks/useMutation.test.tsx urql@1.0.0
+++ src/hooks/useMutation.test.tsx .
@@ -1,134 +1,0 @@
-// Note: Testing for hooks is not yet supported in Enzyme - https://github.com/airbnb/enzyme/issues/2011
-jest.mock('../client', () => {
- const d = { data: 1234, error: 5678 };
- const { delay, fromValue, pipe } = require('wonka');
- const mock = {
- executeMutation: jest.fn(() =>
- pipe(
- fromValue({ data: 1, error: 2 }),
- delay(200)
- )
- ),
- };
-
- return {
- createClient: () => mock,
- data: d,
- };
-});
-
-import React, { FC } from 'react';
-import renderer, { act } from 'react-test-renderer';
-// @ts-ignore - data is imported from mock only
-import { createClient } from '../client';
-import { useMutation } from './useMutation';
-
-// @ts-ignore
-const client = createClient() as { executeMutation: jest.Mock };
-const props = {
- query: 'example query',
-};
-let state: any;
-let execute: any;
-
-const MutationUser: FC<typeof props> = ({ query }) => {
- const [s, e] = useMutation(query);
- state = s;
- execute = e;
- return <p>{s.data}</p>;
-};
-
-beforeAll(() => {
- // tslint:disable-next-line
- console.log(
- 'supressing console.error output due to react-test-renderer spam (hooks related)'
- );
- jest.spyOn(global.console, 'error').mockImplementation();
-});
-
-beforeEach(() => {
- client.executeMutation.mockClear();
- state = undefined;
- execute = undefined;
-});
-
-describe('on initial useEffect', () => {
- it('initialises default state', () => {
- renderer.create(<MutationUser {...props} />);
- expect(state).toMatchSnapshot();
- });
-
- it('does not execute subscription', () => {
- renderer.create(<MutationUser {...props} />);
- expect(client.executeMutation).toBeCalledTimes(0);
- });
-});
-
-describe('on execute', () => {
- const vars = { test: 1234 };
-
- it('sets fetching to true', () => {
- renderer.create(<MutationUser {...props} />);
- act(() => {
- execute(vars);
- });
- expect(state).toHaveProperty('fetching', true);
- });
-
- it('calls executeMutation', () => {
- renderer.create(<MutationUser {...props} />);
- act(() => {
- execute(vars);
- });
- expect(client.executeMutation).toBeCalledTimes(1);
- });
-
- it('calls executeMutation with query', () => {
- renderer.create(<MutationUser {...props} />);
- act(() => {
- execute(vars);
- });
- expect(client.executeMutation.mock.calls[0][0]).toHaveProperty(
- 'query',
- props.query
- );
- });
-
- it('calls executeMutation with variables', () => {
- renderer.create(<MutationUser {...props} />);
- act(() => {
- execute(vars);
- });
- expect(client.executeMutation.mock.calls[0][0]).toHaveProperty(
- 'variables',
- vars
- );
- });
-});
-
-describe('on subscription update', () => {
- it('forwards data response', async () => {
- const wrapper = renderer.create(<MutationUser {...props} />);
- await execute();
- wrapper.update(<MutationUser {...props} />);
-
- expect(state).toHaveProperty('data', 1);
- });
-
- it('forwards error response', async () => {
- const wrapper = renderer.create(<MutationUser {...props} />);
- await execute();
- wrapper.update(<MutationUser {...props} />);
-
- expect(state).toHaveProperty('error', 2);
- });
-
- it('sets fetching to false', async () => {
- const wrapper = renderer.create(<MutationUser {...props} />);
- wrapper.update(<MutationUser {...props} />);
-
- await execute();
- wrapper.update(<MutationUser {...props} />);
- expect(state).toHaveProperty('fetching', false);
- });
-});
\ No newline at end of file
Index: src/hooks/useQuery.test.tsx
===================================================================
--- src/hooks/useQuery.test.tsx urql@1.0.0
+++ src/hooks/useQuery.test.tsx .
@@ -1,155 +1,0 @@
-// Note: Testing for hooks is not yet supported in Enzyme - https://github.com/airbnb/enzyme/issues/2011
-jest.mock('../client', () => {
- const d = { data: 1234, error: 5678 };
- const { map, interval, pipe } = require('wonka');
- const mock = {
- executeQuery: jest.fn(() =>
- pipe(
- interval(400),
- map(i => ({ data: i, error: i + 1 }))
- )
- ),
- };
-
- return {
- createClient: () => mock,
- data: d,
- };
-});
-
-import React, { FC } from 'react';
-import renderer, { act } from 'react-test-renderer';
-// @ts-ignore - data is imported from mock only
-import { createClient } from '../client';
-import { useQuery } from './useQuery';
-
-// @ts-ignore
-const client = createClient() as { executeQuery: jest.Mock };
-const props = {
- query: 'example query',
- variables: {
- myVar: 1234,
- },
-};
-let state: any;
-let execute: any;
-
-const QueryUser: FC<typeof props> = ({ query, variables }) => {
- const [s, e] = useQuery({ query, variables });
- state = s;
- execute = e;
- return <p>{s.data}</p>;
-};
-
-beforeAll(() => {
- // tslint:disable-next-line
- console.log(
- 'supressing console.error output due to react-test-renderer spam (hooks related)'
- );
- jest.spyOn(global.console, 'error').mockImplementation();
-});
-
-beforeEach(() => {
- client.executeQuery.mockClear();
- state = undefined;
- execute = undefined;
-});
-
-describe('on initial useEffect', () => {
- it('initialises default state', () => {
- renderer.create(<QueryUser {...props} />);
- expect(state).toMatchSnapshot();
- });
-
- it('executes subscription', () => {
- renderer.create(<QueryUser {...props} />);
- expect(client.executeQuery).toBeCalledTimes(1);
- });
-
- it('passes query and vars to executeQuery', () => {
- renderer.create(<QueryUser {...props} />);
- expect(client.executeQuery).toBeCalledWith(props, {
- requestPolicy: undefined,
- });
- });
-});
-
-describe('on subscription', () => {
- it('sets fetching to true', () => {
- const wrapper = renderer.create(<QueryUser {...props} />);
- wrapper.update(<QueryUser {...props} />);
- expect(state).toHaveProperty('fetching', true);
- });
-});
-
-describe('on subscription update', () => {
- it('forwards data response', done => {
- const wrapper = renderer.create(<QueryUser {...props} />);
- /**
- * Have to call update (without changes) in order to see the
- * result of the state change.
- */
- wrapper.update(<QueryUser {...props} />);
-
- setTimeout(() => {
- wrapper.update(<QueryUser {...props} />);
- expect(state).toHaveProperty('data', 0);
- done();
- }, 400);
- });
-
- it('forwards error response', done => {
- const wrapper = renderer.create(<QueryUser {...props} />);
- /**
- * Have to call update (without changes) in order to see the
- * result of the state change.
- */
- wrapper.update(<QueryUser {...props} />);
-
- setTimeout(() => {
- wrapper.update(<QueryUser {...props} />);
- expect(state).toHaveProperty('error', 1);
- done();
- }, 400);
- });
-
- it('sets fetching to false', done => {
- const wrapper = renderer.create(<QueryUser {...props} />);
- /**
- * Have to call update (without changes) in order to see the
- * result of the state change.
- */
- wrapper.update(<QueryUser {...props} />);
-
- setTimeout(() => {
- wrapper.update(<QueryUser {...props} />);
- expect(state).toHaveProperty('fetching', false);
- done();
- }, 400);
- });
-});
-
-describe('on change', () => {
- const q = 'new query';
-
- it('new query executes subscription', () => {
- const wrapper = renderer.create(<QueryUser {...props} />);
-
- /**
- * Have to call update twice for the change to be detected.
- * Only a single change is detected (updating 5 times still only calls
- * execute subscription twice).
- */
- wrapper.update(<QueryUser {...props} query={q} />);
- wrapper.update(<QueryUser {...props} query={q} />);
- expect(client.executeQuery).toBeCalledTimes(2);
- });
-});
-
-describe('execute query', () => {
- it('triggers query execution', () => {
- renderer.create(<QueryUser {...props} />);
- act(() => execute());
- expect(client.executeQuery).toBeCalledTimes(2);
- });
-});
\ No newline at end of file
Index: src/hooks/useSubscription.test.tsx
===================================================================
--- src/hooks/useSubscription.test.tsx urql@1.0.0
+++ src/hooks/useSubscription.test.tsx .
@@ -1,81 +1,0 @@
-// Note: Testing for hooks is not yet supported in Enzyme - https://github.com/airbnb/enzyme/issues/2011
-jest.mock('../client', () => {
- const d = { data: 1234, error: 5678 };
- const { fromArray } = require('wonka');
- const mock = {
- executeSubscription: jest.fn(() => fromArray([d])),
- };
-
- return {
- createClient: () => mock,
- data: d,
- };
-});
-
-import React, { FC } from 'react';
-import renderer from 'react-test-renderer';
-// @ts-ignore - data is imported from mock only
-import { createClient, data } from '../client';
-import { useSubscription } from './useSubscription';
-
-// @ts-ignore
-const client = createClient() as { executeSubscription: jest.Mock };
-const query = `example query`;
-let state: any;
-
-const SubscriptionUser: FC<{ q: string }> = ({ q }) => {
- const [s] = useSubscription({ query: q });
- state = s;
- return <p>{s.data}</p>;
-};
-
-beforeEach(() => {
- client.executeSubscription.mockClear();
- state = undefined;
-});
-
-describe('on initial useEffect', () => {
- it('initialises default state', () => {
- renderer.create(<SubscriptionUser q={query} />);
- expect(state).toMatchSnapshot();
- });
-
- it('executes subscription', () => {
- renderer.create(<SubscriptionUser q={query} />);
- expect(client.executeSubscription).toBeCalledTimes(1);
- });
-
- it('passes query to executeSubscription', () => {
- renderer.create(<SubscriptionUser q={query} />);
- expect(client.executeSubscription).toBeCalledWith({ query, variables: {} });
- });
-});
-
-describe('on subscription', () => {
- it('forwards client response', () => {
- const wrapper = renderer.create(<SubscriptionUser q={query} />);
- /**
- * Have to call update (without changes) in order to see the
- * result of the state change.
- */
- wrapper.update(<SubscriptionUser q={query} />);
- expect(state).toEqual(data);
- });
-});
-
-describe('on change', () => {
- const q = 'new query';
-
- it('executes subscription', () => {
- const wrapper = renderer.create(<SubscriptionUser q={query} />);
-
- /**
- * Have to call update twice for the change to be detected.
- * Only a single change is detected (updating 5 times still only calls
- * execute subscription twice).
- */
- wrapper.update(<SubscriptionUser q={q} />);
- wrapper.update(<SubscriptionUser q={q} />);
- expect(client.executeSubscription).toBeCalledTimes(2);
- });
-});
\ No newline at end of file
Index: src/utils/error.test.ts
===================================================================
--- src/utils/error.test.ts urql@1.0.0
+++ src/utils/error.test.ts .
@@ -1,68 +1,0 @@
-import { CombinedError } from './error';
-
-describe('CombinedError', () => {
- it('can be instantiated with graphQLErrors', () => {
- const err = new CombinedError({
- graphQLErrors: [],
- });
-
- expect(err.name).toBe('CombinedError');
- });
-
- it('accepts graphQLError messages and generates a single message from them', () => {
- const graphQLErrors = ['Error Message A', 'Error Message B'];
-
- const err = new CombinedError({ graphQLErrors });
-
- expect(err.message).toBe(
- `
-[GraphQL] Error Message A
-[GraphQL] Error Message B
- `.trim()
- );
-
- expect(err.graphQLErrors).toEqual(graphQLErrors.map(x => new Error(x)));
- });
-
- it('accepts a network error and generates a message from it', () => {
- const networkError = new Error('Network Shenanigans');
- const err = new CombinedError({ networkError });
-
- expect(err.message).toBe(`[Network] ${networkError.message}`);
- });
-
- it('accepts actual errors for graphQLError', () => {
- const graphQLErrors = [
- new Error('Error Message A'),
- new Error('Error Message B'),
- ];
-
- const err = new CombinedError({ graphQLErrors });
-
- expect(err.message).toBe(
- `
-[GraphQL] Error Message A
-[GraphQL] Error Message B
- `.trim()
- );
-
- expect(err.graphQLErrors).toEqual(graphQLErrors);
- });
-
- it('passes graphQLErrors through as a last resort', () => {
- const graphQLErrors = [{ x: 'y' }] as any;
- const err = new CombinedError({ graphQLErrors });
-
- expect(err.graphQLErrors).toEqual(graphQLErrors);
- });
-
- it('accepts a response that is attached to the resulting error', () => {
- const response = {};
- const err = new CombinedError({
- graphQLErrors: [],
- response,
- });
-
- expect(err.response).toBe(response);
- });
-});
\ No newline at end of file
Index: src/utils/hash.test.ts
===================================================================
--- src/utils/hash.test.ts urql@1.0.0
+++ src/utils/hash.test.ts .
@@ -1,7 +1,0 @@
-import { hashString } from './hash';
-
-describe('hash', () => {
- it('should returned a murmur hashed string from a query string', () => {
- expect(hashString(`{ todos { id } }`)).toMatchSnapshot();
- });
-});
\ No newline at end of file
Index: src/utils/query.test.ts
===================================================================
--- src/utils/query.test.ts urql@1.0.0
+++ src/utils/query.test.ts .
@@ -1,16 +1,0 @@
-import { createQuery } from './query';
-
-describe('query / mutation / subscription', () => {
- it('should return a valid query object', () => {
- const val = createQuery(`{ todos { id } }`);
- expect(val).toMatchObject({ query: `{ todos { id } }`, variables: {} });
- });
-
- it('should return a valid query object with variables', () => {
- const val = createQuery(`{ todos { id } }`, { test: 5 });
- expect(val).toMatchObject({
- query: `{ todos { id } }`,
- variables: { test: 5 },
- });
- });
-});
\ No newline at end of file
Index: src/utils/typenames.test.ts
===================================================================
--- src/utils/typenames.test.ts urql@1.0.0
+++ src/utils/typenames.test.ts .
@@ -1,79 +1,0 @@
-import { formatTypeNames, gankTypeNamesFromResponse } from './typenames';
-
-describe('formatTypeNames', () => {
- it('should add typenames to a query string', () => {
- expect(formatTypeNames(`{ todos { id } }`)).toBe(`{
- todos {
- id
- __typename
- }
- __typename
-}
-`);
- });
-});
-
-describe('gankTypeNamesFromResponse', () => {
- it('returns all typenames included in a response as an array', () => {
- const typeNames = gankTypeNamesFromResponse({
- todos: [
- {
- id: 1,
- __typename: 'Todo',
- },
- ],
- });
- expect(typeNames).toEqual(['Todo']);
- });
-
- it('does not duplicate typenames', () => {
- const typeNames = gankTypeNamesFromResponse({
- todos: [
- {
- id: 1,
- __typename: 'Todo',
- },
- {
- id: 3,
- __typename: 'Todo',
- },
- ],
- });
- expect(typeNames).toEqual(['Todo']);
- });
-
- it('returns multiple different typenames', () => {
- const typeNames = gankTypeNamesFromResponse({
- todos: [
- {
- id: 1,
- __typename: 'Todo',
- },
- {
- id: 3,
- __typename: 'Avocado',
- },
- ],
- });
- expect(typeNames).toEqual(['Todo', 'Avocado']);
- });
-
- it('works on nested objects', () => {
- const typeNames = gankTypeNamesFromResponse({
- todos: [
- {
- id: 1,
- __typename: 'Todo',
- },
- {
- id: 2,
- subTask: {
- id: 3,
- __typename: 'SubTask',
- },
- },
- ],
- });
- expect(typeNames).toEqual(['Todo', 'SubTask']);
- });
-});
\ No newline at end of file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment