Skip to content

Commit

Permalink
feat: Create a react query hook plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Embraser01 committed May 19, 2024
1 parent 41d6e62 commit d474bc4
Show file tree
Hide file tree
Showing 96 changed files with 3,103 additions and 371 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
examples/src/
lib/

packages/typoas-react-query/src/__tests__/sample-client.ts
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module.exports = {
node: true,
},
plugins: ['jest', '@typescript-eslint'],
ignorePatterns: ['**/dist/'],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
parser: '@typescript-eslint/parser',
};
868 changes: 841 additions & 27 deletions .pnp.cjs

Large diffs are not rendered by default.

42 changes: 38 additions & 4 deletions .pnp.loader.mjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
595 changes: 298 additions & 297 deletions .yarn/releases/yarn-4.1.0.cjs → .yarn/releases/yarn-4.2.2.cjs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .yarn/versions/f5d9f57f.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
releases:
"@typoas/react-query": major
"@typoas/runtime": patch
2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ enableGlobalCache: false

npmPublishAccess: public

yarnPath: .yarn/releases/yarn-4.1.0.cjs
yarnPath: .yarn/releases/yarn-4.2.2.cjs
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
"prettier": "^3.2.5",
"typescript": "^5.3.3"
},
"packageManager": "yarn@4.1.0"
"packageManager": "yarn@4.2.2"
}
11 changes: 11 additions & 0 deletions packages/typoas-react-query/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# `@typoas/react-query`

> This package is related to the [_Typoas_](https://github.com/Embraser01/typoas) project.
## Install

This dependency should be added into your dev dependencies.

```shell
yarn add @typoas/react-query -D
```
6 changes: 6 additions & 0 deletions packages/typoas-react-query/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
testMatch: ['**/__tests__/**/*.spec.[jt]s?(x)'],
testPathIgnorePatterns: ['/node_modules/', '/lib/'],
};
45 changes: 45 additions & 0 deletions packages/typoas-react-query/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "@typoas/react-query",
"version": "3.0.0",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/embraser01/typoas",
"directory": "packages/typoas-react-query"
},
"main": "./src/index.ts",
"scripts": {
"prepack": "tsc",
"start": "ts-node ./src/bin.ts",
"test:types": "tsc --noEmit",
"test": "jest"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@tanstack/react-query": "^5.35.5",
"@testing-library/react": "^15.0.7",
"@types/node": "^20.11.24",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.3.0",
"@typoas/runtime": "workspace:^",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"ts-jest": "^29.1.2",
"typescript": "^5.3.3"
},
"peerDependencies": {
"@tanstack/react-query": "^5.35.5",
"@typoas/runtime": "workspace:^"
},
"files": [
"/lib/**/*.js",
"/lib/**/*.d.ts",
"!/lib/**/__tests__/*"
],
"publishConfig": {
"main": "./lib/index.js",
"types": "./lib/index.d.ts"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { describe, expect, it } from '@jest/globals';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { PropsWithChildren } from 'react';
import { renderHook, waitFor } from '@testing-library/react';
import { createContext, findPetsByStatus, Pet } from './sample-client';
import { ApiContextProvider } from '../api-context';
import { MockFetcher } from './mock-fetcher';
import { createInfiniteQueryHook } from '../infinite-query-factory';

describe('createInfiniteQueryHook', () => {
const queryClient = new QueryClient();
const fetcher = new MockFetcher();
const ctx = createContext({ fetcher });

const wrapper = ({ children }: PropsWithChildren) => (
<ApiContextProvider context={ctx}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</ApiContextProvider>
);

it('should work for simple cases', async () => {
const useFindPetsByStatus = createInfiniteQueryHook(findPetsByStatus, {
initialPageParam: { page: 1 },
getNextPageParam: (lastPage, allPages) => {
if (allPages.length === 1) {
return { page: 2 };
}
return undefined;
},
});
fetcher
.mockResponseOnce<Pet[]>([
{ id: 3, name: 'Rocky', status: 'available', photoUrls: [] },
{ id: 4, name: 'Beethoven', status: 'available', photoUrls: [] },
])
.mockResponseOnce<Pet[]>([
{ id: 1, name: 'Bob', status: 'available', photoUrls: [] },
{ id: 2, name: 'Rufus', status: 'available', photoUrls: [] },
]);

const { result } = renderHook(
() => useFindPetsByStatus({ queryKey: [{ status: 'available' }] }),
{ wrapper },
);

await waitFor(() => {
expect(result.current.data?.pages.length).toEqual(1);
expect(result.current.data?.pages[0].map((d) => d.id)).toEqual([1, 2]);
});

result.current.fetchNextPage();

await waitFor(() => {
expect(result.current.data?.pages.length).toEqual(2);
expect(result.current.data?.pages[1].map((d) => d.id)).toEqual([3, 4]);
});
});
});
36 changes: 36 additions & 0 deletions packages/typoas-react-query/src/__tests__/mock-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Fetcher, RequestContext, ResponseContext } from '@typoas/runtime';

export class MockFetcher implements Fetcher {
private data: unknown = undefined;

private resQueue: unknown[] = [];

mockResponse<T>(data: T): void {
this.data = data;
}

mockResponseOnce<T>(data: T): MockFetcher {
this.resQueue.push(data);
return this;
}

async send(
request: RequestContext,

Check failure on line 18 in packages/typoas-react-query/src/__tests__/mock-fetcher.ts

View workflow job for this annotation

GitHub Actions / Lint

'request' is defined but never used
options?: string,

Check failure on line 19 in packages/typoas-react-query/src/__tests__/mock-fetcher.ts

View workflow job for this annotation

GitHub Actions / Lint

'options' is defined but never used
): Promise<ResponseContext> {
let data = this.resQueue.pop();
if (!data) {
data = this.data;
}

return new ResponseContext(
200,
{ 'content-type': 'application/json' },
{
binary: async () => new Blob([]),
text: async () => '',
json: async () => data,
},
);
}
}
39 changes: 39 additions & 0 deletions packages/typoas-react-query/src/__tests__/query-factory.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { describe, expect, it } from '@jest/globals';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { PropsWithChildren } from 'react';
import { renderHook, waitFor } from '@testing-library/react';
import { createQueryHook } from '../query-factory';
import { createContext, findPetsByStatus, Pet } from './sample-client';
import { ApiContextProvider } from '../api-context';
import { MockFetcher } from './mock-fetcher';

describe('createQueryHook', () => {
const queryClient = new QueryClient();
const fetcher = new MockFetcher();
const ctx = createContext({ fetcher });

const wrapper = ({ children }: PropsWithChildren) => (
<ApiContextProvider context={ctx}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</ApiContextProvider>
);

it('should work for simple cases', async () => {
const useFindPetsByStatus = createQueryHook(findPetsByStatus, {
successStatus: 200,
});
fetcher.mockResponse<Pet[]>([
{ id: 1, name: 'Rufus', status: 'available', photoUrls: [] },
{ id: 2, name: 'Rocky', status: 'available', photoUrls: [] },
]);

const { result } = renderHook(
() => useFindPetsByStatus({ queryKey: [{ status: 'available' }] }),
{ wrapper },
);

await waitFor(() =>
expect(result.current.data?.map((d) => d.id)).toEqual([1, 2]),
);
});
});
Loading

0 comments on commit d474bc4

Please sign in to comment.