@jaypie/testkit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.cjs ADDED
@@ -0,0 +1,40 @@
1
+ module.exports = {
2
+ root: true,
3
+ env: {
4
+ es6: true,
5
+ node: true,
6
+ },
7
+ extends: [
8
+ "eslint:recommended",
9
+ "plugin:import/errors",
10
+ // "Add plugin:prettier/recommended as the last item in the extends array in your .eslintrc* config file, so that eslint-config-prettier has the opportunity to override other configs"
11
+ "plugin:prettier/recommended",
12
+ ],
13
+ overrides: [
14
+ {
15
+ files: ["__tests__/**", "**/*.spec.js", "**/*.test.js"],
16
+ plugins: ["vitest"],
17
+ extends: ["plugin:vitest/recommended"],
18
+ rules: {
19
+ "vitest/no-focused-tests": "error",
20
+ "vitest/no-disabled-tests": "warn",
21
+ },
22
+ },
23
+ {
24
+ files: ["*.cjs"],
25
+ rules: {
26
+ "import/no-commonjs": "off",
27
+ },
28
+ },
29
+ ],
30
+ parserOptions: {
31
+ ecmaVersion: "latest",
32
+ sourceType: "module",
33
+ },
34
+ plugins: ["prettier"],
35
+ rules: {
36
+ "import/extensions": ["error", "ignorePackages"],
37
+ "import/no-commonjs": "error",
38
+ "no-console": "warn",
39
+ },
40
+ };
@@ -0,0 +1,55 @@
1
+ name: NPM Deploy
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - v*
7
+
8
+ env:
9
+ PROJECT_ENV: meta
10
+ PROJECT_SERVICE: libraries
11
+
12
+ jobs:
13
+ deploy:
14
+ name: NPM Deploy
15
+ permissions:
16
+ id-token: write # for aws-actions/configure-aws-credentials
17
+ contents: read # for actions/checkout
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - name: Checkout Code
21
+ uses: actions/checkout@v4
22
+ - name: NPM Install (`npm install`)
23
+ run: npm install
24
+ - name: NPM Deploy
25
+ run: |
26
+ npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}
27
+ npm publish --access public
28
+ lint:
29
+ name: Lint (in parallel)
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - name: Checkout code
33
+ uses: actions/checkout@v4
34
+ - name: Install dependencies
35
+ run: npm ci
36
+ - name: Run ESLint
37
+ run: npm run lint
38
+ # run: npx eslint . --max-warnings=0
39
+ test:
40
+ name: Unit Test (in parallel)
41
+ runs-on: ubuntu-latest
42
+ strategy:
43
+ matrix:
44
+ node-version: [18.x, 20.x]
45
+ # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ - name: Use Node.js ${{ matrix.node-version }}
49
+ uses: actions/setup-node@v4
50
+ with:
51
+ node-version: ${{ matrix.node-version }}
52
+ cache: 'npm'
53
+ - run: npm ci
54
+ - run: |
55
+ npm test
@@ -0,0 +1,23 @@
1
+ {
2
+ "cSpell.words": [
3
+ "certificatemanager",
4
+ "clonedeep",
5
+ "composables",
6
+ "Finlayson",
7
+ "fontface",
8
+ "hygen",
9
+ "iconsets",
10
+ "initzero",
11
+ "jaypie",
12
+ "knowdev",
13
+ "oidc",
14
+ "pinia",
15
+ "roboto",
16
+ "testkit",
17
+ "unplugin",
18
+ "vendia",
19
+ "vuekit",
20
+ "vuetify",
21
+ "wght"
22
+ ]
23
+ }
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Jaypie Testkit 🐦‍⬛🫒
2
+
3
+ TODO: update the project header and optionally write a description here
4
+
5
+ ## 📋 Usage
6
+
7
+ ### Installation
8
+
9
+ ```bash
10
+ npm install --save-dev @jaypie/testkit
11
+ ```
12
+
13
+ ### Example
14
+
15
+ TODO: Example should include one trivial and possibly one thorough example of using the library
16
+
17
+ ## 📖 Reference
18
+
19
+ TODO: Reference should be a complete list of everything in the package
20
+
21
+ ## 📝 Changelog
22
+
23
+ | Date | Version | Summary |
24
+ | ---------- | ------- | -------------- |
25
+ | 3/15/2024 | 0.0.1 | Initial commit |
26
+
27
+ ## 📜 License
28
+
29
+ Published by Finlayson Studio. All rights reserved
@@ -0,0 +1,14 @@
1
+ ---
2
+ to: <%= hygen %>/<%= generator %>/<%= action %>/jest.command.ejs.t
3
+ ---
4
+ ---
5
+ inject: true
6
+ to: package.json
7
+ after: scripts
8
+ skip_if: spec<%- '<' %>%= colonSubspec %<%- '>' %>.+<%- '<' %>%= path %<%- '>' %>/__tests__/<%- '<' %>%= name %<%- '>' %><%- '<' %>%= dotSubtype %<%- '>' %>.spec.js
9
+ sh: |
10
+ if jq -e '.scripts["format:package"]' package.json <%- '>' %> /dev/null; then
11
+ npm run format:package 2<%- '>' %> /dev/null || true
12
+ fi
13
+ ---
14
+ "test:spec<%- '<' %>%= colonSubspec %<%- '>' %>:<%- '<' %>%= name %<%- '>' %><%- '<' %>%= dotSubtype %<%- '>' %>": "vitest run ./<%- '<' %>%= path %<%- '>' %>/__tests__/<%- '<' %>%= name %<%- '>' %><%- '<' %>%= dotSubtype %<%- '>' %>.spec.js",
@@ -0,0 +1,31 @@
1
+ ---
2
+ to: <%= hygen %>/<%= generator %>/<%= action %>/new.ejs.t
3
+ ---
4
+ ---
5
+ to: <%- '<' %>%= path %<%- '>' %>/<%- '<' %>%= name %<%- '>' %><%- '<' %>%= dotSubtype %<%- '>' %>.js
6
+ ---
7
+ //
8
+ //
9
+ // Constants
10
+ //
11
+
12
+ //
13
+ //
14
+ // Helper Functions
15
+ //
16
+
17
+ //
18
+ //
19
+ // Main
20
+ //
21
+
22
+ const <%- '<' %>%= name %<%- '>' %> = () =<%- '>' %> {
23
+ //
24
+ };
25
+
26
+ //
27
+ //
28
+ // Export
29
+ //
30
+
31
+ export default <%- '<' %>%= name %<%- '>' %>;
@@ -0,0 +1,37 @@
1
+ // see types of prompts:
2
+ // https://github.com/enquirer/enquirer/tree/master/examples
3
+ //
4
+ module.exports = [
5
+ {
6
+ type: "input",
7
+ name: "actionInput",
8
+ message: "Action name (e.g., 'file'):",
9
+ onSubmit: (name, value, input) => {
10
+ // Remove leading './' and trailing '/'
11
+ value = value.replace(/^\.?\/|\/$/g, "");
12
+ input.state.answers.action = value;
13
+ },
14
+ },
15
+ {
16
+ type: "input",
17
+ name: "generatorInput",
18
+ initial: "project",
19
+ message: "Hygen generator directory (e.g., 'jaypie'):",
20
+ onSubmit: (name, value, input) => {
21
+ // Remove leading './' and trailing '/'
22
+ value = value.replace(/^\.?\/|\/$/g, "");
23
+ input.state.answers.generator = value;
24
+ },
25
+ },
26
+ {
27
+ type: "input",
28
+ name: "hygenInput",
29
+ initial: "_templates",
30
+ message: "Hygen template directory (always '_templates'):",
31
+ onSubmit: (name, value, input) => {
32
+ // Remove leading './' and trailing '/'
33
+ value = value.replace(/^\.?\/|\/$/g, "");
34
+ input.state.answers.hygen = value;
35
+ },
36
+ },
37
+ ];
@@ -0,0 +1,44 @@
1
+ ---
2
+ to: <%= hygen %>/<%= generator %>/<%= action %>/prompt.cjs
3
+ ---
4
+ // see types of prompts:
5
+ // https://github.com/enquirer/enquirer/tree/master/examples
6
+ //
7
+ module.exports = [
8
+ {
9
+ type: "input",
10
+ name: "pathInput",
11
+ initial: "src/util",
12
+ message: "Path (e.g., 'cdk/lib'):",
13
+ onSubmit: (name, value, input) =<%- '>' %> {
14
+ input.state.answers.path = value;
15
+ },
16
+ },
17
+ {
18
+ type: "input",
19
+ name: "nameInput",
20
+ message: "File name (e.g., 'sum'):",
21
+ onSubmit: (name, value, input) =<%- '>' %> {
22
+ input.state.answers.name = value;
23
+ },
24
+ },
25
+ {
26
+ type: "input",
27
+ name: "subtypeInput",
28
+ message: "Subtype (optional; e.g., 'function'):",
29
+ onSubmit: (name, value, input) =<%- '>' %> {
30
+ input.state.answers.subtype = value;
31
+ input.state.answers.dotSubtype = value ? `.${value}` : "";
32
+ },
33
+ },
34
+ {
35
+ type: "input",
36
+ name: "subspecInput",
37
+ message:
38
+ "Sub-spec test, for `npm run test:spec:SUBSPEC:sum.function` command (e.g., 'express' or 'lib:project'):",
39
+ onSubmit: (name, value, input) =<%- '>' %> {
40
+ input.state.answers.subspec = value;
41
+ input.state.answers.colonSubspec = value ? `:${value}` : "";
42
+ },
43
+ },
44
+ ];
@@ -0,0 +1,52 @@
1
+ ---
2
+ to: <%= hygen %>/<%= generator %>/<%= action %>/test.ejs.t
3
+ ---
4
+ ---
5
+ to: <%- '<' %>%= path %<%- '>' %>/__tests__/<%- '<' %>%= name %<%- '>' %><%- '<' %>%= dotSubtype %<%- '>' %>.spec.js
6
+ ---
7
+ // eslint-disable-next-line no-unused-vars
8
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
9
+
10
+ // Subject
11
+ import <%- '<' %>%= name %<%- '>' %> from "../<%- '<' %>%= name %<%- '>' %><%- '<' %>%= dotSubtype %<%- '>' %>.js";
12
+
13
+ //
14
+ //
15
+ // Mock constants
16
+ //
17
+
18
+ //
19
+ //
20
+ // Mock modules
21
+ //
22
+
23
+ //
24
+ //
25
+ // Mock environment
26
+ //
27
+
28
+ const DEFAULT_ENV = process.env;
29
+ beforeEach(() =<%- '>' %> {
30
+ process.env = { ...process.env };
31
+ });
32
+ afterEach(() =<%- '>' %> {
33
+ process.env = DEFAULT_ENV;
34
+ });
35
+
36
+ //
37
+ //
38
+ // Run tests
39
+ //
40
+
41
+ <%- '<' %>%_
42
+ let Subtype = "";
43
+ // If subtype is defined, capitalize the first letter
44
+ if(subtype) Subtype = " " + subtype.charAt(0).toUpperCase() + subtype.slice(1);
45
+ _%<%- '>' %>
46
+ describe("<%- '<' %>%= Name %<%- '>' %><%- '<' %>%= Subtype %<%- '>' %>", () =<%- '>' %> {
47
+ it("Works", () =<%- '>' %> {
48
+ const response = <%- '<' %>%= name %<%- '>' %>();
49
+ console.log("response :<%- '>' %><%- '>' %> ", response);
50
+ expect(response).not.toBeUndefined();
51
+ });
52
+ });
@@ -0,0 +1,28 @@
1
+ ---
2
+ to: <%= path %>/<%= name %><%= dotSubtype %>.js
3
+ ---
4
+ //
5
+ //
6
+ // Constants
7
+ //
8
+
9
+ //
10
+ //
11
+ // Helper Functions
12
+ //
13
+
14
+ //
15
+ //
16
+ // Main
17
+ //
18
+
19
+ const <%= name %> = () => {
20
+ //
21
+ };
22
+
23
+ //
24
+ //
25
+ // Export
26
+ //
27
+
28
+ export default <%= name %>;
@@ -0,0 +1,35 @@
1
+ // see types of prompts:
2
+ // https://github.com/enquirer/enquirer/tree/master/examples
3
+ //
4
+ module.exports = [
5
+ {
6
+ type: "input",
7
+ name: "path",
8
+ initial: "src",
9
+ message: "Path (e.g., 'src/util' no leading './' or trailing '/'):",
10
+ },
11
+ {
12
+ type: "input",
13
+ name: "name",
14
+ message: "File name (e.g., 'sum' not 'sum.function'):",
15
+ },
16
+ {
17
+ type: "input",
18
+ name: "subtype",
19
+ message: "Subtype (optional; e.g., 'function'):",
20
+ onSubmit: (name, value, input) => {
21
+ // eslint-disable-next-line no-param-reassign
22
+ input.state.answers.dotSubtype = value ? `.${value}` : "";
23
+ },
24
+ },
25
+ {
26
+ type: "input",
27
+ name: "subspec",
28
+ message:
29
+ "Sub-spec test, for `npm run test:spec:SUBSPEC:sum.function` command (e.g., 'express'):",
30
+ onSubmit: (name, value, input) => {
31
+ // eslint-disable-next-line no-param-reassign
32
+ input.state.answers.colonSubspec = value ? `:${value}` : "";
33
+ },
34
+ },
35
+ ];
@@ -0,0 +1,49 @@
1
+ ---
2
+ to: <%= path %>/__tests__/<%= name %><%= dotSubtype %>.spec.js
3
+ ---
4
+ // eslint-disable-next-line no-unused-vars
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
+
7
+ // Subject
8
+ import <%= name %> from "../<%= name %><%= dotSubtype %>.js";
9
+
10
+ //
11
+ //
12
+ // Mock constants
13
+ //
14
+
15
+ //
16
+ //
17
+ // Mock modules
18
+ //
19
+
20
+ //
21
+ //
22
+ // Mock environment
23
+ //
24
+
25
+ const DEFAULT_ENV = process.env;
26
+ beforeEach(() => {
27
+ process.env = { ...process.env };
28
+ });
29
+ afterEach(() => {
30
+ process.env = DEFAULT_ENV;
31
+ });
32
+
33
+ //
34
+ //
35
+ // Run tests
36
+ //
37
+
38
+ <%_
39
+ let Subtype = "";
40
+ // If subtype is defined, capitalize the first letter
41
+ if(subtype) Subtype = " " + subtype.charAt(0).toUpperCase() + subtype.slice(1);
42
+ _%>
43
+ describe("<%= Name %><%= Subtype %>", () => {
44
+ it("Works", () => {
45
+ const response = <%= name %>();
46
+ console.log("response :>> ", response);
47
+ expect(response).not.toBeUndefined();
48
+ });
49
+ });
@@ -0,0 +1,11 @@
1
+ ---
2
+ inject: true
3
+ to: package.json
4
+ after: scripts
5
+ skip_if: spec<%= colonSubspec %>.+<%= path %>/__tests__/<%= name %><%= dotSubtype %>.spec.js
6
+ sh: |
7
+ if jq -e '.scripts["format:package"]' package.json > /dev/null; then
8
+ npm run format:package 2> /dev/null || true
9
+ fi
10
+ ---
11
+ "test:spec<%= colonSubspec %>:<%= name %><%= dotSubtype %>": "vitest run ./<%= path %>/__tests__/<%= name %><%= dotSubtype %>.spec.js",
@@ -0,0 +1,11 @@
1
+ ---
2
+ inject: true
3
+ to: package.json
4
+ after: scripts
5
+ skip_if: spec<%= colonSubspec %>.+<%= path %>/__tests__/<%= name %><%= dotSubtype %>.spec.js
6
+ sh: |
7
+ if jq -e '.scripts["format:package"]' package.json > /dev/null; then
8
+ npm run format:package 2> /dev/null || true
9
+ fi
10
+ ---
11
+ "test:spec<%= colonSubspec %>:<%= name %><%= dotSubtype %>": "vitest run ./<%= path %>/__tests__/<%= name %><%= dotSubtype %>.spec.js",
@@ -0,0 +1,41 @@
1
+ // see types of prompts:
2
+ // https://github.com/enquirer/enquirer/tree/master/examples
3
+ //
4
+ module.exports = [
5
+ {
6
+ type: "input",
7
+ name: "pathInput",
8
+ initial: "src",
9
+ message: "Path (e.g., 'src/util'):",
10
+ onSubmit: (name, value, input) => {
11
+ input.state.answers.path = value;
12
+ },
13
+ },
14
+ {
15
+ type: "input",
16
+ name: "nameInput",
17
+ message: "File name (e.g., 'sum'):",
18
+ onSubmit: (name, value, input) => {
19
+ input.state.answers.name = value;
20
+ },
21
+ },
22
+ {
23
+ type: "input",
24
+ name: "subtypeInput",
25
+ message: "Subtype (optional; e.g., 'function'):",
26
+ onSubmit: (name, value, input) => {
27
+ input.state.answers.subtype = value;
28
+ input.state.answers.dotSubtype = value ? `.${value}` : "";
29
+ },
30
+ },
31
+ {
32
+ type: "input",
33
+ name: "subspecInput",
34
+ message:
35
+ "Sub-spec test, for `npm run test:spec:SUBSPEC:sum.function` command (e.g., 'express' or 'lib:project'):",
36
+ onSubmit: (name, value, input) => {
37
+ input.state.answers.subspec = value;
38
+ input.state.answers.colonSubspec = value ? `:${value}` : "";
39
+ },
40
+ },
41
+ ];
@@ -0,0 +1,49 @@
1
+ ---
2
+ to: <%= path %>/__tests__/<%= name %><%= dotSubtype %>.spec.js
3
+ ---
4
+ // eslint-disable-next-line no-unused-vars
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
+
7
+ // Subject
8
+ import <%= name %> from "../<%= name %><%= dotSubtype %>.js";
9
+
10
+ //
11
+ //
12
+ // Mock constants
13
+ //
14
+
15
+ //
16
+ //
17
+ // Mock modules
18
+ //
19
+
20
+ //
21
+ //
22
+ // Mock environment
23
+ //
24
+
25
+ const DEFAULT_ENV = process.env;
26
+ beforeEach(() => {
27
+ process.env = { ...process.env };
28
+ });
29
+ afterEach(() => {
30
+ process.env = DEFAULT_ENV;
31
+ });
32
+
33
+ //
34
+ //
35
+ // Run tests
36
+ //
37
+
38
+ <%_
39
+ let Subtype = "";
40
+ // If subtype is defined, capitalize the first letter
41
+ if(subtype) Subtype = " " + subtype.charAt(0).toUpperCase() + subtype.slice(1);
42
+ _%>
43
+ describe("<%= Name %><%= Subtype %>", () => {
44
+ it("Works", () => {
45
+ const response = <%= name %>();
46
+ console.log("response :>> ", response);
47
+ expect(response).not.toBeUndefined();
48
+ });
49
+ });
@@ -0,0 +1,58 @@
1
+ ---
2
+ to: <%= path %>/<%= name %>.yml
3
+ ---
4
+ name: NPM Deploy
5
+
6
+ on:
7
+ push:
8
+ tags:
9
+ - v*
10
+
11
+ env:
12
+ PROJECT_ENV: meta
13
+ PROJECT_SERVICE: libraries
14
+
15
+ jobs:
16
+ deploy:
17
+ name: NPM Deploy
18
+ permissions:
19
+ id-token: write # for aws-actions/configure-aws-credentials
20
+ contents: read # for actions/checkout
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - name: Checkout Code
24
+ uses: actions/checkout@v4
25
+ - name: NPM Install (`npm install`)
26
+ run: npm install
27
+ - name: NPM Deploy
28
+ run: |
29
+ npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}
30
+ npm publish --access <%= access %>
31
+ lint:
32
+ name: Lint (in parallel)
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - name: Checkout code
36
+ uses: actions/checkout@v4
37
+ - name: Install dependencies
38
+ run: npm ci
39
+ - name: Run ESLint
40
+ run: npm run lint
41
+ # run: npx eslint . --max-warnings=0
42
+ test:
43
+ name: Unit Test (in parallel)
44
+ runs-on: ubuntu-latest
45
+ strategy:
46
+ matrix:
47
+ node-version: [18.x, 20.x]
48
+ # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+ - name: Use Node.js ${{ matrix.node-version }}
52
+ uses: actions/setup-node@v4
53
+ with:
54
+ node-version: ${{ matrix.node-version }}
55
+ cache: 'npm'
56
+ - run: npm ci
57
+ - run: |
58
+ npm test
@@ -0,0 +1,32 @@
1
+ // see types of prompts:
2
+ // https://github.com/enquirer/enquirer/tree/master/examples
3
+ //
4
+ module.exports = [
5
+ {
6
+ type: "input",
7
+ name: "accessInput",
8
+ initial: "public",
9
+ message: "Access ('public' or 'restricted'):",
10
+ onSubmit: (name, value, input) => {
11
+ input.state.answers.access = value;
12
+ },
13
+ },
14
+ {
15
+ type: "input",
16
+ name: "pathInput",
17
+ initial: ".github/workflows",
18
+ message: "Path (always '.github/workflows'):",
19
+ onSubmit: (name, value, input) => {
20
+ input.state.answers.path = value;
21
+ },
22
+ },
23
+ {
24
+ type: "input",
25
+ name: "nameInput",
26
+ initial: "npm-deploy",
27
+ message: "File name, no extension (always 'npm-deploy'):",
28
+ onSubmit: (name, value, input) => {
29
+ input.state.answers.name = value;
30
+ },
31
+ },
32
+ ];
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@jaypie/testkit",
3
+ "version": "0.1.0",
4
+ "author": "Finlayson Studio",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "scripts": {
8
+ "format": "npm run format:package && npm run format:lint",
9
+ "format:lint": "eslint --fix .",
10
+ "format:package": "sort-package-json ./package.json",
11
+ "init:deploy": "hygen jaypie workflow-npm",
12
+ "lint": "eslint .",
13
+ "new": "hygen jaypie vite",
14
+ "test": "vitest",
15
+ "test:spec:index": "vitest run ./src/__tests__/index.spec.js",
16
+ "test:spec:mockLog.module": "vitest run ./src/__tests__/mockLog.module.spec.js"
17
+ },
18
+ "devDependencies": {
19
+ "eslint": "^8.57.0",
20
+ "eslint-config-prettier": "^9.1.0",
21
+ "eslint-plugin-import": "^2.29.1",
22
+ "eslint-plugin-prettier": "^5.1.3",
23
+ "eslint-plugin-vitest": "^0.3.26",
24
+ "hygen": "^6.2.11",
25
+ "jest-extended": "^4.0.2",
26
+ "prettier": "^3.2.5",
27
+ "sort-package-json": "^2.8.0",
28
+ "vitest": "^1.4.0"
29
+ }
30
+ }
@@ -0,0 +1,17 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ // Subject
4
+ import { mockLogFactory, restoreLog, spyLog } from "../index.js";
5
+
6
+ //
7
+ //
8
+ // Run tests
9
+ //
10
+
11
+ describe("Index", () => {
12
+ it("Exports functions", () => {
13
+ expect(mockLogFactory).toBeFunction();
14
+ expect(restoreLog).toBeFunction();
15
+ expect(spyLog).toBeFunction();
16
+ });
17
+ });
@@ -0,0 +1,95 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+
3
+ // Subject
4
+ import { mockLogFactory, restoreLog, spyLog } from "../mockLog.module.js";
5
+
6
+ //
7
+ //
8
+ // Mock environment
9
+ //
10
+
11
+ afterEach(() => {
12
+ vi.clearAllMocks();
13
+ });
14
+
15
+ //
16
+ //
17
+ // Run tests
18
+ //
19
+
20
+ describe("Mock Log Function", () => {
21
+ it("Exports functions", () => {
22
+ expect(mockLogFactory).toBeFunction();
23
+ expect(restoreLog).toBeFunction();
24
+ expect(spyLog).toBeFunction();
25
+ });
26
+ describe("Features", () => {
27
+ it("mockLogFactory produces a Jaypie logger", () => {
28
+ const log = mockLogFactory();
29
+ expect(log).toBeObject();
30
+ expect(log.debug).toBeFunction();
31
+ expect(log.error).toBeFunction();
32
+ expect(log.fatal).toBeFunction();
33
+ expect(log.info).toBeFunction();
34
+ expect(log.tag).toBeFunction();
35
+ expect(log.trace).toBeFunction();
36
+ expect(log.untag).toBeFunction();
37
+ expect(log.var).toBeFunction();
38
+ expect(log.warn).toBeFunction();
39
+ expect(log.with).toBeFunction();
40
+ });
41
+ it("spyLog swaps out log functions", () => {
42
+ const log = mockLogFactory();
43
+ const original = { ...log };
44
+ spyLog(log);
45
+ expect(log).toBeObject();
46
+ expect(log.debug).toBeFunction();
47
+ expect(log.error).toBeFunction();
48
+ expect(log.fatal).toBeFunction();
49
+ expect(log.info).toBeFunction();
50
+ expect(log.tag).toBeFunction();
51
+ expect(log.trace).toBeFunction();
52
+ expect(log.untag).toBeFunction();
53
+ expect(log.var).toBeFunction();
54
+ expect(log.warn).toBeFunction();
55
+ expect(log.with).toBeFunction();
56
+ expect(log.debug).not.toEqual(original.debug);
57
+ expect(log.error).not.toEqual(original.error);
58
+ expect(log.fatal).not.toEqual(original.fatal);
59
+ expect(log.info).not.toEqual(original.info);
60
+ expect(log.tag).not.toEqual(original.tag);
61
+ expect(log.trace).not.toEqual(original.trace);
62
+ expect(log.untag).not.toEqual(original.untag);
63
+ expect(log.var).not.toEqual(original.var);
64
+ expect(log.warn).not.toEqual(original.warn);
65
+ expect(log.with).not.toEqual(original.with);
66
+ });
67
+ it("restoreLog swaps back original log functions", () => {
68
+ const log = mockLogFactory();
69
+ const original = { ...log };
70
+ spyLog(log);
71
+ restoreLog(log);
72
+ expect(log).toBeObject();
73
+ expect(log.debug).toBeFunction();
74
+ expect(log.error).toBeFunction();
75
+ expect(log.fatal).toBeFunction();
76
+ expect(log.info).toBeFunction();
77
+ expect(log.tag).toBeFunction();
78
+ expect(log.trace).toBeFunction();
79
+ expect(log.untag).toBeFunction();
80
+ expect(log.var).toBeFunction();
81
+ expect(log.warn).toBeFunction();
82
+ expect(log.with).toBeFunction();
83
+ expect(log.debug).toEqual(original.debug);
84
+ expect(log.error).toEqual(original.error);
85
+ expect(log.fatal).toEqual(original.fatal);
86
+ expect(log.info).toEqual(original.info);
87
+ expect(log.tag).toEqual(original.tag);
88
+ expect(log.trace).toEqual(original.trace);
89
+ expect(log.untag).toEqual(original.untag);
90
+ expect(log.var).toEqual(original.var);
91
+ expect(log.warn).toEqual(original.warn);
92
+ expect(log.with).toEqual(original.with);
93
+ });
94
+ });
95
+ });
package/src/index.js ADDED
@@ -0,0 +1,6 @@
1
+ //
2
+ //
3
+ // Export
4
+ //
5
+
6
+ export { mockLogFactory, restoreLog, spyLog } from "./mockLog.module.js";
@@ -0,0 +1,91 @@
1
+ import { vi } from "vitest";
2
+
3
+ export function mockLogFactory() {
4
+ // Create skeleton of mock objects, as much as possible
5
+ const mock = {
6
+ debug: vi.fn(),
7
+ error: vi.fn(),
8
+ fatal: vi.fn(),
9
+ info: vi.fn(),
10
+ tag: vi.fn(),
11
+ trace: vi.fn(),
12
+ untag: vi.fn(),
13
+ var: vi.fn(),
14
+ warn: vi.fn(),
15
+ with: vi.fn(),
16
+ };
17
+ // Fill out nested mocks
18
+ mock.debug.var = mock.var;
19
+ mock.error.var = mock.var;
20
+ mock.fatal.var = mock.var;
21
+ mock.info.var = mock.var;
22
+ mock.trace.var = mock.var;
23
+ mock.warn.var = mock.var;
24
+ // Have modules return correct objects
25
+ mock.with.mockReturnValue(mock);
26
+
27
+ // Create something in the shape of the module
28
+ const module = {
29
+ debug: mock.debug,
30
+ error: mock.error,
31
+ fatal: mock.fatal,
32
+ info: mock.info,
33
+ tag: mock.tag,
34
+ trace: mock.trace,
35
+ untag: mock.untag,
36
+ var: mock.var,
37
+ warn: mock.warn,
38
+ with: mock.with,
39
+ };
40
+
41
+ // Pin mocks to the module
42
+ module.mock = mock;
43
+
44
+ // return the module
45
+ return module;
46
+ }
47
+
48
+ // export default mockLogFactory();
49
+
50
+ const logMethodNames = [
51
+ "debug",
52
+ "error",
53
+ "fatal",
54
+ "info",
55
+ "tag",
56
+ "trace",
57
+ "untag",
58
+ "var",
59
+ "warn",
60
+ "with",
61
+ ];
62
+ const originalLogMethods = new WeakMap();
63
+
64
+ export function spyLog(log) {
65
+ if (!originalLogMethods.has(log)) {
66
+ const mockLog = mockLogFactory();
67
+ const originalMethods = {};
68
+ logMethodNames.forEach((method) => {
69
+ originalMethods[method] = log[method];
70
+ log[method] = mockLog[method];
71
+ });
72
+ // Add custom properties
73
+ originalMethods.mock = log.mock;
74
+ log.mock = mockLog.mock;
75
+
76
+ originalLogMethods.set(log, originalMethods);
77
+ }
78
+ }
79
+
80
+ export function restoreLog(log) {
81
+ const originalMethods = originalLogMethods.get(log);
82
+ if (originalMethods) {
83
+ logMethodNames.forEach((method) => {
84
+ log[method] = originalMethods[method];
85
+ });
86
+ // Restore custom properties
87
+ log.mock = originalMethods.mock;
88
+
89
+ originalLogMethods.delete(log);
90
+ }
91
+ }
package/testSetup.js ADDED
@@ -0,0 +1,3 @@
1
+ import { expect } from "vitest";
2
+ import * as matchers from "jest-extended";
3
+ expect.extend(matchers);
package/vite.config.js ADDED
@@ -0,0 +1,10 @@
1
+ /// <reference types="vitest" />
2
+
3
+ import { defineConfig } from "vite";
4
+
5
+ // https://vitejs.dev/config/
6
+ export default defineConfig({
7
+ test: {
8
+ setupFiles: ["./testSetup.js"],
9
+ },
10
+ });