From e9a1df618e6a7cbe9615bb808de5b605db2c06dd Mon Sep 17 00:00:00 2001 From: wolfy1339 Date: Fri, 25 Jun 2021 17:17:38 -0400 Subject: [PATCH] refactor(tests): move to jest --- package.json | 18 +++-- ...et-upload-test.js => asset-upload.test.js} | 10 +-- ...sponse-test.js => binary-response.test.js} | 12 ++-- ...cts-test.js => fixtures-conflicts.test.js} | 10 +-- ...ository-test.js => get-repository.test.js} | 28 +++----- ...fixtures-test.js => load-fixtures.test.js} | 33 ++++----- .../{redirects-test.js => redirects.test.js} | 57 +++++----------- ...-errors-test.js => request-errors.test.js} | 9 +-- ...> same-request-different-response.test.js} | 68 ++++++------------- test/integration/smoke-test.js | 6 -- test/integration/smoke.test.js | 3 + test/unit/glob-to-fixtures-test.js | 17 ----- test/unit/glob-to-fixtures.test.js | 11 +++ test/unit/map-values-deep-test.js | 9 --- test/unit/map-values-deep.test.js | 6 ++ 15 files changed, 111 insertions(+), 186 deletions(-) rename test/integration/{asset-upload-test.js => asset-upload.test.js} (92%) rename test/integration/{binary-response-test.js => binary-response.test.js} (85%) rename test/integration/{fixtures-conflicts-test.js => fixtures-conflicts.test.js} (91%) rename test/integration/{get-repository-test.js => get-repository.test.js} (83%) rename test/integration/{load-fixtures-test.js => load-fixtures.test.js} (61%) rename test/integration/{redirects-test.js => redirects.test.js} (72%) rename test/integration/{request-errors-test.js => request-errors.test.js} (82%) rename test/integration/{same-request-different-response-test.js => same-request-different-response.test.js} (71%) delete mode 100644 test/integration/smoke-test.js create mode 100644 test/integration/smoke.test.js delete mode 100644 test/unit/glob-to-fixtures-test.js create mode 100644 test/unit/glob-to-fixtures.test.js delete mode 100644 test/unit/map-values-deep-test.js create mode 100644 test/unit/map-values-deep.test.js diff --git a/package.json b/package.json index 90682a7..086cdf7 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "lint": "prettier --check '{bin,lib,scripts,test}/**/*.{js,json}' index.js README.md package.json", "lint:fix": "prettier --write '{bin,lib,scripts,test}/**/*.{js,json}' index.js README.md package.json", "pretest": "npm run -s lint", - "test": "tap --100 --coverage 'test/**/*-test.js'", + "test": "NODE_OPTIONS=--experimental-vm-modules npx jest --coverage -i 'test/.*/.*'", "test:e2e": "npm run test:e2e:smoke && npm run test:e2e:custom-fixtures", "test:e2e:smoke": "test/end-to-end/smoke-test.sh", "test:e2e:custom-fixtures": "test/end-to-end/custom-fixtures-test.sh" @@ -42,13 +42,13 @@ "yargs": "^17.0.0" }, "devDependencies": { + "@types/jest": "^26.0.23", "axios": "^0.21.0", + "jest": "^27.0.5", "pkg": "^5.0.0", "prettier": "^2.0.1", - "proxyquire": "^2.0.0", "semantic-release": "^17.2.1", - "supertest": "^6.0.0", - "tap": "^15.0.0" + "supertest": "^6.0.0" }, "release": { "plugins": [ @@ -79,5 +79,15 @@ "extends": [ "github>octokit/.github" ] + }, + "jest": { + "coverageThreshold": { + "global": { + "branches": 100, + "functions": 100, + "lines": 100, + "statements": 100 + } + } } } diff --git a/test/integration/asset-upload-test.js b/test/integration/asset-upload.test.js similarity index 92% rename from test/integration/asset-upload-test.js rename to test/integration/asset-upload.test.js index 25652f4..439de2e 100644 --- a/test/integration/asset-upload-test.js +++ b/test/integration/asset-upload.test.js @@ -1,11 +1,10 @@ import express from "express"; import supertest from "supertest"; -import { test } from "tap"; import { getScenarioFixture } from "../util.js"; import middleware from "../../index.js"; -test("release asset (gr2m/octokit-rest-browser-experimental#5)", async (t) => { +test("release asset (gr2m/octokit-rest-browser-experimental#5)", async () => { const app = express(); app.use( middleware({ @@ -32,8 +31,7 @@ test("release asset (gr2m/octokit-rest-browser-experimental#5)", async (t) => { authorization: "token 0000000000000000000000000000000000000001", }); - t.is( - updateUrl, + expect(updateUrl).toBe( `http://localhost:3000/uploads.github.com/${fixtureId}/repos/octokit-fixture-org/release-assets/releases/1000/assets{?name,label}` ); @@ -54,7 +52,5 @@ test("release asset (gr2m/octokit-rest-browser-experimental#5)", async (t) => { }) .catch((error) => console.log(error.stack)); - t.is(result.body.name, "test-upload.txt"); - - t.end(); + expect(result.body.name).toBe("test-upload.txt"); }); diff --git a/test/integration/binary-response-test.js b/test/integration/binary-response.test.js similarity index 85% rename from test/integration/binary-response-test.js rename to test/integration/binary-response.test.js index 5ed44c6..eb102cd 100644 --- a/test/integration/binary-response-test.js +++ b/test/integration/binary-response.test.js @@ -2,12 +2,11 @@ import { URL } from "url"; import express from "express"; import supertest from "supertest"; -import { test } from "tap"; import { getScenarioFixture } from "../util.js"; import middleware from "../../index.js"; -test("binary response (octokit/rest.js#743)", async (t) => { +test("binary response (octokit/rest.js#743)", async () => { const app = express(); app.use( middleware({ @@ -34,9 +33,8 @@ test("binary response (octokit/rest.js#743)", async (t) => { }) .catch((error) => error.response); - t.is(getArchiveResponse.status, 302); - t.is( - getArchiveResponse.headers.location, + expect(getArchiveResponse.status).toBe(302); + expect(getArchiveResponse.headers.location).toBe( `http://localhost:3000/codeload.github.com/${fixtureId}/octokit-fixture-org/get-archive/legacy.tar.gz/refs/heads/main` ); @@ -47,7 +45,5 @@ test("binary response (octokit/rest.js#743)", async (t) => { authorization: "token 0000000000000000000000000000000000000001", }); - t.is(status, 200); - - t.end(); + expect(status).toBe(200); }); diff --git a/test/integration/fixtures-conflicts-test.js b/test/integration/fixtures-conflicts.test.js similarity index 91% rename from test/integration/fixtures-conflicts-test.js rename to test/integration/fixtures-conflicts.test.js index 9603b30..af4e2dd 100644 --- a/test/integration/fixtures-conflicts-test.js +++ b/test/integration/fixtures-conflicts.test.js @@ -1,11 +1,10 @@ import express from "express"; import supertest from "supertest"; -import { test } from "tap"; import { getScenarioFixture } from "../util.js"; import middleware from "../../index.js"; -test("conflicts test (#8)", async (t) => { +test("conflicts test (#8)", async () => { const app = express(); app.use( middleware({ @@ -35,8 +34,7 @@ test("conflicts test (#8)", async (t) => { authorization: "token 0000000000000000000000000000000000000001", }); - t.is( - uploadUrl, + expect(uploadUrl).toBe( `http://localhost:3000/uploads.github.com/${fixtureId}/repos/octokit-fixture-org/release-assets/releases/1000/assets{?name,label}` ); @@ -57,7 +55,5 @@ test("conflicts test (#8)", async (t) => { }) .catch((error) => console.log(error.stack)); - t.is(result.body.name, "test-upload.txt"); - - t.end(); + expect(result.body.name).toBe("test-upload.txt"); }); diff --git a/test/integration/get-repository-test.js b/test/integration/get-repository.test.js similarity index 83% rename from test/integration/get-repository-test.js rename to test/integration/get-repository.test.js index 90b584f..46134a1 100644 --- a/test/integration/get-repository-test.js +++ b/test/integration/get-repository.test.js @@ -2,12 +2,11 @@ import { URL } from "url"; import express from "express"; import supertest from "supertest"; -import { test } from "tap"; import { getScenarioFixture } from "../util.js"; import middleware from "../../index.js"; -test("get repository success", async (t) => { +test("get repository success", async () => { const app = express(); app.use( middleware({ @@ -31,11 +30,10 @@ test("get repository success", async (t) => { authorization: "token 0000000000000000000000000000000000000001", }); - t.is(body.name, "hello-world"); - t.end(); + expect(body.name).toBe("hello-world"); }); -test("get repository without Accept header", async (t) => { +test("get repository without Accept header", async () => { const app = express(); app.use( middleware({ @@ -52,12 +50,11 @@ test("get repository without Accept header", async (t) => { .get("/api.github.com/fixturesid123/repos/octokit-fixture-org/hello-world") .catch((error) => error.response); - t.is(status, 400); - t.is(body.error, "Accept header required"); - t.end(); + expect(status).toBe(400); + expect(body.error).toBe("Accept header required"); }); -test("get repository with invalid X-Fixtures-Id header", async (t) => { +test("get repository with invalid X-Fixtures-Id header", async () => { const app = express(); app.use( middleware({ @@ -78,12 +75,11 @@ test("get repository with invalid X-Fixtures-Id header", async (t) => { }) .catch((error) => error.response); - t.is(status, 404); - t.is(body.error, 'Fixture "fixturesid123" not found'); - t.end(); + expect(status).toBe(404); + expect(body.error).toBe('Fixture "fixturesid123" not found'); }); -test("get repository with incorrect path", async (t) => { +test("get repository with incorrect path", async () => { const app = express(); app.use( middleware({ @@ -108,10 +104,8 @@ test("get repository with incorrect path", async (t) => { }) .catch((error) => error.response); - t.is(status, 404); - t.is( - body.error, + expect(status).toBe(404); + expect(body.error).toBe( "GET /foo does not match next fixture: GET /repos/octokit-fixture-org/hello-world" ); - t.end(); }); diff --git a/test/integration/load-fixtures-test.js b/test/integration/load-fixtures.test.js similarity index 61% rename from test/integration/load-fixtures-test.js rename to test/integration/load-fixtures.test.js index 3970efc..e851b10 100644 --- a/test/integration/load-fixtures-test.js +++ b/test/integration/load-fixtures.test.js @@ -1,10 +1,9 @@ import express from "express"; import supertest from "supertest"; -import { test } from "tap"; import middleware from "../../index.js"; -test("create fixture success", (t) => { +test("create fixture success", (done) => { const app = express(); app.use( middleware({ @@ -18,14 +17,14 @@ test("create fixture success", (t) => { .send({ scenario: "get-repository" }) .then((response) => { const { id, url } = response.body; - t.ok(id); - t.is(url, `http://localhost:3000/api.github.com/${id}`); - t.end(); + expect(id).toBeTruthy(); + expect(url).toBe(`http://localhost:3000/api.github.com/${id}`); + done(); }) - .catch(t.error); + .catch(done.fail); }); -test("create fixture error", (t) => { +test("create fixture error", (done) => { const app = express(); app.use( middleware({ @@ -39,14 +38,14 @@ test("create fixture error", (t) => { .send({ scenario: "nope" }) .catch((error) => error.response) .then((response) => { - t.is(response.status, 400); - t.is(response.body.error, 'Scenario "nope" not found'); - t.end(); + expect(response.status).toBe(400); + expect(response.body.error).toBe('Scenario "nope" not found'); + done(); }) - .catch(t.error); + .catch(done.fail); }); -test("create fixture with custom url", (t) => { +test("create fixture with custom url", (done) => { const app = express(); app.use( middleware({ @@ -61,9 +60,11 @@ test("create fixture with custom url", (t) => { .send({ scenario: "get-repository" }) .then((response) => { const { id, url } = response.body; - t.ok(id); - t.is(url, `https://deployment-123.my-fixtures.com/api.github.com/${id}`); - t.end(); + expect(id).toBeTruthy(); + expect(url).toBe( + `https://deployment-123.my-fixtures.com/api.github.com/${id}` + ); + done(); }) - .catch(t.error); + .catch(done.fail); }); diff --git a/test/integration/redirects-test.js b/test/integration/redirects.test.js similarity index 72% rename from test/integration/redirects-test.js rename to test/integration/redirects.test.js index 5e807cd..78f6ed0 100644 --- a/test/integration/redirects-test.js +++ b/test/integration/redirects.test.js @@ -2,12 +2,11 @@ import { URL } from "url"; import express from "express"; import supertest from "supertest"; -import { test } from "tap"; import { getScenarioFixture } from "../util.js"; import middleware from "../../index.js"; -test("get repository redirect (gr2m/octokit-rest-browser-experimental#6)", async (t) => { +test("get repository redirect (gr2m/octokit-rest-browser-experimental#6)", async (done) => { const app = express(); app.use( middleware({ @@ -23,9 +22,9 @@ test("get repository redirect (gr2m/octokit-rest-browser-experimental#6)", async const fixtureResponse = await agent .post("/fixtures") .send({ scenario: "rename-repository" }) - .catch(t.error); + .catch(done.fail); - t.is(fixtureResponse.status, 201, fixtureResponse.body.error); + expect(fixtureResponse.status).toBe(201); const path = new URL(fixtureResponse.body.url).pathname; const renameResponse = await agent @@ -38,13 +37,9 @@ test("get repository redirect (gr2m/octokit-rest-browser-experimental#6)", async .send({ name: "rename-repository-newname", }) - .catch(t.error); + .catch(done.fail); - t.is( - renameResponse.status, - 200, - renameResponse.body.detail || renameResponse.body.error - ); + expect(renameResponse.status).toBe(200); const getResponse = await agent .get(`${path}/repos/octokit-fixture-org/rename-repository`) @@ -54,21 +49,13 @@ test("get repository redirect (gr2m/octokit-rest-browser-experimental#6)", async }) .catch((error) => error.response); - t.is( - getResponse.status, - 301, - getResponse.body.detail || getResponse.body.error - ); - t.is( - getResponse.headers.location, - `http://localhost:3000${path}/repositories/1000`, - "redirect URL is prefixed correctly" + expect(getResponse.status).toBe(301); + expect(getResponse.headers.location).toBe( + `http://localhost:3000${path}/repositories/1000` ); - - t.end(); }); -test("get repository success (redirect with custom URL test)", async (t) => { +test("get repository success (redirect with custom URL test)", async (done) => { const app = express(); app.use( middleware({ @@ -85,9 +72,9 @@ test("get repository success (redirect with custom URL test)", async (t) => { const fixtureResponse = await agent .post("/fixtures") .send({ scenario: "rename-repository" }) - .catch(t.error); + .catch(done.fail); - t.is(fixtureResponse.status, 201, fixtureResponse.body.error); + expect(fixtureResponse.status).toBe(201); const path = new URL(fixtureResponse.body.url).pathname; const renameResponse = await agent @@ -100,13 +87,9 @@ test("get repository success (redirect with custom URL test)", async (t) => { .send({ name: "rename-repository-newname", }) - .catch(t.error); + .catch(done.fail); - t.is( - renameResponse.status, - 200, - renameResponse.body.detail || renameResponse.body.error - ); + expect(renameResponse.status).toBe(200); const getResponse = await agent .get(`${path}/repos/octokit-fixture-org/rename-repository`) @@ -116,16 +99,8 @@ test("get repository success (redirect with custom URL test)", async (t) => { }) .catch((error) => error.response); - t.is( - getResponse.status, - 301, - getResponse.body.detail || getResponse.body.error - ); - t.is( - getResponse.headers.location, - `https://deployment123.my-mock-server.com${path}/repositories/1000`, - "redirect URL is prefixed correctly" + expect(getResponse.status).toBe(301); + expect(getResponse.headers.location).toBe( + `https://deployment123.my-mock-server.com${path}/repositories/1000` ); - - t.end(); }); diff --git a/test/integration/request-errors-test.js b/test/integration/request-errors.test.js similarity index 82% rename from test/integration/request-errors-test.js rename to test/integration/request-errors.test.js index c8dc2a2..392d1f1 100644 --- a/test/integration/request-errors-test.js +++ b/test/integration/request-errors.test.js @@ -2,11 +2,10 @@ import { URL } from "url"; import express from "express"; import supertest from "supertest"; -import { test } from "tap"; import middleware from "../../index.js"; -test("request error: no matching fixture found", async (t) => { +test("request error: no matching fixture found", async () => { const app = express(); app.use( middleware({ @@ -36,8 +35,6 @@ test("request error: no matching fixture found", async (t) => { }) .catch((error) => error.response); - t.is(status, 404); - t.is(body.error, "Nock: No match for request"); - - t.end(); + expect(status).toBe(404); + expect(body.error).toBe("Nock: No match for request"); }); diff --git a/test/integration/same-request-different-response-test.js b/test/integration/same-request-different-response.test.js similarity index 71% rename from test/integration/same-request-different-response-test.js rename to test/integration/same-request-different-response.test.js index 5ea700a..06fa526 100644 --- a/test/integration/same-request-different-response-test.js +++ b/test/integration/same-request-different-response.test.js @@ -1,13 +1,12 @@ import express from "express"; import supertest from "supertest"; -import { test } from "tap"; import { getScenarioFixture } from "../util.js"; import middleware from "../../index.js"; // Two GET /api.github.com/repos/octokit-fixture-org/add-and-remove-repository-collaborator/collaborators // requests return different results based on order, see gr2m/octokit-rest-browser-experimental#4 -test("add-and-remove-repository-collaborator (same request/different response)", async (t) => { +test("add-and-remove-repository-collaborator (same request/different response)", async (done) => { const app = express(); app.use( middleware({ @@ -25,9 +24,9 @@ test("add-and-remove-repository-collaborator (same request/different response)", const fixtureResponse = await agent .post("/fixtures") .send({ scenario: "add-and-remove-repository-collaborator" }) - .catch(t.error); + .catch(done.fail); - t.is(fixtureResponse.status, 201, fixtureResponse.body.error); + expect(fixtureResponse.status).toBe(201); const { id } = fixtureResponse.body; // https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator @@ -39,13 +38,9 @@ test("add-and-remove-repository-collaborator (same request/different response)", accept: "application/vnd.github.v3+json", authorization: "token 0000000000000000000000000000000000000001", }) - .catch(t.error); + .catch(done.fail); - t.is( - addCollaboratorResponse.status, - 201, - addCollaboratorResponse.body.detail || addCollaboratorResponse.body.error - ); + expect(addCollaboratorResponse.status).toBe(201); // https://developer.github.com/v3/repos/invitations/ const getInvitationsResponse = await agent @@ -56,14 +51,10 @@ test("add-and-remove-repository-collaborator (same request/different response)", accept: "application/vnd.github.v3+json", authorization: "token 0000000000000000000000000000000000000001", }) - .catch(t.error); + .catch(done.fail()); - t.is( - getInvitationsResponse.status, - 200, - getInvitationsResponse.body.detail || getInvitationsResponse.body.error - ); - t.is(getInvitationsResponse.body[0].id, 1000); + expect(getInvitationsResponse.status).toBe(200); + expect(getInvitationsResponse.body[0].id).toBe(1000); // https://developer.github.com/v3/repos/invitations/#accept-a-repository-invitation const acceptInvitationResponse = await agent @@ -72,13 +63,9 @@ test("add-and-remove-repository-collaborator (same request/different response)", accept: "application/vnd.github.v3+json", authorization: "token 0000000000000000000000000000000000000002", }) - .catch(t.error); + .catch(done.fail); - t.is( - acceptInvitationResponse.status, - 204, - acceptInvitationResponse.body.detail || acceptInvitationResponse.body.error - ); + expect(acceptInvitationResponse.status).toBe(204); // https://developer.github.com/v3/repos/collaborators/#list-collaborators const listCollaborators1Response = await agent @@ -89,16 +76,13 @@ test("add-and-remove-repository-collaborator (same request/different response)", accept: "application/vnd.github.v3+json", authorization: "token 0000000000000000000000000000000000000001", }) - .catch(t.error); + .catch(done.fail); - t.is( - listCollaborators1Response.status, - 200, - listCollaborators1Response.body.detail || - listCollaborators1Response.body.error - ); + expect(listCollaborators1Response.status).toBe(200); // listCollaborators1Response.body should be an array, but instead is an {'1': {}, '2': {}} object ¯\_(ツ)_/¯ - t.is(listCollaborators1Response.body[1].login, "octokit-fixture-user-b"); + expect(listCollaborators1Response.body[1].login).toBe( + "octokit-fixture-user-b" + ); // https://developer.github.com/v3/repos/collaborators/#remove-user-as-a-collaborator const removeCollaboratorResponse = await agent @@ -109,14 +93,9 @@ test("add-and-remove-repository-collaborator (same request/different response)", accept: "application/vnd.github.v3+json", authorization: "token 0000000000000000000000000000000000000001", }) - .catch(t.error); + .catch(done.fail); - t.is( - removeCollaboratorResponse.status, - 204, - removeCollaboratorResponse.body.detail || - removeCollaboratorResponse.body.error - ); + expect(removeCollaboratorResponse.status).toBe(204); // https://developer.github.com/v3/repos/collaborators/#list-collaborators const listCollaborators2Response = await agent @@ -127,15 +106,8 @@ test("add-and-remove-repository-collaborator (same request/different response)", accept: "application/vnd.github.v3+json", authorization: "token 0000000000000000000000000000000000000001", }) - .catch(t.error); - - t.is( - listCollaborators2Response.status, - 200, - listCollaborators2Response.body.detail || - listCollaborators2Response.body.error - ); - t.is(listCollaborators2Response.body[1], undefined); + .catch(done.fail); - t.end(); + expect(listCollaborators2Response.status).toBe(200); + expect(listCollaborators2Response.body[1]).toBe(undefined); }); diff --git a/test/integration/smoke-test.js b/test/integration/smoke-test.js deleted file mode 100644 index f2a643f..0000000 --- a/test/integration/smoke-test.js +++ /dev/null @@ -1,6 +0,0 @@ -import { test } from "tap"; - -test("loads @octokit/fixtures-server", async (t) => { - await import("../../index.js").default; - t.end(); -}); diff --git a/test/integration/smoke.test.js b/test/integration/smoke.test.js new file mode 100644 index 0000000..a3059d6 --- /dev/null +++ b/test/integration/smoke.test.js @@ -0,0 +1,3 @@ +test("loads @octokit/fixtures-server", async () => { + await import("../../index.js").default; +}); diff --git a/test/unit/glob-to-fixtures-test.js b/test/unit/glob-to-fixtures-test.js deleted file mode 100644 index 6a514ac..0000000 --- a/test/unit/glob-to-fixtures-test.js +++ /dev/null @@ -1,17 +0,0 @@ -import _proxyquire from "proxyquire"; - -const proxyquire = _proxyquire.noCallThru(); -import { test } from "tap"; - -test("globToFixture globbing JSON file != normalized-fixture.json", (t) => { - const globToFixture = proxyquire("../../lib/glob-to-fixtures", { - glob: { - sync: () => ["/foo/bar.json"], - }, - "/foo/bar.json": "baz", - }); - const fixtures = globToFixture(); - t.deepEqual(fixtures, { bar: "baz" }); - - t.end(); -}); diff --git a/test/unit/glob-to-fixtures.test.js b/test/unit/glob-to-fixtures.test.js new file mode 100644 index 0000000..1c1359b --- /dev/null +++ b/test/unit/glob-to-fixtures.test.js @@ -0,0 +1,11 @@ +jest.mock("glob", () => ({ + sync: () => ["/foo/bar.json"], +})); + +jest.mock("/foo/bar.json", () => "baz"); + +test("globToFixture globbing JSON file != normalized-fixture.json", async () => { + const globToFixture = (await import("../../lib/glob-to-fixtures.js")).default; + const fixtures = globToFixture(); + expect(fixtures).toEqual({ bar: "baz" }); +}); diff --git a/test/unit/map-values-deep-test.js b/test/unit/map-values-deep-test.js deleted file mode 100644 index ba1b935..0000000 --- a/test/unit/map-values-deep-test.js +++ /dev/null @@ -1,9 +0,0 @@ -import { test } from "tap"; -import mapValuesDeep from "../../lib/map-values-deep.js"; - -test("mapValuesDeep leaves arrays intact (#5)", (t) => { - const result = mapValuesDeep([1, 2], () => 0); - t.ok(Array.isArray(result)); - - t.end(); -}); diff --git a/test/unit/map-values-deep.test.js b/test/unit/map-values-deep.test.js new file mode 100644 index 0000000..ffc6f9a --- /dev/null +++ b/test/unit/map-values-deep.test.js @@ -0,0 +1,6 @@ +import mapValuesDeep from "../../lib/map-values-deep.js"; + +test("mapValuesDeep leaves arrays intact (#5)", () => { + const result = mapValuesDeep([1, 2], () => 0); + expect(Array.isArray(result)).toBeTruthy(); +});