generated from blueplum/typescript-template
feat: config files, readme
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
import * as esbuild from "esbuild";
|
||||||
|
|
||||||
|
const result = await esbuild.build({
|
||||||
|
entryPoints: ["src/index.ts", "src/config.ts"],
|
||||||
|
minify: true,
|
||||||
|
bundle: true,
|
||||||
|
outdir: "dist",
|
||||||
|
define: {
|
||||||
|
["import.meta.vitest"]: "undefined",
|
||||||
|
},
|
||||||
|
format: "esm",
|
||||||
|
platform: "node",
|
||||||
|
packages: "external",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.errors.length !== 0) {
|
||||||
|
throw result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
# gen-doctests
|
||||||
|
|
||||||
|
Generate tests from your JSDoc documentation for whichever testing harness you prefer.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
> See `gen-doctests --help` for more detail.
|
||||||
|
|
||||||
|
Write a doctest alongside your source code:
|
||||||
|
|
||||||
|
````ts
|
||||||
|
// src/isEven.ts
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the specified number is divisible by 2
|
||||||
|
* @param x The number to check
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* expect(isEven(5)).toBe(false);
|
||||||
|
* expect(isEven(4)).toBe(true);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function isEven(x: number) {
|
||||||
|
return x % 2 === 0;
|
||||||
|
}
|
||||||
|
````
|
||||||
|
|
||||||
|
And generate your doctests using either the library or the CLI:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ gen-doctests src/**.ts --format vitest -o tests/generated
|
||||||
|
```
|
||||||
|
|
||||||
|
With the above produces the following test file:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// tests/generated/isEven.doc.test.ts
|
||||||
|
|
||||||
|
// Automatically generated tests for ../../src/isEven.ts
|
||||||
|
|
||||||
|
import { describe, expect, test, vi } from "vitest";
|
||||||
|
import { isEven } from "../../src/isEven";
|
||||||
|
|
||||||
|
test("isEven()", () => {
|
||||||
|
expect(isEven(5)).toBe(false);
|
||||||
|
expect(isEven(4)).toBe(true);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also define a `doctests.config.ts` file to skip the command arguments:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// doctests.config.ts
|
||||||
|
import { defineConfig } from "gen-doctests/config";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
include: ["src/**.{js,jsx,ts,tsx}"],
|
||||||
|
outDir: "dist/",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { defineConfig } from "./dist/config";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
include: ["src/**.ts"],
|
||||||
|
templateHeader: ["console.log('hello, world!');"],
|
||||||
|
});
|
||||||
+9
-4
@@ -1,17 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "gen-doctests",
|
"name": "gen-doctests",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": "dist/index.js",
|
"bin": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "vitest --run --reporter=tree",
|
"test": "vitest --run --reporter=tree",
|
||||||
"build": "tsc -b && esbuild --minify --bundle src/index.ts --outdir=dist --define:import.meta.vitest=undefined --platform=node --format=esm --packages=external",
|
"build": "tsc -b && node .config/build.js",
|
||||||
"prepublishOnly": "pnpm build",
|
"prepublishOnly": "pnpm test && pnpm fmt && pnpm build",
|
||||||
"fmt": "prettier --write .",
|
"fmt": "prettier --write .",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
|
"exports": {
|
||||||
|
".": "./dist/index.js"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@types/node": "^24.12.3",
|
"@types/node": "^24.12.3",
|
||||||
@@ -19,13 +22,15 @@
|
|||||||
"@typescript-eslint/types": "^8.61.1",
|
"@typescript-eslint/types": "^8.61.1",
|
||||||
"esbuild": "^0.28.1",
|
"esbuild": "^0.28.1",
|
||||||
"eslint": "^10.3.0",
|
"eslint": "^10.3.0",
|
||||||
"jiti": "^2.7.0",
|
|
||||||
"prettier": "^3.8.4",
|
"prettier": "^3.8.4",
|
||||||
"typescript-eslint": "^8.59.2",
|
"typescript-eslint": "^8.59.2",
|
||||||
"vitest": "^4.1.9"
|
"vitest": "^4.1.9"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"arktype": "^2.2.2",
|
||||||
"citty": "^0.2.2",
|
"citty": "^0.2.2",
|
||||||
|
"find-up": "^8.0.0",
|
||||||
|
"jiti": "^2.7.0",
|
||||||
"picomatch": "^4.0.5",
|
"picomatch": "^4.0.5",
|
||||||
"typescript": "^6.0.3"
|
"typescript": "^6.0.3"
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+82
-3
@@ -8,9 +8,18 @@ importers:
|
|||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
arktype:
|
||||||
|
specifier: ^2.2.2
|
||||||
|
version: 2.2.2
|
||||||
citty:
|
citty:
|
||||||
specifier: ^0.2.2
|
specifier: ^0.2.2
|
||||||
version: 0.2.2
|
version: 0.2.2
|
||||||
|
find-up:
|
||||||
|
specifier: ^8.0.0
|
||||||
|
version: 8.0.0
|
||||||
|
jiti:
|
||||||
|
specifier: ^2.7.0
|
||||||
|
version: 2.7.0
|
||||||
picomatch:
|
picomatch:
|
||||||
specifier: ^4.0.5
|
specifier: ^4.0.5
|
||||||
version: 4.0.5
|
version: 4.0.5
|
||||||
@@ -36,9 +45,6 @@ importers:
|
|||||||
eslint:
|
eslint:
|
||||||
specifier: ^10.3.0
|
specifier: ^10.3.0
|
||||||
version: 10.5.0(jiti@2.7.0)
|
version: 10.5.0(jiti@2.7.0)
|
||||||
jiti:
|
|
||||||
specifier: ^2.7.0
|
|
||||||
version: 2.7.0
|
|
||||||
prettier:
|
prettier:
|
||||||
specifier: ^3.8.4
|
specifier: ^3.8.4
|
||||||
version: 3.8.4
|
version: 3.8.4
|
||||||
@@ -51,6 +57,12 @@ importers:
|
|||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
'@ark/schema@0.56.1':
|
||||||
|
resolution: {integrity: sha512-1Cf2g9nKD8K/3JGRu+gCCfYw5d4qR8YLLjDs5W5kpmaButCYWAPFUJqSXyBATPjglzCd4tIkp398iPYVs8MjRA==}
|
||||||
|
|
||||||
|
'@ark/util@0.56.1':
|
||||||
|
resolution: {integrity: sha512-Tp1rTik3q5Z+jAeeDxr5JZpmVIw0miti1ykSEHyZv5Pw3TIJl2xbN6KTacOxITp0l3s9ytlrWd30Zvqcy5vzoQ==}
|
||||||
|
|
||||||
'@emnapi/core@1.10.0':
|
'@emnapi/core@1.10.0':
|
||||||
resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
|
resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
|
||||||
|
|
||||||
@@ -507,6 +519,12 @@ packages:
|
|||||||
ajv@6.15.0:
|
ajv@6.15.0:
|
||||||
resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
|
resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
|
||||||
|
|
||||||
|
arkregex@0.0.7:
|
||||||
|
resolution: {integrity: sha512-O/Ltrn9EUSn3ui0KVzfyrWGDUsHlzKxDVBtpQxL/6JmLRMAZAebfSNf/A/J5Ny5S6QIwrXX+RfXsu888HMs35A==}
|
||||||
|
|
||||||
|
arktype@2.2.2:
|
||||||
|
resolution: {integrity: sha512-YYf1xhL2dh5aPZFlsY0RAsxv5HZqfLGLptH2ZP3JidTmsGRW8VOymhPjjMTkerL12vR2YtX0SK4c1mATtae8SA==}
|
||||||
|
|
||||||
assertion-error@2.0.1:
|
assertion-error@2.0.1:
|
||||||
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
|
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -636,6 +654,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
find-up@8.0.0:
|
||||||
|
resolution: {integrity: sha512-JGG8pvDi2C+JxidYdIwQDyS/CgcrIdh18cvgxcBge3wSHRQOrooMD3GlFBcmMJAN9M42SAZjDp5zv1dglJjwww==}
|
||||||
|
engines: {node: '>=20'}
|
||||||
|
|
||||||
flat-cache@4.0.1:
|
flat-cache@4.0.1:
|
||||||
resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
|
resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
@@ -769,6 +791,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
locate-path@8.0.0:
|
||||||
|
resolution: {integrity: sha512-XT9ewWAC43tiAV7xDAPflMkG0qOPn2QjHqlgX8FOqmWa/rxnyYDulF9T0F7tRy1u+TVTmK/M//6VIOye+2zDXg==}
|
||||||
|
engines: {node: '>=20'}
|
||||||
|
|
||||||
magic-string@0.30.21:
|
magic-string@0.30.21:
|
||||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||||
|
|
||||||
@@ -799,10 +825,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
p-limit@4.0.0:
|
||||||
|
resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
|
||||||
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
p-locate@5.0.0:
|
p-locate@5.0.0:
|
||||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
p-locate@6.0.0:
|
||||||
|
resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==}
|
||||||
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
path-exists@4.0.0:
|
path-exists@4.0.0:
|
||||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -912,6 +946,10 @@ packages:
|
|||||||
undici-types@7.18.2:
|
undici-types@7.18.2:
|
||||||
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
|
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
|
||||||
|
|
||||||
|
unicorn-magic@0.3.0:
|
||||||
|
resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||||
|
|
||||||
@@ -1017,8 +1055,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
yocto-queue@1.2.2:
|
||||||
|
resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==}
|
||||||
|
engines: {node: '>=12.20'}
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
|
'@ark/schema@0.56.1':
|
||||||
|
dependencies:
|
||||||
|
'@ark/util': 0.56.1
|
||||||
|
|
||||||
|
'@ark/util@0.56.1': {}
|
||||||
|
|
||||||
'@emnapi/core@1.10.0':
|
'@emnapi/core@1.10.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emnapi/wasi-threads': 1.2.1
|
'@emnapi/wasi-threads': 1.2.1
|
||||||
@@ -1396,6 +1444,16 @@ snapshots:
|
|||||||
json-schema-traverse: 0.4.1
|
json-schema-traverse: 0.4.1
|
||||||
uri-js: 4.4.1
|
uri-js: 4.4.1
|
||||||
|
|
||||||
|
arkregex@0.0.7:
|
||||||
|
dependencies:
|
||||||
|
'@ark/util': 0.56.1
|
||||||
|
|
||||||
|
arktype@2.2.2:
|
||||||
|
dependencies:
|
||||||
|
'@ark/schema': 0.56.1
|
||||||
|
'@ark/util': 0.56.1
|
||||||
|
arkregex: 0.0.7
|
||||||
|
|
||||||
assertion-error@2.0.1: {}
|
assertion-error@2.0.1: {}
|
||||||
|
|
||||||
balanced-match@4.0.4: {}
|
balanced-match@4.0.4: {}
|
||||||
@@ -1548,6 +1606,11 @@ snapshots:
|
|||||||
locate-path: 6.0.0
|
locate-path: 6.0.0
|
||||||
path-exists: 4.0.0
|
path-exists: 4.0.0
|
||||||
|
|
||||||
|
find-up@8.0.0:
|
||||||
|
dependencies:
|
||||||
|
locate-path: 8.0.0
|
||||||
|
unicorn-magic: 0.3.0
|
||||||
|
|
||||||
flat-cache@4.0.1:
|
flat-cache@4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
flatted: 3.4.2
|
flatted: 3.4.2
|
||||||
@@ -1646,6 +1709,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
p-locate: 5.0.0
|
p-locate: 5.0.0
|
||||||
|
|
||||||
|
locate-path@8.0.0:
|
||||||
|
dependencies:
|
||||||
|
p-locate: 6.0.0
|
||||||
|
|
||||||
magic-string@0.30.21:
|
magic-string@0.30.21:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
@@ -1675,10 +1742,18 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
yocto-queue: 0.1.0
|
yocto-queue: 0.1.0
|
||||||
|
|
||||||
|
p-limit@4.0.0:
|
||||||
|
dependencies:
|
||||||
|
yocto-queue: 1.2.2
|
||||||
|
|
||||||
p-locate@5.0.0:
|
p-locate@5.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
p-limit: 3.1.0
|
p-limit: 3.1.0
|
||||||
|
|
||||||
|
p-locate@6.0.0:
|
||||||
|
dependencies:
|
||||||
|
p-limit: 4.0.0
|
||||||
|
|
||||||
path-exists@4.0.0: {}
|
path-exists@4.0.0: {}
|
||||||
|
|
||||||
path-key@3.1.1: {}
|
path-key@3.1.1: {}
|
||||||
@@ -1775,6 +1850,8 @@ snapshots:
|
|||||||
|
|
||||||
undici-types@7.18.2: {}
|
undici-types@7.18.2: {}
|
||||||
|
|
||||||
|
unicorn-magic@0.3.0: {}
|
||||||
|
|
||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
@@ -1831,3 +1908,5 @@ snapshots:
|
|||||||
word-wrap@1.2.5: {}
|
word-wrap@1.2.5: {}
|
||||||
|
|
||||||
yocto-queue@0.1.0: {}
|
yocto-queue@0.1.0: {}
|
||||||
|
|
||||||
|
yocto-queue@1.2.2: {}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export { defineConfig, type Options } from "./options";
|
||||||
+2
-2
@@ -111,6 +111,8 @@ export function createGenerator(options: Options) {
|
|||||||
if (!isInclude(file.filePath) || isExclude(file.filePath))
|
if (!isInclude(file.filePath) || isExclude(file.filePath))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (file.tests.length === 0) return;
|
||||||
|
|
||||||
let source = "";
|
let source = "";
|
||||||
|
|
||||||
const regions: Region = {};
|
const regions: Region = {};
|
||||||
@@ -195,8 +197,6 @@ export function createGenerator(options: Options) {
|
|||||||
const tests: string[] = [];
|
const tests: string[] = [];
|
||||||
const regions: string[] = [];
|
const regions: string[] = [];
|
||||||
|
|
||||||
console.log(region);
|
|
||||||
|
|
||||||
for (const key of Reflect.ownKeys(region)) {
|
for (const key of Reflect.ownKeys(region)) {
|
||||||
const value = region[key];
|
const value = region[key];
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
|
|||||||
+71
-3
@@ -1,12 +1,68 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { globSync } from "fs";
|
import { globSync, lstatSync, readFileSync } from "fs";
|
||||||
import { runCli } from "./cli";
|
import { runCli } from "./cli";
|
||||||
import { DEFAULT_OPTIONS } from "./options";
|
import { DEFAULT_OPTIONS, Options } from "./options";
|
||||||
import { parseFile } from "./parser";
|
import { parseFile } from "./parser";
|
||||||
import { createGenerator } from "./generator";
|
import { createGenerator } from "./generator";
|
||||||
|
import { createJiti } from "jiti";
|
||||||
|
import picomatch from "picomatch";
|
||||||
|
import { findUp } from "find-up";
|
||||||
|
import { basename } from "path";
|
||||||
|
import { pathToFileURL } from "url";
|
||||||
|
import { type } from "arktype";
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
const configFilePath = await findUp([
|
||||||
|
"doctests.config.ts",
|
||||||
|
"doctest.config.ts",
|
||||||
|
"doctests.config.js",
|
||||||
|
"doctest.config.js",
|
||||||
|
]);
|
||||||
|
if (process.argv.length <= 2 && configFilePath !== undefined) {
|
||||||
|
const jit = createJiti(import.meta.url);
|
||||||
|
const config = readFileSync(configFilePath, {
|
||||||
|
encoding: "utf-8",
|
||||||
|
});
|
||||||
|
|
||||||
|
const configFile = basename(configFilePath);
|
||||||
|
const result = jit.evalModule(config, {
|
||||||
|
filename: pathToFileURL(configFile).toString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof result === "object" &&
|
||||||
|
result !== null &&
|
||||||
|
"default" in result &&
|
||||||
|
typeof result.default === "object" &&
|
||||||
|
result.default !== null
|
||||||
|
) {
|
||||||
|
const config = Options(result.default);
|
||||||
|
|
||||||
|
if (config instanceof type.errors) {
|
||||||
|
console.error(
|
||||||
|
`error while reading ${configFile}: ${config.summary}`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseWithOptions({
|
||||||
|
...DEFAULT_OPTIONS,
|
||||||
|
...config,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`error while reading ${configFile}: expected a default export with the config keys`,
|
||||||
|
);
|
||||||
|
console.info(
|
||||||
|
"see `defineConfig()` from `gen-doctests/config`",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const result = await runCli();
|
const result = await runCli();
|
||||||
if (result === undefined) return;
|
if (result === undefined) return;
|
||||||
|
|
||||||
@@ -21,6 +77,10 @@ async function main() {
|
|||||||
options.include = include;
|
options.include = include;
|
||||||
|
|
||||||
const { args } = result;
|
const { args } = result;
|
||||||
|
options.exclude =
|
||||||
|
args.exclude !== undefined
|
||||||
|
? [args.exclude]
|
||||||
|
: DEFAULT_OPTIONS.exclude;
|
||||||
options.outDir = args["out-dir"] ?? DEFAULT_OPTIONS.outDir;
|
options.outDir = args["out-dir"] ?? DEFAULT_OPTIONS.outDir;
|
||||||
options.fileExtension = args["test-extension"];
|
options.fileExtension = args["test-extension"];
|
||||||
options.testName = args["test-name"] ?? DEFAULT_OPTIONS.testName;
|
options.testName = args["test-name"] ?? DEFAULT_OPTIONS.testName;
|
||||||
@@ -38,7 +98,15 @@ async function main() {
|
|||||||
options.requireCodeBlock = args["must-codeblock"];
|
options.requireCodeBlock = args["must-codeblock"];
|
||||||
options.includePath = args.annotate;
|
options.includePath = args.annotate;
|
||||||
|
|
||||||
const files = globSync(include);
|
parseWithOptions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseWithOptions(options: Options) {
|
||||||
|
const doctest = picomatch("**/*" + options.fileExtension + ".*");
|
||||||
|
|
||||||
|
const files = globSync(options.include)
|
||||||
|
.filter((v) => !doctest(v))
|
||||||
|
.filter((path) => !lstatSync(path).isDirectory());
|
||||||
const parsed = files
|
const parsed = files
|
||||||
.map((path) => parseFile(path, options))
|
.map((path) => parseFile(path, options))
|
||||||
.filter((v) => v !== null);
|
.filter((v) => v !== null);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { type } from "arktype";
|
||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
/**
|
/**
|
||||||
* Pattern matching files to include in parsing
|
* Pattern matching files to include in parsing
|
||||||
@@ -66,6 +68,22 @@ export interface Options {
|
|||||||
emitRegions: boolean;
|
emitRegions: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const Options = type({
|
||||||
|
include: "string[]",
|
||||||
|
"exclude?": "string[]",
|
||||||
|
"outDir?": "string | null",
|
||||||
|
"fileExtension?": "string",
|
||||||
|
"testName?": "string | null",
|
||||||
|
"templateRoot?": "boolean",
|
||||||
|
"templateHeader?": "string[]",
|
||||||
|
"templateFooter?": "string[]",
|
||||||
|
"format?": '"jest" | "vitest" | "assert"',
|
||||||
|
"onlyGenerateTests?": "boolean",
|
||||||
|
"requireCodeBlock?": "boolean",
|
||||||
|
"includePath?": "boolean",
|
||||||
|
"emitRegions?": "boolean",
|
||||||
|
});
|
||||||
|
|
||||||
export const DEFAULT_OPTIONS: Required<Options> = {
|
export const DEFAULT_OPTIONS: Required<Options> = {
|
||||||
include: [],
|
include: [],
|
||||||
exclude: [],
|
exclude: [],
|
||||||
@@ -81,3 +99,13 @@ export const DEFAULT_OPTIONS: Required<Options> = {
|
|||||||
includePath: true,
|
includePath: true,
|
||||||
emitRegions: true,
|
emitRegions: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function defineConfig(
|
||||||
|
opts: Partial<Omit<Options, "include">> &
|
||||||
|
Pick<Options, "include">,
|
||||||
|
): Options {
|
||||||
|
return {
|
||||||
|
...DEFAULT_OPTIONS,
|
||||||
|
...opts,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -346,8 +346,6 @@ export function parseFile(
|
|||||||
|
|
||||||
visit(node);
|
visit(node);
|
||||||
|
|
||||||
console.log(tests);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: basename(filePath, extension),
|
name: basename(filePath, extension),
|
||||||
extension: extension,
|
extension: extension,
|
||||||
|
|||||||
+7
-2
@@ -11,13 +11,18 @@
|
|||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
"verbatimModuleSyntax": true,
|
"verbatimModuleSyntax": true,
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"declaration": true,
|
||||||
"moduleDetection": "force",
|
"moduleDetection": "force",
|
||||||
"noEmit": true,
|
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
|
|
||||||
/* Linting */
|
/* Linting */
|
||||||
"noUnusedLocals": false,
|
"noUnusedLocals": false,
|
||||||
"erasableSyntaxOnly": true,
|
"erasableSyntaxOnly": true,
|
||||||
|
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src"
|
||||||
},
|
},
|
||||||
"include": ["src", "tests"]
|
"include": ["src"],
|
||||||
|
"exclude": ["src/config.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"target": "es2023",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "esnext",
|
||||||
|
"types": ["vitest/importMeta", "node"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"declaration": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src"
|
||||||
|
},
|
||||||
|
"include": ["src/config.ts"]
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
"files": [],
|
"files": [],
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "./tsconfig.app.json" },
|
{ "path": "./tsconfig.app.json" },
|
||||||
|
{ "path": "./tsconfig.config.json" },
|
||||||
{ "path": "./tsconfig.node.json" }
|
{ "path": "./tsconfig.node.json" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user