Skip to content

Commit

Permalink
Add Biome code formatter and linter (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
DRFR0ST authored Sep 22, 2024
1 parent 4810abe commit 6feaa15
Show file tree
Hide file tree
Showing 14 changed files with 432 additions and 372 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ jobs:
- name: Install dependencies
run: bun install

- name: Build library
run: bun run build
- name: Lint library
run: bun run lint

- name: Test library
run: bun run test

- name: Build library
run: bun run build

- name: Publish
run: npm publish
env:
Expand Down
9 changes: 6 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ jobs:
- name: Install dependencies
run: bun install

- name: Build library
run: bun run build
- name: Check library code
run: bun run check

- name: Run unit tests
run: bun run test
run: bun run test

- name: Build library
run: bun run build
7 changes: 7 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"recommendations": [
"biomejs.biome",
"eamodio.gitlens",
"aaron-bond.better-comments"
]
}
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

## Coding Style 🎨

**Coming soon!**
* **Linting:** We use [Biome](https://biomejs.dev/) to lint our code. You can run `bun run lint` or `bun run check` to run the linter. To auto-fix issues, please run `bun run check:fix`.
* **Formatting:** We format the code using [Biome](https://biomejs.dev/) as well. Run `bun run format` to format the code.
* **Testing:** We use `bun test` to run our tests.

## Code Review 🔍

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ To contribute to bun-bagel, follow these steps:
1. Clone the repository: `git clone https://github.com/DRFR0ST/bun-bagel.git`
2. Install dependencies: `bun install`
3. Run tests: `bun test`
4. Build the library: `bun run build`
4. Run linter & formatter: `bun run check`
5. Build the library: `bun run build`

> [!NOTE]
>You can also play around with bun-bagel by making changes in the `/sandbox` directory and running `bun run sandbox`. Make sure to build the library after making changes in the `/src` directory.
Expand Down
30 changes: 30 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.2/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"ignore": []
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
}
}
Binary file modified bun.lockb
Binary file not shown.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@
"build:emitDeclarations": "tsc --emitDeclarationOnly --project tsconfig.json --tsBuildInfoFile './dist/.tsbuildinfo'",
"sandbox": "bun run ./sandbox/index.ts",
"test": "bun test --coverage",
"lint": "bunx biome lint --write ./src ./tests",
"format": "bunx biome format --write ./src ./tests",
"check": "bunx biome check --write ./src ./tests",
"check:fix": "bunx biome check --unsafe --fix ./src ./tests",
"prepublish": "bun run build"
},
"devDependencies": {
"@biomejs/biome": "1.9.2",
"bun-types": "latest"
},
"peerDependencies": {
Expand Down
20 changes: 10 additions & 10 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { MockOptions } from "./types";
import type { MockOptions } from "./types";

/**
* The default value for mock options.
*/
export const DEFAULT_MOCK_OPTIONS: MockOptions = {
method: 'GET',
data: null,
headers: new Headers(),
response: {
data: null,
headers: new Headers(),
status: 200,
}
};
method: "GET",
data: null,
headers: new Headers(),
response: {
data: null,
headers: new Headers(),
status: 200,
},
};
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './mock';
export * from './types';
export type * from './types';
export * from "./mock";
export * from "./types";
export type * from "./types";
140 changes: 78 additions & 62 deletions src/mock.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { DEFAULT_MOCK_OPTIONS } from "./constants";
import { MockOptions } from "./types";
import type { MockOptions } from "./types";
import { findRequest, makeResponse, wildcardToRegex } from "./utils";

let ORIGINAL_FETCH: (request: Request, init?: RequestInit | undefined) => Promise<Response>;
let ORIGINAL_FETCH: (
request: Request,
init?: RequestInit | undefined,
) => Promise<Response>;

/**
* The cache for registered mocked requests.
Expand All @@ -12,78 +15,91 @@ const MOCKED_REQUESTS = new Map<RegExp, MockOptions>();
/**
* @description Mock the fetch method.
*/
export const mock = (request: Request | RegExp | string, options: MockOptions = DEFAULT_MOCK_OPTIONS) => {
const input = request instanceof Request ? request.url : request;

// Create regex class from input.
const regexInput = input instanceof RegExp ? input : new RegExp(wildcardToRegex(input.toString()));

// Check if request is already mocked.
const isRequestMocked = [...MOCKED_REQUESTS.entries()].find(findRequest([regexInput.toString(), options]));

if(process.env.VERBOSE) {
if (!isRequestMocked)
console.debug("\x1b[1mRegistered mocked request\x1b[0m");
else
console.debug("\x1b[1mRequest already mocked\x1b[0m \x1b[2mupdated\x1b[0m");

console.debug("\x1b[2mURL\x1b[0m", input);
console.debug("\x1b[2mPath Pattern\x1b[0m", regexInput);
console.debug("\x1b[2mStatus\x1b[0m", options.response?.status || 200);
console.debug("\x1b[2mMethod\x1b[0m", options.method || "GET");
console.debug("\n");
}

if(!isRequestMocked)
// Use regex as key.
MOCKED_REQUESTS.set(regexInput, options);
else
return;

if (!ORIGINAL_FETCH) {
// Cache the original fetch method before mocking it. Might be useful in the future to clean the mock.
ORIGINAL_FETCH = globalThis.fetch;

// @ts-ignore
globalThis.fetch = MOCKED_FETCH;
}
return true;
}
export const mock = (
request: Request | RegExp | string,
options: MockOptions = DEFAULT_MOCK_OPTIONS,
) => {
const input = request instanceof Request ? request.url : request;

// Create regex class from input.
const regexInput =
input instanceof RegExp
? input
: new RegExp(wildcardToRegex(input.toString()));

// Check if request is already mocked.
const isRequestMocked = [...MOCKED_REQUESTS.entries()].find(
findRequest([regexInput.toString(), options]),
);

if (process.env.VERBOSE) {
if (!isRequestMocked)
console.debug("\x1b[1mRegistered mocked request\x1b[0m");
else
console.debug(
"\x1b[1mRequest already mocked\x1b[0m \x1b[2mupdated\x1b[0m",
);

console.debug("\x1b[2mURL\x1b[0m", input);
console.debug("\x1b[2mPath Pattern\x1b[0m", regexInput);
console.debug("\x1b[2mStatus\x1b[0m", options.response?.status || 200);
console.debug("\x1b[2mMethod\x1b[0m", options.method || "GET");
console.debug("\n");
}

if (!isRequestMocked)
// Use regex as key.
MOCKED_REQUESTS.set(regexInput, options);
else return;

if (!ORIGINAL_FETCH) {
// Cache the original fetch method before mocking it. Might be useful in the future to clean the mock.
ORIGINAL_FETCH = globalThis.fetch;

// @ts-ignore
globalThis.fetch = MOCKED_FETCH;
}
return true;
};

/**
* @description Clear the fetch mock.
*/
export const clearMocks = () => {
MOCKED_REQUESTS.clear();

// Restore the original fetch method, if it was mocked.
if(!!ORIGINAL_FETCH) {
// @ts-ignore
globalThis.fetch = ORIGINAL_FETCH.bind({});
// @ts-ignore
ORIGINAL_FETCH = undefined;
}
}
MOCKED_REQUESTS.clear();

// Restore the original fetch method, if it was mocked.
if (ORIGINAL_FETCH) {
// @ts-ignore
globalThis.fetch = ORIGINAL_FETCH.bind({});
// @ts-ignore
ORIGINAL_FETCH = undefined;
}
};

/**
* @description A mocked fetch method.
*/
const MOCKED_FETCH = async (_request: Request | RegExp | string, init?: RequestInit) => {
const _path = _request instanceof Request ? _request.url : _request.toString();
const MOCKED_FETCH = async (
_request: Request | RegExp | string,
init?: RequestInit,
) => {
const _path =
_request instanceof Request ? _request.url : _request.toString();

// When the request it fired, check if it matches a mocked request.
const mockedRequest = [...MOCKED_REQUESTS.entries()].find(findRequest([_path, init]));
// When the request it fired, check if it matches a mocked request.
const mockedRequest = [...MOCKED_REQUESTS.entries()].find(
findRequest([_path, init]),
);

if (!mockedRequest)
return Promise.reject(makeResponse(404, _path));
if (!mockedRequest) return Promise.reject(makeResponse(404, _path));

if(process.env.VERBOSE)
console.debug("\x1b[2mMocked fetch called\x1b[0m", _path);
if (process.env.VERBOSE)
console.debug("\x1b[2mMocked fetch called\x1b[0m", _path);

if (mockedRequest[1].throw) throw mockedRequest[1].throw;

const mockedStatus = mockedRequest[1].response?.status || 200;
if (mockedRequest[1].throw) throw mockedRequest[1].throw;

return makeResponse(mockedStatus, _path, mockedRequest[1]);
};
const mockedStatus = mockedRequest[1].response?.status || 200;

return makeResponse(mockedStatus, _path, mockedRequest[1]);
};
22 changes: 12 additions & 10 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@
* Partial implementation of RequestInit with the addition of "data" property which value will be returned from the mock.
*/
export type MockOptions = {
/** @deprecated use response.data */
data?: any;
headers?: RequestInit['headers'];
method?: RequestInit['method'];
response?: MockResponse;
throw?: Error;
/** @deprecated use response.data */
// biome-ignore lint/suspicious/noExplicitAny: TODO
data?: any;
headers?: RequestInit["headers"];
method?: RequestInit["method"];
response?: MockResponse;
throw?: Error;
};

/**
* @description The response for a mocked request.
* Partial implementation of Response with the addition of "data" property which value will be returned from the mock.
*/
export interface MockResponse {
data?: any;
status?: number;
headers?: RequestInit['headers'];
};
// biome-ignore lint/suspicious/noExplicitAny: TODO
data?: any;
status?: number;
headers?: RequestInit["headers"];
}
Loading

0 comments on commit 6feaa15

Please sign in to comment.