remove axios, better api
This commit is contained in:
parent
d48ea17c63
commit
d1aa79eae8
@ -78,7 +78,7 @@ const buildConfigNode = {
|
||||
|
||||
const buildConfigBrowser = {
|
||||
...buildConfigBase,
|
||||
entryPoints: ["src/tests/axios.ts", "src/tests/swr.ts", "src/index.browser.ts", "src/live-reload.ts", 'src/stories.tsx'],
|
||||
entryPoints: ["src/tests/mock.ts", "src/tests/swr.ts", "src/index.browser.ts", "src/live-reload.ts", 'src/stories.tsx'],
|
||||
outExtension: {
|
||||
'.js': '.mjs'
|
||||
},
|
||||
|
@ -13,7 +13,7 @@
|
||||
"private": false,
|
||||
"exports": {
|
||||
"./lib/tests/swr": "./lib/tests/swr.mjs",
|
||||
"./lib/tests/axios": "./lib/tests/axios.mjs",
|
||||
"./lib/tests/mock": "./lib/tests/mock.mjs",
|
||||
"./lib/index.browser": "./lib/index.browser.mjs",
|
||||
"./lib/index.node": "./lib/index.node.cjs"
|
||||
},
|
||||
@ -29,7 +29,6 @@
|
||||
"@types/node": "^18.11.17",
|
||||
"@types/web": "^0.0.82",
|
||||
"@types/ws": "^8.5.3",
|
||||
"axios": "^1.2.1",
|
||||
"chokidar": "^3.5.3",
|
||||
"esbuild": "^0.14.21",
|
||||
"express": "^4.18.2",
|
||||
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
This file is part of GNU Taler
|
||||
(C) 2022 Taler Systems S.A.
|
||||
|
||||
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
// import axios, { AxiosPromise, AxiosRequestConfig } from "axios";
|
||||
import * as axios from "axios";
|
||||
import {
|
||||
setAxiosRequestAsTestingEnvironment,
|
||||
mockAxiosOnce,
|
||||
} from "../utils/axios.js";
|
||||
|
||||
const TESTING_DEBUG_LOG = process.env["TESTING_DEBUG_LOG"] !== undefined;
|
||||
|
||||
const defaultCallback = (
|
||||
actualQuery?: axios.AxiosRequestConfig,
|
||||
): axios.AxiosPromise<any> => {
|
||||
if (TESTING_DEBUG_LOG) {
|
||||
console.log("UNEXPECTED QUERY", actualQuery);
|
||||
}
|
||||
throw Error(
|
||||
"Default Axios mock callback is called, this mean that the test did a tried to use axios but there was no expectation in place, try using JEST_DEBUG_LOG env",
|
||||
);
|
||||
};
|
||||
|
||||
setAxiosRequestAsTestingEnvironment(defaultCallback);
|
||||
|
||||
export type Query<Req, Res> = {
|
||||
method: axios.Method;
|
||||
url: string;
|
||||
code?: number;
|
||||
};
|
||||
|
||||
type ExpectationValues = {
|
||||
query: Query<any, any>;
|
||||
params?: {
|
||||
auth?: string;
|
||||
request?: object;
|
||||
qparam?: Record<string, string>;
|
||||
response?: object;
|
||||
};
|
||||
};
|
||||
|
||||
type TestValues = [
|
||||
axios.AxiosRequestConfig | undefined,
|
||||
ExpectationValues | undefined,
|
||||
];
|
||||
|
||||
export class AxiosMockEnvironment {
|
||||
expectations: Array<
|
||||
| {
|
||||
query: Query<any, any>;
|
||||
auth?: string;
|
||||
params?: {
|
||||
request?: object;
|
||||
qparam?: Record<string, string>;
|
||||
response?: object;
|
||||
};
|
||||
result: { args: axios.AxiosRequestConfig | undefined };
|
||||
}
|
||||
| undefined
|
||||
> = [];
|
||||
// axiosMock: jest.MockedFunction<axios.AxiosStatic>
|
||||
|
||||
addRequestExpectation<
|
||||
RequestType extends object,
|
||||
ResponseType extends object,
|
||||
>(
|
||||
expectedQuery: Query<RequestType, ResponseType>,
|
||||
params: {
|
||||
auth?: string;
|
||||
request?: RequestType;
|
||||
qparam?: any;
|
||||
response?: ResponseType;
|
||||
},
|
||||
): void {
|
||||
const result = mockAxiosOnce(function (
|
||||
actualQuery?: axios.AxiosRequestConfig,
|
||||
): axios.AxiosPromise {
|
||||
if (TESTING_DEBUG_LOG) {
|
||||
console.log("query to the backend is made", actualQuery);
|
||||
}
|
||||
if (!expectedQuery) {
|
||||
return Promise.reject("a query was made but it was not expected");
|
||||
}
|
||||
if (TESTING_DEBUG_LOG) {
|
||||
console.log("expected query:", params?.request);
|
||||
console.log("expected qparams:", params?.qparam);
|
||||
console.log("sending response:", params?.response);
|
||||
}
|
||||
|
||||
const responseCode = expectedQuery.code || 200;
|
||||
|
||||
//This response is what buildRequestOk is expecting in file hook/backend.ts
|
||||
if (responseCode >= 200 && responseCode < 300) {
|
||||
return Promise.resolve({
|
||||
data: params?.response,
|
||||
config: {
|
||||
data: params?.response,
|
||||
params: actualQuery?.params || {},
|
||||
},
|
||||
request: { params: actualQuery?.params || {} },
|
||||
} as any);
|
||||
}
|
||||
//This response is what buildRequestFailed is expecting in file hook/backend.ts
|
||||
return Promise.reject({
|
||||
response: {
|
||||
status: responseCode,
|
||||
},
|
||||
request: {
|
||||
data: params?.response,
|
||||
params: actualQuery?.params || {},
|
||||
},
|
||||
});
|
||||
} as any);
|
||||
|
||||
this.expectations.push({ query: expectedQuery, params, result });
|
||||
}
|
||||
|
||||
getLastTestValues(): TestValues {
|
||||
const expectedQuery = this.expectations.shift();
|
||||
|
||||
return [expectedQuery?.result.args, expectedQuery];
|
||||
}
|
||||
}
|
@ -44,31 +44,6 @@ export function createExample<Props>(
|
||||
};
|
||||
}
|
||||
|
||||
// export function createExampleWithCustomContext<Props, ContextProps>(
|
||||
// Component: FunctionalComponent<Props>,
|
||||
// props: Partial<Props> | (() => Partial<Props>),
|
||||
// ContextProvider: FunctionalComponent<ContextProps>,
|
||||
// contextProps: Partial<ContextProps>,
|
||||
// ): ComponentChildren {
|
||||
// /**
|
||||
// * FIXME:
|
||||
// * This may not be useful since the example can be created with context
|
||||
// * already
|
||||
// */
|
||||
// const evaluatedProps = typeof props === "function" ? props() : props;
|
||||
// const Render = (args: any): VNode => create(Component, args);
|
||||
// const WithContext = (args: any): VNode =>
|
||||
// create(ContextProvider, {
|
||||
// ...contextProps,
|
||||
// children: [Render(args)],
|
||||
// } as any);
|
||||
|
||||
// return {
|
||||
// component: WithContext,
|
||||
// props: evaluatedProps,
|
||||
// };
|
||||
// }
|
||||
|
||||
const isNode = typeof window === "undefined";
|
||||
|
||||
/**
|
||||
|
@ -48,8 +48,10 @@ type ExpectationValues = {
|
||||
query: Query<any, any>;
|
||||
auth?: string;
|
||||
params?: {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
request?: object;
|
||||
qparam?: Record<string, string>;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
response?: object;
|
||||
};
|
||||
};
|
||||
@ -59,7 +61,7 @@ type TestValues = {
|
||||
lastQuery: ExpectationValues | undefined;
|
||||
};
|
||||
|
||||
const logger = new Logger("testing/swr.ts");
|
||||
const logger = new Logger("testing/mock.ts");
|
||||
|
||||
export abstract class MockEnvironment {
|
||||
expectations: Array<ExpectationValues> = [];
|
||||
@ -69,11 +71,13 @@ export abstract class MockEnvironment {
|
||||
debug: boolean;
|
||||
constructor(debug: boolean) {
|
||||
this.debug = debug;
|
||||
this.registerRequest.bind(this);
|
||||
this.saveRequestAndGetMockedResponse.bind(this);
|
||||
}
|
||||
|
||||
public addRequestExpectation<
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
RequestType extends object,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
ResponseType extends object,
|
||||
>(
|
||||
query: Query<RequestType, ResponseType>,
|
||||
@ -89,13 +93,12 @@ export abstract class MockEnvironment {
|
||||
if (this.debug) {
|
||||
logger.info("saving query as expected", expected);
|
||||
}
|
||||
this.mockApiIfNeeded();
|
||||
}
|
||||
|
||||
abstract mockApiIfNeeded(): void;
|
||||
|
||||
public registerRequest<
|
||||
public saveRequestAndGetMockedResponse<
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
RequestType extends object,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
ResponseType extends object,
|
||||
>(
|
||||
query: Query<RequestType, ResponseType>,
|
||||
@ -167,8 +170,8 @@ export abstract class MockEnvironment {
|
||||
};
|
||||
}
|
||||
|
||||
private assertNextRequest(idx: number): AssertStatus {
|
||||
const { currentExpectedQuery, lastQuery } = this.getLastTestValues(idx);
|
||||
private assertNextRequest(index: number): AssertStatus {
|
||||
const { currentExpectedQuery, lastQuery } = this.getLastTestValues(index);
|
||||
|
||||
if (!currentExpectedQuery) {
|
||||
return {
|
||||
@ -194,6 +197,9 @@ export abstract class MockEnvironment {
|
||||
return {
|
||||
result: "error-difference",
|
||||
diff: "url",
|
||||
last: lastQuery.query.url,
|
||||
expected: currentExpectedQuery.query.url,
|
||||
index,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -206,6 +212,9 @@ export abstract class MockEnvironment {
|
||||
return {
|
||||
result: "error-difference",
|
||||
diff: "query-body",
|
||||
expected: currentExpectedQuery.params?.request,
|
||||
last: lastQuery.params?.request,
|
||||
index,
|
||||
};
|
||||
}
|
||||
if (
|
||||
@ -214,12 +223,18 @@ export abstract class MockEnvironment {
|
||||
return {
|
||||
result: "error-difference",
|
||||
diff: "query-params",
|
||||
expected: currentExpectedQuery.params?.qparam,
|
||||
last: lastQuery.params?.qparam,
|
||||
index,
|
||||
};
|
||||
}
|
||||
if (!deepEquals(currentExpectedQuery.auth, lastQuery.auth)) {
|
||||
return {
|
||||
result: "error-difference",
|
||||
diff: "query-auth",
|
||||
expected: currentExpectedQuery.auth,
|
||||
last: lastQuery.auth,
|
||||
index,
|
||||
};
|
||||
}
|
||||
|
||||
@ -269,18 +284,30 @@ interface AssertExpectedQueryMethodMismatch {
|
||||
interface AssertExpectedQueryUrlMismatch {
|
||||
result: "error-difference";
|
||||
diff: "url";
|
||||
last: string;
|
||||
expected: string;
|
||||
index: number;
|
||||
}
|
||||
interface AssertExpectedQueryAuthMismatch {
|
||||
result: "error-difference";
|
||||
diff: "query-auth";
|
||||
last: string | undefined;
|
||||
expected: string | undefined;
|
||||
index: number;
|
||||
}
|
||||
interface AssertExpectedQueryBodyMismatch {
|
||||
result: "error-difference";
|
||||
diff: "query-body";
|
||||
last: any;
|
||||
expected: any;
|
||||
index: number;
|
||||
}
|
||||
interface AssertExpectedQueryParamsMismatch {
|
||||
result: "error-difference";
|
||||
diff: "query-params";
|
||||
last: any;
|
||||
expected: any;
|
||||
index: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -383,7 +410,9 @@ function deepEquals(
|
||||
|
||||
let keyIterator: string;
|
||||
while (keySize--) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
const _a = a as Record<string, object>;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
const _b = b as Record<string, object>;
|
||||
|
||||
keyIterator = aKeys[keySize];
|
||||
@ -400,6 +429,7 @@ function deepEquals(
|
||||
return true;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
function allKeysFromObject(obj: object): Array<string> {
|
||||
const keys = [];
|
||||
for (const key in obj) {
|
||||
|
@ -15,10 +15,9 @@
|
||||
*/
|
||||
|
||||
import { ComponentChildren, FunctionalComponent, h, VNode } from "preact";
|
||||
import { MockEnvironment, Query } from "./mock.js";
|
||||
import { MockEnvironment } from "./mock.js";
|
||||
import { SWRConfig } from "swr";
|
||||
|
||||
export { Query };
|
||||
/**
|
||||
* Helper for hook that use SWR inside.
|
||||
*
|
||||
@ -30,14 +29,10 @@ export class SwrMockEnvironment extends MockEnvironment {
|
||||
super(debug);
|
||||
}
|
||||
|
||||
mockApiIfNeeded(): void {
|
||||
null; // do nothing
|
||||
}
|
||||
|
||||
public buildTestingContext(): FunctionalComponent<{
|
||||
children: ComponentChildren;
|
||||
}> {
|
||||
const __REGISTER_REQUEST = this.registerRequest.bind(this);
|
||||
const __SAVE_REQUEST_AND_GET_MOCKED_RESPONSE = this.saveRequestAndGetMockedResponse.bind(this);
|
||||
return function TestingContext({
|
||||
children,
|
||||
}: {
|
||||
@ -47,8 +42,9 @@ export class SwrMockEnvironment extends MockEnvironment {
|
||||
SWRConfig,
|
||||
{
|
||||
value: {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
fetcher: (url: string, options: object) => {
|
||||
const mocked = __REGISTER_REQUEST(
|
||||
const mocked = __SAVE_REQUEST_AND_GET_MOCKED_RESPONSE(
|
||||
{
|
||||
method: "get",
|
||||
url,
|
||||
|
Loading…
Reference in New Issue
Block a user