From 2233216b3a514f4d88e517f6e8f88a3152443cf7 Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Mon, 25 Oct 2021 22:37:45 +0100 Subject: [PATCH 01/62] BREAKING: Remove rhum runner --- .github/workflows/master.yml | 10 +- README.md | 36 +- deps.ts | 7 - egg.json | 4 +- example_tests/basic/1.ts | 29 -- example_tests/basic/1_fail.ts | 29 -- example_tests/basic/2.ts | 47 --- example_tests/basic/3.ts | 32 -- example_tests/basic/tests_fail.ts | 3 - example_tests/basic/tests_pass.ts | 3 - mod.ts | 390 -------------------- src/interfaces.ts | 131 ------- src/mock_builder.ts | 164 -------- src/mocks/server_request.ts | 59 --- src/rhum_asserts.ts | 30 -- src/test_case.ts | 119 ------ src/types.ts | 18 - tests/integration/asserts_test.ts | 45 --- tests/integration/hooks/after_all_test.ts | 71 ---- tests/integration/hooks/after_each_test.ts | 62 ---- tests/integration/hooks/before_all_test.ts | 63 ---- tests/integration/hooks/before_each_test.ts | 71 ---- tests/integration/mock_test.ts | 1 + tests/unit/mod_test.ts | 76 ---- tests/unit/quick_start.ts | 33 -- tests/unit/test_case_test.ts | 24 -- 26 files changed, 13 insertions(+), 1544 deletions(-) delete mode 100644 deps.ts delete mode 100644 example_tests/basic/1.ts delete mode 100644 example_tests/basic/1_fail.ts delete mode 100644 example_tests/basic/2.ts delete mode 100644 example_tests/basic/3.ts delete mode 100644 example_tests/basic/tests_fail.ts delete mode 100644 example_tests/basic/tests_pass.ts delete mode 100644 src/interfaces.ts delete mode 100644 src/mock_builder.ts delete mode 100644 src/mocks/server_request.ts delete mode 100644 src/rhum_asserts.ts delete mode 100644 src/test_case.ts delete mode 100644 src/types.ts delete mode 100644 tests/integration/asserts_test.ts delete mode 100644 tests/integration/hooks/after_all_test.ts delete mode 100644 tests/integration/hooks/after_each_test.ts delete mode 100644 tests/integration/hooks/before_all_test.ts delete mode 100644 tests/integration/hooks/before_each_test.ts delete mode 100644 tests/unit/mod_test.ts delete mode 100644 tests/unit/quick_start.ts delete mode 100644 tests/unit/test_case_test.ts diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index aff77b1b..68d7de96 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -22,10 +22,10 @@ jobs: uses: denolib/setup-deno@master - name: Unit - run: deno test --allow-env tests/unit + run: deno test tests/unit - name: Integration - run: deno test --allow-run --allow-env tests/integration + run: deno test tests/integration linter: # Only one OS is required since fmt is cross platform @@ -35,10 +35,10 @@ jobs: - uses: actions/checkout@v2 - name: Install Deno - uses: denolib/setup-deno@master + uses: denoland/setup-deno@v1 - # - name: Lint - # run: deno lint --unstable + - name: Lint + run: deno lint - name: Formatter run: deno fmt --check diff --git a/README.md b/README.md index d85f416e..7ea820a5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Rhum - A lightweight testing framework for Deno.

Rhum

-

A lightweight testing framework for Deno.

+

A test double module to stub and mock your code

@@ -25,13 +25,10 @@ ### Features -- Descriptive naming for your tests - Lightweight - Zero 3rd party dependencies - Simple and easy to use - Asynchronous support -- Still uses `Deno.test` under the hood -- Skip functionality - Mock requests - Hooks @@ -40,32 +37,11 @@ To add Rhum to your project, follow the quick start guide [here](https://drash.land/rhum/#/#quickstart). -### Why Use Rhum? +## Contributing -Rhum allows you to write tests in a very descriptive way -- from a code -perspective or output perspective. - -Rhum is designed to aid your testing efforts -- providing many utilities as -wrappers around Deno's existing `Deno.test`. Rhum is meant to improve the user -experience when it comes to writing tests, such as: - -- Readability for test cases -- Features that aren't available in Deno yet (hooks) - -Rhum takes concepts from the following: - -- Mocha — For how you - write tests in Rhum, and the use of - hooks -- Baretest — - Being minimalistic - -Rhum can be added directly into any project. All you need to do is import Rhum -and you are ready to start writing tests or bring your existing tests under -Rhum. +Want to contribute? Follow the Contributing Guidelines +[here](https://github.com/drashland/.github/blob/master/CONTRIBUTING.md). ---- +## License -Want to contribute? Follow the Contributing Guidelines -[here](https://github.com/drashland/.github/blob/master/CONTRIBUTING.md). All -code is released under the [MIT License](./LICENSE). +All code is released under the [MIT License](./LICENSE). diff --git a/deps.ts b/deps.ts deleted file mode 100644 index 715241eb..00000000 --- a/deps.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { ServerRequest } from "https://deno.land/std@0.106.0/http/server.ts"; - -export { BufReader } from "https://deno.land/std@0.106.0/io/bufio.ts"; - -export * as StdAsserts from "https://deno.land/std@0.106.0/testing/asserts.ts"; - -export * as colors from "https://deno.land/std@0.106.0/fmt/colors.ts"; diff --git a/egg.json b/egg.json index 95699add..b3578378 100644 --- a/egg.json +++ b/egg.json @@ -1,13 +1,11 @@ { "name": "rhum", - "description": "A lightweight testing framework for Deno.", + "description": "A test double mdoule to stub and mock your code.", "version": "1.1.11", "stable": true, "repository": "https://github.com/drashland/rhum", "files": [ "./mod.ts", - "./deps.ts", - "./src/**/*", "./README.md", "./logo.svg", "LICENSE" diff --git a/example_tests/basic/1.ts b/example_tests/basic/1.ts deleted file mode 100644 index eaae3d3e..00000000 --- a/example_tests/basic/1.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Rhum } from "../../mod.ts"; - -Rhum.testPlan("test_plan_1", () => { - Rhum.testSuite("test_suite_1a", () => { - Rhum.testCase("test_case_1a1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_1a2", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_1a3", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); - - Rhum.testSuite("test_suite_1b", () => { - Rhum.testCase("test_case_1b1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_1b2", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_1b3", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); -}); - -Rhum.run(); diff --git a/example_tests/basic/1_fail.ts b/example_tests/basic/1_fail.ts deleted file mode 100644 index 5924602d..00000000 --- a/example_tests/basic/1_fail.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Rhum } from "../../mod.ts"; - -Rhum.testPlan("test_plan_1", () => { - Rhum.testSuite("test_suite_1a", () => { - Rhum.testCase("test_case_1a1", () => { - Rhum.asserts.assertEquals(true, false); - }); - Rhum.testCase("test_case_1a2", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_1a3", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); - - Rhum.testSuite("test_suite_1b", () => { - Rhum.testCase("test_case_1b1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_1b2", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_1b3", () => { - Rhum.asserts.assertEquals(true, false); - }); - }); -}); - -Rhum.run(); diff --git a/example_tests/basic/2.ts b/example_tests/basic/2.ts deleted file mode 100644 index c45c87fc..00000000 --- a/example_tests/basic/2.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Rhum } from "../../mod.ts"; - -Rhum.testPlan("test_plan_2", () => { - Rhum.testSuite("test_suite_2a", () => { - Rhum.testCase("test_case_2a1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_2a2", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_2a3", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); - - Rhum.testSuite("test_suite_2b", () => { - Rhum.testCase("test_case_2b1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_2b2", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); - - Rhum.testSuite("test_suite_2c", () => { - Rhum.testCase("test_case_2c1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_2c2", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_2c3", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); - - Rhum.testSuite("test_suite_2d", () => { - Rhum.testCase("test_case_2d1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_2d2", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); -}); - -Rhum.run(); diff --git a/example_tests/basic/3.ts b/example_tests/basic/3.ts deleted file mode 100644 index 40b52b0c..00000000 --- a/example_tests/basic/3.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Rhum } from "../../mod.ts"; - -Rhum.testPlan("test_plan_3", () => { - Rhum.testSuite("test_suite_3a", () => { - Rhum.testCase("test_case_3a1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_3a2", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); - - Rhum.testSuite("test_suite_3b", () => { - Rhum.testCase("test_case_3b1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_3b2", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); - - Rhum.testSuite("test_suite_3c", () => { - Rhum.testCase("test_case_3c1", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("test_case_3c2", () => { - Rhum.asserts.assertEquals(true, true); - }); - }); -}); - -Rhum.run(); diff --git a/example_tests/basic/tests_fail.ts b/example_tests/basic/tests_fail.ts deleted file mode 100644 index 978ca4eb..00000000 --- a/example_tests/basic/tests_fail.ts +++ /dev/null @@ -1,3 +0,0 @@ -import "./1_fail.ts"; -import "./2.ts"; -import "./3.ts"; diff --git a/example_tests/basic/tests_pass.ts b/example_tests/basic/tests_pass.ts deleted file mode 100644 index a48c96b7..00000000 --- a/example_tests/basic/tests_pass.ts +++ /dev/null @@ -1,3 +0,0 @@ -import "./1.ts"; -import "./2.ts"; -import "./3.ts"; diff --git a/mod.ts b/mod.ts index 1ef6de0b..e0e7eb89 100644 --- a/mod.ts +++ b/mod.ts @@ -1,253 +1,13 @@ -import { assertions, asserts } from "./src/rhum_asserts.ts"; -import { MockServerRequestFn } from "./src/mocks/server_request.ts"; -import { TestCase } from "./src/test_case.ts"; -import type { ITestPlan, RhumMocks } from "./src/interfaces.ts"; import type { Constructor, Stubbed } from "./src/types.ts"; import { MockBuilder } from "./src/mock_builder.ts"; export type { Constructor, Stubbed } from "./src/types.ts"; export { MockBuilder } from "./src/mock_builder.ts"; -/** - * Deno's test runner outputs "test ", which has a length of 5. This module - * erases the "test " string by backspacing the test plan line and test suite - * line by that number. For safety, it substracts twice that number. This is - * how we get the number 10 here. - */ -const extraChars = 10; - -/** - * This testing framework allows the following syntax: - * - * import { Rhum } from "/path/to/rhum/mod.ts"; - * - * Rhum.testPlan("test_plan_1", () => { - * - * Rhum.testSuite("test_suite_1a", () => { - * Rhum.testCase("test_case_1a1", () => { - * Rhum.asserts.assertEquals(true, true); - * }); - * Rhum.testCase("test_case_1a2", () => { - * Rhum.asserts.assertEquals(true, true); - * }); - * Rhum.testCase("test_case_1a3", () => { - * Rhum.asserts.assertEquals(true, true); - * }); - * }); - * - * Rhum.testSuite("test_suite_1b", () => { - * Rhum.testCase("test_case_1b1", () => { - * Rhum.asserts.assertEquals(true, true); - * }); - * Rhum.testCase("test_case_1b2", () => { - * Rhum.asserts.assertEquals(true, true); - * }); - * Rhum.testCase("test_case_1b3", () => { - * Rhum.asserts.assertEquals(true, true); - * }); - * }); - * - * }); - */ export class RhumRunner { - /** - * The asserts module from https://deno.land/std/testing, but attached to Rhum - * for accessibility. - * - * Rhum.asserts.assertEquals(true, true); // pass - * Rhum.asserts.assertEquals(true, false); // fail - */ - // deno-lint-ignore ban-types Reason for this is, deno lint no longer allows `Function` and instead needs us to be explicit: `() => void`, but because we couldn't use that to type the properties (we would just be copying Deno's interfaces word for word), we have to deal with `Function - public asserts: { [key in assertions]: Function } = asserts; - - public mocks: RhumMocks; - - protected passed_in_test_plan = ""; - - protected passed_in_test_suite = ""; - - protected test_plan_in_progress = ""; - - protected test_suite_in_progress = ""; - - protected plan: ITestPlan = { suites: {} }; - - // FILE MARKER - METHODS - CONSTRUCTOR /////////////////////////////////////// - - /** - * Construct an object of this class. - */ - constructor() { - this.mocks = { ServerRequest: MockServerRequestFn }; - } // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// - /** - * Used to define a hook that will execute before each test suite or test - * case. If this is used inside of a test plan, then it will execute before - * each test suite. If this is used inside of a test suite, then it will - * execute before each test case. - * - * @param cb - The callback to invoke. Would contain the required logic you - * need to do what you want, before each test suite or case. - * - * Rhum.testPlan("My Plan", () => { - * Rhum.beforeEach(() => { - * // Runs before each test suite in this test plan - * }); - * Rhum.testSuite("My Suite 1", () => { - * Rhum.beforeEach(() => { - * // Runs before each test case in this test suite - * }); - * Rhum.testCase("My Test Case 1", () => { - * ... - * }); - * }); - * }); - */ - public beforeEach(cb: () => void): void { - // Check if the hook is for test cases inside of a suite - if (this.passed_in_test_plan && this.passed_in_test_suite) { - // is a before each inside a suite for every test case - this.plan.suites![this.passed_in_test_suite].before_each_case_hook = cb; - } else if (this.passed_in_test_plan && !this.passed_in_test_suite) { - // before each hooks for the suites - this.plan.before_each_suite_hook = cb; - } - } - - /** - * Used to define a hook that will execute after each test suite or test case. - * If this is used inside of a test plan, then it will execute after each test - * suite. If this is used inside of a test suite, then it will execute after - * each test case. - * - * @param cb - The callback to invoke. Would contain the required logic you - * need to do what you want, after each test suite or case. - * - * Rhum.testPlan("My Plan", () => { - * Rhum.afterEach(() => { - * // Runs after each test suite in this test plan - * }); - * Rhum.testSuite("My Suite 1", () => { - * Rhum.afterEach(() => { - * // Runs after each test case in this test suite - * }); - * Rhum.testCase("My Test Case 1", () => { - * ... - * }); - * }); - * }); - */ - public afterEach(cb: () => void): void { - // Check if the hook is for test cases inside of a suite - if (this.passed_in_test_plan && this.passed_in_test_suite) { - // is a after each inside a suite for every test case - this.plan.suites![this.passed_in_test_suite].after_each_case_hook = cb; - } else if (this.passed_in_test_plan && !this.passed_in_test_suite) { - // after each hooks for the suites - this.plan.after_each_suite_hook = cb; - } - } - - /** - * Used to define a hook that will execute after all test suites or test - * cases. If this is used inside of a test plan, then it will execute after - * all test suites. If this is used inside of a test suite, then it will - * execute after all test cases. - * - * @param cb - The callback to invoke. Would contain the required logic you - * need to do what you want, after all test suites or cases. - * - * Rhum.testPlan("My Plan", () => { - * Rhum.afterAll(() => { - * // Runs once after all test suites in this test plan - * }); - * Rhum.testSuite("My Suite 1", () => { - * Rhum.afterAll(() => { - * // Runs once after all test cases in this test suite - * }); - * Rhum.testCase("My Test Case 1", () => { - * ... - * }); - * }); - * }); - */ - public afterAll(cb: () => void): void { - // Check if the hook is for test cases inside of a suite - if (this.passed_in_test_plan && this.passed_in_test_suite) { - // is a before all inside a suite for every test case - this.plan.suites![this.passed_in_test_suite].after_all_case_hook = cb; - } else if (this.passed_in_test_plan && !this.passed_in_test_suite) { - // before all hooks for the suites - this.plan.after_all_suite_hook = cb; - } - } - - /** - * Used to define a hook that will execute before all test suites or test - * cases. If this is used inside of a test plan, then it will execute before - * all test suites. If this is used inside of a test suite, then it will - * execute before all test cases. - * - * @param cb - The callback to invoke. Would contain the required logic you - * need to do what you want, before all test suites or cases. - * - * Rhum.testPlan("My Plan", () => { - * Rhum.beforeAll(() => { - * // Runs once before all test suites in this test plan - * }); - * Rhum.testSuite("My Suite 1", () => { - * Rhum.beforeAll(() => { - * // Runs once before all test cases in this test suite - * }); - * Rhum.testCase("My Test Case 1", () => { - * ... - * }); - * }); - * }); - */ - public beforeAll(cb: () => void): void { - // Check if the hook is for test cases inside of a suite - if (this.passed_in_test_plan && this.passed_in_test_suite) { - // is a before all inside a suite for every test case - this.plan.suites![this.passed_in_test_suite].before_all_case_hook = cb; - } else if (this.passed_in_test_plan && !this.passed_in_test_suite) { - // before all hooks for the suites - this.plan.before_all_suite_hook = cb; - } - } - - // public only(cb: Function): void { - // // Do something - // } - - /** - * Allows a test plan, suite, or case to be skipped when the tests run. - * - * Rhum.testPlan("My Plan", () => { - * Rhum.skip("My Suite 1", () => { // will not run this block - * Rhum.testCase("My Test Case In Suite 1", () => { - * ... - * }); - * }); - * Rhum.testSuite("My Suite 2", () => { - * Rhum.testCase("My Test Case In Suite 2", () => { - * ... - * }); - * Rhum.skip("My Other Test Case In Suite 2", () => { // will not run this block - * ... - * }); - * }); - * }); - */ - public skip(name: string, cb: () => void): void { - // TODO(ebebbington|crookse) Maybe we could still call run, but pass in { - // ignore: true } which the Deno.Test will use? just so it displays ignored - // in the console - } - /** * Stub a member of an object. * @@ -305,156 +65,6 @@ export class RhumRunner { public mock(constructorFn: Constructor): MockBuilder { return new MockBuilder(constructorFn); } - - /** - * A test case is grouped by a test suite and it is what makes the assertions - * - it is the test. You can define multiple test cases under a test suite. - * Test cases can also be asynchronous. Test cases can only be defined inside - * of a test suite. - * - * @param name - The name of the test case. - * @param testFn - The test to execute. - * - * Rhum.testPlan("My Plan", () => { - * Rhum.testSuite("My Suite 1", () => { - * Rhum.testCase("My Test Case 1", () => { - * Rhum.assert.assertEquals(something, true); - * }); - * Rhum.testCase("My Test Case 2", () => { - * Rhum.assert.assertEquals(something, false); - * }); - * }); - * }); - */ - public testCase(name: string, testFn: () => void): void { - this.plan.suites[this.passed_in_test_suite].cases!.push({ - name, - new_name: this.formatTestCaseName(name), - testFn, - }); - } - - /** - * Groups up test suites to describe a test plan. Usually, a test plan is per - * file and contains the tests suites and test cases for a single file. Test - * plans are required in order to define a test suite with test cases. - * - * @param name - The name of the test plan. - * @param testSuites - The test suites to execute. - * - * Rhum.testPlan("My Plan", () => { - * ... - * }); - */ - public testPlan(name: string, testSuites: () => void): void { - this.passed_in_test_suite = ""; // New plan - this.passed_in_test_plan = name; - testSuites(); - } - - /** - * A test suite usually describes a method or property name and groups up all - * test cases for that method or property. You can define multiple test suites - * under a test plan. Test suites can only be defined inside of a test plan. - * - * @param name - The name of the test suite. - * @param testCases - The test cases to execute. - * - * Rhum.testPlan("My Plan", () => { - * Rhum.testSuite("My Suite 1", () => { - * ... - * }); - * Rhum.testSuite("My Suite 2", () => { - * ... - * }); - * }); - */ - public testSuite(name: string, testCases: () => void): void { - this.passed_in_test_suite = name; - this.plan.suites![name] = { cases: [] }; - testCases(); - } - - /** - * Run the test plan. - * - * Rhum.testPlan("My Plan", () => { - * ... - * }); - * - * Rhum.run(); - */ - public run(): void { - const tc = new TestCase(this.plan); - tc.run(); - this.deconstruct(); - } - - ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - METHODS - PROTECTED ///////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - - /** - * Figure out the name of the test case for output purposes. - * - * @param name - The name of the test case. - * - * Returns the new test name for outputting purposes. - */ - protected formatTestCaseName(name: string): string { - let newName: string; - // (ebebbington) Unfortunately, due to the CI not correctly displaying output - // (it is all over the place and just completely unreadable as - // it doesn't play well with our control characters), we need to - // display the test output differently, based on if the tests are - // being ran inside a CI or not. Nothing will change for the current - // way of doing things, but if the tests are being ran inside a CI, - // the format would be: - // test | | ... ok (2ms) - // test | | ... ok (2ms) - // Even if plans and/or suites are the same. I believe this the best - // way we can display the output - if (Deno.env.get("CI") === "true") { - newName = - `${this.passed_in_test_plan} | ${this.passed_in_test_suite} | ${name}`; - return newName; - } - - if (this.test_plan_in_progress != this.passed_in_test_plan) { - this.test_plan_in_progress = this.passed_in_test_plan; - this.test_suite_in_progress = this.passed_in_test_suite; - newName = - `${ - "\u0008".repeat(name.length + extraChars) - } ${this.passed_in_test_suite}` + - `\n ${name}`; - } else { - if (this.test_suite_in_progress != this.passed_in_test_suite) { - this.test_suite_in_progress = this.passed_in_test_suite; - newName = `${"\u0008".repeat(name.length + extraChars)}` + - ` ${this.passed_in_test_suite}` + - `${" ".repeat(name.length + extraChars)}` + - `\n ${name}`; - } else { - newName = `${"\u0008".repeat(name.length + extraChars)}` + - ` ${name}`; - } - } - - return newName; - } - - /** - * 'Empty' this object. After calling this, Rhum should be ready for another - * test plan. - */ - protected deconstruct(): void { - this.passed_in_test_suite = ""; - this.passed_in_test_plan = ""; - this.test_plan_in_progress = ""; - this.test_suite_in_progress = ""; - this.plan = { suites: {} }; - } } /** diff --git a/src/interfaces.ts b/src/interfaces.ts deleted file mode 100644 index f887fac9..00000000 --- a/src/interfaces.ts +++ /dev/null @@ -1,131 +0,0 @@ -import type { MockServerRequestFn } from "./mocks/server_request.ts"; - -/** - * @remarks - * suites - * An object of objects matching the ITestSuite interface. - * - * after_all_suite_hook? - * A callback function to execute after all test suites. - * - * after_each_suite_hook? - * A callback function to execute after each test suite. - * - * before_all_suite_hook? - * A callback function to execute before all test suites. - * - * before_each_suite_hook? - * A callback function to execute before each test suite. - * - * Example below ... - * - * { - * suites: { - * "My Suite": { - * cases: [ - * { - * name: "My Case", - * new_name: this.formatTestCaseName(name), - * testFn: Function - * }, - * ... - * ], - * after_all_case_hook: Function, - * after_each_case_hook: Function, - * before_all_case_hook: Function, - * before_each_case_hook: Function - * }, - * ... // More suites allowed - * }, - * after_all_suite_hook: Function; - * after_each_suite_hook: Function; - * before_all_suite_hook: Function; - * before_each_suite_hook: Function; - * } - * - * ... or ... - * - * { - * suites: { - * run(): { - * cases: [Array], - * after_all_case_hook: [Function], - * before_all_case_hook: [Function], - * before_each_case_hook: [Function], - * after_each_case_hook: [Function] - * }, - * close(): { - * cases: [Array], - * after_all_case_hook: [Function], - * before_all_case_hook: [Function], - * before_each_case_hook: [Function], - * after_each_case_hook: [Function] - * } - * }, - * before_each_suite_hook: [Function], - * after_each_suite_hook: [Function], - * after_all_suite_hook: [Function], - * before_all_suite_hook: [Function] - * } - */ -export interface ITestPlan { - suites: { - [key: string]: ITestSuite; // "key" is the suite name - }; - after_all_suite_hook?: () => void; - after_each_suite_hook?: () => void; - before_all_suite_hook?: () => void; - before_each_suite_hook?: () => void; -} - -/** - * cases? - * An array of objects matching the ITestCase interface. - * - * after_all_case_hook? - * A callback function to execute after all test cases. - * - * after_each_case_hook? - * A callback function to execute after each test case. - * - * before_all_case_hook? - * A callback function to execute before all test cases. - * - * before_each_case_hook? - * A callback function to execute before each test case. - */ -export interface ITestSuite { - cases?: ITestCase[]; - after_all_case_hook?: () => void; - after_each_case_hook?: () => void; - before_all_case_hook?: () => void; - before_each_case_hook?: () => void; -} - -/** - * name - * The name of the test case. - * - * new_name - * The new name of the test. This is strictly for outputting purposes. - * Deno's test runner outputs "test name of test" and we want to - * overwrite that text. This new_name string helps us do that. See - * formatTestCaseName() in mod.ts for more information. - * - * testFn - * The test function. Ultimately, this gets passed as the second - * argument of Deno.test(). - */ -export interface ITestCase { - name: string; - new_name: string; - testFn: () => void; -} - -/** - * ServerRequest - * Type for the ServerRequest on the `Rhum.mocks` property - */ -export interface RhumMocks { - ServerRequest: typeof MockServerRequestFn; -} diff --git a/src/mock_builder.ts b/src/mock_builder.ts deleted file mode 100644 index 3fa4a491..00000000 --- a/src/mock_builder.ts +++ /dev/null @@ -1,164 +0,0 @@ -import type { Constructor, Mocked } from "./types.ts"; - -export class MockBuilder { - /** - * Properties of the class that is passed in - */ - protected properties: string[] = []; - - /** - * Functions of the class passed in - */ - protected functions: string[] = []; - - /** - * The class object passed into the constructor - */ - protected constructor_fn: Constructor; - - /** - * A list of arguments the class constructor takes - */ - protected constructor_args: unknown[] = []; - - ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - - /** - * Construct an object of this class. - * - * @param constructorFn - The object's constructor function to instantiate. - */ - constructor(constructorFn: Constructor) { - this.constructor_fn = constructorFn; - } - - ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - - /** - * Create the mock object. - * - * @returns A mocked object. - */ - public create(): Mocked { - // deno-lint-ignore no-explicit-any - const mock: Mocked = { - calls: {}, - is_mock: true, - }; - const original = new this.constructor_fn(...this.constructor_args); - - // Attach all of the original's properties to the mock - this.getAllProperties(original).forEach((property: string) => { - const desc = Object.getOwnPropertyDescriptor(original, property); - mock[property] = desc!.value; - }); - - // Attach all of the original's functions to the mock - this.getAllFunctions(original).forEach((method: string) => { - const nativeMethods = [ - "__defineGetter__", - "__defineSetter__", - "__lookupGetter__", - "__lookupSetter__", - "constructor", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "toLocaleString", - "toString", - "valueOf", - ]; - - if (nativeMethods.indexOf(method) == -1) { - if (!mock.calls[method]) { - mock.calls[method] = 0; - } - mock[method] = function () { - mock.calls[method]++; - return (original[method as keyof T] as unknown as ( - ...params: unknown[] - ) => unknown)(); - }; - } else { - // copy nativeMethod directly without mocking - mock[method] = original[method as keyof T]; - } - }); - - return mock; - } - - /** - * Before constructing the mock object, track any constructur function args - * that need to be passed in when constructing the mock object. - * - * @param args - A rest parameter of arguments that will get passed in to - * the constructor function of the class being mocked. - * - * @returns `this` so that methods in this class can be chained. - */ - public withConstructorArgs(...args: unknown[]): this { - this.constructor_args = args; - return this; - } - - ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - METHODS - PROTECTED ///////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - - /** - * Get all properties--public, protected, private--from the object that will - * be mocked. - * - * @param obj - The object that will be mocked. - * - * @returns An array of the object's properties. - */ - protected getAllProperties(obj: T): string[] { - let functions: string[] = []; - let clone = obj; - do { - functions = functions.concat(Object.getOwnPropertyNames(clone)); - } while ((clone = Object.getPrototypeOf(clone))); - - return functions.sort().filter( - function (e: string, i: number, arr: unknown[]) { - if ( - e != arr[i + 1] && typeof obj[e as keyof T] != "function" - ) { - return true; - } - }, - ); - } - - /** - * Get all functions--public, protected, private--from the object that will be - * mocked. - * - * @param obj - The object that will be mocked. - * - * @returns An array of the object's functions. - */ - protected getAllFunctions(obj: T): string[] { - let functions: string[] = []; - let clone = obj; - do { - functions = functions.concat(Object.getOwnPropertyNames(clone)); - } while ((clone = Object.getPrototypeOf(clone))); - - return functions.sort().filter( - function (e: string, i: number, arr: unknown[]) { - if ( - e != arr[i + 1] && typeof obj[e as keyof T] == "function" - ) { - return true; - } - }, - ); - } -} diff --git a/src/mocks/server_request.ts b/src/mocks/server_request.ts deleted file mode 100644 index f204b8c8..00000000 --- a/src/mocks/server_request.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { BufReader, ServerRequest } from "../../deps.ts"; - -/** - * Contains options for a server request - * - * @remarks - * headers: {[key: string]: string} - * - * The headers for the request - * - * body?: Deno.Buffer - * - * The body of the request before sending - */ -export interface MockServerRequestOptions { - headers: { [key: string]: string }; - body?: Deno.Buffer; -} - -// TODO remove lint ignore when extended and add tsdoc block -// deno-lint-ignore no-empty-interface, eslint-ignore-next-line no-empty-interface -export interface MockServerRequest extends ServerRequest { -} - -/** - * Constructs a server request object - * - * @example - * ```ts - * const request = MockServerRequestFn("/", "get", { ... }); - * ``` - * - * @param url - Url to make the request to - * @param method - The method of the request - * @param options - HTTP request options, such as headers and body - */ -export const MockServerRequestFn = function ( - url = "/", - method = "get", - options?: MockServerRequestOptions, -): MockServerRequest { - const request: MockServerRequest = new ServerRequest(); - request.url = url; - request.method = method; - request.headers = new Headers(); - if (options) { - if (options.headers) { - for (const key in options.headers) { - request.headers.set(key, options.headers[key]); - } - } - if (options.body) { - request.headers.set("Content-Length", options.body.length.toString()); - request.r = new BufReader(options.body); - } - } - - return request; -}; diff --git a/src/rhum_asserts.ts b/src/rhum_asserts.ts deleted file mode 100644 index 981caac8..00000000 --- a/src/rhum_asserts.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { StdAsserts } from "../deps.ts"; - -// Saving this so i don't have to type it out for the 10th time -// export const asserts = { -// AssertionError: StdAsserts.AssertionError, -// _format: StdAsserts._format, -// assert: StdAsserts.assert, -// assertArrayIncludes: StdAsserts.assertArrayIncludes, -// assertEquals: StdAsserts.assertEquals, -// assertNotEquals: StdAsserts.assertNotEquals, -// assertNotMatch: StdAsserts.assertNotMatch, -// assertNotStrictEquals: StdAsserts.assertNotStrictEquals, -// assertStrictEquals: StdAsserts.assertStrictEquals, -// assertStringIncludes: StdAsserts.assertStringIncludes, -// assertMatch: StdAsserts.assertMatch, -// assertThrows: StdAsserts.assertThrows, -// assertThrowsAsync: StdAsserts.assertThrowsAsync, -// equal: StdAsserts.equal, -// fail: StdAsserts.fail, -// unimplemented: StdAsserts.unimplemented, -// unreachable: StdAsserts.unreachable -// }; - -export const asserts = { - ...StdAsserts, - assertArrayContains: StdAsserts.assertArrayIncludes, - assertStringContains: StdAsserts.assertStringIncludes, -}; - -export type assertions = keyof typeof asserts; diff --git a/src/test_case.ts b/src/test_case.ts deleted file mode 100644 index c02193bf..00000000 --- a/src/test_case.ts +++ /dev/null @@ -1,119 +0,0 @@ -const encoder = new TextEncoder(); -import type { ITestCase, ITestPlan } from "./interfaces.ts"; - -/** - * A class to help create uniform test case objects. - */ -export class TestCase { - /** - * The whole test plan for a given test - */ - protected plan: ITestPlan; - - /** - * @param plan - The test plan for a given test - */ - constructor(plan: ITestPlan) { - this.plan = plan; - } - - /** - * Runs the test plan and each test and hook - */ - public async run() { - // deno-lint-ignore no-prototype-builtins, eslint-ignore-next-line no-prototype-builtins - if (this.plan.hasOwnProperty("suites") === false) { - return; - } - - // Track the execution of hooks - let executedBeforeAllSuiteHook = false; - let executedAfterAllSuiteHook = false; - - Object.keys(this.plan.suites).forEach((suiteName, suiteIndex) => { - // Track the execution of hooks - let executedBeforeEachSuiteHook = false; - let executedAfterEachSuiteHook = false; - let executedBeforeAllCaseHook = false; - let executedAfterAllCaseHook = false; - - // Run cases - this.plan!.suites[suiteName].cases!.forEach( - async (c: ITestCase, caseIndex) => { - const isLastCase = - (this.plan!.suites[suiteName].cases!.length - 1) == caseIndex; - const isLastSuite = - (Object.keys(this.plan!.suites).length - 1) == suiteIndex; - // Run the case - required to run like this because the - // hooks need to be ran inside the Deno.test call. Deno.test seems to queue - // the tests, meaning all hooks are ran, and **then** the tests are ran - const hookAttachedTestFn = async () => { - if ( - this.plan.before_all_suite_hook && !executedBeforeAllSuiteHook - ) { - await this.plan.before_all_suite_hook(); - executedBeforeAllSuiteHook = true; - } - if ( - this.plan.before_each_suite_hook && !executedBeforeEachSuiteHook - ) { - await this.plan.before_each_suite_hook(); - executedBeforeEachSuiteHook = true; - } - if ( - this.plan.suites[suiteName].before_all_case_hook && - !executedBeforeAllCaseHook - ) { - await this.plan.suites[suiteName].before_all_case_hook!(); - executedBeforeAllCaseHook = true; - } - if (this.plan.suites[suiteName].before_each_case_hook) { - await this.plan.suites[suiteName].before_each_case_hook!(); - } - - await c.testFn(); - - if (this.plan.suites[suiteName].after_each_case_hook) { - await this.plan.suites[suiteName].after_each_case_hook!(); - } - if ( - this.plan.suites[suiteName].after_all_case_hook && - !executedAfterAllCaseHook && isLastCase - ) { - await this.plan.suites[suiteName].after_all_case_hook!(); - executedAfterAllCaseHook = true; - } - if ( - this.plan.after_each_suite_hook && !executedAfterEachSuiteHook - ) { - await this.plan.after_each_suite_hook(); - executedAfterEachSuiteHook = true; - } - if ( - this.plan.after_all_suite_hook && !executedAfterAllSuiteHook && - isLastSuite - ) { - await this.plan.after_all_suite_hook(); - executedAfterAllSuiteHook = true; - } - }; - // (ebebbington) To stop the output of test running being horrible - // in the CI, we will only display the new name which should be - // "plan | suite " case", as opposed to the "super saiyan" - // version. This name is generated differently inside `formatTestCaseName` - // based on if the tests are being ran inside a CI job - if (Deno.env.get("CI") === "true") { - await Deno.test(c.new_name, async () => { - await hookAttachedTestFn(); - }); - } else { - await Deno.test(c.new_name, async () => { - // Deno.stdout.writeSync(encoder.encode(c.new_name)); - await hookAttachedTestFn(); - }); - } - }, - ); - }); - } -} diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index 4c6125a6..00000000 --- a/src/types.ts +++ /dev/null @@ -1,18 +0,0 @@ -export type TConstructorFunction = { - new (...args: unknown[]): T; - [key: string]: unknown; -}; - -// deno-lint-ignore no-explicit-any -export type Constructor = new (...args: any[]) => T; - -export type Mocked = T & { - calls: { [k in keyof T]: T[k] extends () => void ? number : never }; - is_mock: true; -}; - -export type Stubbed = T & { - calls: { [k in keyof T]?: T[k] extends () => void ? number : never }; - stub: (p: string, v: unknown) => void; - is_stubbed: true; -}; diff --git a/tests/integration/asserts_test.ts b/tests/integration/asserts_test.ts deleted file mode 100644 index d22e922a..00000000 --- a/tests/integration/asserts_test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Rhum } from "../../mod.ts"; - -Rhum.testPlan("asserts_test.ts", () => { - Rhum.testSuite("Deno std asserts", () => { - Rhum.testCase("asserts", () => { - Rhum.asserts.assert(true); - }); - Rhum.testCase("assertEquals", () => { - Rhum.asserts.assertEquals(true, true); - }); - Rhum.testCase("assertNotEquals", () => { - Rhum.asserts.assertNotEquals(true, false); - Rhum.asserts.assertNotEquals("1", 1); - }); - Rhum.testCase("assertStrictEquals", () => { - Rhum.asserts.assertStrictEquals(true, true); - const a = {}; - const b = a; - Rhum.asserts.assertStrictEquals(a, b); - }); - Rhum.testCase("assertStringContains", () => { - Rhum.asserts.assertStringContains("Test hello", "hello"); - }); - Rhum.testCase("assertMatch", () => { - Rhum.asserts.assertMatch("Test hello", /hello/g); - }); - Rhum.testCase("assertArrayContains", () => { - Rhum.asserts.assertArrayContains(["t", "e", "s", "t"], ["t", "e"]); - }); - Rhum.testCase("assertThrows", () => { - Rhum.asserts.assertThrows(() => { - throw new Error("test"); - }); - }); - Rhum.testCase("assertThrowsAsync", () => { - Rhum.asserts.assertThrowsAsync(() => { - return Rhum.asserts.assertThrowsAsync(() => { - return Promise.reject("Panic!"); - }); - }); - }); - }); -}); - -Rhum.run(); diff --git a/tests/integration/hooks/after_all_test.ts b/tests/integration/hooks/after_all_test.ts deleted file mode 100644 index 79a19289..00000000 --- a/tests/integration/hooks/after_all_test.ts +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Purpose of this test is to ensure a test using before_all succeeds - */ - -import { Rhum } from "../../../mod.ts"; - -let suite_val = 0; -let case_val = 0; -let async_case_val = 0; -Rhum.testPlan("after_all_test.ts", () => { - Rhum.afterAll(() => { - Rhum.asserts.assertEquals(suite_val, 3); - }); - // Run the first test suite - Rhum.testSuite("test suite 1", () => { - Rhum.afterAll(() => { - Rhum.asserts.assertEquals(case_val, 2); - case_val = 3; - }); - Rhum.testCase("hooks properly set suite_val and case_val", () => { - // Asserting that the suite val should not have been changed by the hook - Rhum.asserts.assertEquals(suite_val, 0); - suite_val = 1; - // Asserting that the case val should not have been changed by the hook - Rhum.asserts.assertEquals(case_val, 0); - case_val = 1; - }); - Rhum.testCase("hooks properly set case_val", () => { - // Asserting that the suite val should not have been changed by the hook - Rhum.asserts.assertEquals(suite_val, 1); - suite_val = 2; - // Asserting that the case val should not have been changed by the hook - Rhum.asserts.assertEquals(case_val, 1); - case_val = 2; - }); - }); - - // Run the second test suite - Rhum.testSuite("test suite 2", () => { - Rhum.afterAll(() => { - Rhum.asserts.assertEquals(case_val, 4); - }); - Rhum.testCase("hooks properly set suite_val and case_val", async () => { - // Asserting that the suite val should not have been changed by the hook - Rhum.asserts.assertEquals(suite_val, 2); - suite_val = 3; - // Asserting that the case val has been changed by the hook - Rhum.asserts.assertEquals(case_val, 3); - case_val = 4; - }); - }); - Rhum.testSuite("test suite 3", () => { - Rhum.afterAll(async () => { - Rhum.asserts.assertEquals(async_case_val, 1); - await new Promise((resolve) => { - setTimeout(() => resolve((async_case_val = 2)), 1000); - }); - }); - Rhum.testCase("Async afterAll hook has no effect before case", () => { - Rhum.asserts.assertEquals(async_case_val, 0); - async_case_val = 1; - }); - }); - Rhum.testSuite("test suite 4", () => { - Rhum.testCase("Async afterAll hook has effect after case", () => { - Rhum.asserts.assertEquals(async_case_val, 2); - }); - }); -}); - -Rhum.run(); diff --git a/tests/integration/hooks/after_each_test.ts b/tests/integration/hooks/after_each_test.ts deleted file mode 100644 index 9e935256..00000000 --- a/tests/integration/hooks/after_each_test.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Purpose of this test is to ensure a test using before_each succeeds - */ - -import { Rhum } from "../../../mod.ts"; - -let suite_val = "Ed"; -let case_val = 22; - -Rhum.testPlan("after_each_test.ts", () => { - Rhum.afterEach(() => { - suite_val = "Eric"; - }); - // Run the first test suite - Rhum.testSuite("test suite 1", () => { - Rhum.afterEach(() => { - case_val = 2; - }); - Rhum.testCase("hooks properly set suite_val and case_val", () => { - // Asserting that the suite val should not have been changed by the hook (yet) - Rhum.asserts.assertEquals(suite_val, "Ed"); - // Revert it back for the next test that uses it - suite_val = "Ed"; - // Assert the value is kept the same (hook hasn't ran yet) - Rhum.asserts.assertEquals(case_val, 22); - }); - Rhum.testCase("Returns false", () => { - // Assert the value has changes as the hook should have ran - Rhum.asserts.assertEquals(case_val, 2); - }); - }); - - // Run the second test suite - Rhum.testSuite("test suite 2", () => { - Rhum.afterEach(() => { - case_val = 0; - }); - Rhum.testCase("hooks properly set suite_val and case_val", async () => { - // Asserting the hook should have replaced the name - Rhum.asserts.assertEquals(suite_val, "Eric"); - suite_val = "Ed"; - // Should be kept the same as the after each hook should have updated the value - Rhum.asserts.assertEquals(case_val, 2); - }); - }); - Rhum.testSuite("test suite 3", () => { - let async_case_val = 5; - Rhum.afterEach(async () => { - await new Promise((resolve) => { - setTimeout(() => resolve((async_case_val = 15)), 1000); - }); - }); - Rhum.testCase("async afterEach hook has no effect before case", () => { - Rhum.asserts.assertEquals(async_case_val, 5); - }); - Rhum.testCase("async afterEach has effect after case", () => { - Rhum.asserts.assertEquals(async_case_val, 15); - }); - }); -}); - -Rhum.run(); diff --git a/tests/integration/hooks/before_all_test.ts b/tests/integration/hooks/before_all_test.ts deleted file mode 100644 index 6ae22809..00000000 --- a/tests/integration/hooks/before_all_test.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Purpose of this test is to ensure a test using before_each succeeds - */ - -import { Rhum } from "../../../mod.ts"; - -let suite_val = "Ed"; -let case_val = 22; - -Rhum.testPlan("before_all_test.ts", () => { - Rhum.beforeAll(() => { - suite_val = "Eric"; - }); - - // Run the first test suite - Rhum.testSuite("test suite 1", () => { - Rhum.beforeAll(() => { - case_val = 2; - }); - - Rhum.testCase("hooks properly set suite_val and case_val", () => { - // Asserting the value has changed - Rhum.asserts.assertEquals(suite_val, "Eric"); - // Revert it back for the next test that uses it - suite_val = "Ed"; - // Assert the value has changed from 22 to 2 - Rhum.asserts.assertEquals(case_val, 2); - case_val = 22; - }); - Rhum.testCase("hooks properly set case_val", () => { - // Assert the value has changed from 22 to 2 (after setting it to 22 in the above case) - Rhum.asserts.assertEquals(case_val, 22); - Rhum.asserts.assertEquals(suite_val, "Ed"); - }); - }); - - // Run the second test suite - Rhum.testSuite("test suite 2", () => { - Rhum.beforeAll(() => { - case_val = 0; - }); - Rhum.testCase("hooks properly set suite_val and case_val", async () => { - // Asserting the hook should have replaced the name - Rhum.asserts.assertEquals(suite_val, "Ed"); - Rhum.asserts.assertEquals(case_val, 0); - }); - }); - - Rhum.testSuite("test suite 3", () => { - let async_case_val = 5; - Rhum.beforeAll(async () => { - await new Promise((resolve) => { - setTimeout(() => resolve((async_case_val = 15)), 1000); - }); - }); - Rhum.testCase("beforeAll hook can be async", () => { - Rhum.asserts.assertEquals(suite_val, "Ed"); - Rhum.asserts.assertEquals(async_case_val, 15); - }); - }); -}); - -Rhum.run(); diff --git a/tests/integration/hooks/before_each_test.ts b/tests/integration/hooks/before_each_test.ts deleted file mode 100644 index a6b5af48..00000000 --- a/tests/integration/hooks/before_each_test.ts +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Purpose of this test is to ensure a test using before_each succeeds - */ - -import { Rhum } from "../../../mod.ts"; - -let suite_val = "Ed"; -let case_val = 22; - -Rhum.testPlan("before_each_test.ts", () => { - Rhum.beforeEach(() => { - suite_val = "Eric"; - }); - - // Run the first test suite - Rhum.testSuite("test suite 1", () => { - Rhum.beforeEach(() => { - case_val = 2; - }); - - Rhum.testCase("suite_val is Eric", () => { - Rhum.asserts.assertEquals(suite_val, "Eric"); - suite_val = "Ed"; - }); - Rhum.testCase("suite_val is Ed", () => { - Rhum.asserts.assertEquals(suite_val, "Ed"); - }); - Rhum.testCase("case_val is 2", () => { - Rhum.asserts.assertEquals(case_val, 2); - case_val = 22; - }); - Rhum.testCase("case_val is still 2", () => { - Rhum.asserts.assertEquals(case_val, 2); - }); - }); - - // Run the second test suite - Rhum.testSuite("test suite 2", () => { - Rhum.beforeEach(() => { - case_val = 0; - }); - - Rhum.testCase("suite_val is Eric", async () => { - Rhum.asserts.assertEquals(suite_val, "Eric"); - suite_val = "Ed"; - }); - Rhum.testCase("suite_val is Ed", async () => { - Rhum.asserts.assertEquals(suite_val, "Ed"); - case_val = 1; - }); - Rhum.testCase("case_val is 0", () => { - Rhum.asserts.assertEquals(case_val, 0); - }); - }); - - Rhum.testSuite("test suite 3", () => { - let async_case_val = 5; - - Rhum.beforeEach(async () => { - await new Promise((resolve) => { - setTimeout(() => resolve((async_case_val = 15)), 1000); - }); - }); - - Rhum.testCase("beforeEach hook can be async", () => { - Rhum.asserts.assertEquals(async_case_val, 15); - }); - }); -}); - -Rhum.run(); diff --git a/tests/integration/mock_test.ts b/tests/integration/mock_test.ts index cda3cb92..a0675e82 100644 --- a/tests/integration/mock_test.ts +++ b/tests/integration/mock_test.ts @@ -23,6 +23,7 @@ class TestObject { } } +De Rhum.testPlan("mock_test.ts", () => { Rhum.testSuite("mock()", () => { Rhum.testCase("can mock an object", () => { diff --git a/tests/unit/mod_test.ts b/tests/unit/mod_test.ts deleted file mode 100644 index aa38d34f..00000000 --- a/tests/unit/mod_test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { StdAsserts as asserts } from "../../deps.ts"; -import { Rhum } from "../../mod.ts"; - -// TODO(any) When this feature is properly implemented -// Deno.test({ -// name: "Unit | Rhum | SetUp() | Assigns the correct callback", -// async fn(): Promise { -// function cb () { -// return "Hello world!" -// } -// Rhum.SetUp(cb) -// asserts.assertEquals(typeof Rhum.set_up_hook, "function") -// if (Rhum.set_up_hook) { -// asserts.assertEquals(Rhum.set_up_hook(), "Hello world!") -// } else { -// throw new Error("Rhum.set_up_hook should be defined") -// } -// } -// }) - -// TODO(any) When this feature is properly implemented -// Deno.test({ -// name: "Unit | Rhum | Skip() | Correctly skips the test", -// async fn(): Promise { -// -// } -// }) - -// TODO(any) When this feature is properly implemented -// Deno.test({ -// name: "Unit | Rhum | TearDown() | Correctly tears down", -// async fn(): Promise { -// -// } -// }) - -Deno.test({ - name: "Unit | Rhum | testCase() | Runs a test without failing", - async fn(): Promise { - Rhum.testPlan("test plan", () => { - Rhum.testSuite("test suite", () => { - Rhum.testCase("Testing testCase", () => { - console.log("Running!"); - }); - }); - }); - }, -}); - -Deno.test({ - name: "Unit | Rhum | testPlan() | Registers the test plan name", - async fn(): Promise { - let functionWasCalled = false; - function testFn() { - functionWasCalled = true; - return "Hello world!"; - } - const copyTestFn = testFn; - Rhum.testPlan("Testing testCase", copyTestFn); - Rhum.asserts.assert(functionWasCalled); - }, -}); - -Deno.test({ - name: "Unit | Rhum | testSuite() | Registers the test suite name", - async fn(): Promise { - let functionWasCalled = false; - function testFn() { - functionWasCalled = true; - return "Hello world!"; - } - const copyTestFn = testFn; - Rhum.testSuite("Testing testCase", copyTestFn); - asserts.assertEquals(functionWasCalled, true); - }, -}); diff --git a/tests/unit/quick_start.ts b/tests/unit/quick_start.ts deleted file mode 100644 index 561566a8..00000000 --- a/tests/unit/quick_start.ts +++ /dev/null @@ -1,33 +0,0 @@ -// File: app_test.ts - -import { Rhum } from "../../mod.ts"; - -let value = false; - -function run() { - return true; -} - -async function close() { - value = true; - return value; -} - -Rhum.testPlan("app_test.ts", () => { - // Run the first test suite - Rhum.testSuite("run()", () => { - Rhum.testCase("Returns true", () => { - const result = run(); - Rhum.asserts.assertEquals(true, result); - }); - }); - // Run the second test suite - Rhum.testSuite("close()", () => { - Rhum.testCase("Returns true", async () => { - const result = await close(); - Rhum.asserts.assertEquals(true, result); - }); - }); -}); - -Rhum.run(); diff --git a/tests/unit/test_case_test.ts b/tests/unit/test_case_test.ts deleted file mode 100644 index f8eaecde..00000000 --- a/tests/unit/test_case_test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { StdAsserts as asserts } from "../../deps.ts"; -import { TestCase } from "../../src/test_case.ts"; -import { ITestPlan } from "../../src/interfaces.ts"; - -Deno.test({ - name: "Unit | TestCase | run() | Runs the test without failing", - async fn(): Promise { - const plan: ITestPlan = { - suites: { - "suite_1": { - cases: [{ - name: "case_1", - new_name: "123 case_1", - testFn: function () { - asserts.assertEquals(true, true); - }, - }], - }, - }, - }; - const testCase = new TestCase(plan); - await testCase.run(); - }, -}); From 38d2fd2dc7f5cf46d54254d1e3a757ef97bb6db6 Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Mon, 24 Jan 2022 23:24:43 +0000 Subject: [PATCH 02/62] add back mock builder and types --- mod.ts | 1 - src/mock_builder.ts | 164 +++++++++++++++++++++++++++++++++ src/types.ts | 18 ++++ tests/integration/mock_test.ts | 2 +- 4 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 src/mock_builder.ts create mode 100644 src/types.ts diff --git a/mod.ts b/mod.ts index e0e7eb89..461bf765 100644 --- a/mod.ts +++ b/mod.ts @@ -5,7 +5,6 @@ export type { Constructor, Stubbed } from "./src/types.ts"; export { MockBuilder } from "./src/mock_builder.ts"; export class RhumRunner { - // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// /** diff --git a/src/mock_builder.ts b/src/mock_builder.ts new file mode 100644 index 00000000..3fa4a491 --- /dev/null +++ b/src/mock_builder.ts @@ -0,0 +1,164 @@ +import type { Constructor, Mocked } from "./types.ts"; + +export class MockBuilder { + /** + * Properties of the class that is passed in + */ + protected properties: string[] = []; + + /** + * Functions of the class passed in + */ + protected functions: string[] = []; + + /** + * The class object passed into the constructor + */ + protected constructor_fn: Constructor; + + /** + * A list of arguments the class constructor takes + */ + protected constructor_args: unknown[] = []; + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Construct an object of this class. + * + * @param constructorFn - The object's constructor function to instantiate. + */ + constructor(constructorFn: Constructor) { + this.constructor_fn = constructorFn; + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Create the mock object. + * + * @returns A mocked object. + */ + public create(): Mocked { + // deno-lint-ignore no-explicit-any + const mock: Mocked = { + calls: {}, + is_mock: true, + }; + const original = new this.constructor_fn(...this.constructor_args); + + // Attach all of the original's properties to the mock + this.getAllProperties(original).forEach((property: string) => { + const desc = Object.getOwnPropertyDescriptor(original, property); + mock[property] = desc!.value; + }); + + // Attach all of the original's functions to the mock + this.getAllFunctions(original).forEach((method: string) => { + const nativeMethods = [ + "__defineGetter__", + "__defineSetter__", + "__lookupGetter__", + "__lookupSetter__", + "constructor", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "toLocaleString", + "toString", + "valueOf", + ]; + + if (nativeMethods.indexOf(method) == -1) { + if (!mock.calls[method]) { + mock.calls[method] = 0; + } + mock[method] = function () { + mock.calls[method]++; + return (original[method as keyof T] as unknown as ( + ...params: unknown[] + ) => unknown)(); + }; + } else { + // copy nativeMethod directly without mocking + mock[method] = original[method as keyof T]; + } + }); + + return mock; + } + + /** + * Before constructing the mock object, track any constructur function args + * that need to be passed in when constructing the mock object. + * + * @param args - A rest parameter of arguments that will get passed in to + * the constructor function of the class being mocked. + * + * @returns `this` so that methods in this class can be chained. + */ + public withConstructorArgs(...args: unknown[]): this { + this.constructor_args = args; + return this; + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - METHODS - PROTECTED ///////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Get all properties--public, protected, private--from the object that will + * be mocked. + * + * @param obj - The object that will be mocked. + * + * @returns An array of the object's properties. + */ + protected getAllProperties(obj: T): string[] { + let functions: string[] = []; + let clone = obj; + do { + functions = functions.concat(Object.getOwnPropertyNames(clone)); + } while ((clone = Object.getPrototypeOf(clone))); + + return functions.sort().filter( + function (e: string, i: number, arr: unknown[]) { + if ( + e != arr[i + 1] && typeof obj[e as keyof T] != "function" + ) { + return true; + } + }, + ); + } + + /** + * Get all functions--public, protected, private--from the object that will be + * mocked. + * + * @param obj - The object that will be mocked. + * + * @returns An array of the object's functions. + */ + protected getAllFunctions(obj: T): string[] { + let functions: string[] = []; + let clone = obj; + do { + functions = functions.concat(Object.getOwnPropertyNames(clone)); + } while ((clone = Object.getPrototypeOf(clone))); + + return functions.sort().filter( + function (e: string, i: number, arr: unknown[]) { + if ( + e != arr[i + 1] && typeof obj[e as keyof T] == "function" + ) { + return true; + } + }, + ); + } +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 00000000..4c6125a6 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,18 @@ +export type TConstructorFunction = { + new (...args: unknown[]): T; + [key: string]: unknown; +}; + +// deno-lint-ignore no-explicit-any +export type Constructor = new (...args: any[]) => T; + +export type Mocked = T & { + calls: { [k in keyof T]: T[k] extends () => void ? number : never }; + is_mock: true; +}; + +export type Stubbed = T & { + calls: { [k in keyof T]?: T[k] extends () => void ? number : never }; + stub: (p: string, v: unknown) => void; + is_stubbed: true; +}; diff --git a/tests/integration/mock_test.ts b/tests/integration/mock_test.ts index a0675e82..46ff2d97 100644 --- a/tests/integration/mock_test.ts +++ b/tests/integration/mock_test.ts @@ -23,7 +23,7 @@ class TestObject { } } -De +De; Rhum.testPlan("mock_test.ts", () => { Rhum.testSuite("mock()", () => { Rhum.testCase("can mock an object", () => { From cc0cc1d63a8851e623e080d0ba914047a7c18ab3 Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Mon, 24 Jan 2022 23:34:56 +0000 Subject: [PATCH 03/62] fmt --- tests/deps.ts | 2 +- tests/integration/mock_test.ts | 137 ++++++++++++++++----------------- tests/integration/stub_test.ts | 16 ++-- 3 files changed, 77 insertions(+), 78 deletions(-) diff --git a/tests/deps.ts b/tests/deps.ts index cf3c3844..906a5b56 100644 --- a/tests/deps.ts +++ b/tests/deps.ts @@ -1 +1 @@ -export { assertEquals } from "https://deno.land/std@0.116.0/testing/asserts.ts"; +export { assertEquals } from "https://deno.land/std@0.116.0/testing/asserts.ts"; diff --git a/tests/integration/mock_test.ts b/tests/integration/mock_test.ts index efcd3530..84d8d723 100644 --- a/tests/integration/mock_test.ts +++ b/tests/integration/mock_test.ts @@ -1,5 +1,5 @@ import { Rhum } from "../../mod.ts"; -import { assertEquals } from "../deps.ts" +import { assertEquals } from "../deps.ts"; class MathService { public add(num1: number, num2: number): number { @@ -24,7 +24,6 @@ class TestObject { } } - class TestRequestHandler { // deno-lint-ignore require-await async handle(request: Request): Promise { @@ -43,7 +42,7 @@ class TestRequestHandler { } } -Deno.test("mock()", t => { +Deno.test("mock()", (t) => { t.step({ name: "can mock an object", fn() { @@ -52,83 +51,83 @@ Deno.test("mock()", t => { .create(); assertEquals(mock.constructor.name, "TestObject"); assertEquals(mock.is_mock, true); - } - }) - + }, + }); + t.step("Can mock an object with constructor args", () => { const mock = Rhum - .mock(TestObject) - .withConstructorArgs("my server", new MathService()) - .create(); - assertEquals(mock.constructor.name, "TestObject"); - assertEquals(mock.is_mock, true); - assertEquals(mock.name, "my server"); - }) + .mock(TestObject) + .withConstructorArgs("my server", new MathService()) + .create(); + assertEquals(mock.constructor.name, "TestObject"); + assertEquals(mock.is_mock, true); + assertEquals(mock.name, "my server"); + }); t.step("can access protected property", () => { const mock = Rhum - .mock(TestObject) - .create(); - assertEquals( - (mock as unknown as { [key: string]: string }).protected_property, - "I AM PROTECTED PROPERTY.", - ); - }) + .mock(TestObject) + .create(); + assertEquals( + (mock as unknown as { [key: string]: string }).protected_property, + "I AM PROTECTED PROPERTY.", + ); + }); - t.step('Can access protected method', () => { + t.step("Can access protected method", () => { const mock = Rhum - .mock(TestObject) - .create(); - assertEquals( - (mock as unknown as { [key: string]: () => string }).protectedMethod(), - "I AM A PROTECTED METHOD.", - ); - }) + .mock(TestObject) + .create(); + assertEquals( + (mock as unknown as { [key: string]: () => string }).protectedMethod(), + "I AM A PROTECTED METHOD.", + ); + }); - t.step('has mocked math service', () => { + t.step("has mocked math service", () => { const mockMathService = Rhum - .mock(MathService) - .create(); - const mockTestObject = Rhum - .mock(TestObject) - .withConstructorArgs("has mocked math service", mockMathService) - .create(); - assertEquals(mockMathService.calls.add, 0); - mockTestObject.sum(1, 1); - assertEquals(mockMathService.calls.add, 1); - }) + .mock(MathService) + .create(); + const mockTestObject = Rhum + .mock(TestObject) + .withConstructorArgs("has mocked math service", mockMathService) + .create(); + assertEquals(mockMathService.calls.add, 0); + mockTestObject.sum(1, 1); + assertEquals(mockMathService.calls.add, 1); + }); - t.step('Native request mock', async () => { + t.step("Native request mock", async () => { const router = Rhum.mock(TestRequestHandler).create(); - const reqPost = new Request("https://google.com", { - method: "post", - headers: { - "content-type": "application/json", - }, - }); - assertEquals(router.calls.handle, 0); - assertEquals(await router.handle(reqPost), "posted"); - assertEquals(router.calls.handle, 1); + const reqPost = new Request("https://google.com", { + method: "post", + headers: { + "content-type": "application/json", + }, + }); + assertEquals(router.calls.handle, 0); + assertEquals(await router.handle(reqPost), "posted"); + assertEquals(router.calls.handle, 1); - const reqPostNotJson = new Request("https://google.com", { - method: "post", - }); - assertEquals(router.calls.handle, 1); - assertEquals( - await router.handle(reqPostNotJson), - "Content-Type is incorrect", - ); - assertEquals(router.calls.handle, 2); + const reqPostNotJson = new Request("https://google.com", { + method: "post", + }); + assertEquals(router.calls.handle, 1); + assertEquals( + await router.handle(reqPostNotJson), + "Content-Type is incorrect", + ); + assertEquals(router.calls.handle, 2); - const reqGet = new Request("https://google.com", { - method: "get", - }); - assertEquals(router.calls.handle, 2); - assertEquals( - await router.handle(reqGet), - "Method is not post", - ); - assertEquals(router.calls.handle, 3); - }) -}) + const reqGet = new Request("https://google.com", { + method: "get", + }); + assertEquals(router.calls.handle, 2); + assertEquals( + await router.handle(reqGet), + "Method is not post", + ); + assertEquals(router.calls.handle, 3); + }); +}); diff --git a/tests/integration/stub_test.ts b/tests/integration/stub_test.ts index ec50154e..90ac247c 100644 --- a/tests/integration/stub_test.ts +++ b/tests/integration/stub_test.ts @@ -1,5 +1,5 @@ import { Rhum } from "../../mod.ts"; -import { assertEquals } from "../deps.ts" +import { assertEquals } from "../deps.ts"; class Server { public greeting = "hello"; @@ -12,12 +12,12 @@ class Server { } } -Deno.test("stub()", t => { - t.step('Can stub a propert', () => { +Deno.test("stub()", (t) => { + t.step("Can stub a propert", () => { const server = Rhum.stubbed(new Server()); - server.stub("greeting", "you got changed"); - assertEquals(server.greeting, "you got changed"); - }) + server.stub("greeting", "you got changed"); + assertEquals(server.greeting, "you got changed"); + }); t.step("Can stub a method", () => { const server = Rhum.stubbed(new Server()); @@ -32,5 +32,5 @@ Deno.test("stub()", t => { server.is_stubbed, true, ); - }) -}) \ No newline at end of file + }); +}); From 83e749382e03c86ddc8b90cb6681926716af8de8 Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Mon, 24 Jan 2022 23:38:56 +0000 Subject: [PATCH 04/62] fix tests --- tests/integration/mock_test.ts | 14 ++++++------ tests/integration/stub_test.ts | 6 ++--- tests/unit/mock_builder_test.ts | 40 +++++++++++++++++---------------- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/tests/integration/mock_test.ts b/tests/integration/mock_test.ts index 84d8d723..492058a7 100644 --- a/tests/integration/mock_test.ts +++ b/tests/integration/mock_test.ts @@ -42,8 +42,8 @@ class TestRequestHandler { } } -Deno.test("mock()", (t) => { - t.step({ +Deno.test("mock()", async (t) => { + await t.step({ name: "can mock an object", fn() { const mock = Rhum @@ -54,7 +54,7 @@ Deno.test("mock()", (t) => { }, }); - t.step("Can mock an object with constructor args", () => { + await t.step("Can mock an object with constructor args", () => { const mock = Rhum .mock(TestObject) .withConstructorArgs("my server", new MathService()) @@ -64,7 +64,7 @@ Deno.test("mock()", (t) => { assertEquals(mock.name, "my server"); }); - t.step("can access protected property", () => { + await t.step("can access protected property", () => { const mock = Rhum .mock(TestObject) .create(); @@ -74,7 +74,7 @@ Deno.test("mock()", (t) => { ); }); - t.step("Can access protected method", () => { + await t.step("Can access protected method", () => { const mock = Rhum .mock(TestObject) .create(); @@ -84,7 +84,7 @@ Deno.test("mock()", (t) => { ); }); - t.step("has mocked math service", () => { + await t.step("has mocked math service", () => { const mockMathService = Rhum .mock(MathService) .create(); @@ -97,7 +97,7 @@ Deno.test("mock()", (t) => { assertEquals(mockMathService.calls.add, 1); }); - t.step("Native request mock", async () => { + await t.step("Native request mock", async () => { const router = Rhum.mock(TestRequestHandler).create(); const reqPost = new Request("https://google.com", { diff --git a/tests/integration/stub_test.ts b/tests/integration/stub_test.ts index 90ac247c..9aeaf5aa 100644 --- a/tests/integration/stub_test.ts +++ b/tests/integration/stub_test.ts @@ -12,14 +12,14 @@ class Server { } } -Deno.test("stub()", (t) => { - t.step("Can stub a propert", () => { +Deno.test("stub()", async (t) => { + await t.step("Can stub a propert", () => { const server = Rhum.stubbed(new Server()); server.stub("greeting", "you got changed"); assertEquals(server.greeting, "you got changed"); }); - t.step("Can stub a method", () => { + await t.step("Can stub a method", () => { const server = Rhum.stubbed(new Server()); server.stub("methodThatLogs", () => { return "don't run the console.log()"; diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index cf1d81d8..68fce244 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -1,31 +1,33 @@ -import { StdAsserts as asserts } from "../../deps.ts"; +import { assertEquals } from "../deps.ts"; import { MockBuilder } from "../../src/mock_builder.ts"; Deno.test({ name: "Unit | MockBuilder | constructor() | returns a MockBuilder object", fn(): void { const mock = new MockBuilder(TestObjectOne); - asserts.assertEquals(mock.constructor.name, "MockBuilder"); + assertEquals(mock.constructor.name, "MockBuilder"); }, }); -Deno.test({ - name: "Unit | MockBuilder | create() | creates mock without constructor args", - fn(): void { - const mock = new MockBuilder(TestObjectTwo) - .create(); - asserts.assertEquals(mock.name, undefined); - }, -}); - -Deno.test({ - name: "Unit | MockBuilder | create() | creates mock with constructor args", - fn(): void { - const mock = new MockBuilder(TestObjectTwo) - .withConstructorArgs("some name") - .create(); - asserts.assertEquals(mock.name, "some name"); - }, +Deno.test("create()", async (t) => { + await t.step({ + name: "create() | creates mock without constructor args", + fn(): void { + const mock = new MockBuilder(TestObjectTwo) + .create(); + assertEquals(mock.name, undefined); + }, + }); + + await t.step({ + name: "Unit | MockBuilder | create() | creates mock with constructor args", + fn(): void { + const mock = new MockBuilder(TestObjectTwo) + .withConstructorArgs("some name") + .create(); + assertEquals(mock.name, "some name"); + }, + }); }); // TODO(crookse) Write this test when we can invoke non-public members. From 809b168aa9f84b1aa222e636b723b8082483e438 Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Mon, 24 Jan 2022 23:39:53 +0000 Subject: [PATCH 05/62] tpo --- egg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/egg.json b/egg.json index b3578378..08dce5ea 100644 --- a/egg.json +++ b/egg.json @@ -1,6 +1,6 @@ { "name": "rhum", - "description": "A test double mdoule to stub and mock your code.", + "description": "A test double module to stub and mock your code.", "version": "1.1.11", "stable": true, "repository": "https://github.com/drashland/rhum", From ee9f820643d02e76a416961a815b5a5509db20fd Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Sat, 9 Apr 2022 14:46:52 +0100 Subject: [PATCH 06/62] use mock and stub --- mod.ts | 117 +++++++++++++++------------------ src/mock_builder.ts | 2 +- tests/integration/mock_test.ts | 35 ++++------ tests/integration/stub_test.ts | 6 +- 4 files changed, 70 insertions(+), 90 deletions(-) diff --git a/mod.ts b/mod.ts index 461bf765..3ee3ac39 100644 --- a/mod.ts +++ b/mod.ts @@ -4,71 +4,60 @@ import { MockBuilder } from "./src/mock_builder.ts"; export type { Constructor, Stubbed } from "./src/types.ts"; export { MockBuilder } from "./src/mock_builder.ts"; -export class RhumRunner { - // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// - - /** - * Stub a member of an object. - * - * @param obj -The object containing the member to stub. - * @param member -The member to stub. - * @param value - The return value of the stubbed member. - * - * Returns the object in question as a Stubbed type. Being a Stubbed type - * means it has access to a `.stub()` method for stubbing properties and - * methods. - * - * class MyObject { - * public some_property = "someValue"; - * } - * - * // Define the object that will have stubbed members as a stubbed object - * const myStubbedObject = Rhum.stubbed(new MyObject()); - * - * // Stub the object's some_property property to a certain value - * myStubbedObject.stub("some_property", "this property is now stubbed"); - * - * // Assert that the property was stubbed - * Rhum.asserts.assertEquals(myStubbedObject.some_property, "this property is now stubbed"); - */ - public stubbed(obj: T): Stubbed { - (obj as unknown as { [key: string]: boolean }).is_stubbed = true; - (obj as unknown as { - [key: string]: (property: string, value: unknown) => void; - }).stub = function ( - property: string, - value: unknown, - ): void { - Object.defineProperty(obj, property, { - value: value, - }); - }; - - return obj as Stubbed; - } - - /** - * Get the mock builder to mock classes. - * - * @param constructorFn - The constructor function of the object to mock. - * - * Returns an instance of the MockBuilder class. - * - * class ToBeMocked { ... } - * - * const mock = Rhum - * .mock(ToBeMocked) - * .withConstructorArgs("someArg") // if the class to be mocked has a constructor and it requires args - * .create(); - */ - public mock(constructorFn: Constructor): MockBuilder { - return new MockBuilder(constructorFn); - } -} +/** + * Get the mock builder to mock classes. + * + * @param constructorFn - The constructor function of the object to mock. + * + * Returns an instance of the MockBuilder class. + * + * class ToBeMocked { ... } + * + * const mock = Rhum + * .mock(ToBeMocked) + * .withConstructorArgs("someArg") // if the class to be mocked has a constructor and it requires args + * .create(); + */ +export const Mock = (constructorFn: Constructor): MockBuilder => { + return new MockBuilder(constructorFn); +}; /** - * An instance of the RhumRunner. + * Stub a member of an object. + * + * @param obj -The object containing the member to stub. + * @param member -The member to stub. + * @param value - The return value of the stubbed member. + * + * Returns the object in question as a Stubbed type. Being a Stubbed type + * means it has access to a `.stub()` method for stubbing properties and + * methods. + * + * class MyObject { + * public some_property = "someValue"; + * } * - * const Rhum = new RhumRunner(); + * // Define the object that will have stubbed members as a stubbed object + * const myStubbedObject = Rhum.stubbed(new MyObject()); + * + * // Stub the object's some_property property to a certain value + * myStubbedObject.stub("some_property", "this property is now stubbed"); + * + * // Assert that the property was stubbed + * Rhum.asserts.assertEquals(myStubbedObject.some_property, "this property is now stubbed"); */ -export const Rhum = new RhumRunner(); +export const Stub = (obj: T): Stubbed => { + (obj as unknown as { [key: string]: boolean }).is_stubbed = true; + (obj as unknown as { + [key: string]: (property: string, value: unknown) => void; + }).stub = function ( + property: string, + value: unknown, + ): void { + Object.defineProperty(obj, property, { + value: value, + }); + }; + + return obj as Stubbed; +}; diff --git a/src/mock_builder.ts b/src/mock_builder.ts index bcc8db8f..174d8ac8 100644 --- a/src/mock_builder.ts +++ b/src/mock_builder.ts @@ -86,7 +86,7 @@ export class MockBuilder { mock.calls[method]++; // Make sure the method calls its original self - let unbound = (original[method as keyof T] as unknown as ( + const unbound = (original[method as keyof T] as unknown as ( ...params: unknown[] ) => unknown); diff --git a/tests/integration/mock_test.ts b/tests/integration/mock_test.ts index ff327831..3ca57de9 100644 --- a/tests/integration/mock_test.ts +++ b/tests/integration/mock_test.ts @@ -1,11 +1,11 @@ -import { Rhum } from "../../mod.ts"; +import { Mock } from "../../mod.ts"; import { assertEquals } from "../deps.ts"; class MathService { public add( num1: number, num2: number, - useNestedAdd: boolean = false, + useNestedAdd = false, ): number { if (useNestedAdd) { return this.nestedAdd(num1, num2); @@ -30,7 +30,7 @@ class TestObject { public sum( num1: number, num2: number, - useNestedAdd: boolean = false, + useNestedAdd = false, ): number { const sum = this.math_service.add(num1, num2, useNestedAdd); return sum; @@ -70,8 +70,7 @@ Deno.test("mock()", async (t) => { await t.step({ name: "can mock an object", fn() { - const mock = Rhum - .mock(TestObject) + const mock = Mock(TestObject) .create(); assertEquals(mock.constructor.name, "TestObject"); assertEquals(mock.is_mock, true); @@ -79,8 +78,7 @@ Deno.test("mock()", async (t) => { }); await t.step("Can mock an object with constructor args", () => { - const mock = Rhum - .mock(TestObject) + const mock = Mock(TestObject) .withConstructorArgs("my server", new MathService()) .create(); assertEquals(mock.constructor.name, "TestObject"); @@ -89,8 +87,7 @@ Deno.test("mock()", async (t) => { }); await t.step("can access protected property", () => { - const mock = Rhum - .mock(TestObject) + const mock = Mock(TestObject) .create(); assertEquals( (mock as unknown as { [key: string]: string }).protected_property, @@ -99,8 +96,7 @@ Deno.test("mock()", async (t) => { }); await t.step("Can access protected method", () => { - const mock = Rhum - .mock(TestObject) + const mock = Mock(TestObject) .create(); assertEquals( (mock as unknown as { [key: string]: () => string }).protectedMethod(), @@ -109,11 +105,9 @@ Deno.test("mock()", async (t) => { }); await t.step("has mocked math service", () => { - const mockMathService = Rhum - .mock(MathService) + const mockMathService = Mock(MathService) .create(); - const mockTestObject = Rhum - .mock(TestObject) + const mockTestObject = Mock(TestObject) .withConstructorArgs("has mocked math service", mockMathService) .create(); assertEquals(mockMathService.calls.add, 0); @@ -122,11 +116,9 @@ Deno.test("mock()", async (t) => { }); await t.step("call count for outside nested function is increased", () => { - const mockMathService = Rhum - .mock(MathService) + const mockMathService = Mock(MathService) .create(); - const mockTestObject = Rhum - .mock(TestObject) + const mockTestObject = Mock(TestObject) .withConstructorArgs("has mocked math service", mockMathService) .create(); assertEquals(mockMathService.calls.add, 0); @@ -137,15 +129,14 @@ Deno.test("mock()", async (t) => { }); await t.step("can mock getters and setters", () => { - const mock = Rhum - .mock(TestObject) + const mock = Mock(TestObject) .create(); mock.age = 999; assertEquals(mock.age, 999); }); await t.step("Native request mock", async () => { - const router = Rhum.mock(TestRequestHandler).create(); + const router = Mock(TestRequestHandler).create(); const reqPost = new Request("https://google.com", { method: "post", diff --git a/tests/integration/stub_test.ts b/tests/integration/stub_test.ts index 9aeaf5aa..e19dff0b 100644 --- a/tests/integration/stub_test.ts +++ b/tests/integration/stub_test.ts @@ -1,4 +1,4 @@ -import { Rhum } from "../../mod.ts"; +import { Stub } from "../../mod.ts"; import { assertEquals } from "../deps.ts"; class Server { @@ -14,13 +14,13 @@ class Server { Deno.test("stub()", async (t) => { await t.step("Can stub a propert", () => { - const server = Rhum.stubbed(new Server()); + const server = Stub(new Server()); server.stub("greeting", "you got changed"); assertEquals(server.greeting, "you got changed"); }); await t.step("Can stub a method", () => { - const server = Rhum.stubbed(new Server()); + const server = Stub(new Server()); server.stub("methodThatLogs", () => { return "don't run the console.log()"; }); From 289c455c79b2768e0fa8adb599894c6a5ab32673 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sun, 10 Apr 2022 12:08:05 -0400 Subject: [PATCH 07/62] feat(mock): add mock.method(...).willReturn(...); --- mod.ts | 28 +--- src/mock.ts | 89 +++++++++++ src/mock_builder.ts | 252 ++++++++++++++++++++++---------- src/pre_programmed_method.ts | 51 +++++++ src/types.ts | 17 +-- tests/deps.ts | 5 +- tests/unit/mock_builder_test.ts | 145 +++++++++++++----- 7 files changed, 433 insertions(+), 154 deletions(-) create mode 100644 src/mock.ts create mode 100644 src/pre_programmed_method.ts diff --git a/mod.ts b/mod.ts index 3ee3ac39..b04125a1 100644 --- a/mod.ts +++ b/mod.ts @@ -5,18 +5,11 @@ export type { Constructor, Stubbed } from "./src/types.ts"; export { MockBuilder } from "./src/mock_builder.ts"; /** - * Get the mock builder to mock classes. + * Get the builder to help you create mocked objects. * * @param constructorFn - The constructor function of the object to mock. * - * Returns an instance of the MockBuilder class. - * - * class ToBeMocked { ... } - * - * const mock = Rhum - * .mock(ToBeMocked) - * .withConstructorArgs("someArg") // if the class to be mocked has a constructor and it requires args - * .create(); + * @returns Instance of `MockBuilder`. */ export const Mock = (constructorFn: Constructor): MockBuilder => { return new MockBuilder(constructorFn); @@ -28,23 +21,6 @@ export const Mock = (constructorFn: Constructor): MockBuilder => { * @param obj -The object containing the member to stub. * @param member -The member to stub. * @param value - The return value of the stubbed member. - * - * Returns the object in question as a Stubbed type. Being a Stubbed type - * means it has access to a `.stub()` method for stubbing properties and - * methods. - * - * class MyObject { - * public some_property = "someValue"; - * } - * - * // Define the object that will have stubbed members as a stubbed object - * const myStubbedObject = Rhum.stubbed(new MyObject()); - * - * // Stub the object's some_property property to a certain value - * myStubbedObject.stub("some_property", "this property is now stubbed"); - * - * // Assert that the property was stubbed - * Rhum.asserts.assertEquals(myStubbedObject.some_property, "this property is now stubbed"); */ export const Stub = (obj: T): Stubbed => { (obj as unknown as { [key: string]: boolean }).is_stubbed = true; diff --git a/src/mock.ts b/src/mock.ts new file mode 100644 index 00000000..362fbe08 --- /dev/null +++ b/src/mock.ts @@ -0,0 +1,89 @@ +import type { MethodCalls, MethodOf } from "./types.ts"; +import { PreProgrammedMethod } from "./pre_programmed_method.ts"; + +class MockError extends Error {} + +/** + * Class to mock an object. This class is the original object with data members + * that can be used for verifying behavior (e.g., using `mock.calls.someMethod` + * to see how many `someMethod` was called). + */ +export class Mock { + readonly #calls: MethodCalls; + is_mock = true; + #original: OriginalObject; + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * @param original - The original object to mock. + * @param methodsToTrack - The original object's method to make trackable. + */ + constructor(original: OriginalObject, methodsToTrack: string[]) { + this.#original = original; + this.#calls = this.#constructCallsProperty(methodsToTrack); + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - GETTERS / SETTERS /////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + get calls(): MethodCalls { + return this.#calls; + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Pre-program a method on the original to return a specific value. + * @param methodName The method name on the original. + * @returns A pre-programmed method that will be called instead of original. + */ + public method( + methodName: MethodOf, + ): PreProgrammedMethod { + const methodConfiguration = new PreProgrammedMethod< + OriginalObject, + MethodReturnValue + >( + methodName, + ); + + if (!((methodName as string) in this.#original)) { + throw new MockError( + `Method "${methodName}" does not exist.`, + ); + } + + Object.defineProperty(this.#original, methodName, { + value: methodConfiguration, + writable: true, + }); + + return methodConfiguration; + } + + /** + * Construct the calls property. Only construct it, do not set it. The + * constructor will set it. + * @param methodsToTrack - All of the methods on the original object to make + * trackable. + * @returns - Key-value object where the key is the method name and the value + * is the number of calls. All calls start at 0. + */ + #constructCallsProperty( + methodsToTrack: string[], + ): Record { + const calls: Partial> = {}; + + methodsToTrack.map((key: string) => { + calls[key as keyof OriginalObject] = 0; + }); + + return calls as Record; + } +} diff --git a/src/mock_builder.ts b/src/mock_builder.ts index 174d8ac8..2b69de0b 100644 --- a/src/mock_builder.ts +++ b/src/mock_builder.ts @@ -1,25 +1,23 @@ -import type { Constructor, Mocked } from "./types.ts"; - -export class MockBuilder { - /** - * Properties of the class that is passed in - */ - protected properties: string[] = []; - - /** - * Functions of the class passed in - */ - protected functions: string[] = []; +import type { Constructor } from "./types.ts"; +import { Mock } from "./mock.ts"; +import { PreProgrammedMethod } from "./pre_programmed_method.ts"; +/** + * Builder to help build a mock object. This does all of the heavy-lifting to + * create a mock object. Its `create()` method returns an instance of `Mock`, + * which is basically an original object with added data members for verifying + * behavior. + */ +export class MockBuilder { /** * The class object passed into the constructor */ - protected constructor_fn: Constructor; + #constructor_fn: Constructor; /** * A list of arguments the class constructor takes */ - protected constructor_args: unknown[] = []; + #constructor_args: unknown[] = []; ////////////////////////////////////////////////////////////////////////////// // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// @@ -28,10 +26,10 @@ export class MockBuilder { /** * Construct an object of this class. * - * @param constructorFn - The object's constructor function to instantiate. + * @param constructorFn - The constructor function of the object to mock. */ - constructor(constructorFn: Constructor) { - this.constructor_fn = constructorFn; + constructor(constructorFn: Constructor) { + this.#constructor_fn = constructorFn; } ////////////////////////////////////////////////////////////////////////////// @@ -41,88 +39,182 @@ export class MockBuilder { /** * Create the mock object. * - * @returns A mocked object. + * @returns The original object with capabilities from the Mock class. */ - public create(): Mocked { - // deno-lint-ignore no-explicit-any - const mock: Mocked = { - calls: {}, - is_mock: true, - }; - const original = new this.constructor_fn(...this.constructor_args); + public create(): ClassToMock & Mock { + const original = new this.#constructor_fn(...this.#constructor_args); + + const mock = new Mock( + original, + this.#getAllFunctionNames(original), + ); // Attach all of the original's properties to the mock - this.getAllProperties(original).forEach((property: string) => { - const desc = Object.getOwnPropertyDescriptor(original, property) ?? - Object.getOwnPropertyDescriptor( - this.constructor_fn.prototype, - property, - ); - mock[property] = desc!.value; + this.#getAllPropertyNames(original).forEach((property: string) => { + this.#addOriginalObjectPropertyToMockObject(original, mock, property); }); // Attach all of the original's functions to the mock - this.getAllFunctions(original).forEach((method: string) => { - const nativeMethods = [ - "__defineGetter__", - "__defineSetter__", - "__lookupGetter__", - "__lookupSetter__", - "constructor", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "toLocaleString", - "toString", - "valueOf", - ]; - - if (nativeMethods.indexOf(method) == -1) { - if (!mock.calls[method]) { - mock.calls[method] = 0; - } - mock[method] = function (...args: unknown[]) { - // Add tracking - mock.calls[method]++; - - // Make sure the method calls its original self - const unbound = (original[method as keyof T] as unknown as ( - ...params: unknown[] - ) => unknown); - - // When method calls its original self, let `this` be the mock. Reason - // being the mock has tracking and the original does not. - const bound = unbound.bind(mock); - - return bound(...args); - }; - } else { - // copy nativeMethod directly without mocking - mock[method] = original[method as keyof T]; - } + this.#getAllFunctionNames(original).forEach((method: string) => { + this.#addOriginalObjectMethodToMockObject( + original, + mock, + method, + ); }); - return mock; + return mock as ClassToMock & Mock; } /** - * Before constructing the mock object, track any constructur function args + * Before constructing the mock object, track any constructor function args * that need to be passed in when constructing the mock object. * - * @param args - A rest parameter of arguments that will get passed in to - * the constructor function of the class being mocked. + * @param args - A rest parameter of arguments that will get passed in to the + * constructor function of the object being mocked. * * @returns `this` so that methods in this class can be chained. */ public withConstructorArgs(...args: unknown[]): this { - this.constructor_args = args; + this.#constructor_args = args; return this; } ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - METHODS - PROTECTED ///////////////////////////////////////// + // FILE MARKER - METHODS - PRIVATE /////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// + /** + * Add an original object's method to a mock object without doing anything + * else. + * + * @param original - The original object containing the method to mock. + * @param mock - The mock object receiving the method to mock. + * @param method - The name of the method to mock -- callable via + * `mock[method](...)`. + */ + #addMethodToMockObject( + original: ClassToMock, + mock: Mock, + method: string, + ): void { + Object.defineProperty(mock, method, { + value: original[method as keyof ClassToMock], + }); + } + + /** + * Add an original object's method to a mock object -- determining whether the + * method should or should not be trackable. + * + * @param original - The original object containing the method to add. + * @param mock - The mock object receiving the method. + * @param method - The name of the method to mock -- callable via + * `mock[method](...)`. + */ + #addOriginalObjectMethodToMockObject( + original: ClassToMock, + mock: Mock, + method: string, + ): void { + const nativeMethods = [ + "__defineGetter__", + "__defineSetter__", + "__lookupGetter__", + "__lookupSetter__", + "constructor", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "toLocaleString", + "toString", + "valueOf", + ]; + + // If this is a native method, then do not do anything fancy. Just add it to + // the mock. + if (nativeMethods.includes(method as string)) { + return this.#addMethodToMockObject( + original, + mock, + method, + ); + } + + // Otherwise, make the method trackable via `.calls` usage. + this.#addTrackableMethodToMockObject( + original, + mock, + method as keyof ClassToMock, + ); + } + + /** + * Add an original object's property to a mock object. + * + * @param original The original object containing the property. + * @param mock The mock object receiving the property. + * @param property The name of the property -- retrievable via + * `mock[property]`. + */ + #addOriginalObjectPropertyToMockObject( + original: ClassToMock, + mock: Mock, + property: string, + ): void { + const desc = Object.getOwnPropertyDescriptor(original, property) ?? + Object.getOwnPropertyDescriptor( + this.#constructor_fn.prototype, + property, + ); + + Object.defineProperty(mock, property, { + value: desc!.value, + writable: true, // Make writable because getters/setters can be mocked + }); + } + + /** + * Add a trackable method to a mock object. A trackable method is one that can + * be verified using `mock.calls[someMethod]`. + * + * @param original - The original object containing the method to add. + * @param mock - The mock object receiving the method. + * @param method - The name of the method. + */ + #addTrackableMethodToMockObject( + original: ClassToMock, + mock: Mock, + method: keyof ClassToMock, + ): void { + Object.defineProperty(mock, method, { + value: (...args: unknown[]) => { + // Track that this method was called + mock.calls[method]++; + + // Make sure the method calls its original self + const methodToCall = + (original[method as keyof ClassToMock] as unknown as ( + ...params: unknown[] + ) => unknown); + + // We need to check if the method was pre-preprogrammed to return + // something. If it was, then we make sure that this method we are + // currently defining returns that pre-programmed value. + if (methodToCall instanceof PreProgrammedMethod) { + return methodToCall.return_value; + } + + // When method calls its original self, let the `this` context of the + // original be the mock. Reason being the mock has tracking and the + // original does not. + const bound = methodToCall.bind(mock); + + return bound(...args); + }, + }); + } + /** * Get all properties--public, protected, private--from the object that will * be mocked. @@ -131,7 +223,7 @@ export class MockBuilder { * * @returns An array of the object's properties. */ - protected getAllProperties(obj: T): string[] { + #getAllPropertyNames(obj: ClassToMock): string[] { let functions: string[] = []; let clone = obj; do { @@ -141,7 +233,7 @@ export class MockBuilder { return functions.sort().filter( function (e: string, i: number, arr: unknown[]) { if ( - e != arr[i + 1] && typeof obj[e as keyof T] != "function" + e != arr[i + 1] && typeof obj[e as keyof ClassToMock] != "function" ) { return true; } @@ -157,7 +249,7 @@ export class MockBuilder { * * @returns An array of the object's functions. */ - protected getAllFunctions(obj: T): string[] { + #getAllFunctionNames(obj: ClassToMock): string[] { let functions: string[] = []; let clone = obj; do { @@ -167,7 +259,7 @@ export class MockBuilder { return functions.sort().filter( function (e: string, i: number, arr: unknown[]) { if ( - e != arr[i + 1] && typeof obj[e as keyof T] == "function" + e != arr[i + 1] && typeof obj[e as keyof ClassToMock] == "function" ) { return true; } diff --git a/src/pre_programmed_method.ts b/src/pre_programmed_method.ts new file mode 100644 index 00000000..b55a1de4 --- /dev/null +++ b/src/pre_programmed_method.ts @@ -0,0 +1,51 @@ +import type { MethodOf } from "./types.ts"; + +class PreProgrammedMethodError extends Error {} + +/** + * Class that allows to be a "stand-in" for a method. For example, when used in a mock object, the mock object can replace methods with pre-programmed methods (using this class), and have a system under test use the pre-programmed methods. + */ +export class PreProgrammedMethod { + #method_name: MethodOf; + #return_value?: MethodReturnValue; + public is_pre_programmed = true; + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * @param methodName - The name of the method to program. Must be a method of + * the original object in question. + */ + constructor(methodName: MethodOf) { + this.#method_name = methodName; + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - GETTERS / SETTERS ////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + get return_value(): MethodReturnValue { + if (this.#return_value === undefined) { + throw new PreProgrammedMethodError( + `Pre-programmed method "${this.#method_name}" does not have a return value.`, + ); + } + + return this.#return_value; + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - METHODS - PUBLIC /////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Pre-program this method to return the given value. + * @param returnValue The value that should be returned when this object is + * being used in place of an original method. + */ + public willReturn(returnValue: MethodReturnValue): void { + this.#return_value = returnValue; + } +} diff --git a/src/types.ts b/src/types.ts index 4c6125a6..0bd77f1d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,18 +1,17 @@ -export type TConstructorFunction = { - new (...args: unknown[]): T; - [key: string]: unknown; -}; - // deno-lint-ignore no-explicit-any export type Constructor = new (...args: any[]) => T; -export type Mocked = T & { - calls: { [k in keyof T]: T[k] extends () => void ? number : never }; - is_mock: true; -}; +export type MockedObject = { [k: string]: unknown }; export type Stubbed = T & { calls: { [k in keyof T]?: T[k] extends () => void ? number : never }; stub: (p: string, v: unknown) => void; is_stubbed: true; }; + +export type MethodCalls = Record; + +export type MethodOf = { + [K in keyof Object]: Object[K] extends (...args: unknown[]) => unknown ? K + : never; +}[keyof Object]; diff --git a/tests/deps.ts b/tests/deps.ts index 906a5b56..28112501 100644 --- a/tests/deps.ts +++ b/tests/deps.ts @@ -1 +1,4 @@ -export { assertEquals } from "https://deno.land/std@0.116.0/testing/asserts.ts"; +export { + assertEquals, + assertThrows, +} from "https://deno.land/std@0.134.0/testing/asserts.ts"; diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index 68fce244..4b299dbc 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -1,48 +1,105 @@ -import { assertEquals } from "../deps.ts"; +import { assertEquals, assertThrows } from "../deps.ts"; import { MockBuilder } from "../../src/mock_builder.ts"; -Deno.test({ - name: "Unit | MockBuilder | constructor() | returns a MockBuilder object", - fn(): void { - const mock = new MockBuilder(TestObjectOne); - assertEquals(mock.constructor.name, "MockBuilder"); - }, -}); +Deno.test("MockBuilder", async (t) => { + await t.step("create()", async (t) => { + await t.step({ + name: "creates mock builder", + fn(): void { + const mock = new MockBuilder(TestObjectOne); + assertEquals(mock.constructor.name, "MockBuilder"); + }, + }); -Deno.test("create()", async (t) => { - await t.step({ - name: "create() | creates mock without constructor args", - fn(): void { - const mock = new MockBuilder(TestObjectTwo) - .create(); - assertEquals(mock.name, undefined); - }, - }); + await t.step({ + name: "creates mock without constructor args", + fn(): void { + const mock = new MockBuilder(TestObjectTwo) + .create(); + assertEquals(mock.name, undefined); + assertEquals(mock.is_mock, true); + }, + }); - await t.step({ - name: "Unit | MockBuilder | create() | creates mock with constructor args", - fn(): void { - const mock = new MockBuilder(TestObjectTwo) - .withConstructorArgs("some name") - .create(); - assertEquals(mock.name, "some name"); - }, + await t.step({ + name: "creates mock with constructor args", + fn(): void { + const mock = new MockBuilder(TestObjectTwo) + .withConstructorArgs("some name") + .create(); + assertEquals(mock.name, "some name"); + assertEquals(mock.is_mock, true); + }, + }); }); -}); -// TODO(crookse) Write this test when we can invoke non-public members. -// Deno.test({ -// name: "Unit | MockBuilder | getAllProperties() | gets all properties", -// fn(): void { -// }, -// }); + await t.step("method()", async (t) => { + await t.step({ + name: "allows pre-programming a method", + fn(): void { + const mock = new MockBuilder(WillReturnObjectOne).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Change original to return "Hello" + mock.method("test").willReturn("Hello"); + + // Should output "Hello" and make the following calls + assertEquals(mock.test(), "Hello"); + assertEquals(mock.calls.test, 2); + assertEquals(mock.calls.hello, 2); + }, + }); + + await t.step({ + name: "allows pre-programming a method more than once", + fn(): void { + const mock = new MockBuilder(WillReturnObjectOne).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Change original to return "Hello" + mock.method("test").willReturn("Hello"); + mock.method("test").willReturn("Hello!"); + + // Should output "Hello" and make the following calls + assertEquals(mock.test(), "Hello!"); + assertEquals(mock.calls.test, 2); + assertEquals(mock.calls.hello, 2); + }, + }); -// TODO(crookse) Write this test when we can invoke non-public members. -// Deno.test({ -// name: "Unit | MockBuilder | getAllFunctions() | gets all functions", -// fn(): void { -// }, -// }); + await t.step({ + name: "causes an error to be thrown if no return value is provided", + fn(): void { + const mock = new MockBuilder(WillReturnObjectOne).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Don't fully pre-program the method. This should cause an error during assertions. + mock.method("test"); + + // Should output "Hello" and make the following calls + try { + mock.test(); + } catch (error) { + assertEquals( + error.message, + `Pre-programmed method "test" does not have a return value.`, + ); + } + assertEquals(mock.calls.test, 2); + assertEquals(mock.calls.hello, 2); + }, + }); + }); +}); // FILE MARKER - DATA ////////////////////////////////////////////////////////// @@ -55,3 +112,15 @@ class TestObjectTwo { this.name = name; } } + +class WillReturnObjectOne { + public hello(): void { + return; + } + + public test(): string { + this.hello(); + this.hello(); + return "World"; + } +} From caf0ea8ca34704ee19d8cbe42db4c0cf427568aa Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 09:42:33 -0400 Subject: [PATCH 08/62] chore: cleaning up --- mod.ts | 2 -- src/interfaces.ts | 4 ++++ src/mock.ts | 8 ++++---- src/mock_builder.ts | 5 +++-- 4 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 src/interfaces.ts diff --git a/mod.ts b/mod.ts index b04125a1..81826663 100644 --- a/mod.ts +++ b/mod.ts @@ -19,8 +19,6 @@ export const Mock = (constructorFn: Constructor): MockBuilder => { * Stub a member of an object. * * @param obj -The object containing the member to stub. - * @param member -The member to stub. - * @param value - The return value of the stubbed member. */ export const Stub = (obj: T): Stubbed => { (obj as unknown as { [key: string]: boolean }).is_stubbed = true; diff --git a/src/interfaces.ts b/src/interfaces.ts new file mode 100644 index 00000000..626ee986 --- /dev/null +++ b/src/interfaces.ts @@ -0,0 +1,4 @@ +export interface IError { + name: string; + message?: string; +} \ No newline at end of file diff --git a/src/mock.ts b/src/mock.ts index 362fbe08..cf42caac 100644 --- a/src/mock.ts +++ b/src/mock.ts @@ -43,14 +43,14 @@ export class Mock { * @param methodName The method name on the original. * @returns A pre-programmed method that will be called instead of original. */ - public method( + public method( methodName: MethodOf, - ): PreProgrammedMethod { + ): PreProgrammedMethod { const methodConfiguration = new PreProgrammedMethod< OriginalObject, - MethodReturnValue + ReturnValueType >( - methodName, + methodName ); if (!((methodName as string) in this.#original)) { diff --git a/src/mock_builder.ts b/src/mock_builder.ts index 2b69de0b..f8394229 100644 --- a/src/mock_builder.ts +++ b/src/mock_builder.ts @@ -170,7 +170,7 @@ export class MockBuilder { Object.defineProperty(mock, property, { value: desc!.value, - writable: true, // Make writable because getters/setters can be mocked + writable: true, // Make writable because getters/setters can be configured }); } @@ -210,8 +210,9 @@ export class MockBuilder { // original does not. const bound = methodToCall.bind(mock); + // Use `return` because the original function could return a value return bound(...args); - }, + } }); } From 62fed942495a1251edc302db42ce63547d729c63 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 09:43:41 -0400 Subject: [PATCH 09/62] feat: add mock.method(...).willThrow(...) --- src/mock_builder.ts | 5 +++- src/pre_programmed_method.ts | 48 ++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/mock_builder.ts b/src/mock_builder.ts index f8394229..a18ac719 100644 --- a/src/mock_builder.ts +++ b/src/mock_builder.ts @@ -202,7 +202,10 @@ export class MockBuilder { // something. If it was, then we make sure that this method we are // currently defining returns that pre-programmed value. if (methodToCall instanceof PreProgrammedMethod) { - return methodToCall.return_value; + if (methodToCall.will_throw) { + throw methodToCall.error + } + return methodToCall.return; } // When method calls its original self, let the `this` context of the diff --git a/src/pre_programmed_method.ts b/src/pre_programmed_method.ts index b55a1de4..0da1d5fd 100644 --- a/src/pre_programmed_method.ts +++ b/src/pre_programmed_method.ts @@ -1,14 +1,17 @@ import type { MethodOf } from "./types.ts"; +import type { IError } from "./interfaces.ts"; class PreProgrammedMethodError extends Error {} /** * Class that allows to be a "stand-in" for a method. For example, when used in a mock object, the mock object can replace methods with pre-programmed methods (using this class), and have a system under test use the pre-programmed methods. */ -export class PreProgrammedMethod { +export class PreProgrammedMethod { #method_name: MethodOf; - #return_value?: MethodReturnValue; - public is_pre_programmed = true; + #will_throw = false; + #will_return = false; + #return?: ReturnValue; + #error?: IError; ////////////////////////////////////////////////////////////////////////////// // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// @@ -26,14 +29,37 @@ export class PreProgrammedMethod { // FILE MARKER - GETTERS / SETTERS ////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// - get return_value(): MethodReturnValue { - if (this.#return_value === undefined) { + get error(): void { + if (!this.#will_throw) { + throw new PreProgrammedMethodError( + `Pre-programmed method "${this.#method_name}" is not set up to throw an error.`, + ); + } + if (this.#error === undefined) { + throw new PreProgrammedMethodError( + `Pre-programmed method "${this.#method_name}" is set up to throw an error, but no error was provided.`, + ); + } + + throw this.#error; + } + + get return(): ReturnValue { + if (this.#return === undefined) { throw new PreProgrammedMethodError( `Pre-programmed method "${this.#method_name}" does not have a return value.`, ); } - return this.#return_value; + return this.#return; + } + + get will_return(): boolean { + return this.#will_return; + } + + get will_throw(): boolean { + return this.#will_throw; } ////////////////////////////////////////////////////////////////////////////// @@ -45,7 +71,13 @@ export class PreProgrammedMethod { * @param returnValue The value that should be returned when this object is * being used in place of an original method. */ - public willReturn(returnValue: MethodReturnValue): void { - this.#return_value = returnValue; + public willReturn(returnValue: ReturnValue): void { + this.#will_return = true; + this.#return = returnValue; + } + + public willThrow(error: IError): void { + this.#will_throw = true; + this.#error = error; } } From fd258ac42b6be7a2bd7f2f66bbfcb4497216338f Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 10:47:15 -0400 Subject: [PATCH 10/62] test: mock.method().willThrow() and mock.method().willReturn() --- src/mock_builder.ts | 6 +- tests/unit/mock_builder_test.ts | 127 ++++++++++++++++++++++++++++++-- 2 files changed, 122 insertions(+), 11 deletions(-) diff --git a/src/mock_builder.ts b/src/mock_builder.ts index a18ac719..6f5c4c5c 100644 --- a/src/mock_builder.ts +++ b/src/mock_builder.ts @@ -220,8 +220,7 @@ export class MockBuilder { } /** - * Get all properties--public, protected, private--from the object that will - * be mocked. + * Get all properties from the original so they can be added to the mock. * * @param obj - The object that will be mocked. * @@ -246,8 +245,7 @@ export class MockBuilder { } /** - * Get all functions--public, protected, private--from the object that will be - * mocked. + * Get all functions from the original so they can be added to the mock. * * @param obj - The object that will be mocked. * diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index 4b299dbc..a9ea4c50 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -37,7 +37,7 @@ Deno.test("MockBuilder", async (t) => { await t.step({ name: "allows pre-programming a method", fn(): void { - const mock = new MockBuilder(WillReturnObjectOne).create(); + const mock = new MockBuilder(TestObjectThree).create(); assertEquals(mock.is_mock, true); // Original returns "World" @@ -56,7 +56,7 @@ Deno.test("MockBuilder", async (t) => { await t.step({ name: "allows pre-programming a method more than once", fn(): void { - const mock = new MockBuilder(WillReturnObjectOne).create(); + const mock = new MockBuilder(TestObjectThree).create(); assertEquals(mock.is_mock, true); // Original returns "World" @@ -66,7 +66,6 @@ Deno.test("MockBuilder", async (t) => { mock.method("test").willReturn("Hello"); mock.method("test").willReturn("Hello!"); - // Should output "Hello" and make the following calls assertEquals(mock.test(), "Hello!"); assertEquals(mock.calls.test, 2); assertEquals(mock.calls.hello, 2); @@ -76,7 +75,7 @@ Deno.test("MockBuilder", async (t) => { await t.step({ name: "causes an error to be thrown if no return value is provided", fn(): void { - const mock = new MockBuilder(WillReturnObjectOne).create(); + const mock = new MockBuilder(TestObjectThree).create(); assertEquals(mock.is_mock, true); // Original returns "World" @@ -85,7 +84,6 @@ Deno.test("MockBuilder", async (t) => { // Don't fully pre-program the method. This should cause an error during assertions. mock.method("test"); - // Should output "Hello" and make the following calls try { mock.test(); } catch (error) { @@ -98,9 +96,91 @@ Deno.test("MockBuilder", async (t) => { assertEquals(mock.calls.hello, 2); }, }); + + await t.step({ + name: ".willReturn() returns specified value", + fn(): void { + const mock = new MockBuilder(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Don't fully pre-program the method. This should cause an error during assertions. + mock + .method("test") + .willReturn({ + name: "something" + }); + + assertEquals(mock.test(), {name: "something"}); + assertEquals(mock.calls.test, 2); + assertEquals(mock.calls.hello, 2); + }, + }); + + await t.step({ + name: ".willReturn(mock) returns the mock object (basic)", + fn(): void { + const mock = new MockBuilder(TestObjectFourBuilder).create(); + assertEquals(mock.is_mock, true); + + // mock + // .method("someComplexMethod") + // .willReturn(mock) + + assertEquals(mock.someComplexMethod(), mock); + assertEquals(mock.calls.someComplexMethod, 1); + }, + }); + + await t.step({ + name: ".willThrow() causes throwing RandomError (with constructor)", + fn(): void { + const mock = new MockBuilder(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Make the original method throw RandomError + mock + .method("test") + .willThrow(new RandomError("Random error message.")) + + assertThrows( + () => mock.test(), + RandomError, + "Random error message." + ); + assertEquals(mock.calls.test, 2); + }, + }); + + await t.step({ + name: ".willThrow() causes throwing RandomError2 (no constructor)", + fn(): void { + const mock = new MockBuilder(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Make the original method throw RandomError + mock + .method("test") + .willThrow(new RandomError2()) + + assertThrows( + () => mock.test(), + RandomError2, + "Some message not by the constructor." + ); + assertEquals(mock.calls.test, 2); + }, + }); }); }); - // FILE MARKER - DATA ////////////////////////////////////////////////////////// class TestObjectOne { @@ -113,7 +193,7 @@ class TestObjectTwo { } } -class WillReturnObjectOne { +class TestObjectThree { public hello(): void { return; } @@ -124,3 +204,36 @@ class WillReturnObjectOne { return "World"; } } + +class TestObjectFourBuilder { + #something_one?: string; + #something_two?: string; + + get something_one(): string | undefined { + return this.#something_one; + } + + get something_two(): string | undefined { + return this.#something_two; + } + + someComplexMethod(): this { + this.#setSomethingOne(); + this.#setSomethingTwo(); + return this; + } + + #setSomethingOne(): void { + this.#something_one = "one"; + } + + #setSomethingTwo(): void { + this.#something_two = "two"; + } +} + +class RandomError extends Error {} +class RandomError2 extends Error { + public name = "RandomError2Name" + public message = "Some message not by the constructor." +} \ No newline at end of file From df288996fca161dd72d2be945c29c0e0006221d6 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 11:16:53 -0400 Subject: [PATCH 11/62] feat: add mixin for mock --- extend.js | 11 +++++ extend.ts | 9 ++++ src/mock.ts | 88 ++++++++++++++++++++++++++++++++- src/mock_builder.ts | 4 +- src/pre_programmed_method.ts | 1 + src/types.ts | 2 +- tests/unit/mock_builder_test.ts | 25 ++++++++++ 7 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 extend.js create mode 100644 extend.ts diff --git a/extend.js b/extend.js new file mode 100644 index 00000000..ae67172e --- /dev/null +++ b/extend.js @@ -0,0 +1,11 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file +// This code was bundled using `deno bundle` and it's not recommended to edit it manually + +class Base { + base_prop = "base prop"; +} +class Hello extends Base { + sub_prop = "sub prop"; +} +new Hello(); diff --git a/extend.ts b/extend.ts new file mode 100644 index 00000000..a97e901a --- /dev/null +++ b/extend.ts @@ -0,0 +1,9 @@ +class Base { + public base_prop = "base prop"; +} + +class Hello extends Base { + public sub_prop = "sub prop"; +} + +const t = new Hello(); \ No newline at end of file diff --git a/src/mock.ts b/src/mock.ts index cf42caac..269603b2 100644 --- a/src/mock.ts +++ b/src/mock.ts @@ -1,4 +1,4 @@ -import type { MethodCalls, MethodOf } from "./types.ts"; +import type { Constructor, MethodCalls, MethodOf } from "./types.ts"; import { PreProgrammedMethod } from "./pre_programmed_method.ts"; class MockError extends Error {} @@ -87,3 +87,89 @@ export class Mock { return calls as Record; } } + +// This mixin adds a scale property, with getters and setters +// for changing it with an encapsulated private property: + +export function createMock>(OriginalClass: OriginalObject) { + // @ts-ignore + return class MockExtension extends OriginalClass { + #calls!: MethodCalls; + is_mock = true; + #original!: OriginalObject; + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * @param original - The original object to mock. + * @param methodsToTrack - The original object's method to make trackable. + */ + public init(original: OriginalObject, methodsToTrack: string[]) { + this.#original = original; + this.#calls = this.#constructCallsProperty(methodsToTrack); + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - GETTERS / SETTERS /////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + get calls(): MethodCalls { + return this.#calls; + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Pre-program a method on the original to return a specific value. + * @param methodName The method name on the original. + * @returns A pre-programmed method that will be called instead of original. + */ + public method( + methodName: MethodOf, + ): PreProgrammedMethod { + const methodConfiguration = new PreProgrammedMethod< + OriginalObject, + ReturnValueType + >( + methodName + ); + + if (!((methodName as string) in this.#original)) { + throw new MockError( + `Method "${methodName}" does not exist.`, + ); + } + + Object.defineProperty(this.#original, methodName, { + value: methodConfiguration, + writable: true, + }); + + return methodConfiguration; + } + + /** + * Construct the calls property. Only construct it, do not set it. The + * constructor will set it. + * @param methodsToTrack - All of the methods on the original object to make + * trackable. + * @returns - Key-value object where the key is the method name and the value + * is the number of calls. All calls start at 0. + */ + #constructCallsProperty( + methodsToTrack: string[], + ): Record { + const calls: Partial> = {}; + + methodsToTrack.map((key: string) => { + calls[key as keyof OriginalObject] = 0; + }); + + return calls as Record; + } + } +} \ No newline at end of file diff --git a/src/mock_builder.ts b/src/mock_builder.ts index 6f5c4c5c..935dbe53 100644 --- a/src/mock_builder.ts +++ b/src/mock_builder.ts @@ -1,5 +1,5 @@ import type { Constructor } from "./types.ts"; -import { Mock } from "./mock.ts"; +import { createMock, Mock } from "./mock.ts"; import { PreProgrammedMethod } from "./pre_programmed_method.ts"; /** @@ -268,4 +268,4 @@ export class MockBuilder { }, ); } -} +} \ No newline at end of file diff --git a/src/pre_programmed_method.ts b/src/pre_programmed_method.ts index 0da1d5fd..6cdbd21d 100644 --- a/src/pre_programmed_method.ts +++ b/src/pre_programmed_method.ts @@ -20,6 +20,7 @@ export class PreProgrammedMethod { /** * @param methodName - The name of the method to program. Must be a method of * the original object in question. + * @param original - The original object object that contains the method. */ constructor(methodName: MethodOf) { this.#method_name = methodName; diff --git a/src/types.ts b/src/types.ts index 0bd77f1d..2e02c942 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,5 @@ // deno-lint-ignore no-explicit-any -export type Constructor = new (...args: any[]) => T; +export type Constructor = new (...args: any[]) => T; export type MockedObject = { [k: string]: unknown }; diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index a9ea4c50..5c9f5757 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -134,6 +134,31 @@ Deno.test("MockBuilder", async (t) => { }, }); + // await t.step({ + // name: ".willReturn(mock) returns the mock object (extra)", + // fn(): void { + // // Assert that the original implementation sets properties + // const mock1 = new MockBuilder(TestObjectFourBuilder).create(); + // assertEquals(mock1.is_mock, true); + // mock1.someComplexMethod(); + // assertEquals(mock1.something_one, "one"); + // assertEquals(mock1.something_two, "two"); + // assertEquals(mock1.calls.someComplexMethod, 1); + + // // // Assert that `.willReturnSelf()` does not set properties + // // const mock2 = new MockBuilder(TestObjectFourBuilder).create(); + // // assertEquals(mock2.is_mock, true); + // // mock2 + // // .method("someComplexMethod") + // // .willReturn(mock2); + + // // assertEquals(mock2.someComplexMethod(), mock2); + // // assertEquals(mock2.something_one, undefined); + // // assertEquals(mock2.something_two, undefined); + // // assertEquals(mock2.calls.someComplexMethod, 1); + // }, + // }); + await t.step({ name: ".willThrow() causes throwing RandomError (with constructor)", fn(): void { From d5833f19d3a22e90af95f5b57449a2cfc612f3a0 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 17:54:22 -0400 Subject: [PATCH 12/62] fix: issue with redefining getters and setters --- src/interfaces.ts | 22 ++++++++- src/mock.ts | 109 +++++++------------------------------------- src/mock_builder.ts | 51 ++++++++++++++------- 3 files changed, 73 insertions(+), 109 deletions(-) diff --git a/src/interfaces.ts b/src/interfaces.ts index 626ee986..a40a7874 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,4 +1,24 @@ +import type { + MethodCalls, + MethodOf, +} from "./types.ts"; +import { PreProgrammedMethod } from "./pre_programmed_method.ts"; + export interface IError { name: string; message?: string; -} \ No newline at end of file +} + +export interface IMock { + calls: MethodCalls; + is_mock: boolean; + + init( + original: OriginalObject, + methodsToTrack: string[], + ): void; + + method( + methodName: MethodOf + ): PreProgrammedMethod; +} diff --git a/src/mock.ts b/src/mock.ts index 269603b2..b14b49fa 100644 --- a/src/mock.ts +++ b/src/mock.ts @@ -1,101 +1,26 @@ import type { Constructor, MethodCalls, MethodOf } from "./types.ts"; import { PreProgrammedMethod } from "./pre_programmed_method.ts"; +import type { IMock } from "./interfaces.ts"; class MockError extends Error {} -/** - * Class to mock an object. This class is the original object with data members - * that can be used for verifying behavior (e.g., using `mock.calls.someMethod` - * to see how many `someMethod` was called). - */ -export class Mock { - readonly #calls: MethodCalls; - is_mock = true; - #original: OriginalObject; - - ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - - /** - * @param original - The original object to mock. - * @param methodsToTrack - The original object's method to make trackable. - */ - constructor(original: OriginalObject, methodsToTrack: string[]) { - this.#original = original; - this.#calls = this.#constructCallsProperty(methodsToTrack); - } - - ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - GETTERS / SETTERS /////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - - get calls(): MethodCalls { - return this.#calls; - } - - ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - - /** - * Pre-program a method on the original to return a specific value. - * @param methodName The method name on the original. - * @returns A pre-programmed method that will be called instead of original. - */ - public method( - methodName: MethodOf, - ): PreProgrammedMethod { - const methodConfiguration = new PreProgrammedMethod< - OriginalObject, - ReturnValueType - >( - methodName - ); - - if (!((methodName as string) in this.#original)) { - throw new MockError( - `Method "${methodName}" does not exist.`, - ); - } - - Object.defineProperty(this.#original, methodName, { - value: methodConfiguration, - writable: true, - }); - - return methodConfiguration; - } - - /** - * Construct the calls property. Only construct it, do not set it. The - * constructor will set it. - * @param methodsToTrack - All of the methods on the original object to make - * trackable. - * @returns - Key-value object where the key is the method name and the value - * is the number of calls. All calls start at 0. - */ - #constructCallsProperty( - methodsToTrack: string[], - ): Record { - const calls: Partial> = {}; - - methodsToTrack.map((key: string) => { - calls[key as keyof OriginalObject] = 0; - }); - - return calls as Record; - } -} - -// This mixin adds a scale property, with getters and setters -// for changing it with an encapsulated private property: +export function createMock(OriginalClass: OriginalConstructor): IMock { + // deno-lint-ignore no-explicit-any + const Original = OriginalClass as unknown as Constructor<(...args: any[]) => any>; + return new class MockExtension extends Original { + /** + * Helper property to see that this is a mock object and not the original. + */ + is_mock = true; -export function createMock>(OriginalClass: OriginalObject) { - // @ts-ignore - return class MockExtension extends OriginalClass { + /** + * Property to track method calls. + */ #calls!: MethodCalls; - is_mock = true; + + /** + * The original object that this class creates a mock of. + */ #original!: OriginalObject; ////////////////////////////////////////////////////////////////////////////// @@ -172,4 +97,4 @@ export function createMock>(O return calls as Record; } } -} \ No newline at end of file +} diff --git a/src/mock_builder.ts b/src/mock_builder.ts index 935dbe53..7716fd27 100644 --- a/src/mock_builder.ts +++ b/src/mock_builder.ts @@ -1,5 +1,6 @@ import type { Constructor } from "./types.ts"; -import { createMock, Mock } from "./mock.ts"; +import type { IMock } from "./interfaces.ts"; +import { createMock } from "./mock.ts"; import { PreProgrammedMethod } from "./pre_programmed_method.ts"; /** @@ -41,17 +42,21 @@ export class MockBuilder { * * @returns The original object with capabilities from the Mock class. */ - public create(): ClassToMock & Mock { + public create(): ClassToMock & IMock { const original = new this.#constructor_fn(...this.#constructor_args); - const mock = new Mock( - original, - this.#getAllFunctionNames(original), + const mock = createMock, ClassToMock>( + this.#constructor_fn ); + mock.init(original, this.#getAllFunctionNames(original)); // Attach all of the original's properties to the mock this.#getAllPropertyNames(original).forEach((property: string) => { - this.#addOriginalObjectPropertyToMockObject(original, mock, property); + this.#addOriginalObjectPropertyToMockObject( + original, + mock, + property + ); }); // Attach all of the original's functions to the mock @@ -63,7 +68,7 @@ export class MockBuilder { ); }); - return mock as ClassToMock & Mock; + return mock as ClassToMock & IMock; } /** @@ -95,7 +100,7 @@ export class MockBuilder { */ #addMethodToMockObject( original: ClassToMock, - mock: Mock, + mock: IMock, method: string, ): void { Object.defineProperty(mock, method, { @@ -114,7 +119,7 @@ export class MockBuilder { */ #addOriginalObjectMethodToMockObject( original: ClassToMock, - mock: Mock, + mock: IMock, method: string, ): void { const nativeMethods = [ @@ -159,7 +164,7 @@ export class MockBuilder { */ #addOriginalObjectPropertyToMockObject( original: ClassToMock, - mock: Mock, + mock: IMock, property: string, ): void { const desc = Object.getOwnPropertyDescriptor(original, property) ?? @@ -168,10 +173,20 @@ export class MockBuilder { property, ); - Object.defineProperty(mock, property, { - value: desc!.value, - writable: true, // Make writable because getters/setters can be configured - }); + // If we do not have a desc, then we have no idea what the value should be. + // Also, we have no idea what we are copying, so we should just not do it. + if (!desc) { + return; + } + + // Basic property (e.g., public test = "hello"). We do not handle get() and + // set() because those are handled by the mock mixin. + if (("value" in desc)) { + Object.defineProperty(mock, property, { + value: desc.value, + writable: true, + }); + } } /** @@ -184,9 +199,11 @@ export class MockBuilder { */ #addTrackableMethodToMockObject( original: ClassToMock, - mock: Mock, + mock: IMock, method: keyof ClassToMock, ): void { + // console.log(`METHOD IS THIS: `, method); + Object.defineProperty(mock, method, { value: (...args: unknown[]) => { // Track that this method was called @@ -213,6 +230,8 @@ export class MockBuilder { // original does not. const bound = methodToCall.bind(mock); + // console.log(`calling bound()`); + // Use `return` because the original function could return a value return bound(...args); } @@ -268,4 +287,4 @@ export class MockBuilder { }, ); } -} \ No newline at end of file +} From 73996ee6a991487edf5c96fd19eb898d14d188d6 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 17:54:35 -0400 Subject: [PATCH 13/62] test: testing current implementations thus far --- tests/unit/mock_builder_test.ts | 77 ++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index 5c9f5757..d94f327b 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -106,7 +106,8 @@ Deno.test("MockBuilder", async (t) => { // Original returns "World" assertEquals(mock.test(), "World"); - // Don't fully pre-program the method. This should cause an error during assertions. + // Don't fully pre-program the method. This should cause an error during + // assertions. mock .method("test") .willReturn({ @@ -125,39 +126,49 @@ Deno.test("MockBuilder", async (t) => { const mock = new MockBuilder(TestObjectFourBuilder).create(); assertEquals(mock.is_mock, true); - // mock - // .method("someComplexMethod") - // .willReturn(mock) + mock + .method("someComplexMethod") + .willReturn(mock) assertEquals(mock.someComplexMethod(), mock); assertEquals(mock.calls.someComplexMethod, 1); }, }); - // await t.step({ - // name: ".willReturn(mock) returns the mock object (extra)", - // fn(): void { - // // Assert that the original implementation sets properties - // const mock1 = new MockBuilder(TestObjectFourBuilder).create(); - // assertEquals(mock1.is_mock, true); - // mock1.someComplexMethod(); - // assertEquals(mock1.something_one, "one"); - // assertEquals(mock1.something_two, "two"); - // assertEquals(mock1.calls.someComplexMethod, 1); - - // // // Assert that `.willReturnSelf()` does not set properties - // // const mock2 = new MockBuilder(TestObjectFourBuilder).create(); - // // assertEquals(mock2.is_mock, true); - // // mock2 - // // .method("someComplexMethod") - // // .willReturn(mock2); - - // // assertEquals(mock2.someComplexMethod(), mock2); - // // assertEquals(mock2.something_one, undefined); - // // assertEquals(mock2.something_two, undefined); - // // assertEquals(mock2.calls.someComplexMethod, 1); - // }, - // }); + await t.step({ + name: ".willReturn(mock) returns the mock object (extra)", + fn(): void { + // Assert that the original implementation sets properties + const mock1 = new MockBuilder(TestObjectFourBuilder).create(); + assertEquals(mock1.is_mock, true); + mock1.someComplexMethod(); + assertEquals(mock1.something_one, "one"); + assertEquals(mock1.something_two, "two"); + assertEquals(mock1.calls.someComplexMethod, 1); + + // Assert that the mock implementation will not set properties + const mock2 = new MockBuilder(TestObjectFourBuilder).create(); + assertEquals(mock2.is_mock, true); + mock2 + .method("someComplexMethod") + .willReturn(mock2); + + assertEquals(mock2.someComplexMethod(), mock2); + assertEquals(mock2.something_one, undefined); + assertEquals(mock2.something_two, undefined); + assertEquals(mock2.calls.someComplexMethod, 1); + + // Assert that we can also use setters + const mock3= new MockBuilder(TestObjectFourBuilder).create(); + assertEquals(mock3.is_mock, true); + mock3.someComplexMethod(); + assertEquals(mock3.something_one, "one"); + assertEquals(mock3.something_two, "two"); + mock3.something_one = "you got changed"; + assertEquals(mock3.something_one, "you got changed"); + assertEquals(mock3.calls.someComplexMethod, 1); + }, + }); await t.step({ name: ".willThrow() causes throwing RandomError (with constructor)", @@ -242,6 +253,10 @@ class TestObjectFourBuilder { return this.#something_two; } + set something_one(value: string | undefined) { + this.#something_one = value; + } + someComplexMethod(): this { this.#setSomethingOne(); this.#setSomethingTwo(); @@ -249,7 +264,11 @@ class TestObjectFourBuilder { } #setSomethingOne(): void { + // console.log("inside setSomethingOne()"); + // console.log(this); this.#something_one = "one"; + // console.log(`set something_one:`, this.#something_one); + // console.log(this); } #setSomethingTwo(): void { @@ -261,4 +280,4 @@ class RandomError extends Error {} class RandomError2 extends Error { public name = "RandomError2Name" public message = "Some message not by the constructor." -} \ No newline at end of file +} From 6299ba2a281391f63ffbc78b0e71b4394c95d463 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 21:20:57 -0400 Subject: [PATCH 14/62] feat: add dummy logic --- mod.ts | 16 ++++++++++ tests/unit/mod_test.ts | 69 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 tests/unit/mod_test.ts diff --git a/mod.ts b/mod.ts index 81826663..d4f18872 100644 --- a/mod.ts +++ b/mod.ts @@ -3,6 +3,22 @@ import { MockBuilder } from "./src/mock_builder.ts"; export type { Constructor, Stubbed } from "./src/types.ts"; export { MockBuilder } from "./src/mock_builder.ts"; +/** + * Create an object that can be passed around, but never actually used. A dummy + * is usually just used to fill a parameter. + * + * @param constructorFn - The constructor function to use to become the + * prototype of the dummy. Dummy objects should be the same instance as what + * they are standing in for. For example, if a `SomeClass` parameter needs to be + * filled with a dummy because it is out of scope for a test, then the dummy + * should be an instance of `SomeClass`. + * @returns A dummy object being an instance of the given constructor function. + */ +export const Dummy = (constructorFn?: Constructor): T => { + const dummy = Object.create({}); + Object.setPrototypeOf(dummy, constructorFn ?? Object); + return dummy; +} /** * Get the builder to help you create mocked objects. diff --git a/tests/unit/mod_test.ts b/tests/unit/mod_test.ts new file mode 100644 index 00000000..14ee16fb --- /dev/null +++ b/tests/unit/mod_test.ts @@ -0,0 +1,69 @@ +import { Dummy, Mock } from "../../mod.ts"; +import { assertEquals } from "../deps.ts"; + +Deno.test("mod", async (t) => { + await t.step("Dummy()", async (t) => { + await t.step({ + name: "can fill parameter lists", + fn(): void { + const mockServiceOne = Mock(ServiceOne).create(); + const dummy3 = Dummy(ServiceThree); + + const resource = new Resource( + mockServiceOne, + Dummy(ServiceTwo), + dummy3, + ); + + resource.callServiceOne(); + assertEquals(mockServiceOne.calls.methodServiceOne, 1); + }, + }); + }); +}); + +class Resource { + #service_one: ServiceOne; + #service_two: ServiceTwo; + #service_three: ServiceThree; + + constructor( + serviceOne: ServiceOne, + serviceTwo: ServiceTwo, + serviceThree: ServiceThree + ) { + this.#service_one = serviceOne; + this.#service_two = serviceTwo; + this.#service_three = serviceThree; + } + + public callServiceOne() { + this.#service_one.methodServiceOne(); + } + + public callServiceTwo() { + this.#service_two.methodServiceTwo(); + } + + public callServiceThree() { + this.#service_three.methodServiceThree(); + } +} + +class ServiceOne { + public methodServiceOne() { + return "Method from ServiceOne was called."; + } +} + +class ServiceTwo { + public methodServiceTwo() { + return "Method from ServiceTwo was called."; + } +} + +class ServiceThree { + public methodServiceThree() { + return "Method from ServiceThree was called."; + } +} \ No newline at end of file From 8f5f5d926619cb0ae08cc023d9b6e039c6fa6233 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 21:21:43 -0400 Subject: [PATCH 15/62] chore: clean up --- mod.ts | 5 ++--- tests/integration/stub_test.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mod.ts b/mod.ts index d4f18872..6b0c9952 100644 --- a/mod.ts +++ b/mod.ts @@ -1,8 +1,7 @@ import type { Constructor, Stubbed } from "./src/types.ts"; import { MockBuilder } from "./src/mock_builder.ts"; +export * as Types from "./src/types.ts"; -export type { Constructor, Stubbed } from "./src/types.ts"; -export { MockBuilder } from "./src/mock_builder.ts"; /** * Create an object that can be passed around, but never actually used. A dummy * is usually just used to fill a parameter. @@ -21,7 +20,7 @@ export const Dummy = (constructorFn?: Constructor): T => { } /** - * Get the builder to help you create mocked objects. + * Get the builder to create mocked objects. * * @param constructorFn - The constructor function of the object to mock. * diff --git a/tests/integration/stub_test.ts b/tests/integration/stub_test.ts index e19dff0b..6cb39dfe 100644 --- a/tests/integration/stub_test.ts +++ b/tests/integration/stub_test.ts @@ -13,7 +13,7 @@ class Server { } Deno.test("stub()", async (t) => { - await t.step("Can stub a propert", () => { + await t.step("Can stub a property", () => { const server = Stub(new Server()); server.stub("greeting", "you got changed"); assertEquals(server.greeting, "you got changed"); From 825748b3556890f130ffd0cba3cbbd04d98f36b7 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 21:24:49 -0400 Subject: [PATCH 16/62] chore: move mock logic into mock folder --- mod.ts | 2 +- src/interfaces.ts | 2 +- src/{ => mock}/mock_builder.ts | 6 +++--- src/{mock.ts => mock/mock_mixin.ts} | 4 ++-- src/{ => mock}/pre_programmed_method.ts | 4 ++-- tests/unit/mock_builder_test.ts | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) rename src/{ => mock}/mock_builder.ts (98%) rename src/{mock.ts => mock/mock_mixin.ts} (96%) rename src/{ => mock}/pre_programmed_method.ts (96%) diff --git a/mod.ts b/mod.ts index 6b0c9952..746bc6de 100644 --- a/mod.ts +++ b/mod.ts @@ -1,5 +1,5 @@ import type { Constructor, Stubbed } from "./src/types.ts"; -import { MockBuilder } from "./src/mock_builder.ts"; +import { MockBuilder } from "./src/mock/mock_builder.ts"; export * as Types from "./src/types.ts"; /** diff --git a/src/interfaces.ts b/src/interfaces.ts index a40a7874..62f0bd17 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -2,7 +2,7 @@ import type { MethodCalls, MethodOf, } from "./types.ts"; -import { PreProgrammedMethod } from "./pre_programmed_method.ts"; +import { PreProgrammedMethod } from "./mock/pre_programmed_method.ts"; export interface IError { name: string; diff --git a/src/mock_builder.ts b/src/mock/mock_builder.ts similarity index 98% rename from src/mock_builder.ts rename to src/mock/mock_builder.ts index 7716fd27..a8de90d1 100644 --- a/src/mock_builder.ts +++ b/src/mock/mock_builder.ts @@ -1,6 +1,6 @@ -import type { Constructor } from "./types.ts"; -import type { IMock } from "./interfaces.ts"; -import { createMock } from "./mock.ts"; +import type { Constructor } from "../types.ts"; +import type { IMock } from "../interfaces.ts"; +import { createMock } from "./mock_mixin.ts"; import { PreProgrammedMethod } from "./pre_programmed_method.ts"; /** diff --git a/src/mock.ts b/src/mock/mock_mixin.ts similarity index 96% rename from src/mock.ts rename to src/mock/mock_mixin.ts index b14b49fa..729d4d66 100644 --- a/src/mock.ts +++ b/src/mock/mock_mixin.ts @@ -1,6 +1,6 @@ -import type { Constructor, MethodCalls, MethodOf } from "./types.ts"; +import type { Constructor, MethodCalls, MethodOf } from "../types.ts"; import { PreProgrammedMethod } from "./pre_programmed_method.ts"; -import type { IMock } from "./interfaces.ts"; +import type { IMock } from "../interfaces.ts"; class MockError extends Error {} diff --git a/src/pre_programmed_method.ts b/src/mock/pre_programmed_method.ts similarity index 96% rename from src/pre_programmed_method.ts rename to src/mock/pre_programmed_method.ts index 6cdbd21d..0fdd35ee 100644 --- a/src/pre_programmed_method.ts +++ b/src/mock/pre_programmed_method.ts @@ -1,5 +1,5 @@ -import type { MethodOf } from "./types.ts"; -import type { IError } from "./interfaces.ts"; +import type { MethodOf } from "../types.ts"; +import type { IError } from "../interfaces.ts"; class PreProgrammedMethodError extends Error {} diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index d94f327b..16fc5c6b 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -1,5 +1,5 @@ import { assertEquals, assertThrows } from "../deps.ts"; -import { MockBuilder } from "../../src/mock_builder.ts"; +import { MockBuilder } from "../../src/mock/mock_builder.ts"; Deno.test("MockBuilder", async (t) => { await t.step("create()", async (t) => { From 068993033f7c19a32c2df93abe17d147de888557 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 22:05:27 -0400 Subject: [PATCH 17/62] feat: fakes --- mod.ts | 23 +- src/fake/fake_builder.ts | 282 ++++++++++++++++++ src/fake/fake_mixin.ts | 66 ++++ src/interfaces.ts | 21 +- src/mock/mock_builder.ts | 2 +- src/mock/mock_mixin.ts | 2 +- src/{mock => }/pre_programmed_method.ts | 4 +- src/types.ts | 6 +- tests/unit/{mod_test.ts => mod/dummy_test.ts} | 34 +-- tests/unit/mod/fake_test.ts | 78 +++++ 10 files changed, 489 insertions(+), 29 deletions(-) create mode 100644 src/fake/fake_builder.ts create mode 100644 src/fake/fake_mixin.ts rename src/{mock => }/pre_programmed_method.ts (96%) rename tests/unit/{mod_test.ts => mod/dummy_test.ts} (60%) create mode 100644 tests/unit/mod/fake_test.ts diff --git a/mod.ts b/mod.ts index 746bc6de..1e7b7200 100644 --- a/mod.ts +++ b/mod.ts @@ -1,10 +1,12 @@ import type { Constructor, Stubbed } from "./src/types.ts"; import { MockBuilder } from "./src/mock/mock_builder.ts"; +import { FakeBuilder } from "./src/fake/fake_builder.ts"; export * as Types from "./src/types.ts"; /** - * Create an object that can be passed around, but never actually used. A dummy - * is usually just used to fill a parameter. + * Create a dummy. + * + *Per Martin Fowler, "Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists." * * @param constructorFn - The constructor function to use to become the * prototype of the dummy. Dummy objects should be the same instance as what @@ -19,9 +21,24 @@ export const Dummy = (constructorFn?: Constructor): T => { return dummy; } +/** + * Get the builder to create fake objects. + * + * Per Martin Fowler, "Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an InMemoryTestDatabase is a good example)." + * + * @param constructorFn - The constructor function of the object to fake. + * + * @returns Instance of `FakeBuilder`. + */ + export const Fake = (constructorFn: Constructor): FakeBuilder => { + return new FakeBuilder(constructorFn); +}; + /** * Get the builder to create mocked objects. * + * Per Martin Fowler, "Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting." + * * @param constructorFn - The constructor function of the object to mock. * * @returns Instance of `MockBuilder`. @@ -33,6 +50,8 @@ export const Mock = (constructorFn: Constructor): MockBuilder => { /** * Stub a member of an object. * + * Per Martin Fowler, "Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test." + * * @param obj -The object containing the member to stub. */ export const Stub = (obj: T): Stubbed => { diff --git a/src/fake/fake_builder.ts b/src/fake/fake_builder.ts new file mode 100644 index 00000000..acd668ef --- /dev/null +++ b/src/fake/fake_builder.ts @@ -0,0 +1,282 @@ +import type { Constructor } from "../types.ts"; +import type { IFake } from "../interfaces.ts"; +import { createFake } from "./fake_mixin.ts"; +import { PreProgrammedMethod } from "../pre_programmed_method.ts"; + +/** + * Builder to help build a fake object. This does all of the heavy-lifting to + * create a fake object. + */ +export class FakeBuilder { + /** + * The class to fake (should be constructable). + */ + #constructor_fn: Constructor; + + /** + * A list of arguments the class constructor takes. + */ + #constructor_args: unknown[] = []; + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Construct an object of this class. + * + * @param constructorFn - The class to fake (should be constructable). + */ + constructor(constructorFn: Constructor) { + this.#constructor_fn = constructorFn; + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Create the fake object. + * + * @returns The original object with capabilities from the fake class. + */ + public create(): ClassToFake & IFake { + const original = new this.#constructor_fn(...this.#constructor_args); + + const fake = createFake, ClassToFake>( + this.#constructor_fn + ); + fake.init(original, this.#getAllFunctionNames(original)); + + // Attach all of the original's properties to the fake + this.#getAllPropertyNames(original).forEach((property: string) => { + this.#addOriginalObjectPropertyToFakeObject( + original, + fake, + property + ); + }); + + // Attach all of the original's functions to the fake + this.#getAllFunctionNames(original).forEach((method: string) => { + this.#addOriginalObjectMethodToFakeObject( + original, + fake, + method, + ); + }); + + return fake as ClassToFake & IFake; + } + + /** + * Before constructing the fake object, track any constructor function args + * that need to be passed in when constructing the fake object. + * + * @param args - A rest parameter of arguments that will get passed in to the + * constructor function of the object being faked. + * + * @returns `this` so that methods in this class can be chained. + */ + public withConstructorArgs(...args: unknown[]): this { + this.#constructor_args = args; + return this; + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - METHODS - PRIVATE /////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Add an original object's method to a fake object without doing anything + * else. + * + * @param original - The original object containing the method to fake. + * @param fake - The fake object receiving the method to fake. + * @param method - The name of the method to fake -- callable via + * `fake[method](...)`. + */ + #addMethodToFakeObject( + original: ClassToFake, + fake: IFake, + method: string, + ): void { + Object.defineProperty(fake, method, { + value: original[method as keyof ClassToFake], + }); + } + + /** + * Add an original object's method to a fake object -- determining whether the + * method should or should not be trackable. + * + * @param original - The original object containing the method to add. + * @param fake - The fake object receiving the method. + * @param method - The name of the method to fake -- callable via + * `fake[method](...)`. + */ + #addOriginalObjectMethodToFakeObject( + original: ClassToFake, + fake: IFake, + method: string, + ): void { + const nativeMethods = [ + "__defineGetter__", + "__defineSetter__", + "__lookupGetter__", + "__lookupSetter__", + "constructor", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "toLocaleString", + "toString", + "valueOf", + ]; + + // If this is a native method, then do not do anything fancy. Just add it to + // the fake. + if (nativeMethods.includes(method as string)) { + return this.#addMethodToFakeObject( + original, + fake, + method, + ); + } + + // Otherwise, make the method trackable via `.calls` usage. + this.#addTrackableMethodToFakeObject( + original, + fake, + method as keyof ClassToFake, + ); + } + + /** + * Add an original object's property to a fake object. + * + * @param original The original object containing the property. + * @param fake The fake object receiving the property. + * @param property The name of the property -- retrievable via + * `fake[property]`. + */ + #addOriginalObjectPropertyToFakeObject( + original: ClassToFake, + fake: IFake, + property: string, + ): void { + const desc = Object.getOwnPropertyDescriptor(original, property) ?? + Object.getOwnPropertyDescriptor( + this.#constructor_fn.prototype, + property, + ); + + // If we do not have a desc, then we have no idea what the value should be. + // Also, we have no idea what we are copying, so we should just not do it. + if (!desc) { + return; + } + + // Basic property (e.g., public test = "hello"). We do not handle get() and + // set() because those are handled by the fake mixin. + if (("value" in desc)) { + Object.defineProperty(fake, property, { + value: desc.value, + writable: true, + }); + } + } + + /** + * Add a trackable method to a fake object. A trackable method is one that can + * be verified using `fake.calls[someMethod]`. + * + * @param original - The original object containing the method to add. + * @param fake - The fake object receiving the method. + * @param method - The name of the method. + */ + #addTrackableMethodToFakeObject( + original: ClassToFake, + fake: IFake, + method: keyof ClassToFake, + ): void { + // console.log(`METHOD IS THIS: `, method); + + Object.defineProperty(fake, method, { + value: (...args: unknown[]) => { + // Make sure the method calls its original self + const methodToCall = + (original[method as keyof ClassToFake] as unknown as ( + ...params: unknown[] + ) => unknown); + + // We need to check if the method was pre-preprogrammed to return + // something. If it was, then we make sure that this method we are + // currently defining returns that pre-programmed value. + if (methodToCall instanceof PreProgrammedMethod) { + return methodToCall.return; + } + + // When method calls its original self, let the `this` context of the + // original be the fake. Reason being the fake has tracking and the + // original does not. + const bound = methodToCall.bind(fake); + + // console.log(`calling bound()`); + + // Use `return` because the original function could return a value + return bound(...args); + } + }); + } + + /** + * Get all properties from the original so they can be added to the fake. + * + * @param obj - The object that will be faked. + * + * @returns An array of the object's properties. + */ + #getAllPropertyNames(obj: ClassToFake): string[] { + let functions: string[] = []; + let clone = obj; + do { + functions = functions.concat(Object.getOwnPropertyNames(clone)); + } while ((clone = Object.getPrototypeOf(clone))); + + return functions.sort().filter( + function (e: string, i: number, arr: unknown[]) { + if ( + e != arr[i + 1] && typeof obj[e as keyof ClassToFake] != "function" + ) { + return true; + } + }, + ); + } + + /** + * Get all functions from the original so they can be added to the fake. + * + * @param obj - The object that will be faked. + * + * @returns An array of the object's functions. + */ + #getAllFunctionNames(obj: ClassToFake): string[] { + let functions: string[] = []; + let clone = obj; + do { + functions = functions.concat(Object.getOwnPropertyNames(clone)); + } while ((clone = Object.getPrototypeOf(clone))); + + return functions.sort().filter( + function (e: string, i: number, arr: unknown[]) { + if ( + e != arr[i + 1] && typeof obj[e as keyof ClassToFake] == "function" + ) { + return true; + } + }, + ); + } +} diff --git a/src/fake/fake_mixin.ts b/src/fake/fake_mixin.ts new file mode 100644 index 00000000..9f346343 --- /dev/null +++ b/src/fake/fake_mixin.ts @@ -0,0 +1,66 @@ +import type { Constructor, MethodOf } from "../types.ts"; +import { PreProgrammedMethod } from "../pre_programmed_method.ts"; +import type { IFake } from "../interfaces.ts"; + +class FakeError extends Error {} + +export function createFake(OriginalClass: OriginalConstructor): IFake { + // deno-lint-ignore no-explicit-any + const Original = OriginalClass as unknown as Constructor<(...args: any[]) => any>; + return new class FakeExtension extends Original { + /** + * Helper property to see that this is a fake object and not the original. + */ + is_fake = true; + + /** + * The original object that this class creates a fake of. + */ + #original!: OriginalObject; + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * @param original - The original object to fake. + */ + public init(original: OriginalObject) { + this.#original = original; + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + /** + * Pre-program a method on the original to return a specific value. + * + * @param methodName The method name on the original. + * @returns A pre-programmed method that will be called instead of original. + */ + public method( + methodName: MethodOf, + ): PreProgrammedMethod { + const methodConfiguration = new PreProgrammedMethod< + OriginalObject, + ReturnValueType + >( + methodName + ); + + if (!((methodName as string) in this.#original)) { + throw new FakeError( + `Method "${methodName}" does not exist.`, + ); + } + + Object.defineProperty(this.#original, methodName, { + value: methodConfiguration, + writable: true, + }); + + return methodConfiguration; + } + } +} diff --git a/src/interfaces.ts b/src/interfaces.ts index 62f0bd17..80532e0f 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -2,13 +2,30 @@ import type { MethodCalls, MethodOf, } from "./types.ts"; -import { PreProgrammedMethod } from "./mock/pre_programmed_method.ts"; export interface IError { name: string; message?: string; } +export interface IPreProgrammedMethod { + willReturn(returnValue: ReturnValue): void; + willThrow(error: IError): void; +} + +export interface IFake { + is_fake: boolean; + + init( + original: OriginalObject, + methodsToTrack: string[], + ): void; + + method( + methodName: MethodOf + ): IPreProgrammedMethod; +} + export interface IMock { calls: MethodCalls; is_mock: boolean; @@ -20,5 +37,5 @@ export interface IMock { method( methodName: MethodOf - ): PreProgrammedMethod; + ): IPreProgrammedMethod; } diff --git a/src/mock/mock_builder.ts b/src/mock/mock_builder.ts index a8de90d1..802d08a9 100644 --- a/src/mock/mock_builder.ts +++ b/src/mock/mock_builder.ts @@ -1,7 +1,7 @@ import type { Constructor } from "../types.ts"; import type { IMock } from "../interfaces.ts"; import { createMock } from "./mock_mixin.ts"; -import { PreProgrammedMethod } from "./pre_programmed_method.ts"; +import { PreProgrammedMethod } from "../pre_programmed_method.ts"; /** * Builder to help build a mock object. This does all of the heavy-lifting to diff --git a/src/mock/mock_mixin.ts b/src/mock/mock_mixin.ts index 729d4d66..cc975050 100644 --- a/src/mock/mock_mixin.ts +++ b/src/mock/mock_mixin.ts @@ -1,5 +1,5 @@ import type { Constructor, MethodCalls, MethodOf } from "../types.ts"; -import { PreProgrammedMethod } from "./pre_programmed_method.ts"; +import { PreProgrammedMethod } from "../pre_programmed_method.ts"; import type { IMock } from "../interfaces.ts"; class MockError extends Error {} diff --git a/src/mock/pre_programmed_method.ts b/src/pre_programmed_method.ts similarity index 96% rename from src/mock/pre_programmed_method.ts rename to src/pre_programmed_method.ts index 0fdd35ee..6cdbd21d 100644 --- a/src/mock/pre_programmed_method.ts +++ b/src/pre_programmed_method.ts @@ -1,5 +1,5 @@ -import type { MethodOf } from "../types.ts"; -import type { IError } from "../interfaces.ts"; +import type { MethodOf } from "./types.ts"; +import type { IError } from "./interfaces.ts"; class PreProgrammedMethodError extends Error {} diff --git a/src/types.ts b/src/types.ts index 2e02c942..e9b7764b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -12,6 +12,6 @@ export type Stubbed = T & { export type MethodCalls = Record; export type MethodOf = { - [K in keyof Object]: Object[K] extends (...args: unknown[]) => unknown ? K - : never; -}[keyof Object]; + // deno-lint-ignore no-explicit-any + [K in keyof Object]: Object[K] extends (...args: any) => any ? K : never +}[keyof Object]; \ No newline at end of file diff --git a/tests/unit/mod_test.ts b/tests/unit/mod/dummy_test.ts similarity index 60% rename from tests/unit/mod_test.ts rename to tests/unit/mod/dummy_test.ts index 14ee16fb..cc37f49d 100644 --- a/tests/unit/mod_test.ts +++ b/tests/unit/mod/dummy_test.ts @@ -1,24 +1,22 @@ -import { Dummy, Mock } from "../../mod.ts"; -import { assertEquals } from "../deps.ts"; +import { Dummy, Mock } from "../../../mod.ts"; +import { assertEquals } from "../../deps.ts"; -Deno.test("mod", async (t) => { - await t.step("Dummy()", async (t) => { - await t.step({ - name: "can fill parameter lists", - fn(): void { - const mockServiceOne = Mock(ServiceOne).create(); - const dummy3 = Dummy(ServiceThree); +Deno.test("Dummy()", async (t) => { + await t.step({ + name: "can fill parameter lists", + fn(): void { + const mockServiceOne = Mock(ServiceOne).create(); + const dummy3 = Dummy(ServiceThree); - const resource = new Resource( - mockServiceOne, - Dummy(ServiceTwo), - dummy3, - ); + const resource = new Resource( + mockServiceOne, + Dummy(ServiceTwo), + dummy3, + ); - resource.callServiceOne(); - assertEquals(mockServiceOne.calls.methodServiceOne, 1); - }, - }); + resource.callServiceOne(); + assertEquals(mockServiceOne.calls.methodServiceOne, 1); + }, }); }); diff --git a/tests/unit/mod/fake_test.ts b/tests/unit/mod/fake_test.ts new file mode 100644 index 00000000..a2df308a --- /dev/null +++ b/tests/unit/mod/fake_test.ts @@ -0,0 +1,78 @@ +import { Fake } from "../../../mod.ts"; +import { assertEquals } from "../../deps.ts"; + +Deno.test("Fake()", async (t) => { + await t.step({ + name: "can cause shortcuts", + fn(): void { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findAllUsers").willReturn("shortcut"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUsers(); + assertEquals(fakeServiceDoingShortcut.anotha_one_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_else_called, false); + + // Assert that the fake service is not yet doing a shortcut + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUsers(); + assertEquals(fakeServiceNotDoingShortcut.anotha_one_called, true); + assertEquals(fakeServiceNotDoingShortcut.do_something_called, true); + assertEquals(fakeServiceNotDoingShortcut.do_something_else_called, true); + }, + }); +}); + +class Resource { + #repository: Repository; + + constructor( + serviceOne: Repository, + ) { + this.#repository = serviceOne; + } + + public getUsers() { + this.#repository.findAllUsers(); + } + + public getUser(id: number) { + this.#repository.findUserById(id); + } +} + +class Repository { + public anotha_one_called = false; + public do_something_called = false; + public do_something_else_called = false; + + public findAllUsers(): string { + this.#doSomething(); + this.#doSomethingElse(); + this.#anothaOne(); + return "Finding all users"; + } + + public findUserById(id: number): string { + return `Finding user by id #${id}`; + } + + + #anothaOne() { + this.anotha_one_called = true; + } + + #doSomething() { + this.do_something_called = true; + } + + #doSomethingElse() { + this.do_something_else_called = true; + } +} From 647bd2dd6c1c101b67a1cf5b0d0169c788395cdb Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 22:08:09 -0400 Subject: [PATCH 18/62] chore: deno fmt --- extend.ts | 2 +- mod.ts | 23 ++++++++++++++++------- src/fake/fake_builder.ts | 6 +++--- src/fake/fake_mixin.ts | 12 ++++++++---- src/interfaces.ts | 9 +++------ src/mock/mock_builder.ts | 8 ++++---- src/mock/mock_mixin.ts | 12 ++++++++---- src/pre_programmed_method.ts | 7 ++++++- src/types.ts | 4 ++-- tests/unit/mock_builder_test.ts | 22 +++++++++++----------- tests/unit/mod/dummy_test.ts | 4 ++-- tests/unit/mod/fake_test.ts | 1 - 12 files changed, 64 insertions(+), 46 deletions(-) diff --git a/extend.ts b/extend.ts index a97e901a..c7fcf0c5 100644 --- a/extend.ts +++ b/extend.ts @@ -6,4 +6,4 @@ class Hello extends Base { public sub_prop = "sub prop"; } -const t = new Hello(); \ No newline at end of file +const t = new Hello(); diff --git a/mod.ts b/mod.ts index 1e7b7200..10afea27 100644 --- a/mod.ts +++ b/mod.ts @@ -2,11 +2,13 @@ import type { Constructor, Stubbed } from "./src/types.ts"; import { MockBuilder } from "./src/mock/mock_builder.ts"; import { FakeBuilder } from "./src/fake/fake_builder.ts"; export * as Types from "./src/types.ts"; +export * as Interfaces from "./src/interfaces.ts"; /** * Create a dummy. * - *Per Martin Fowler, "Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists." + * Per Martin Fowler, "Dummy objects are passed around but never actually used. + * Usually they are just used to fill parameter lists." * * @param constructorFn - The constructor function to use to become the * prototype of the dummy. Dummy objects should be the same instance as what @@ -19,25 +21,30 @@ export const Dummy = (constructorFn?: Constructor): T => { const dummy = Object.create({}); Object.setPrototypeOf(dummy, constructorFn ?? Object); return dummy; -} +}; /** * Get the builder to create fake objects. * - * Per Martin Fowler, "Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an InMemoryTestDatabase is a good example)." + * Per Martin Fowler, "Fake objects actually have working implementations, but + * usually take some shortcut which makes them not suitable for production (an + * InMemoryTestDatabase is a good example)." * * @param constructorFn - The constructor function of the object to fake. * * @returns Instance of `FakeBuilder`. */ - export const Fake = (constructorFn: Constructor): FakeBuilder => { +export const Fake = (constructorFn: Constructor): FakeBuilder => { return new FakeBuilder(constructorFn); }; /** * Get the builder to create mocked objects. * - * Per Martin Fowler, "Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting." + * Per Martin Fowler, "Mocks are pre-programmed with expectations which form a + * specification of the calls they are expected to receive. They can throw an + * exception if they receive a call they don't expect and are checked during + * verification to ensure they got all the calls they were expecting." * * @param constructorFn - The constructor function of the object to mock. * @@ -48,9 +55,11 @@ export const Mock = (constructorFn: Constructor): MockBuilder => { }; /** - * Stub a member of an object. + * Create a stub. * - * Per Martin Fowler, "Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test." + * Per Martin Fowler, "Stubs provide canned answers to calls made during the + * test, usually not responding at all to anything outside what's programmed in + * for the test." * * @param obj -The object containing the member to stub. */ diff --git a/src/fake/fake_builder.ts b/src/fake/fake_builder.ts index acd668ef..0cb14efe 100644 --- a/src/fake/fake_builder.ts +++ b/src/fake/fake_builder.ts @@ -44,7 +44,7 @@ export class FakeBuilder { const original = new this.#constructor_fn(...this.#constructor_args); const fake = createFake, ClassToFake>( - this.#constructor_fn + this.#constructor_fn, ); fake.init(original, this.#getAllFunctionNames(original)); @@ -53,7 +53,7 @@ export class FakeBuilder { this.#addOriginalObjectPropertyToFakeObject( original, fake, - property + property, ); }); @@ -226,7 +226,7 @@ export class FakeBuilder { // Use `return` because the original function could return a value return bound(...args); - } + }, }); } diff --git a/src/fake/fake_mixin.ts b/src/fake/fake_mixin.ts index 9f346343..775ea609 100644 --- a/src/fake/fake_mixin.ts +++ b/src/fake/fake_mixin.ts @@ -4,9 +4,13 @@ import type { IFake } from "../interfaces.ts"; class FakeError extends Error {} -export function createFake(OriginalClass: OriginalConstructor): IFake { +export function createFake( + OriginalClass: OriginalConstructor, +): IFake { // deno-lint-ignore no-explicit-any - const Original = OriginalClass as unknown as Constructor<(...args: any[]) => any>; + const Original = OriginalClass as unknown as Constructor< + (...args: any[]) => any + >; return new class FakeExtension extends Original { /** * Helper property to see that this is a fake object and not the original. @@ -46,7 +50,7 @@ export function createFake(OriginalClass: O OriginalObject, ReturnValueType >( - methodName + methodName, ); if (!((methodName as string) in this.#original)) { @@ -62,5 +66,5 @@ export function createFake(OriginalClass: O return methodConfiguration; } - } + }(); } diff --git a/src/interfaces.ts b/src/interfaces.ts index 80532e0f..c13d17b7 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,7 +1,4 @@ -import type { - MethodCalls, - MethodOf, -} from "./types.ts"; +import type { MethodCalls, MethodOf } from "./types.ts"; export interface IError { name: string; @@ -22,7 +19,7 @@ export interface IFake { ): void; method( - methodName: MethodOf + methodName: MethodOf, ): IPreProgrammedMethod; } @@ -36,6 +33,6 @@ export interface IMock { ): void; method( - methodName: MethodOf + methodName: MethodOf, ): IPreProgrammedMethod; } diff --git a/src/mock/mock_builder.ts b/src/mock/mock_builder.ts index 802d08a9..13c679ed 100644 --- a/src/mock/mock_builder.ts +++ b/src/mock/mock_builder.ts @@ -46,7 +46,7 @@ export class MockBuilder { const original = new this.#constructor_fn(...this.#constructor_args); const mock = createMock, ClassToMock>( - this.#constructor_fn + this.#constructor_fn, ); mock.init(original, this.#getAllFunctionNames(original)); @@ -55,7 +55,7 @@ export class MockBuilder { this.#addOriginalObjectPropertyToMockObject( original, mock, - property + property, ); }); @@ -220,7 +220,7 @@ export class MockBuilder { // currently defining returns that pre-programmed value. if (methodToCall instanceof PreProgrammedMethod) { if (methodToCall.will_throw) { - throw methodToCall.error + throw methodToCall.error; } return methodToCall.return; } @@ -234,7 +234,7 @@ export class MockBuilder { // Use `return` because the original function could return a value return bound(...args); - } + }, }); } diff --git a/src/mock/mock_mixin.ts b/src/mock/mock_mixin.ts index cc975050..002fc078 100644 --- a/src/mock/mock_mixin.ts +++ b/src/mock/mock_mixin.ts @@ -4,9 +4,13 @@ import type { IMock } from "../interfaces.ts"; class MockError extends Error {} -export function createMock(OriginalClass: OriginalConstructor): IMock { +export function createMock( + OriginalClass: OriginalConstructor, +): IMock { // deno-lint-ignore no-explicit-any - const Original = OriginalClass as unknown as Constructor<(...args: any[]) => any>; + const Original = OriginalClass as unknown as Constructor< + (...args: any[]) => any + >; return new class MockExtension extends Original { /** * Helper property to see that this is a mock object and not the original. @@ -60,7 +64,7 @@ export function createMock(OriginalClass: O OriginalObject, ReturnValueType >( - methodName + methodName, ); if (!((methodName as string) in this.#original)) { @@ -96,5 +100,5 @@ export function createMock(OriginalClass: O return calls as Record; } - } + }(); } diff --git a/src/pre_programmed_method.ts b/src/pre_programmed_method.ts index 6cdbd21d..c3cff6a1 100644 --- a/src/pre_programmed_method.ts +++ b/src/pre_programmed_method.ts @@ -20,7 +20,6 @@ export class PreProgrammedMethod { /** * @param methodName - The name of the method to program. Must be a method of * the original object in question. - * @param original - The original object object that contains the method. */ constructor(methodName: MethodOf) { this.#method_name = methodName; @@ -69,6 +68,7 @@ export class PreProgrammedMethod { /** * Pre-program this method to return the given value. + * @param returnValue The value that should be returned when this object is * being used in place of an original method. */ @@ -77,6 +77,11 @@ export class PreProgrammedMethod { this.#return = returnValue; } + /** + * Pre-program this method to throw the given error. + * + * @param error - The error to throw. + */ public willThrow(error: IError): void { this.#will_throw = true; this.#error = error; diff --git a/src/types.ts b/src/types.ts index e9b7764b..3509db19 100644 --- a/src/types.ts +++ b/src/types.ts @@ -13,5 +13,5 @@ export type MethodCalls = Record; export type MethodOf = { // deno-lint-ignore no-explicit-any - [K in keyof Object]: Object[K] extends (...args: any) => any ? K : never -}[keyof Object]; \ No newline at end of file + [K in keyof Object]: Object[K] extends (...args: any) => any ? K : never; +}[keyof Object]; diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index 16fc5c6b..1e7af019 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -111,10 +111,10 @@ Deno.test("MockBuilder", async (t) => { mock .method("test") .willReturn({ - name: "something" + name: "something", }); - assertEquals(mock.test(), {name: "something"}); + assertEquals(mock.test(), { name: "something" }); assertEquals(mock.calls.test, 2); assertEquals(mock.calls.hello, 2); }, @@ -128,7 +128,7 @@ Deno.test("MockBuilder", async (t) => { mock .method("someComplexMethod") - .willReturn(mock) + .willReturn(mock); assertEquals(mock.someComplexMethod(), mock); assertEquals(mock.calls.someComplexMethod, 1); @@ -159,7 +159,7 @@ Deno.test("MockBuilder", async (t) => { assertEquals(mock2.calls.someComplexMethod, 1); // Assert that we can also use setters - const mock3= new MockBuilder(TestObjectFourBuilder).create(); + const mock3 = new MockBuilder(TestObjectFourBuilder).create(); assertEquals(mock3.is_mock, true); mock3.someComplexMethod(); assertEquals(mock3.something_one, "one"); @@ -182,12 +182,12 @@ Deno.test("MockBuilder", async (t) => { // Make the original method throw RandomError mock .method("test") - .willThrow(new RandomError("Random error message.")) + .willThrow(new RandomError("Random error message.")); assertThrows( () => mock.test(), RandomError, - "Random error message." + "Random error message.", ); assertEquals(mock.calls.test, 2); }, @@ -205,12 +205,12 @@ Deno.test("MockBuilder", async (t) => { // Make the original method throw RandomError mock .method("test") - .willThrow(new RandomError2()) + .willThrow(new RandomError2()); assertThrows( () => mock.test(), RandomError2, - "Some message not by the constructor." + "Some message not by the constructor.", ); assertEquals(mock.calls.test, 2); }, @@ -253,7 +253,7 @@ class TestObjectFourBuilder { return this.#something_two; } - set something_one(value: string | undefined) { + set something_one(value: string | undefined) { this.#something_one = value; } @@ -278,6 +278,6 @@ class TestObjectFourBuilder { class RandomError extends Error {} class RandomError2 extends Error { - public name = "RandomError2Name" - public message = "Some message not by the constructor." + public name = "RandomError2Name"; + public message = "Some message not by the constructor."; } diff --git a/tests/unit/mod/dummy_test.ts b/tests/unit/mod/dummy_test.ts index cc37f49d..bbf1b6c0 100644 --- a/tests/unit/mod/dummy_test.ts +++ b/tests/unit/mod/dummy_test.ts @@ -28,7 +28,7 @@ class Resource { constructor( serviceOne: ServiceOne, serviceTwo: ServiceTwo, - serviceThree: ServiceThree + serviceThree: ServiceThree, ) { this.#service_one = serviceOne; this.#service_two = serviceTwo; @@ -64,4 +64,4 @@ class ServiceThree { public methodServiceThree() { return "Method from ServiceThree was called."; } -} \ No newline at end of file +} diff --git a/tests/unit/mod/fake_test.ts b/tests/unit/mod/fake_test.ts index a2df308a..fdd94351 100644 --- a/tests/unit/mod/fake_test.ts +++ b/tests/unit/mod/fake_test.ts @@ -63,7 +63,6 @@ class Repository { return `Finding user by id #${id}`; } - #anothaOne() { this.anotha_one_called = true; } From 0cb4c75b4aeb707e1bd6d083a14aaf39e251c889 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 22:08:46 -0400 Subject: [PATCH 19/62] chore: fix doc block --- src/pre_programmed_method.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pre_programmed_method.ts b/src/pre_programmed_method.ts index c3cff6a1..9ae32f85 100644 --- a/src/pre_programmed_method.ts +++ b/src/pre_programmed_method.ts @@ -4,7 +4,10 @@ import type { IError } from "./interfaces.ts"; class PreProgrammedMethodError extends Error {} /** - * Class that allows to be a "stand-in" for a method. For example, when used in a mock object, the mock object can replace methods with pre-programmed methods (using this class), and have a system under test use the pre-programmed methods. + * Class that allows to be a "stand-in" for a method. For example, when used in + * a mock object, the mock object can replace methods with pre-programmed + * methods (using this class), and have a system under test use the + * pre-programmed methods. */ export class PreProgrammedMethod { #method_name: MethodOf; From 937c23fb00c541ac950925ca1ca6ff5a60ed2fdb Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 22:28:34 -0400 Subject: [PATCH 20/62] feat: add method expectation calls for mocks --- src/interfaces.ts | 8 +++++ src/mock/mock_mixin.ts | 58 +++++++++++++++++++++++++++++++++ tests/unit/mock_builder_test.ts | 12 +++++++ 3 files changed, 78 insertions(+) diff --git a/src/interfaces.ts b/src/interfaces.ts index c13d17b7..f0f74189 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,5 +1,9 @@ import type { MethodCalls, MethodOf } from "./types.ts"; +export interface IMethodExpectation { + toBeCalled(numCalls: number): void; +} + export interface IError { name: string; message?: string; @@ -32,7 +36,11 @@ export interface IMock { methodsToTrack: string[], ): void; + expects(method: MethodOf): IMethodExpectation; + method( methodName: MethodOf, ): IPreProgrammedMethod; + + verifyExpectations(): void; } diff --git a/src/mock/mock_mixin.ts b/src/mock/mock_mixin.ts index 002fc078..ceade07c 100644 --- a/src/mock/mock_mixin.ts +++ b/src/mock/mock_mixin.ts @@ -4,6 +4,27 @@ import type { IMock } from "../interfaces.ts"; class MockError extends Error {} +class MethodExpectation { + #method_name: MethodOf; + #expected_calls = 0; + + get method_name(): MethodOf { + return this.#method_name; + } + + get expected_calls(): number { + return this.#expected_calls; + } + + constructor(methodName: MethodOf) { + this.#method_name = methodName; + } + + public toBeCalled(expectedCalls: number) { + this.#expected_calls = expectedCalls; + } +} + export function createMock( OriginalClass: OriginalConstructor, ): IMock { @@ -22,6 +43,11 @@ export function createMock( */ #calls!: MethodCalls; + /** + * An array of expectations to verify (if any). + */ + #expectations: MethodExpectation[] = []; + /** * The original object that this class creates a mock of. */ @@ -52,8 +78,21 @@ export function createMock( // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// + /** + * Create a method expectation, which is basically asserting calls. + * + * @param method - The method to create an expectation for. + * @returns A method expectation. + */ + public expects(method: MethodOf): MethodExpectation { + const expectation = new MethodExpectation(method); + this.#expectations.push(expectation); + return expectation; + } + /** * Pre-program a method on the original to return a specific value. + * * @param methodName The method name on the original. * @returns A pre-programmed method that will be called instead of original. */ @@ -81,6 +120,25 @@ export function createMock( return methodConfiguration; } + /** + * Verify all expectations created in this mock. + */ + public verifyExpectations(): void { + this.#expectations.forEach((e: MethodExpectation) => { + const expectedCalls = e.expected_calls; + const actualCalls = this.#calls[e.method_name]; + if (expectedCalls !== actualCalls) { + throw new MockError( + `Method "${e.method_name}" expected ${expectedCalls} call(s), but received ${actualCalls} call(s).` + ); + } + }); + } + + ////////////////////////////////////////////////////////////////////////////// + // FILE MARKER - METHODS - PRIVATE /////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + /** * Construct the calls property. Only construct it, do not set it. The * constructor will set it. diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index 1e7af019..0da6374a 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -215,6 +215,18 @@ Deno.test("MockBuilder", async (t) => { assertEquals(mock.calls.test, 2); }, }); + + await t.step({ + name: ".expects(...).toBeCalled(...)", + fn(): void { + const mock = new MockBuilder(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + mock.expects("hello").toBeCalled(2); + mock.test(); + mock.verifyExpectations(); + }, + }); }); }); // FILE MARKER - DATA ////////////////////////////////////////////////////////// From 3d00a2514e084000b14f26f18324ef08d69cb4cf Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 22:33:01 -0400 Subject: [PATCH 21/62] chore: fix param name --- src/interfaces.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces.ts b/src/interfaces.ts index f0f74189..72374642 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,7 +1,7 @@ import type { MethodCalls, MethodOf } from "./types.ts"; export interface IMethodExpectation { - toBeCalled(numCalls: number): void; + toBeCalled(expectedCalls: number): void; } export interface IError { From b45e231ab166cdd1a68037f11d853a1152a2d873 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 22:54:38 -0400 Subject: [PATCH 22/62] test: add test creating dummy without constructor args --- tests/unit/mod/dummy_test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/unit/mod/dummy_test.ts b/tests/unit/mod/dummy_test.ts index bbf1b6c0..eb5bc9b6 100644 --- a/tests/unit/mod/dummy_test.ts +++ b/tests/unit/mod/dummy_test.ts @@ -18,6 +18,14 @@ Deno.test("Dummy()", async (t) => { assertEquals(mockServiceOne.calls.methodServiceOne, 1); }, }); + + await t.step({ + name: "can be made without specifying constructor args", + fn(): void { + const dummy = Dummy(Resource); + assertEquals(Object.getPrototypeOf(dummy), Resource); + }, + }); }); class Resource { From 4d05200b27e7416bd4e78d62e6b854c3b923a195 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 22:57:32 -0400 Subject: [PATCH 23/62] chore: make setter adjacent to getter --- tests/unit/mock_builder_test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index 0da6374a..f5a82aec 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -261,14 +261,14 @@ class TestObjectFourBuilder { return this.#something_one; } - get something_two(): string | undefined { - return this.#something_two; - } - set something_one(value: string | undefined) { this.#something_one = value; } + get something_two(): string | undefined { + return this.#something_two; + } + someComplexMethod(): this { this.#setSomethingOne(); this.#setSomethingTwo(); From 37cacc0d5b38a058714d3e24a90320f5aae25a59 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 22:58:05 -0400 Subject: [PATCH 24/62] chore: make file marker comment bigger --- tests/unit/mock_builder_test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index f5a82aec..acaa2c72 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -229,7 +229,10 @@ Deno.test("MockBuilder", async (t) => { }); }); }); + +//////////////////////////////////////////////////////////////////////////////// // FILE MARKER - DATA ////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// class TestObjectOne { } From 49e9fbe6e9e61c21a7cab8f696ea73ffa80a8826 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 23:09:16 -0400 Subject: [PATCH 25/62] refactor!: change stub to only stub data members --- mod.ts | 33 ++++++++++++++---------- src/fake/fake_mixin.ts | 2 +- src/mock/mock_mixin.ts | 8 +++--- src/types.ts | 10 ++------ tests/integration/stub_test.ts | 47 +++++++++++++++++++--------------- 5 files changed, 55 insertions(+), 45 deletions(-) diff --git a/mod.ts b/mod.ts index 10afea27..171dae41 100644 --- a/mod.ts +++ b/mod.ts @@ -1,4 +1,3 @@ -import type { Constructor, Stubbed } from "./src/types.ts"; import { MockBuilder } from "./src/mock/mock_builder.ts"; import { FakeBuilder } from "./src/fake/fake_builder.ts"; export * as Types from "./src/types.ts"; @@ -63,18 +62,26 @@ export const Mock = (constructorFn: Constructor): MockBuilder => { * * @param obj -The object containing the member to stub. */ -export const Stub = (obj: T): Stubbed => { - (obj as unknown as { [key: string]: boolean }).is_stubbed = true; - (obj as unknown as { - [key: string]: (property: string, value: unknown) => void; - }).stub = function ( - property: string, - value: unknown, - ): void { - Object.defineProperty(obj, property, { - value: value, +export const Stub = ( + obj: T, + dataMember: string, + returnValue?: unknown, +): void => { + Object.defineProperty(obj, "is_stubbed", { + value: true, + }); + + const dataMemberToStub = obj[dataMember as keyof T]; + + if (typeof dataMemberToStub === "function") { + Object.defineProperty(obj, dataMember, { + value: () => returnValue ?? null, }); - }; - return obj as Stubbed; + return; + } + + Object.defineProperty(obj, dataMember, { + value: returnValue ?? null, + }); }; diff --git a/src/fake/fake_mixin.ts b/src/fake/fake_mixin.ts index 775ea609..cc796348 100644 --- a/src/fake/fake_mixin.ts +++ b/src/fake/fake_mixin.ts @@ -7,8 +7,8 @@ class FakeError extends Error {} export function createFake( OriginalClass: OriginalConstructor, ): IFake { - // deno-lint-ignore no-explicit-any const Original = OriginalClass as unknown as Constructor< + // deno-lint-ignore no-explicit-any (...args: any[]) => any >; return new class FakeExtension extends Original { diff --git a/src/mock/mock_mixin.ts b/src/mock/mock_mixin.ts index ceade07c..c9fa1dd7 100644 --- a/src/mock/mock_mixin.ts +++ b/src/mock/mock_mixin.ts @@ -28,8 +28,8 @@ class MethodExpectation { export function createMock( OriginalClass: OriginalConstructor, ): IMock { - // deno-lint-ignore no-explicit-any const Original = OriginalClass as unknown as Constructor< + // deno-lint-ignore no-explicit-any (...args: any[]) => any >; return new class MockExtension extends Original { @@ -84,7 +84,9 @@ export function createMock( * @param method - The method to create an expectation for. * @returns A method expectation. */ - public expects(method: MethodOf): MethodExpectation { + public expects( + method: MethodOf, + ): MethodExpectation { const expectation = new MethodExpectation(method); this.#expectations.push(expectation); return expectation; @@ -129,7 +131,7 @@ export function createMock( const actualCalls = this.#calls[e.method_name]; if (expectedCalls !== actualCalls) { throw new MockError( - `Method "${e.method_name}" expected ${expectedCalls} call(s), but received ${actualCalls} call(s).` + `Method "${e.method_name}" expected ${expectedCalls} call(s), but received ${actualCalls} call(s).`, ); } }); diff --git a/src/types.ts b/src/types.ts index 3509db19..7059808e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,17 +1,11 @@ // deno-lint-ignore no-explicit-any export type Constructor = new (...args: any[]) => T; -export type MockedObject = { [k: string]: unknown }; - -export type Stubbed = T & { - calls: { [k in keyof T]?: T[k] extends () => void ? number : never }; - stub: (p: string, v: unknown) => void; - is_stubbed: true; -}; - export type MethodCalls = Record; export type MethodOf = { // deno-lint-ignore no-explicit-any [K in keyof Object]: Object[K] extends (...args: any) => any ? K : never; }[keyof Object]; + +export type MockedObject = { [k: string]: unknown }; diff --git a/tests/integration/stub_test.ts b/tests/integration/stub_test.ts index 6cb39dfe..0209caf8 100644 --- a/tests/integration/stub_test.ts +++ b/tests/integration/stub_test.ts @@ -7,30 +7,37 @@ class Server { public methodThatLogs() { console.log("Server running."); } - - public methodThatThrows() { - } } -Deno.test("stub()", async (t) => { - await t.step("Can stub a property", () => { - const server = Stub(new Server()); - server.stub("greeting", "you got changed"); +Deno.test("Stub()", async (t) => { + await t.step("can stub a property", () => { + const server = new Server(); + Stub(server, "greeting", "you got changed"); assertEquals(server.greeting, "you got changed"); + // `is_stubbed` should be added when stubbing an object + assertEquals("is_stubbed" in server, true); }); - await t.step("Can stub a method", () => { - const server = Stub(new Server()); - server.stub("methodThatLogs", () => { - return "don't run the console.log()"; - }); - assertEquals( - server.methodThatLogs(), - "don't run the console.log()", - ); - assertEquals( - server.is_stubbed, - true, - ); + await t.step("can stub a function", () => { + const server = new Server(); + Stub(server, "methodThatLogs"); + assertEquals(server.methodThatLogs(), null); + // `is_stubbed` should be added when stubbing an object + assertEquals("is_stubbed" in server, true); }); + + // await t.step("Can stub a method", () => { + // const server = Stub(new Server()); + // server.stub("methodThatLogs", () => { + // return "don't run the console.log()"; + // }); + // assertEquals( + // server.methodThatLogs(), + // "don't run the console.log()", + // ); + // assertEquals( + // server.is_stubbed, + // true, + // ); + // }); }); From 5cfcaabfab5928d65722e8830fe112c25290d204 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 23:15:17 -0400 Subject: [PATCH 26/62] feat: new readme --- README.md | 52 ++++++++++------------------------------------------ 1 file changed, 10 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 7ea820a5..2372eb16 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,15 @@ -

- Rhum - A lightweight testing framework for Deno. -

Rhum

-

-

A test double module to stub and mock your code

-

- - - - - - - - - - - - - - - -

+# Drash ---- +[![Latest Release](https://img.shields.io/github/release/drashland/rhum.svg?color=bright_green&label=latest)](#) +[![CI master](https://img.shields.io/github/workflow/status/drashland/rhum/master?label=ci%20-%20master)](#) +[![YouTube](https://img.shields.io/badge/tutorials-youtube-red)](https://rb.gy/vxmeed) -### Features +Rhum logo -- Lightweight -- Zero 3rd party dependencies -- Simple and easy to use -- Asynchronous support -- Mock requests -- Hooks +Rhum is a test double library following [definitions from Martin Fowler](https://martinfowler.com/bliki/TestDouble.html). -### Getting Started +View the full documentation at https://drash.land/rhum. -To add Rhum to your project, follow the quick start guide -[here](https://drash.land/rhum/#/#quickstart). - -## Contributing - -Want to contribute? Follow the Contributing Guidelines -[here](https://github.com/drashland/.github/blob/master/CONTRIBUTING.md). - -## License - -All code is released under the [MIT License](./LICENSE). +In the event the documentation pages are not accessible, please view the raw +version of the documentation at +https://github.com/drashland/website-v2/tree/main/docs. From 05c66d29c5f04db984710a90b9a22f342d6dd19b Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 23:18:23 -0400 Subject: [PATCH 27/62] docs: update README to state Gerard Meszaros --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2372eb16..2a99c66d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Rhum logo -Rhum is a test double library following [definitions from Martin Fowler](https://martinfowler.com/bliki/TestDouble.html). +Rhum is a test double library that follows [test double definitions](https://martinfowler.com/bliki/TestDouble.html) from Gerard Meszaros. View the full documentation at https://drash.land/rhum. From 15dd9cd7747bfbe5089b0ef01c62fcaaf5b02b4a Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Mon, 11 Apr 2022 23:20:52 -0400 Subject: [PATCH 28/62] chore: state Gerard Meszaros in doc blocks --- mod.ts | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/mod.ts b/mod.ts index 171dae41..7b4e526e 100644 --- a/mod.ts +++ b/mod.ts @@ -6,8 +6,9 @@ export * as Interfaces from "./src/interfaces.ts"; /** * Create a dummy. * - * Per Martin Fowler, "Dummy objects are passed around but never actually used. - * Usually they are just used to fill parameter lists." + * Per Martin Fowler (based on Gerard Meszaros), "Dummy objects are passed + * around but never actually used. Usually they are just used to fill parameter + * lists." * * @param constructorFn - The constructor function to use to become the * prototype of the dummy. Dummy objects should be the same instance as what @@ -25,9 +26,9 @@ export const Dummy = (constructorFn?: Constructor): T => { /** * Get the builder to create fake objects. * - * Per Martin Fowler, "Fake objects actually have working implementations, but - * usually take some shortcut which makes them not suitable for production (an - * InMemoryTestDatabase is a good example)." + * Per Martin Fowler (based on Gerard Meszaros), "Fake objects actually have + * working implementations, but usually take some shortcut which makes them not + * suitable for production (an InMemoryTestDatabase is a good example)." * * @param constructorFn - The constructor function of the object to fake. * @@ -40,10 +41,11 @@ export const Fake = (constructorFn: Constructor): FakeBuilder => { /** * Get the builder to create mocked objects. * - * Per Martin Fowler, "Mocks are pre-programmed with expectations which form a - * specification of the calls they are expected to receive. They can throw an - * exception if they receive a call they don't expect and are checked during - * verification to ensure they got all the calls they were expecting." + * Per Martin Fowler (based on Gerard Meszaros), "Mocks are pre-programmed with + * expectations which form a specification of the calls they are expected to + * receive. They can throw an exception if they receive a call they don't expect + * and are checked during verification to ensure they got all the calls they + * were expecting." * * @param constructorFn - The constructor function of the object to mock. * @@ -56,9 +58,9 @@ export const Mock = (constructorFn: Constructor): MockBuilder => { /** * Create a stub. * - * Per Martin Fowler, "Stubs provide canned answers to calls made during the - * test, usually not responding at all to anything outside what's programmed in - * for the test." + * Per Martin Fowler (based on Gerard Meszaros), "Stubs provide canned answers + * to calls made during the test, usually not responding at all to anything + * outside what's programmed in for the test." * * @param obj -The object containing the member to stub. */ From b1e4c77c5edc258e35c17ce907a13238a38fe8eb Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Tue, 12 Apr 2022 05:53:21 -0400 Subject: [PATCH 29/62] fix: accidentally removed Constructor type import --- mod.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/mod.ts b/mod.ts index 7b4e526e..fba45714 100644 --- a/mod.ts +++ b/mod.ts @@ -1,3 +1,4 @@ +import { Constructor } from "./src/types.ts"; import { MockBuilder } from "./src/mock/mock_builder.ts"; import { FakeBuilder } from "./src/fake/fake_builder.ts"; export * as Types from "./src/types.ts"; From cf1297f99018723d091fc4d9aef8a44671e88ec3 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Tue, 12 Apr 2022 08:41:11 -0400 Subject: [PATCH 30/62] chore: deno fmt and clean up --- README.md | 4 +++- src/fake/fake_builder.ts | 2 -- src/mock/mock_builder.ts | 2 -- src/types.ts | 10 ++++++++-- tests/unit/mock_builder_test.ts | 4 ---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2a99c66d..f392ab53 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ Rhum logo -Rhum is a test double library that follows [test double definitions](https://martinfowler.com/bliki/TestDouble.html) from Gerard Meszaros. +Rhum is a test double library that follows +[test double definitions](https://martinfowler.com/bliki/TestDouble.html) from +Gerard Meszaros. View the full documentation at https://drash.land/rhum. diff --git a/src/fake/fake_builder.ts b/src/fake/fake_builder.ts index 0cb14efe..0130fa8d 100644 --- a/src/fake/fake_builder.ts +++ b/src/fake/fake_builder.ts @@ -200,8 +200,6 @@ export class FakeBuilder { fake: IFake, method: keyof ClassToFake, ): void { - // console.log(`METHOD IS THIS: `, method); - Object.defineProperty(fake, method, { value: (...args: unknown[]) => { // Make sure the method calls its original self diff --git a/src/mock/mock_builder.ts b/src/mock/mock_builder.ts index 13c679ed..e3aff42a 100644 --- a/src/mock/mock_builder.ts +++ b/src/mock/mock_builder.ts @@ -202,8 +202,6 @@ export class MockBuilder { mock: IMock, method: keyof ClassToMock, ): void { - // console.log(`METHOD IS THIS: `, method); - Object.defineProperty(mock, method, { value: (...args: unknown[]) => { // Track that this method was called diff --git a/src/types.ts b/src/types.ts index 7059808e..647949f1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,8 +4,14 @@ export type Constructor = new (...args: any[]) => T; export type MethodCalls = Record; export type MethodOf = { - // deno-lint-ignore no-explicit-any - [K in keyof Object]: Object[K] extends (...args: any) => any ? K : never; + [K in keyof Object]: Object[K] extends (...args: unknown[]) => unknown ? K : never; +}[keyof Object]; + +export type MemberOf = { + [K in keyof Object]: Object[K]; }[keyof Object]; export type MockedObject = { [k: string]: unknown }; + +export type StubReturnValue = T extends (...args: unknown[]) => unknown ? () => R + : string; diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mock_builder_test.ts index acaa2c72..1b2ac50d 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mock_builder_test.ts @@ -279,11 +279,7 @@ class TestObjectFourBuilder { } #setSomethingOne(): void { - // console.log("inside setSomethingOne()"); - // console.log(this); this.#something_one = "one"; - // console.log(`set something_one:`, this.#something_one); - // console.log(this); } #setSomethingTwo(): void { From 1e9d2c510ab73b5f30316f9ebe65f44b215f4c90 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Tue, 12 Apr 2022 08:42:35 -0400 Subject: [PATCH 31/62] refactor!: shorten syntax to stub class properties and methods; make blank Stub() call return stub function --- mod.ts | 94 +++++++++++++++++++++++----------- tests/integration/stub_test.ts | 44 ++++++++-------- 2 files changed, 87 insertions(+), 51 deletions(-) diff --git a/mod.ts b/mod.ts index fba45714..53715a7d 100644 --- a/mod.ts +++ b/mod.ts @@ -1,4 +1,4 @@ -import { Constructor } from "./src/types.ts"; +import type { Constructor, StubReturnValue } from "./src/types.ts"; import { MockBuilder } from "./src/mock/mock_builder.ts"; import { FakeBuilder } from "./src/fake/fake_builder.ts"; export * as Types from "./src/types.ts"; @@ -18,11 +18,11 @@ export * as Interfaces from "./src/interfaces.ts"; * should be an instance of `SomeClass`. * @returns A dummy object being an instance of the given constructor function. */ -export const Dummy = (constructorFn?: Constructor): T => { +export function Dummy(constructorFn?: Constructor): T { const dummy = Object.create({}); Object.setPrototypeOf(dummy, constructorFn ?? Object); return dummy; -}; +} /** * Get the builder to create fake objects. @@ -35,9 +35,9 @@ export const Dummy = (constructorFn?: Constructor): T => { * * @returns Instance of `FakeBuilder`. */ -export const Fake = (constructorFn: Constructor): FakeBuilder => { +export function Fake(constructorFn: Constructor): FakeBuilder { return new FakeBuilder(constructorFn); -}; +} /** * Get the builder to create mocked objects. @@ -52,39 +52,73 @@ export const Fake = (constructorFn: Constructor): FakeBuilder => { * * @returns Instance of `MockBuilder`. */ -export const Mock = (constructorFn: Constructor): MockBuilder => { +export function Mock(constructorFn: Constructor): MockBuilder { return new MockBuilder(constructorFn); -}; +} /** - * Create a stub. + * Create a stub function that returns "stubbed". + */ +export function Stub(): () => "stubbed"; +/** + * Take the given object and stub its given data member to return the given + * return value. + * + * @param obj - The object receiving the stub. + * @param dataMember - The data member on the object to be stubbed. + * @param returnValue - (optional) What the stub should return. Defaults to + * "stubbed". + */ +export function Stub( + obj: T, + dataMember: keyof T, + returnValue?: R, +): StubReturnValue; +/** + * Take the given object and stub its given data member to return the given + * return value. * * Per Martin Fowler (based on Gerard Meszaros), "Stubs provide canned answers * to calls made during the test, usually not responding at all to anything * outside what's programmed in for the test." * - * @param obj -The object containing the member to stub. + * @param obj - (optional) The object receiving the stub. Defaults to a stub + * function. + * @param dataMember - (optional) The data member on the object to be stubbed. + * Only used if `obj` is an object. + * @param returnValue - (optional) What the stub should return. Defaults to + * "stubbed" for class properties and a function that returns "stubbed" for + * class methods. Only used if `object` is an object and `dataMember` is a + * member of that object. */ -export const Stub = ( - obj: T, - dataMember: string, - returnValue?: unknown, -): void => { - Object.defineProperty(obj, "is_stubbed", { - value: true, - }); - - const dataMemberToStub = obj[dataMember as keyof T]; - - if (typeof dataMemberToStub === "function") { - Object.defineProperty(obj, dataMember, { - value: () => returnValue ?? null, - }); - - return; +export function Stub( + obj?: T, + dataMember?: keyof T, + returnValue?: R, +): unknown { + if (obj === undefined) { + return function stubbed() { + return "stubbed"; + }; } - Object.defineProperty(obj, dataMember, { - value: returnValue ?? null, - }); -}; + // If we get here, then we know for a fact that we are stubbing object + // properties. Also, we do not care if `returnValue` was passed in here. If it + // is not passed in, then `returnValue` defaults to "stubbed". Otherwise, use + // the value of `returnValue`. + if (typeof obj === "object" && dataMember !== undefined) { + // If we are stubbing a method, then make sure the method is still callable + if (typeof obj[dataMember] === "function") { + Object.defineProperty(obj, dataMember, { + value: () => returnValue !== undefined ? returnValue : "stubbed", + writable: true, + }); + } else { + // If we are stubbing a property, then just reassign the property + Object.defineProperty(obj, dataMember, { + value: returnValue !== undefined ? returnValue : "stubbed", + writable: true, + }); + } + } +} diff --git a/tests/integration/stub_test.ts b/tests/integration/stub_test.ts index 0209caf8..f46e9f14 100644 --- a/tests/integration/stub_test.ts +++ b/tests/integration/stub_test.ts @@ -5,39 +5,41 @@ class Server { public greeting = "hello"; public methodThatLogs() { - console.log("Server running."); + return "server is running!"; } } Deno.test("Stub()", async (t) => { - await t.step("can stub a property", () => { + await t.step("can stub a class property", () => { const server = new Server(); + assertEquals(server.greeting, "hello"); Stub(server, "greeting", "you got changed"); assertEquals(server.greeting, "you got changed"); - // `is_stubbed` should be added when stubbing an object - assertEquals("is_stubbed" in server, true); + Stub(server, "greeting", null); + assertEquals(server.greeting, null); + Stub(server, "greeting", true); + assertEquals(server.greeting, true); + const obj = { test: "hello" }; + Stub(server, "greeting", obj); + assertEquals(server.greeting, obj); }); - await t.step("can stub a function", () => { + await t.step("can stub a class method", () => { const server = new Server(); + assertEquals(server.methodThatLogs(), "server is running!"); Stub(server, "methodThatLogs"); + assertEquals(server.methodThatLogs(), "stubbed"); + Stub(server, "methodThatLogs", null); assertEquals(server.methodThatLogs(), null); - // `is_stubbed` should be added when stubbing an object - assertEquals("is_stubbed" in server, true); + Stub(server, "methodThatLogs", true); + assertEquals(server.methodThatLogs(), true); + const obj = { test: "hello" }; + Stub(server, "methodThatLogs", obj); + assertEquals(server.methodThatLogs(), obj); }); - // await t.step("Can stub a method", () => { - // const server = Stub(new Server()); - // server.stub("methodThatLogs", () => { - // return "don't run the console.log()"; - // }); - // assertEquals( - // server.methodThatLogs(), - // "don't run the console.log()", - // ); - // assertEquals( - // server.is_stubbed, - // true, - // ); - // }); + await t.step("can return a stubbed function", () => { + const stub = Stub(); + assertEquals(stub(), "stubbed"); + }); }); From 50e9dc593581de17b3c539e231b49c093bbfb204 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Tue, 12 Apr 2022 21:22:48 -0400 Subject: [PATCH 32/62] chore: cleaning up --- src/fake/fake_builder.ts | 3 + src/types.ts | 7 +- tests/integration/mock_test.ts | 190 ---------- tests/unit/mod/fake_test.ts | 341 ++++++++++++++++-- tests/unit/mod/mock_2_test.ts | 70 ++++ .../mock_test.ts} | 280 +++++++++++--- tests/{integration => unit/mod}/stub_test.ts | 4 +- 7 files changed, 634 insertions(+), 261 deletions(-) delete mode 100644 tests/integration/mock_test.ts create mode 100644 tests/unit/mod/mock_2_test.ts rename tests/unit/{mock_builder_test.ts => mod/mock_test.ts} (51%) rename tests/{integration => unit/mod}/stub_test.ts (93%) diff --git a/src/fake/fake_builder.ts b/src/fake/fake_builder.ts index 0130fa8d..556b7b97 100644 --- a/src/fake/fake_builder.ts +++ b/src/fake/fake_builder.ts @@ -212,6 +212,9 @@ export class FakeBuilder { // something. If it was, then we make sure that this method we are // currently defining returns that pre-programmed value. if (methodToCall instanceof PreProgrammedMethod) { + if (methodToCall.will_throw) { + throw methodToCall.error; + } return methodToCall.return; } diff --git a/src/types.ts b/src/types.ts index 647949f1..17a6c0bd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,7 +4,9 @@ export type Constructor = new (...args: any[]) => T; export type MethodCalls = Record; export type MethodOf = { - [K in keyof Object]: Object[K] extends (...args: unknown[]) => unknown ? K : never; + // deno-lint-ignore no-explicit-any + [K in keyof Object]: Object[K] extends (...args: any[]) => unknown ? K + : never; }[keyof Object]; export type MemberOf = { @@ -13,5 +15,6 @@ export type MemberOf = { export type MockedObject = { [k: string]: unknown }; -export type StubReturnValue = T extends (...args: unknown[]) => unknown ? () => R +export type StubReturnValue = T extends (...args: unknown[]) => unknown + ? () => R : string; diff --git a/tests/integration/mock_test.ts b/tests/integration/mock_test.ts deleted file mode 100644 index 787c536c..00000000 --- a/tests/integration/mock_test.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { Mock } from "../../mod.ts"; -import { assertEquals } from "../deps.ts"; - -class MathService { - public add( - num1: number, - num2: number, - useNestedAdd = false, - ): number { - if (useNestedAdd) { - return this.nestedAdd(num1, num2); - } - return num1 + num2; - } - - public nestedAdd(num1: number, num2: number): number { - return num1 + num2; - } -} - -class TestObject { - public name: string; - #age = 0; - protected math_service: MathService; - protected protected_property = "I AM PROTECTED PROPERTY."; - constructor(name: string, mathService: MathService) { - this.math_service = mathService; - this.name = name; - } - public sum( - num1: number, - num2: number, - useNestedAdd = false, - ): number { - const sum = this.math_service.add(num1, num2, useNestedAdd); - return sum; - } - protected protectedMethod() { - return "I AM A PROTECTED METHOD."; - } - - public get age() { - return this.#age; - } - - public set age(val: number) { - this.#age = val; - } -} - -class TestRequestHandler { - // deno-lint-ignore require-await - async handle(request: Request): Promise { - const method = request.method.toLowerCase(); - const contentType = request.headers.get("Content-Type"); - - if (method !== "post") { - return "Method is not post"; - } - - if (contentType !== "application/json") { - return "Content-Type is incorrect"; - } - - return "posted"; - } -} - -Deno.test("mock()", async (t) => { - await t.step({ - name: "can mock an object", - fn() { - const mock = Mock(TestObject) - .create(); - assertEquals(mock.constructor.name, "TestObject"); - assertEquals(mock.is_mock, true); - }, - }); - - await t.step("Can mock an object with constructor args", () => { - const mock = Mock(TestObject) - .withConstructorArgs("my server", new MathService()) - .create(); - assertEquals(mock.constructor.name, "TestObject"); - assertEquals(mock.is_mock, true); - assertEquals(mock.name, "my server"); - }); - - await t.step("can access protected property", () => { - const mock = Mock(TestObject) - .create(); - assertEquals( - (mock as unknown as { [key: string]: string }).protected_property, - "I AM PROTECTED PROPERTY.", - ); - }); - - await t.step("Can access protected method", () => { - const mock = Mock(TestObject) - .create(); - assertEquals( - (mock as unknown as { [key: string]: () => string }).protectedMethod(), - "I AM A PROTECTED METHOD.", - ); - }); - - await t.step("has mocked math service", () => { - const mockMathService = Mock(MathService) - .create(); - const mockTestObject = Mock(TestObject) - .withConstructorArgs("has mocked math service", mockMathService) - .create(); - assertEquals(mockMathService.calls.add, 0); - mockTestObject.sum(1, 1); - assertEquals(mockMathService.calls.add, 1); - }); - - await t.step("call count for outside nested function is increased", () => { - const mockMathService = Mock(MathService) - .create(); - const mockTestObject = Mock(TestObject) - .withConstructorArgs("has mocked math service", mockMathService) - .create(); - assertEquals(mockMathService.calls.add, 0); - assertEquals(mockMathService.calls.nestedAdd, 0); - mockTestObject.sum(1, 1, true); - assertEquals(mockMathService.calls.add, 1); - assertEquals(mockMathService.calls.nestedAdd, 1); - }); - - await t.step("can mock getters and setters", () => { - const mock = Mock(TestObject) - .create(); - mock.age = 999; - assertEquals(mock.age, 999); - }); - - await t.step("Native request mock", async () => { - const router = Mock(TestRequestHandler).create(); - - const reqPost = new Request("https://google.com", { - method: "post", - headers: { - "content-type": "application/json", - }, - }); - assertEquals(router.calls.handle, 0); - assertEquals(await router.handle(reqPost), "posted"); - assertEquals(router.calls.handle, 1); - - const reqPostNotJson = new Request("https://google.com", { - method: "post", - }); - assertEquals(router.calls.handle, 1); - assertEquals( - await router.handle(reqPostNotJson), - "Content-Type is incorrect", - ); - assertEquals(router.calls.handle, 2); - - const reqGet = new Request("https://google.com", { - method: "get", - }); - - assertEquals(router.calls.handle, 2); - assertEquals( - await router.handle(reqGet), - "Method is not post", - ); - assertEquals(router.calls.handle, 3); - }); - - await t.step("Sets the default value for getters", () => { - class Game { - } - - class PlayersEngine { - private game = new Game(); - get Game() { - return this.game; - } - set Game(val: Game) { - this.game = val; - } - } - - const mock = Mock(PlayersEngine).create(); - assertEquals(mock.Game instanceof Game, true); - }); -}); diff --git a/tests/unit/mod/fake_test.ts b/tests/unit/mod/fake_test.ts index fdd94351..713717d3 100644 --- a/tests/unit/mod/fake_test.ts +++ b/tests/unit/mod/fake_test.ts @@ -1,34 +1,291 @@ import { Fake } from "../../../mod.ts"; -import { assertEquals } from "../../deps.ts"; +import { assertEquals, assertThrows } from "../../deps.ts"; Deno.test("Fake()", async (t) => { await t.step({ - name: "can cause shortcuts", + name: "creates fake builder", fn(): void { - // Assert that a fake can make a class take a shortcut - const fakeServiceDoingShortcut = Fake(Repository).create(); - fakeServiceDoingShortcut.method("findAllUsers").willReturn("shortcut"); - const resourceWithShortcut = new Resource( - fakeServiceDoingShortcut, - ); - resourceWithShortcut.getUsers(); - assertEquals(fakeServiceDoingShortcut.anotha_one_called, false); - assertEquals(fakeServiceDoingShortcut.do_something_called, false); - assertEquals(fakeServiceDoingShortcut.do_something_else_called, false); - - // Assert that the fake service is not yet doing a shortcut - const fakeServiceNotDoingShortcut = Fake(Repository).create(); - const resourceWithoutShortcut = new Resource( - fakeServiceNotDoingShortcut, - ); - resourceWithoutShortcut.getUsers(); - assertEquals(fakeServiceNotDoingShortcut.anotha_one_called, true); - assertEquals(fakeServiceNotDoingShortcut.do_something_called, true); - assertEquals(fakeServiceNotDoingShortcut.do_something_else_called, true); + const fake = Fake(TestObjectOne); + assertEquals(fake.constructor.name, "FakeBuilder"); }, }); + + await t.step(".create()", async (t) => { + await t.step({ + name: "creates fake object", + fn(): void { + const fake = Fake(TestObjectTwo).create(); + assertEquals(fake.name, undefined); + assertEquals(fake.is_fake, true); + }, + }); + }); + + await t.step(".withConstructorArgs(...)", async (t) => { + await t.step({ + name: "can take 1 arg", + fn(): void { + const fake = Fake(TestObjectTwo) + .withConstructorArgs("some name") + .create(); + assertEquals(fake.name, "some name"); + assertEquals(fake.is_fake, true); + }, + }); + + await t.step({ + name: "can take more than 1 arg", + fn(): void { + const fake = Fake(TestObjectTwoMore) + .withConstructorArgs("some name", ["hello"]) + .create(); + assertEquals(fake.name, "some name"); + assertEquals(fake.array, ["hello"]); + assertEquals(fake.is_fake, true); + }, + }); + }); + + await t.step(".method(...)", async (t) => { + await t.step({ + name: "requires .willReturn(...) or .willThrow(...) to be chained", + fn(): void { + const fake = Fake(TestObjectThree).create(); + assertEquals(fake.is_fake, true); + + // Original returns "World" + assertEquals(fake.test(), "World"); + + // Don't fully pre-program the method. This should cause an error during assertions. + fake.method("test"); + + try { + fake.test(); + } catch (error) { + assertEquals( + error.message, + `Pre-programmed method "test" does not have a return value.`, + ); + } + }, + }); + + await t.step({ + name: + ".willReturn(...) does not call original method and returns given value", + fn(): void { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findAllUsers").willReturn("shortcut"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUsers(); + assertEquals(fakeServiceDoingShortcut.anotha_one_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_else_called, false); + + // Assert that the fake service can call original implementations + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUsers(); + assertEquals(fakeServiceNotDoingShortcut.anotha_one_called, true); + assertEquals(fakeServiceNotDoingShortcut.do_something_called, true); + assertEquals( + fakeServiceNotDoingShortcut.do_something_else_called, + true, + ); + }, + }); + + await t.step({ + name: ".willReturn(...) can be performed more than once", + fn(): void { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findUserById").willReturn("shortcut"); + fakeServiceDoingShortcut.method("findUserById").willReturn("shortcut2"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUser(1); + assertEquals(fakeServiceDoingShortcut.anotha_one_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_else_called, false); + + // Assert that the fake service can call original implementations + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUser(1); + assertEquals(fakeServiceNotDoingShortcut.anotha_one_called, true); + assertEquals(fakeServiceNotDoingShortcut.do_something_called, true); + assertEquals( + fakeServiceNotDoingShortcut.do_something_else_called, + true, + ); + }, + }); + + await t.step({ + name: ".willThrow(...) does not call original method and throws error", + fn(): void { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findAllUsers").willReturn("shortcut"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUsers(); + assertEquals(fakeServiceDoingShortcut.anotha_one_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_else_called, false); + + // Assert that the fake service can call original implementations + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUsers(); + assertEquals(fakeServiceNotDoingShortcut.anotha_one_called, true); + assertEquals(fakeServiceNotDoingShortcut.do_something_called, true); + assertEquals( + fakeServiceNotDoingShortcut.do_something_else_called, + true, + ); + }, + }); + + await t.step({ + name: ".willReturn(fake) returns the fake object (basic)", + fn(): void { + const fake = Fake(TestObjectFourBuilder).create(); + assertEquals(fake.is_fake, true); + + fake + .method("someComplexMethod") + .willReturn(fake); + + assertEquals(fake.someComplexMethod(), fake); + }, + }); + + await t.step({ + name: ".willReturn(fake) returns the fake object (extra)", + fn(): void { + // Assert that the original implementation sets properties + const fake1 = Fake(TestObjectFourBuilder).create(); + assertEquals(fake1.is_fake, true); + fake1.someComplexMethod(); + assertEquals(fake1.something_one, "one"); + assertEquals(fake1.something_two, "two"); + + // Assert that the fake implementation will not set properties + const fake2 = Fake(TestObjectFourBuilder).create(); + assertEquals(fake2.is_fake, true); + fake2 + .method("someComplexMethod") + .willReturn(fake2); + + assertEquals(fake2.someComplexMethod(), fake2); + assertEquals(fake2.something_one, undefined); + assertEquals(fake2.something_two, undefined); + + // Assert that we can also use setters + const fake3 = Fake(TestObjectFourBuilder).create(); + assertEquals(fake3.is_fake, true); + fake3.someComplexMethod(); + assertEquals(fake3.something_one, "one"); + assertEquals(fake3.something_two, "two"); + fake3.something_one = "you got changed"; + assertEquals(fake3.something_one, "you got changed"); + }, + }); + + await t.step({ + name: ".willThrow() causes throwing RandomError (with constructor)", + fn(): void { + const fake = Fake(TestObjectThree).create(); + assertEquals(fake.is_fake, true); + + // Original returns "World" + assertEquals(fake.test(), "World"); + + // Make the original method throw RandomError + fake + .method("test") + .willThrow(new RandomError("Random error message.")); + + assertThrows( + () => fake.test(), + RandomError, + "Random error message.", + ); + }, + }); + + await t.step({ + name: ".willThrow() causes throwing RandomError2 (no constructor)", + fn(): void { + const fake = Fake(TestObjectThree).create(); + assertEquals(fake.is_fake, true); + + // Original returns "World" + assertEquals(fake.test(), "World"); + + // Make the original method throw RandomError + fake + .method("test") + .willThrow(new RandomError2()); + + assertThrows( + () => fake.test(), + RandomError2, + "Some message not by the constructor.", + ); + }, + }); + }); }); +//////////////////////////////////////////////////////////////////////////////// +// FILE MARKER - DATA ////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +class TestObjectOne { +} + +class TestObjectTwo { + public name: string; + constructor(name: string) { + this.name = name; + } +} + +class TestObjectTwoMore { + public name: string; + public array: string[]; + constructor(name: string, array: string[]) { + this.name = name; + this.array = array; + } +} + +class TestObjectThree { + public hello(): void { + return; + } + + public test(): string { + this.hello(); + this.hello(); + return "World"; + } +} + class Resource { #repository: Repository; @@ -47,6 +304,37 @@ class Resource { } } +class TestObjectFourBuilder { + #something_one?: string; + #something_two?: string; + + get something_one(): string | undefined { + return this.#something_one; + } + + set something_one(value: string | undefined) { + this.#something_one = value; + } + + get something_two(): string | undefined { + return this.#something_two; + } + + someComplexMethod(): this { + this.#setSomethingOne(); + this.#setSomethingTwo(); + return this; + } + + #setSomethingOne(): void { + this.#something_one = "one"; + } + + #setSomethingTwo(): void { + this.#something_two = "two"; + } +} + class Repository { public anotha_one_called = false; public do_something_called = false; @@ -60,6 +348,9 @@ class Repository { } public findUserById(id: number): string { + this.#doSomething(); + this.#doSomethingElse(); + this.#anothaOne(); return `Finding user by id #${id}`; } @@ -75,3 +366,9 @@ class Repository { this.do_something_else_called = true; } } + +class RandomError extends Error {} +class RandomError2 extends Error { + public name = "RandomError2Name"; + public message = "Some message not by the constructor."; +} diff --git a/tests/unit/mod/mock_2_test.ts b/tests/unit/mod/mock_2_test.ts new file mode 100644 index 00000000..ec60aeb2 --- /dev/null +++ b/tests/unit/mod/mock_2_test.ts @@ -0,0 +1,70 @@ +import { Mock } from "../../../mod.ts"; +import { assertEquals } from "../../deps.ts"; + +class MathService { + public add( + num1: number, + num2: number, + useNestedAdd = false, + ): number { + if (useNestedAdd) { + return this.nestedAdd(num1, num2); + } + return num1 + num2; + } + + public nestedAdd(num1: number, num2: number): number { + return num1 + num2; + } +} + +class TestObjectLotsOfDataMembers { + public name: string; + #age = 0; + protected math_service: MathService; + protected protected_property = "I AM PROTECTED PROPERTY."; + constructor(name: string, mathService: MathService) { + this.math_service = mathService; + this.name = name; + } + public sum( + num1: number, + num2: number, + useNestedAdd = false, + ): number { + const sum = this.math_service.add(num1, num2, useNestedAdd); + return sum; + } + protected protectedMethod() { + return "I AM A PROTECTED METHOD."; + } + + public get age() { + return this.#age; + } + + public set age(val: number) { + this.#age = val; + } +} + +class TestRequestHandler { + // deno-lint-ignore require-await + async handle(request: Request): Promise { + const method = request.method.toLowerCase(); + const contentType = request.headers.get("Content-Type"); + + if (method !== "post") { + return "Method is not post"; + } + + if (contentType !== "application/json") { + return "Content-Type is incorrect"; + } + + return "posted"; + } +} + +Deno.test("mock()", async (t) => { +}); diff --git a/tests/unit/mock_builder_test.ts b/tests/unit/mod/mock_test.ts similarity index 51% rename from tests/unit/mock_builder_test.ts rename to tests/unit/mod/mock_test.ts index 1b2ac50d..973f9a73 100644 --- a/tests/unit/mock_builder_test.ts +++ b/tests/unit/mod/mock_test.ts @@ -1,62 +1,109 @@ -import { assertEquals, assertThrows } from "../deps.ts"; -import { MockBuilder } from "../../src/mock/mock_builder.ts"; +import { Mock } from "../../../mod.ts"; +import { assertEquals, assertThrows } from "../../deps.ts"; + +Deno.test("Mock()", async (t) => { + await t.step({ + name: "creates mock builder", + fn(): void { + const mock = Mock(TestObjectOne); + assertEquals(mock.constructor.name, "MockBuilder"); + }, + }); -Deno.test("MockBuilder", async (t) => { - await t.step("create()", async (t) => { + await t.step(".create()", async (t) => { await t.step({ - name: "creates mock builder", + name: "creates mock object", fn(): void { - const mock = new MockBuilder(TestObjectOne); - assertEquals(mock.constructor.name, "MockBuilder"); + const mock = Mock(TestObjectTwo).create(); + assertEquals(mock.name, undefined); + assertEquals(mock.is_mock, true); }, }); + await t.step("can access protected property", () => { + const mock = Mock(TestObjectLotsOfDataMembers) + .create(); + assertEquals( + (mock as unknown as { [key: string]: string }).protected_property, + "I AM PROTECTED PROPERTY.", + ); + }); + + await t.step("can access protected method", () => { + const mock = Mock(TestObjectLotsOfDataMembers) + .create(); + assertEquals( + (mock as unknown as { [key: string]: () => string }).protectedMethod(), + "I AM A PROTECTED METHOD.", + ); + }); + }); + + await t.step(".withConstructorArgs(...)", async (t) => { await t.step({ - name: "creates mock without constructor args", + name: "can take 1 arg", fn(): void { - const mock = new MockBuilder(TestObjectTwo) + const mock = Mock(TestObjectTwo) + .withConstructorArgs("some name") .create(); - assertEquals(mock.name, undefined); + assertEquals(mock.name, "some name"); assertEquals(mock.is_mock, true); }, }); await t.step({ - name: "creates mock with constructor args", + name: "can take more than 1 arg", fn(): void { - const mock = new MockBuilder(TestObjectTwo) - .withConstructorArgs("some name") + const mock = Mock(TestObjectTwoMore) + .withConstructorArgs("some name", ["hello"]) .create(); assertEquals(mock.name, "some name"); + assertEquals(mock.array, ["hello"]); assertEquals(mock.is_mock, true); + + const mockMathService = Mock(MathService) + .create(); + const mockTestObject = Mock(TestObjectLotsOfDataMembers) + .withConstructorArgs("has mocked math service", mockMathService) + .create(); + assertEquals(mockMathService.calls.add, 0); + mockTestObject.sum(1, 1); + assertEquals(mockMathService.calls.add, 1); }, }); }); - await t.step("method()", async (t) => { + await t.step("method(...)", async (t) => { await t.step({ - name: "allows pre-programming a method", + name: "requires .willReturn(...) or .willThrow(...) to be chained", fn(): void { - const mock = new MockBuilder(TestObjectThree).create(); + const mock = Mock(TestObjectThree).create(); assertEquals(mock.is_mock, true); // Original returns "World" assertEquals(mock.test(), "World"); - // Change original to return "Hello" - mock.method("test").willReturn("Hello"); + // Don't fully pre-program the method. This should cause an error during assertions. + mock.method("test"); - // Should output "Hello" and make the following calls - assertEquals(mock.test(), "Hello"); + try { + mock.test(); + } catch (error) { + assertEquals( + error.message, + `Pre-programmed method "test" does not have a return value.`, + ); + } assertEquals(mock.calls.test, 2); assertEquals(mock.calls.hello, 2); }, }); await t.step({ - name: "allows pre-programming a method more than once", + name: + ".willReturn(...) does not call original method and returns given value", fn(): void { - const mock = new MockBuilder(TestObjectThree).create(); + const mock = Mock(TestObjectThree).create(); assertEquals(mock.is_mock, true); // Original returns "World" @@ -64,43 +111,37 @@ Deno.test("MockBuilder", async (t) => { // Change original to return "Hello" mock.method("test").willReturn("Hello"); - mock.method("test").willReturn("Hello!"); - assertEquals(mock.test(), "Hello!"); + // Should output "Hello" and make the following calls + assertEquals(mock.test(), "Hello"); assertEquals(mock.calls.test, 2); assertEquals(mock.calls.hello, 2); }, }); await t.step({ - name: "causes an error to be thrown if no return value is provided", + name: ".willReturn(...) can be performed more than once", fn(): void { - const mock = new MockBuilder(TestObjectThree).create(); + const mock = Mock(TestObjectThree).create(); assertEquals(mock.is_mock, true); // Original returns "World" assertEquals(mock.test(), "World"); - // Don't fully pre-program the method. This should cause an error during assertions. - mock.method("test"); + // Change original to return "Hello" + mock.method("test").willReturn("Hello"); + mock.method("test").willReturn("Hello!"); - try { - mock.test(); - } catch (error) { - assertEquals( - error.message, - `Pre-programmed method "test" does not have a return value.`, - ); - } + assertEquals(mock.test(), "Hello!"); assertEquals(mock.calls.test, 2); assertEquals(mock.calls.hello, 2); }, }); await t.step({ - name: ".willReturn() returns specified value", + name: ".willReturn(...) returns specified value", fn(): void { - const mock = new MockBuilder(TestObjectThree).create(); + const mock = Mock(TestObjectThree).create(); assertEquals(mock.is_mock, true); // Original returns "World" @@ -123,7 +164,7 @@ Deno.test("MockBuilder", async (t) => { await t.step({ name: ".willReturn(mock) returns the mock object (basic)", fn(): void { - const mock = new MockBuilder(TestObjectFourBuilder).create(); + const mock = Mock(TestObjectFourBuilder).create(); assertEquals(mock.is_mock, true); mock @@ -139,7 +180,7 @@ Deno.test("MockBuilder", async (t) => { name: ".willReturn(mock) returns the mock object (extra)", fn(): void { // Assert that the original implementation sets properties - const mock1 = new MockBuilder(TestObjectFourBuilder).create(); + const mock1 = Mock(TestObjectFourBuilder).create(); assertEquals(mock1.is_mock, true); mock1.someComplexMethod(); assertEquals(mock1.something_one, "one"); @@ -147,7 +188,7 @@ Deno.test("MockBuilder", async (t) => { assertEquals(mock1.calls.someComplexMethod, 1); // Assert that the mock implementation will not set properties - const mock2 = new MockBuilder(TestObjectFourBuilder).create(); + const mock2 = Mock(TestObjectFourBuilder).create(); assertEquals(mock2.is_mock, true); mock2 .method("someComplexMethod") @@ -159,7 +200,7 @@ Deno.test("MockBuilder", async (t) => { assertEquals(mock2.calls.someComplexMethod, 1); // Assert that we can also use setters - const mock3 = new MockBuilder(TestObjectFourBuilder).create(); + const mock3 = Mock(TestObjectFourBuilder).create(); assertEquals(mock3.is_mock, true); mock3.someComplexMethod(); assertEquals(mock3.something_one, "one"); @@ -173,7 +214,7 @@ Deno.test("MockBuilder", async (t) => { await t.step({ name: ".willThrow() causes throwing RandomError (with constructor)", fn(): void { - const mock = new MockBuilder(TestObjectThree).create(); + const mock = Mock(TestObjectThree).create(); assertEquals(mock.is_mock, true); // Original returns "World" @@ -196,7 +237,7 @@ Deno.test("MockBuilder", async (t) => { await t.step({ name: ".willThrow() causes throwing RandomError2 (no constructor)", fn(): void { - const mock = new MockBuilder(TestObjectThree).create(); + const mock = Mock(TestObjectThree).create(); assertEquals(mock.is_mock, true); // Original returns "World" @@ -219,7 +260,7 @@ Deno.test("MockBuilder", async (t) => { await t.step({ name: ".expects(...).toBeCalled(...)", fn(): void { - const mock = new MockBuilder(TestObjectThree).create(); + const mock = Mock(TestObjectThree).create(); assertEquals(mock.is_mock, true); mock.expects("hello").toBeCalled(2); @@ -228,6 +269,81 @@ Deno.test("MockBuilder", async (t) => { }, }); }); + + // TODO(crookse) Put the below tests into one of the groups above this line + + await t.step("call count for outside nested function is increased", () => { + const mockMathService = Mock(MathService) + .create(); + const mockTestObject = Mock(TestObjectLotsOfDataMembers) + .withConstructorArgs("has mocked math service", mockMathService) + .create(); + assertEquals(mockMathService.calls.add, 0); + assertEquals(mockMathService.calls.nestedAdd, 0); + mockTestObject.sum(1, 1, true); + assertEquals(mockMathService.calls.add, 1); + assertEquals(mockMathService.calls.nestedAdd, 1); + }); + + await t.step("can mock getters and setters", () => { + const mock = Mock(TestObjectLotsOfDataMembers) + .create(); + mock.age = 999; + assertEquals(mock.age, 999); + }); + + await t.step("native request mock", async () => { + const router = Mock(TestRequestHandler).create(); + + const reqPost = new Request("https://google.com", { + method: "post", + headers: { + "content-type": "application/json", + }, + }); + assertEquals(router.calls.handle, 0); + assertEquals(await router.handle(reqPost), "posted"); + assertEquals(router.calls.handle, 1); + + const reqPostNotJson = new Request("https://google.com", { + method: "post", + }); + assertEquals(router.calls.handle, 1); + assertEquals( + await router.handle(reqPostNotJson), + "Content-Type is incorrect", + ); + assertEquals(router.calls.handle, 2); + + const reqGet = new Request("https://google.com", { + method: "get", + }); + + assertEquals(router.calls.handle, 2); + assertEquals( + await router.handle(reqGet), + "Method is not post", + ); + assertEquals(router.calls.handle, 3); + }); + + await t.step("sets the default value for getters", () => { + class Game { + } + + class PlayersEngine { + private game = new Game(); + get Game() { + return this.game; + } + set Game(val: Game) { + this.game = val; + } + } + + const mock = Mock(PlayersEngine).create(); + assertEquals(mock.Game instanceof Game, true); + }); }); //////////////////////////////////////////////////////////////////////////////// @@ -244,6 +360,15 @@ class TestObjectTwo { } } +class TestObjectTwoMore { + public name: string; + public array: string[]; + constructor(name: string, array: string[]) { + this.name = name; + this.array = array; + } +} + class TestObjectThree { public hello(): void { return; @@ -292,3 +417,68 @@ class RandomError2 extends Error { public name = "RandomError2Name"; public message = "Some message not by the constructor."; } + +class MathService { + public add( + num1: number, + num2: number, + useNestedAdd = false, + ): number { + if (useNestedAdd) { + return this.nestedAdd(num1, num2); + } + return num1 + num2; + } + + public nestedAdd(num1: number, num2: number): number { + return num1 + num2; + } +} + +class TestObjectLotsOfDataMembers { + public name: string; + #age = 0; + protected math_service: MathService; + protected protected_property = "I AM PROTECTED PROPERTY."; + constructor(name: string, mathService: MathService) { + this.math_service = mathService; + this.name = name; + } + public sum( + num1: number, + num2: number, + useNestedAdd = false, + ): number { + const sum = this.math_service.add(num1, num2, useNestedAdd); + return sum; + } + protected protectedMethod() { + return "I AM A PROTECTED METHOD."; + } + + public get age() { + return this.#age; + } + + public set age(val: number) { + this.#age = val; + } +} + +class TestRequestHandler { + // deno-lint-ignore require-await + async handle(request: Request): Promise { + const method = request.method.toLowerCase(); + const contentType = request.headers.get("Content-Type"); + + if (method !== "post") { + return "Method is not post"; + } + + if (contentType !== "application/json") { + return "Content-Type is incorrect"; + } + + return "posted"; + } +} diff --git a/tests/integration/stub_test.ts b/tests/unit/mod/stub_test.ts similarity index 93% rename from tests/integration/stub_test.ts rename to tests/unit/mod/stub_test.ts index f46e9f14..46107e3d 100644 --- a/tests/integration/stub_test.ts +++ b/tests/unit/mod/stub_test.ts @@ -1,5 +1,5 @@ -import { Stub } from "../../mod.ts"; -import { assertEquals } from "../deps.ts"; +import { Stub } from "../../../mod.ts"; +import { assertEquals } from "../../deps.ts"; class Server { public greeting = "hello"; From ca2b88e1dcbc6c3e6ea6564efa28c0782fe2aa87 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Tue, 12 Apr 2022 21:24:20 -0400 Subject: [PATCH 33/62] chore: remove other mock test file --- tests/unit/mod/mock_2_test.ts | 70 ----------------------------------- 1 file changed, 70 deletions(-) delete mode 100644 tests/unit/mod/mock_2_test.ts diff --git a/tests/unit/mod/mock_2_test.ts b/tests/unit/mod/mock_2_test.ts deleted file mode 100644 index ec60aeb2..00000000 --- a/tests/unit/mod/mock_2_test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Mock } from "../../../mod.ts"; -import { assertEquals } from "../../deps.ts"; - -class MathService { - public add( - num1: number, - num2: number, - useNestedAdd = false, - ): number { - if (useNestedAdd) { - return this.nestedAdd(num1, num2); - } - return num1 + num2; - } - - public nestedAdd(num1: number, num2: number): number { - return num1 + num2; - } -} - -class TestObjectLotsOfDataMembers { - public name: string; - #age = 0; - protected math_service: MathService; - protected protected_property = "I AM PROTECTED PROPERTY."; - constructor(name: string, mathService: MathService) { - this.math_service = mathService; - this.name = name; - } - public sum( - num1: number, - num2: number, - useNestedAdd = false, - ): number { - const sum = this.math_service.add(num1, num2, useNestedAdd); - return sum; - } - protected protectedMethod() { - return "I AM A PROTECTED METHOD."; - } - - public get age() { - return this.#age; - } - - public set age(val: number) { - this.#age = val; - } -} - -class TestRequestHandler { - // deno-lint-ignore require-await - async handle(request: Request): Promise { - const method = request.method.toLowerCase(); - const contentType = request.headers.get("Content-Type"); - - if (method !== "post") { - return "Method is not post"; - } - - if (contentType !== "application/json") { - return "Content-Type is incorrect"; - } - - return "posted"; - } -} - -Deno.test("mock()", async (t) => { -}); From cc0ebdf2313311e28eb185fd605943576b5c3616 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Tue, 12 Apr 2022 21:25:14 -0400 Subject: [PATCH 34/62] fix: change README title to Rhum --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f392ab53..44ef2258 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Drash +# Rhum [![Latest Release](https://img.shields.io/github/release/drashland/rhum.svg?color=bright_green&label=latest)](#) [![CI master](https://img.shields.io/github/workflow/status/drashland/rhum/master?label=ci%20-%20master)](#) From 92bd978cb4dff8f81caf474588f116654aab3f8a Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Tue, 12 Apr 2022 21:25:32 -0400 Subject: [PATCH 35/62] chore: remove playground files --- extend.js | 11 ----------- extend.ts | 9 --------- 2 files changed, 20 deletions(-) delete mode 100644 extend.js delete mode 100644 extend.ts diff --git a/extend.js b/extend.js deleted file mode 100644 index ae67172e..00000000 --- a/extend.js +++ /dev/null @@ -1,11 +0,0 @@ -// deno-fmt-ignore-file -// deno-lint-ignore-file -// This code was bundled using `deno bundle` and it's not recommended to edit it manually - -class Base { - base_prop = "base prop"; -} -class Hello extends Base { - sub_prop = "sub prop"; -} -new Hello(); diff --git a/extend.ts b/extend.ts deleted file mode 100644 index c7fcf0c5..00000000 --- a/extend.ts +++ /dev/null @@ -1,9 +0,0 @@ -class Base { - public base_prop = "base prop"; -} - -class Hello extends Base { - public sub_prop = "sub prop"; -} - -const t = new Hello(); From 08e47efb29339ffe1b1a8044ef45b9e9b07bb361 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Tue, 12 Apr 2022 21:26:51 -0400 Subject: [PATCH 36/62] chore: remove constructor comment; move init method down --- src/fake/fake_mixin.ts | 6 +----- src/mock/mock_mixin.ts | 22 +++++++++------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/fake/fake_mixin.ts b/src/fake/fake_mixin.ts index cc796348..87cd4303 100644 --- a/src/fake/fake_mixin.ts +++ b/src/fake/fake_mixin.ts @@ -23,7 +23,7 @@ export function createFake( #original!: OriginalObject; ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// + // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// /** @@ -33,10 +33,6 @@ export function createFake( this.#original = original; } - ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - /** * Pre-program a method on the original to return a specific value. * diff --git a/src/mock/mock_mixin.ts b/src/mock/mock_mixin.ts index c9fa1dd7..8b642dd1 100644 --- a/src/mock/mock_mixin.ts +++ b/src/mock/mock_mixin.ts @@ -53,19 +53,6 @@ export function createMock( */ #original!: OriginalObject; - ////////////////////////////////////////////////////////////////////////////// - // FILE MARKER - CONSTRUCTOR ///////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////// - - /** - * @param original - The original object to mock. - * @param methodsToTrack - The original object's method to make trackable. - */ - public init(original: OriginalObject, methodsToTrack: string[]) { - this.#original = original; - this.#calls = this.#constructCallsProperty(methodsToTrack); - } - ////////////////////////////////////////////////////////////////////////////// // FILE MARKER - GETTERS / SETTERS /////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -78,6 +65,15 @@ export function createMock( // FILE MARKER - METHODS - PUBLIC //////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// + /** + * @param original - The original object to mock. + * @param methodsToTrack - The original object's method to make trackable. + */ + public init(original: OriginalObject, methodsToTrack: string[]) { + this.#original = original; + this.#calls = this.#constructCallsProperty(methodsToTrack); + } + /** * Create a method expectation, which is basically asserting calls. * From 4975eb157a5becc3a631a137d375d81c8847aeaf Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Wed, 13 Apr 2022 21:50:18 -0400 Subject: [PATCH 37/62] ci(v2): fix workflow file to only run tests/unit folder --- .github/workflows/master.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 8375d272..33e64ac2 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -24,9 +24,6 @@ jobs: - name: Unit run: deno test tests/unit - - name: Integration - run: deno test tests/integration - linter: # Only one OS is required since fmt is cross platform runs-on: ubuntu-latest From 6fb3802949efd09d3f710dd88fdb7154d9b7a27f Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 22:07:04 -0400 Subject: [PATCH 38/62] chore: update gitignore --- .gitignore | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 81bb71ec..7103c86f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,12 @@ .DS_Store # directories -tmp*/* -tmp/* .idea +.vscode +lib/ +node_modules/ +tmp*/ +tmp/ # exceptions !.gitkeep - -.vscode - From 15b2f3823a6cb88ce53bd8ac2bd8c6653a7e073e Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 22:10:00 -0400 Subject: [PATCH 39/62] feat: initial script to compile to cjs and esm --- console/build_esm_lib.ts | 62 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 console/build_esm_lib.ts diff --git a/console/build_esm_lib.ts b/console/build_esm_lib.ts new file mode 100644 index 00000000..0464e397 --- /dev/null +++ b/console/build_esm_lib.ts @@ -0,0 +1,62 @@ +const decoder = new TextDecoder(); +const encoder = new TextEncoder(); + +const filesToRewrite = [ + "tmp/conversion_workspace/src/fake/fake_builder.ts", + "tmp/conversion_workspace/src/fake/fake_mixin.ts", + "tmp/conversion_workspace/src/mock/mock_builder.ts", + "tmp/conversion_workspace/src/mock/mock_mixin.ts", + "tmp/conversion_workspace/src/interfaces.ts", + "tmp/conversion_workspace/src/pre_programmed_method.ts", + "tmp/conversion_workspace/src/types.ts", + "tmp/conversion_workspace/mod.ts", +]; + +Deno.run({ cmd: ["rm", "-r", "tmp/conversion_workspace/"] }); +Deno.run({ cmd: ["mkdir", "-p", "tmp/conversion_workspace/"] }); +Deno.run({ cmd: ["cp", "-r", "src/", `tmp/conversion_workspace/src`] }); +Deno.run({ cmd: ["cp", "mod.ts", `tmp/conversion_workspace/mod.ts`] }); + +let file: any; + +while (!file) { + try { + file = await Deno.lstat("tmp/conversion_workspace/src/fake/fake_builder.ts"); + } catch (error) { + } +} + +for (const index in filesToRewrite) { + const file = filesToRewrite[index]; + + // Step 1: Read contents + let contents = decoder.decode(Deno.readFileSync(file)); + + // Step 2: Create an array of import/export statements from the contents + const importStatements = contents.match(/import.*";/g); + const exportStatements = contents.match(/export.*";/g); + + // Step 3: Remove all .ts extensions from the import/export statements + const newImportStatements = importStatements?.map((statement: string) => { + return statement.replace(/\.ts";/, `";`); + }); + + const newExportStatements = exportStatements?.map((statement: string) => { + return statement.replace(/\.ts";/, `";`); + }); + + // Step 4: Replace the original contents with the new contents + if (newImportStatements) { + importStatements?.forEach((statement: string, index: number) => { + contents = contents.replace(statement, newImportStatements[index]); + }); + } + if (newExportStatements) { + exportStatements?.forEach((statement: string, index: number) => { + contents = contents.replace(statement, newExportStatements[index]); + }); + } + + // Step 5: Rewrite the original file without .ts extensions + Deno.writeFileSync(file, encoder.encode(contents)); +} From 630bfb8c788ce46bcb68d2da60d7a4a430135015 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 22:10:43 -0400 Subject: [PATCH 40/62] feat: add package.json and tsconfig.json files --- package.json | 29 +++++++++++++++++++++++++++++ tsconfig.cjs.json | 7 +++++++ tsconfig.esm.json | 7 +++++++ tsconfig.json | 12 ++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 package.json create mode 100644 tsconfig.cjs.json create mode 100644 tsconfig.esm.json create mode 100644 tsconfig.json diff --git a/package.json b/package.json new file mode 100644 index 00000000..de3c78f3 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "@drashland/rhum", + "version": "2.0.0", + "description": "A test double library", + "main": "./lib/cjs/mod.js", + "types": "./lib/cjs/mod.d.ts", + "repository": "git@github.com:drashland/rhum.git", + "author": "Drash Land", + "license": "MIT", + "scripts": { + "test": "jest --verbose tests", + "build:cjs": "tsc --project tsconfig.cjs.json", + "build:esm": "tsc --project tsconfig.esm.json", + "build:conversion-workspace": "deno run --allow-read --allow-run --allow-write ./console/build_esm_lib.ts", + "build": "yarn build:conversion-workspace && yarn build:cjs && yarn build:esm" + }, + "devDependencies": { + "@types/jest": "27.x", + "@types/node": "16.x", + "jest": "27.x", + "ts-jest": "27.x", + "ts-node": "10.x", + "typescript": "4.x" + }, + "files": [ + "./lib" + ] +} + diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 00000000..d944d7cf --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "./lib/cjs" + } +} diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 00000000..d2489cd0 --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "es2015", + "outDir": "./lib/esm" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..6ab8d8bb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es2015", + "rootDir": "./tmp/conversion_workspace", + "declaration": true, + "sourceMap": true, + "esModuleInterop": true, + "moduleResolution": "node" + }, + "include": ["./tmp/**/*.ts"], + "exclude": ["./tests/**/*"] +} From 4824acc5ec4d18c5ab6f8e7efa946a70ffd9ff99 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 22:11:21 -0400 Subject: [PATCH 41/62] chore: yarn.lock --- yarn.lock | 2648 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2648 insertions(+) create mode 100644 yarn.lock diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..35128528 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,2648 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" + integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.0" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + +"@babel/compat-data@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" + integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== + +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.9.tgz#6bae81a06d95f4d0dec5bb9d74bbc1f58babdcfe" + integrity sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.9" + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helpers" "^7.17.9" + "@babel/parser" "^7.17.9" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.9" + "@babel/types" "^7.17.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/generator@^7.17.9", "@babel/generator@^7.7.2": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.9.tgz#f4af9fd38fa8de143c29fce3f71852406fc1e2fc" + integrity sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ== + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-compilation-targets@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" + integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== + dependencies: + "@babel/compat-data" "^7.17.7" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-function-name@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" + integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== + dependencies: + "@babel/template" "^7.16.7" + "@babel/types" "^7.17.0" + +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-transforms@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" + integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.17.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== + +"@babel/helper-simple-access@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" + integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== + dependencies: + "@babel/types" "^7.17.0" + +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + +"@babel/helpers@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" + integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.9" + "@babel/types" "^7.17.0" + +"@babel/highlight@^7.16.7": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" + integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" + integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" + integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/template@^7.16.7", "@babel/template@^7.3.3": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" + integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.9" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.17.9" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.9" + "@babel/types" "^7.17.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@cspotcode/source-map-consumer@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" + integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== + +"@cspotcode/source-map-support@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" + integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== + dependencies: + "@cspotcode/source-map-consumer" "0.8.0" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + +"@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== + dependencies: + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + +"@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== + dependencies: + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +"@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" + +"@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" + +"@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.9" + source-map "^0.6.0" + +"@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== + dependencies: + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== + dependencies: + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" + +"@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" + integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.11" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" + integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" + integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.1.19" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" + integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.0.tgz#7a9b80f712fe2052bc20da153ff1e552404d8e4b" + integrity sha512-r8aveDbd+rzGP+ykSdF3oPuTVRWRfbBiHl0rVDM2yNEmSMXfkObQLV46b4RnCv3Lra51OlfnZhkkFaDl2MIRaA== + dependencies: + "@babel/types" "^7.3.0" + +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@27.x": + version "27.4.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" + integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== + dependencies: + jest-matcher-utils "^27.0.0" + pretty-format "^27.0.0" + +"@types/node@*": + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.24.tgz#20ba1bf69c1b4ab405c7a01e950c4f446b05029f" + integrity sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g== + +"@types/node@16.x": + version "16.11.27" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.27.tgz#5da19383bdbeda99bc0d09cfbb88cab7297ebc51" + integrity sha512-C1pD3kgLoZ56Uuy5lhfOxie4aZlA3UMGLX9rXteq4WitEZH6Rl80mwactt9QG0w0gLFlN/kLBTFnGXtDVWvWQw== + +"@types/prettier@^2.1.5": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.0.tgz#efcbd41937f9ae7434c714ab698604822d890759" + integrity sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw== + +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" + +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.2.4, acorn@^8.4.1: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== + dependencies: + babel-plugin-jest-hoist "^27.5.1" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browserslist@^4.17.5: + version "4.20.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" + integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== + dependencies: + caniuse-lite "^1.0.30001317" + electron-to-chromium "^1.4.84" + escalade "^3.1.1" + node-releases "^2.0.2" + picocolors "^1.0.0" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001317: + version "1.0.30001332" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" + integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + +debug@4, debug@^4.1.0, debug@^4.1.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decimal.js@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + +electron-to-chromium@^1.4.84: + version "1.4.108" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.108.tgz#380b01ff68e958d2b9fdf4572e054020a506c568" + integrity sha512-/36KkMuL6+WTrodVlOjtHhH9Ro7BgRaQrh0bfKckwDtdRSjTBuZCOddeXxzK1PkwphoeTxGUFVT9xnmvQ7xEdw== + +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== + dependencies: + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== + dependencies: + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + +jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== + dependencies: + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + prompts "^2.0.1" + yargs "^16.2.0" + +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== + dependencies: + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== + dependencies: + detect-newline "^3.0.0" + +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" + +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== + dependencies: + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" + +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== + dependencies: + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.5.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== + +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== + dependencies: + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" + +jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + source-map-support "^0.5.6" + throat "^6.0.1" + +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + +jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + natural-compare "^1.4.0" + pretty-format "^27.5.1" + semver "^7.3.2" + +jest-util@^27.0.0, jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== + dependencies: + "@jest/types" "^27.5.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.5.1" + leven "^3.1.0" + pretty-format "^27.5.1" + +jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== + dependencies: + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.5.1" + string-length "^4.0.1" + +jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@27.x: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== + dependencies: + "@jest/core" "^27.5.1" + import-local "^3.0.2" + jest-cli "^27.5.1" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.6" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json5@2.x, json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@1.x, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-releases@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" + integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +pretty-format@^27.0.0, pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + +resolve@^1.20.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + +semver@7.x, semver@^7.3.2: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-support@^0.5.6: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + dependencies: + escape-string-regexp "^2.0.0" + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + +ts-jest@27.x: + version "27.1.4" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.4.tgz#84d42cf0f4e7157a52e7c64b1492c46330943e00" + integrity sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^27.0.0" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "20.x" + +ts-node@10.x: + version "10.7.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" + integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== + dependencies: + "@cspotcode/source-map-support" "0.7.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.0" + yn "3.1.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typescript@4.x: + version "4.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" + integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== + +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +v8-compile-cache-lib@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" + integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== + +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + +walker@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.4.6: + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.x, yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== From 75c112a5d1deb3410fe0c29974a68c1db3437505 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 22:11:39 -0400 Subject: [PATCH 42/62] chore: move deno unit tests to tests/deno --- tests/{ => deno}/deps.ts | 0 tests/{ => deno}/unit/mod/dummy_test.ts | 4 ++-- tests/{ => deno}/unit/mod/fake_test.ts | 4 ++-- tests/{ => deno}/unit/mod/mock_test.ts | 4 ++-- tests/{ => deno}/unit/mod/stub_test.ts | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) rename tests/{ => deno}/deps.ts (100%) rename tests/{ => deno}/unit/mod/dummy_test.ts (93%) rename tests/{ => deno}/unit/mod/fake_test.ts (99%) rename tests/{ => deno}/unit/mod/mock_test.ts (99%) rename tests/{ => deno}/unit/mod/stub_test.ts (93%) diff --git a/tests/deps.ts b/tests/deno/deps.ts similarity index 100% rename from tests/deps.ts rename to tests/deno/deps.ts diff --git a/tests/unit/mod/dummy_test.ts b/tests/deno/unit/mod/dummy_test.ts similarity index 93% rename from tests/unit/mod/dummy_test.ts rename to tests/deno/unit/mod/dummy_test.ts index eb5bc9b6..0559d506 100644 --- a/tests/unit/mod/dummy_test.ts +++ b/tests/deno/unit/mod/dummy_test.ts @@ -1,5 +1,5 @@ -import { Dummy, Mock } from "../../../mod.ts"; -import { assertEquals } from "../../deps.ts"; +import { Dummy, Mock } from "../../../../mod.ts"; +import { assertEquals } from "../../../deps.ts"; Deno.test("Dummy()", async (t) => { await t.step({ diff --git a/tests/unit/mod/fake_test.ts b/tests/deno/unit/mod/fake_test.ts similarity index 99% rename from tests/unit/mod/fake_test.ts rename to tests/deno/unit/mod/fake_test.ts index 713717d3..7575c61f 100644 --- a/tests/unit/mod/fake_test.ts +++ b/tests/deno/unit/mod/fake_test.ts @@ -1,5 +1,5 @@ -import { Fake } from "../../../mod.ts"; -import { assertEquals, assertThrows } from "../../deps.ts"; +import { Fake } from "../../../../mod.ts"; +import { assertEquals, assertThrows } from "../../../deps.ts"; Deno.test("Fake()", async (t) => { await t.step({ diff --git a/tests/unit/mod/mock_test.ts b/tests/deno/unit/mod/mock_test.ts similarity index 99% rename from tests/unit/mod/mock_test.ts rename to tests/deno/unit/mod/mock_test.ts index 973f9a73..f34a0226 100644 --- a/tests/unit/mod/mock_test.ts +++ b/tests/deno/unit/mod/mock_test.ts @@ -1,5 +1,5 @@ -import { Mock } from "../../../mod.ts"; -import { assertEquals, assertThrows } from "../../deps.ts"; +import { Mock } from "../../../../mod.ts"; +import { assertEquals, assertThrows } from "../../../deps.ts"; Deno.test("Mock()", async (t) => { await t.step({ diff --git a/tests/unit/mod/stub_test.ts b/tests/deno/unit/mod/stub_test.ts similarity index 93% rename from tests/unit/mod/stub_test.ts rename to tests/deno/unit/mod/stub_test.ts index 46107e3d..bc1ca8fc 100644 --- a/tests/unit/mod/stub_test.ts +++ b/tests/deno/unit/mod/stub_test.ts @@ -1,5 +1,5 @@ -import { Stub } from "../../../mod.ts"; -import { assertEquals } from "../../deps.ts"; +import { Stub } from "../../../../mod.ts"; +import { assertEquals } from "../../../deps.ts"; class Server { public greeting = "hello"; From 63057b50ad760ec58094c67ffa80a9f8cec1a2c3 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 22:11:57 -0400 Subject: [PATCH 43/62] fix: issue with compiling down --- src/fake/fake_builder.ts | 2 +- src/mock/mock_builder.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fake/fake_builder.ts b/src/fake/fake_builder.ts index 556b7b97..c2c2df97 100644 --- a/src/fake/fake_builder.ts +++ b/src/fake/fake_builder.ts @@ -136,7 +136,7 @@ export class FakeBuilder { // If this is a native method, then do not do anything fancy. Just add it to // the fake. - if (nativeMethods.includes(method as string)) { + if (nativeMethods.indexOf(method as string) !== -1) { return this.#addMethodToFakeObject( original, fake, diff --git a/src/mock/mock_builder.ts b/src/mock/mock_builder.ts index e3aff42a..382e7704 100644 --- a/src/mock/mock_builder.ts +++ b/src/mock/mock_builder.ts @@ -138,7 +138,7 @@ export class MockBuilder { // If this is a native method, then do not do anything fancy. Just add it to // the mock. - if (nativeMethods.includes(method as string)) { + if (nativeMethods.indexOf(method as string) !== -1) { return this.#addMethodToMockObject( original, mock, From 1f9f95f8d80f8ca4c95b6b79b57ecce9461d5413 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 22:12:03 -0400 Subject: [PATCH 44/62] test: cjs tests --- tests/cjs/unit/mod/dummy.test.js | 64 +++++ tests/cjs/unit/mod/fake.test.js | 299 ++++++++++++++++++++++ tests/cjs/unit/mod/mock.test.js | 426 +++++++++++++++++++++++++++++++ tests/cjs/unit/mod/stub.test.js | 44 ++++ 4 files changed, 833 insertions(+) create mode 100644 tests/cjs/unit/mod/dummy.test.js create mode 100644 tests/cjs/unit/mod/fake.test.js create mode 100644 tests/cjs/unit/mod/mock.test.js create mode 100644 tests/cjs/unit/mod/stub.test.js diff --git a/tests/cjs/unit/mod/dummy.test.js b/tests/cjs/unit/mod/dummy.test.js new file mode 100644 index 00000000..6ffbb45d --- /dev/null +++ b/tests/cjs/unit/mod/dummy.test.js @@ -0,0 +1,64 @@ +const { Dummy, Mock } = require("../../../../lib/cjs/mod"); + +describe("Dummy()", () => { + it("can fill parameter lists", () => { + const mockServiceOne = Mock(ServiceOne).create(); + const dummy3 = Dummy(ServiceThree); + + const resource = new Resource( + mockServiceOne, + Dummy(ServiceTwo), + dummy3, + ); + + resource.callServiceOne(); + expect(mockServiceOne.calls.methodServiceOne).toBe(1); + }); + + it("can be made without specifying constructor args", () => { + const dummy = Dummy(Resource); + expect(Object.getPrototypeOf(dummy)).toBe(Resource); + }); +}); + +class Resource { + constructor( + serviceOne, + serviceTwo, + serviceThree, + ) { + this.service_one = serviceOne; + this.service_two = serviceTwo; + this.service_three = serviceThree; + } + + callServiceOne() { + this.service_one.methodServiceOne(); + } + + callServiceTwo() { + this.service_two.methodServiceTwo(); + } + + callServiceThree() { + this.service_three.methodServiceThree(); + } +} + +class ServiceOne { + methodServiceOne() { + return "Method from ServiceOne was called."; + } +} + +class ServiceTwo { + methodServiceTwo() { + return "Method from ServiceTwo was called."; + } +} + +class ServiceThree { + methodServiceThree() { + return "Method from ServiceThree was called."; + } +} diff --git a/tests/cjs/unit/mod/fake.test.js b/tests/cjs/unit/mod/fake.test.js new file mode 100644 index 00000000..8b280510 --- /dev/null +++ b/tests/cjs/unit/mod/fake.test.js @@ -0,0 +1,299 @@ +const { Fake } = require("../../../../lib/cjs/mod"); + +describe("Fake()", () => { + it("creates fake builder", () => { + const fake = Fake(TestObjectOne); + expect(fake.constructor.name).toBe("FakeBuilder"); + }); + + describe(".create()", () => { + it("creates fake object", () => { + const fake = Fake(TestObjectTwo).create(); + expect(fake.name).toBe(undefined); + expect(fake.is_fake).toBe(true); + }); + }); + + describe(".withConstructorArgs(...)", () => { + it("can take 1 arg", () => { + const fake = Fake(TestObjectTwo) + .withConstructorArgs("some name") + .create(); + expect(fake.name).toBe("some name"); + expect(fake.is_fake).toBe(true); + }); + + it("can take more than 1 arg", () => { + const fake = Fake(TestObjectTwoMore) + .withConstructorArgs("some name", ["hello"]) + .create(); + expect(fake.name).toBe("some name"); + expect(fake.array).toStrictEqual(["hello"]); + expect(fake.is_fake).toBe(true); + }); + }); + + describe(".method(...)", () => { + it("requires .willReturn(...) or .willThrow(...) to be chained", () => { + const fake = Fake(TestObjectThree).create(); + expect(fake.is_fake).toBe(true); + + // Original returns "World" + expect(fake.test()).toBe("World"); + + // Don't fully pre-program the method. This should cause an error during assertions. + fake.method("test"); + + try { + fake.test(); + } catch (error) { + expect(error.message).toBe(`Pre-programmed method "test" does not have a return value.`); + } + }); + + it(".willReturn(...) does not call original method and returns given value", () => { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findAllUsers").willReturn("shortcut"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUsers(); + expect(fakeServiceDoingShortcut.anotha_one_called).toBe(false); + expect(fakeServiceDoingShortcut.do_something_called).toBe(false); + expect(fakeServiceDoingShortcut.do_something_else_called).toBe(false); + + // Assert that the fake service can call original implementations + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUsers(); + expect(fakeServiceNotDoingShortcut.anotha_one_called).toBe(true); + expect(fakeServiceNotDoingShortcut.do_something_called).toBe(true); + expect(fakeServiceNotDoingShortcut.do_something_else_called).toBe(true); + }); + + it(".willReturn(...) can be performed more than once", () => { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findUserById").willReturn("shortcut"); + fakeServiceDoingShortcut.method("findUserById").willReturn("shortcut2"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUser(1); + expect(fakeServiceDoingShortcut.anotha_one_called).toBe(false); + expect(fakeServiceDoingShortcut.do_something_called).toBe(false); + expect(fakeServiceDoingShortcut.do_something_else_called).toBe(false); + + // Assert that the fake service can call original implementations + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUser(1); + expect(fakeServiceNotDoingShortcut.anotha_one_called).toBe(true); + expect(fakeServiceNotDoingShortcut.do_something_called).toBe(true); + expect(fakeServiceNotDoingShortcut.do_something_else_called).toBe(true); + }); + + it(".willThrow(...) does not call original method and throws error", () => { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findAllUsers").willReturn("shortcut"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUsers(); + expect(fakeServiceDoingShortcut.anotha_one_called).toBe(false); + expect(fakeServiceDoingShortcut.do_something_called).toBe(false); + expect(fakeServiceDoingShortcut.do_something_else_called).toBe(false); + + // Assert that the fake service can call original implementations + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUsers(); + expect(fakeServiceNotDoingShortcut.anotha_one_called).toBe(true); + expect(fakeServiceNotDoingShortcut.do_something_called).toBe(true); + expect(fakeServiceNotDoingShortcut.do_something_else_called).toBe(true); + }); + + it(".willReturn(fake) returns the fake object (basic)", () => { + const fake = Fake(TestObjectFourBuilder).create(); + expect(fake.is_fake).toBe(true); + + fake + .method("someComplexMethod") + .willReturn(fake); + + expect(fake.someComplexMethod()).toBe(fake); + }); + + it(".willReturn(fake) returns the fake object (extra)", () => { + // Assert that the original implementation sets properties + const fake1 = Fake(TestObjectFourBuilder).create(); + expect(fake1.is_fake).toBe(true); + fake1.someComplexMethod(); + expect(fake1.something_one).toBe("one"); + expect(fake1.something_two).toBe("two"); + + // Assert that the fake implementation will not set properties + const fake2 = Fake(TestObjectFourBuilder).create(); + expect(fake2.is_fake).toBe(true); + fake2 + .method("someComplexMethod") + .willReturn(fake2); + + expect(fake2.someComplexMethod()).toBe(fake2); + expect(fake2.something_one).toBe(undefined); + expect(fake2.something_two).toBe(undefined); + + // Assert that we can also use setters + const fake3 = Fake(TestObjectFourBuilder).create(); + expect(fake3.is_fake).toBe(true); + fake3.someComplexMethod(); + expect(fake3.something_one).toBe("one"); + expect(fake3.something_two).toBe("two"); + fake3.something_one = "you got changed"; + expect(fake3.something_one).toBe("you got changed"); + }); + + it(".willThrow() causes throwing RandomError (with constructor)", () => { + const fake = Fake(TestObjectThree).create(); + expect(fake.is_fake).toBe(true); + + // Original returns "World" + expect(fake.test()).toBe("World"); + + // Make the original method throw RandomError + fake + .method("test") + .willThrow(new RandomError("Random error message.")); + + expect(() => fake.test()).toThrow(new RandomError("Random error message.")); + }); + + it(".willThrow() causes throwing RandomError2 (no constructor)", () => { + const fake = Fake(TestObjectThree).create(); + expect(fake.is_fake).toBe(true); + + // Original returns "World" + expect(fake.test()).toBe("World"); + + // Make the original method throw RandomError + fake + .method("test") + .willThrow(new RandomError2()); + + expect(() => fake.test()).toThrow(new RandomError2("Some message not by the constructor.")); + }); + }); +}); + +//////////////////////////////////////////////////////////////////////////////// +// FILE MARKER - DATA ////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +class TestObjectOne { +} + +class TestObjectTwo { + constructor(name) { + this.name = name; + } +} + +class TestObjectTwoMore { + constructor(name, array) { + this.name = name; + this.array = array; + } +} + +class TestObjectThree { + hello() { + return; + } + + test() { + this.hello(); + this.hello(); + return "World"; + } +} + +class Resource { + constructor( + serviceOne, + ) { + this.repository = serviceOne; + } + + getUsers() { + this.repository.findAllUsers(); + } + + getUser(id) { + this.repository.findUserById(id); + } +} + +class TestObjectFourBuilder { + someComplexMethod() { + this.setSomethingOne(); + this.setSomethingTwo(); + return this; + } + + setSomethingOne() { + this.something_one = "one"; + } + + setSomethingTwo() { + this.something_two = "two"; + } +} + +class Repository { + constructor() { + this.anotha_one_called = false; + this.do_something_called = false; + this.do_something_else_called = false; + } + + findAllUsers() { + this.doSomething(); + this.doSomethingElse(); + this.anothaOne(); + return "Finding all users"; + } + + findUserById(id) { + this.doSomething(); + this.doSomethingElse(); + this.anothaOne(); + return `Finding user by id #${id}`; + } + + anothaOne() { + this.anotha_one_called = true; + } + + doSomething() { + this.do_something_called = true; + } + + doSomethingElse() { + this.do_something_else_called = true; + } +} + +class RandomError extends Error {} +class RandomError2 extends Error { + name = "RandomError2Name"; + message = "Some message not by the constructor."; +} + diff --git a/tests/cjs/unit/mod/mock.test.js b/tests/cjs/unit/mod/mock.test.js new file mode 100644 index 00000000..11b99ea5 --- /dev/null +++ b/tests/cjs/unit/mod/mock.test.js @@ -0,0 +1,426 @@ +const { Mock } = require("../../../../lib/cjs/mod"); + +class Request { + constructor( + url, + options = {} + ) { + this.url = url; + this.options = options; + this.headers = this.createHeaders(options.headers); + this.method = options.method ? options.method : "get"; + } + + createHeaders(headers) { + const map = new Map(); + for (const header in headers) { + const value = headers[header]; + map.set(header, value); + } + return map; + } +} + +class TestObjectOne { +} + +class TestObjectTwo { + constructor(name) { + this.name = name; + } +} + +class TestObjectTwoMore { + constructor(name, array) { + this.name = name; + this.array = array; + } +} + +class TestObjectThree { + hello() { + return; + } + + test() { + this.hello(); + this.hello(); + return "World"; + } +} + +class TestObjectFourBuilder { + someComplexMethod() { + this.setSomethingOne(); + this.setSomethingTwo(); + return this; + } + + setSomethingOne() { + this.something_one = "one"; + } + + setSomethingTwo() { + this.something_two = "two"; + } +} + +class RandomError extends Error {} +class RandomError2 extends Error { + name = "RandomError2Name"; + message = "Some message not by the constructor."; +} + +class MathService { + add( + num1, + num2, + useNestedAdd = false, + ) { + if (useNestedAdd) { + return this.nestedAdd(num1, num2); + } + return num1 + num2; + } + + nestedAdd(num1, num2) { + return num1 + num2; + } +} + +class TestObjectLotsOfDataMembers { + age = 0; + math_service = undefined; + protected_property = "I AM PROTECTED PROPERTY."; + constructor(name, mathService) { + this.math_service = mathService; + this.name = name; + } + sum( + num1, + num2, + useNestedAdd = false, + ) { + const sum = this.math_service.add(num1, num2, useNestedAdd); + return sum; + } + protectedMethod() { + return "I AM A PROTECTED METHOD."; + } +} + +class TestRequestHandler { + handle(request) { + const method = request.method.toLowerCase(); + const contentType = request.headers.get("content-type"); + + console.log(request.headers) + console.log(request.headers) + console.log(request.headers) + + if (method !== "post") { + return "Method is not post"; + } + + if (contentType !== "application/json") { + return "Content-Type is incorrect"; + } + + return "posted"; + } +} + +describe("Mock()", () => { + it( + "creates mock builder", + () => { + const mock = Mock(TestObjectOne); + expect(mock.constructor.name).toBe("MockBuilder"); + }); + + describe(".create()", () => { + it( + "creates mock object", + () => { + const mock = Mock(TestObjectTwo).create(); + expect(mock.name).toBe(undefined); + expect(mock.is_mock).toBe(true); + }); + }); + + describe(".withConstructorArgs(...)", () => { + it( + "can take 1 arg", + () => { + const mock = Mock(TestObjectTwo) + .withConstructorArgs("some name") + .create(); + expect(mock.name).toBe("some name"); + expect(mock.is_mock).toBe(true); + }); + + it( + "can take more than 1 arg", + () => { + const mock = Mock(TestObjectTwoMore) + .withConstructorArgs("some name", ["hello"]) + .create(); + expect(mock.name).toBe("some name"); + expect(mock.array).toStrictEqual(["hello"]); + expect(mock.is_mock).toBe(true); + + const mockMathService = Mock(MathService) + .create(); + const mockTestObject = Mock(TestObjectLotsOfDataMembers) + .withConstructorArgs("has mocked math service", mockMathService) + .create(); + expect(mockMathService.calls.add).toBe(0); + mockTestObject.sum(1, 1); + expect(mockMathService.calls.add).toBe(1); + }); + }); + + describe("method(...)", () => { + it( + "requires .willReturn(...) or .willThrow(...) to be chained", + () => { + const mock = Mock(TestObjectThree).create(); + expect(mock.is_mock).toBe(true); + + // Original returns "World" + expect(mock.test()).toBe("World"); + + // Don't fully pre-program the method. This should cause an error during assertions. + mock.method("test"); + + try { + mock.test(); + } catch (error) { + expect(error.message).toBe(`Pre-programmed method "test" does not have a return value.`); + } + expect(mock.calls.test).toBe(2); + expect(mock.calls.hello).toBe(2); + }); + + it(".willReturn(...) does not call original method and returns given value",() => { + const mock = Mock(TestObjectThree).create(); + expect(mock.is_mock).toBe(true); + + // Original returns "World" + expect(mock.test()).toBe("World"); + + // Change original to return "Hello" + mock.method("test").willReturn("Hello"); + + // Should output "Hello" and make the following calls + expect(mock.test()).toBe("Hello"); + expect(mock.calls.test).toBe(2); + expect(mock.calls.hello).toBe(2); + }); + + it( + ".willReturn(...) can be performed more than once", + () => { + const mock = Mock(TestObjectThree).create(); + expect(mock.is_mock).toBe(true); + + // Original returns "World" + expect(mock.test()).toBe("World"); + + // Change original to return "Hello" + mock.method("test").willReturn("Hello"); + mock.method("test").willReturn("Hello!"); + + expect(mock.test()).toBe("Hello!"); + expect(mock.calls.test).toBe(2); + expect(mock.calls.hello).toBe(2); + }); + + it( + ".willReturn(...) returns specified value", + () => { + const mock = Mock(TestObjectThree).create(); + expect(mock.is_mock).toBe(true); + + // Original returns "World" + expect(mock.test()).toBe("World"); + + // Don't fully pre-program the method. This should cause an error during + // assertions. + mock + .method("test") + .willReturn({ + "something": undefined + }); + + expect(mock.test()).toStrictEqual({ "something": undefined }); + expect(mock.calls.test).toBe(2); + expect(mock.calls.hello).toBe(2); + }); + + it(".willReturn(mock) returns the mock object (basic)", () => { + const mock = Mock(TestObjectFourBuilder).create(); + expect(mock.is_mock).toBe(true); + + mock + .method("someComplexMethod") + .willReturn(mock); + + expect(mock.someComplexMethod()).toBe(mock); + expect(mock.calls.someComplexMethod).toBe(1); + }); + + it(".willReturn(mock) returns the mock object (extra)", () => { + // Assert that the original implementation sets properties + const mock1 = Mock(TestObjectFourBuilder).create(); + expect(mock1.is_mock).toBe(true); + mock1.someComplexMethod(); + expect(mock1.something_one).toBe("one"); + expect(mock1.something_two).toBe("two"); + expect(mock1.calls.someComplexMethod).toBe(1); + + // Assert that the mock implementation will not set properties + const mock2 = Mock(TestObjectFourBuilder).create(); + expect(mock2.is_mock).toBe(true); + mock2 + .method("someComplexMethod") + .willReturn(mock2); + + expect(mock2.someComplexMethod()).toBe(mock2); + expect(mock2.something_one).toBe(undefined); + expect(mock2.something_two).toBe(undefined); + expect(mock2.calls.someComplexMethod).toBe(1); + + // Assert that we can also use setters + const mock3 = Mock(TestObjectFourBuilder).create(); + expect(mock3.is_mock).toBe(true); + mock3.someComplexMethod(); + expect(mock3.something_one).toBe("one"); + expect(mock3.something_two).toBe("two"); + mock3.something_one = "you got changed"; + expect(mock3.something_one).toBe("you got changed"); + expect(mock3.calls.someComplexMethod).toBe(1); + }); + + it( + ".willThrow() causes throwing RandomError (with constructor)", + () => { + const mock = Mock(TestObjectThree).create(); + expect(mock.is_mock).toBe(true); + + // Original returns "World" + expect(mock.test()).toBe("World"); + + // Make the original method throw RandomError + mock + .method("test") + .willThrow(new RandomError("Random error message.")); + + expect( + () => mock.test() + ).toThrow(new RandomError("Random error message.")); + expect(mock.calls.test).toBe(2); + }); + + it( + ".willThrow() causes throwing RandomError2 (no constructor)", + () => { + const mock = Mock(TestObjectThree).create(); + expect(mock.is_mock).toBe(true); + + // Original returns "World" + expect(mock.test()).toBe("World"); + + // Make the original method throw RandomError + mock + .method("test") + .willThrow(new RandomError2()); + + expect(() => mock.test()).toThrow(new RandomError2("Some message not by the constructor.")); + expect(mock.calls.test).toBe(2); + }); + + it( + ".expects(...).toBeCalled(...)", + () => { + const mock = Mock(TestObjectThree).create(); + expect(mock.is_mock).toBe(true); + + mock.expects("hello").toBeCalled(2); + mock.test(); + mock.verifyExpectations(); + }); + }); + + // TODO(crookse) Put the below tests into one of the groups above this line + + describe("call count for outside nested function is increased", () => { + const mockMathService = Mock(MathService) + .create(); + const mockTestObject = Mock(TestObjectLotsOfDataMembers) + .withConstructorArgs("has mocked math service", mockMathService) + .create(); + expect(mockMathService.calls.add).toBe(0); + expect(mockMathService.calls.nestedAdd).toBe(0); + mockTestObject.sum(1, 1, true); + expect(mockMathService.calls.add).toBe(1); + expect(mockMathService.calls.nestedAdd).toBe(1); + }); + + describe("can mock getters and setters", () => { + const mock = Mock(TestObjectLotsOfDataMembers) + .create(); + mock.age = 999; + expect(mock.age).toBe(999); + }); + + describe("native request mock", () => { + const router = Mock(TestRequestHandler).create(); + + const reqPost = new Request("https://google.com", { + method: "post", + headers: { + "content-type": "application/json", + }, + }); + console.log("testasdfasfasdf") + console.log(reqPost.headers); + console.log("testasdfasfasdf") + expect(router.calls.handle).toBe(0); + expect(router.handle(reqPost)).toBe("posted"); + expect(router.calls.handle).toBe(1); + + const reqPostNotJson = new Request("https://google.com", { + method: "post", + }); + expect(router.calls.handle).toBe(1); + expect(router.handle(reqPostNotJson)).toBe("Content-Type is incorrect"); + expect(router.calls.handle).toBe(2); + + const reqGet = new Request("https://google.com", { + method: "get", + }); + + expect(router.calls.handle).toBe(2); + expect(router.handle(reqGet)).toBe("Method is not post"); + expect(router.calls.handle).toBe(3); + }); + + describe("sets the default value for getters", () => { + class Game { + } + + class PlayersEngine { + game = new Game(); + get Game() { + return this.game; + } + set Game(val) { + this.game = val; + } + } + + const mock = Mock(PlayersEngine).create(); + expect(mock.Game instanceof Game).toBe(true); + }); +}); diff --git a/tests/cjs/unit/mod/stub.test.js b/tests/cjs/unit/mod/stub.test.js new file mode 100644 index 00000000..4bf8afd3 --- /dev/null +++ b/tests/cjs/unit/mod/stub.test.js @@ -0,0 +1,44 @@ +const { Stub } = require("../../../../lib/cjs/mod"); + +class Server { + greeting = "hello"; + + methodThatLogs() { + return "server is running!"; + } +} + +describe("Stub()", () => { + it("can stub a class property", () => { + const server = new Server(); + expect(server.greeting).toBe("hello"); + Stub(server, "greeting", "you got changed"); + expect(server.greeting).toBe("you got changed"); + Stub(server, "greeting", null); + expect(server.greeting).toBe(null); + Stub(server, "greeting", true); + expect(server.greeting).toBe(true); + const obj = { test: "hello" }; + Stub(server, "greeting", obj); + expect(server.greeting).toBe(obj); + }); + + it("can stub a class method", () => { + const server = new Server(); + expect(server.methodThatLogs()).toBe("server is running!"); + Stub(server, "methodThatLogs"); + expect(server.methodThatLogs()).toBe("stubbed"); + Stub(server, "methodThatLogs", null); + expect(server.methodThatLogs()).toBe(null); + Stub(server, "methodThatLogs", true); + expect(server.methodThatLogs()).toBe(true); + const obj = { test: "hello" }; + Stub(server, "methodThatLogs", obj); + expect(server.methodThatLogs()).toBe(obj); + }); + + it("can return a stubbed function", () => { + const stub = Stub(); + expect(stub()).toBe("stubbed"); + }); +}); From 6b0d6cc64652795d8c54115ae5b1484647d1366f Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 22:16:11 -0400 Subject: [PATCH 45/62] fix: issue with erratic builds --- console/build_esm_lib | 9 +++++++++ console/build_esm_lib.ts | 5 ----- package.json | 3 +-- 3 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 console/build_esm_lib diff --git a/console/build_esm_lib b/console/build_esm_lib new file mode 100644 index 00000000..82a53f24 --- /dev/null +++ b/console/build_esm_lib @@ -0,0 +1,9 @@ +#!/bin/bash + +( + rm -r tmp/conversion_workspace/ + mkdir -p tmp/conversion_workspace/ + cp -r src/ tmp/conversion_workspace/src/ + cp mod.ts tmp/conversion_workspace/mod.ts + deno run --allow-read --allow-run --allow-write ./console/build_esm_lib.ts +) diff --git a/console/build_esm_lib.ts b/console/build_esm_lib.ts index 0464e397..49608e68 100644 --- a/console/build_esm_lib.ts +++ b/console/build_esm_lib.ts @@ -12,11 +12,6 @@ const filesToRewrite = [ "tmp/conversion_workspace/mod.ts", ]; -Deno.run({ cmd: ["rm", "-r", "tmp/conversion_workspace/"] }); -Deno.run({ cmd: ["mkdir", "-p", "tmp/conversion_workspace/"] }); -Deno.run({ cmd: ["cp", "-r", "src/", `tmp/conversion_workspace/src`] }); -Deno.run({ cmd: ["cp", "mod.ts", `tmp/conversion_workspace/mod.ts`] }); - let file: any; while (!file) { diff --git a/package.json b/package.json index de3c78f3..b87f1ea6 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,7 @@ "test": "jest --verbose tests", "build:cjs": "tsc --project tsconfig.cjs.json", "build:esm": "tsc --project tsconfig.esm.json", - "build:conversion-workspace": "deno run --allow-read --allow-run --allow-write ./console/build_esm_lib.ts", - "build": "yarn build:conversion-workspace && yarn build:cjs && yarn build:esm" + "build": ". console/build_esm_lib && yarn build:cjs && yarn build:esm" }, "devDependencies": { "@types/jest": "27.x", From 79c26a2c1ec82064f4ec456f03e23645ccb6a6ad Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 23:09:20 -0400 Subject: [PATCH 46/62] fix: issue with testing esm --- babel.config.js | 1 + jest.config.ts | 14 + package.json | 5 +- yarn.lock | 829 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 831 insertions(+), 18 deletions(-) create mode 100644 babel.config.js create mode 100644 jest.config.ts diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..9ea84edd --- /dev/null +++ b/babel.config.js @@ -0,0 +1 @@ +module.exports = {presets: ['@babel/preset-env']} diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 00000000..e11f801b --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,14 @@ +/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ +import type { Config } from "@jest/types" + +const config: Config.InitialOptions = { + preset: "ts-jest", + testEnvironment: "node", + verbose: true, + moduleFileExtensions: ["ts", "js"], + transform: { + '^.+\\.(ts|tsx)?$': 'ts-jest', + "^.+\\.(js|jsx)$": "babel-jest", + } +} +export default config diff --git a/package.json b/package.json index b87f1ea6..4d2660c3 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,16 @@ "author": "Drash Land", "license": "MIT", "scripts": { - "test": "jest --verbose tests", + "test": "jest tests", "build:cjs": "tsc --project tsconfig.cjs.json", "build:esm": "tsc --project tsconfig.esm.json", "build": ". console/build_esm_lib && yarn build:cjs && yarn build:esm" }, "devDependencies": { + "@babel/preset-env": "7.x", "@types/jest": "27.x", "@types/node": "16.x", + "babel-jest": "27.x", "jest": "27.x", "ts-jest": "27.x", "ts-node": "10.x", @@ -25,4 +27,3 @@ "./lib" ] } - diff --git a/yarn.lock b/yarn.lock index 35128528..96f75f00 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,7 +16,7 @@ dependencies: "@babel/highlight" "^7.16.7" -"@babel/compat-data@^7.17.7": +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.8", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== @@ -51,7 +51,22 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-compilation-targets@^7.17.7": +"@babel/helper-annotate-as-pure@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" + integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" + integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== @@ -61,6 +76,41 @@ browserslist "^4.17.5" semver "^6.3.0" +"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7", "@babel/helper-create-class-features-plugin@^7.17.6": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.9.tgz#71835d7fb9f38bd9f1378e40a4c0902fdc2ea49d" + integrity sha512-kUjip3gruz6AJKOq5i3nC6CoCEEF/oHH3cp6tOZhB+IyyyPyW0g1Gfsxn3mkk6S08pIA2y8GQh609v9G/5sHVQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.17.9" + "@babel/helper-member-expression-to-functions" "^7.17.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + +"@babel/helper-create-regexp-features-plugin@^7.16.7": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" + integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + regexpu-core "^5.0.1" + +"@babel/helper-define-polyfill-provider@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" + integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + "@babel/helper-environment-visitor@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" @@ -68,7 +118,14 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-function-name@^7.17.9": +"@babel/helper-explode-assignable-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" + integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== @@ -83,14 +140,21 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-module-imports@^7.16.7": +"@babel/helper-member-expression-to-functions@^7.16.7", "@babel/helper-member-expression-to-functions@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" + integrity sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw== + dependencies: + "@babel/types" "^7.17.0" + +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== dependencies: "@babel/types" "^7.16.7" -"@babel/helper-module-transforms@^7.17.7": +"@babel/helper-module-transforms@^7.16.7", "@babel/helper-module-transforms@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== @@ -104,11 +168,38 @@ "@babel/traverse" "^7.17.3" "@babel/types" "^7.17.0" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0": +"@babel/helper-optimise-call-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" + integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== +"@babel/helper-remap-async-to-generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" + integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-wrap-function" "^7.16.8" + "@babel/types" "^7.16.8" + +"@babel/helper-replace-supers@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" + integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/helper-simple-access@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" @@ -116,6 +207,13 @@ dependencies: "@babel/types" "^7.17.0" +"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" + integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== + dependencies: + "@babel/types" "^7.16.0" + "@babel/helper-split-export-declaration@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" @@ -133,6 +231,16 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== +"@babel/helper-wrap-function@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" + integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== + dependencies: + "@babel/helper-function-name" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.8" + "@babel/types" "^7.16.8" + "@babel/helpers@^7.17.9": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" @@ -156,6 +264,150 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" + integrity sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9" + integrity sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + +"@babel/plugin-proposal-async-generator-functions@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" + integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" + integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-proposal-class-static-block@^7.16.7": + version "7.17.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz#164e8fd25f0d80fa48c5a4d1438a6629325ad83c" + integrity sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.17.6" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-dynamic-import@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" + integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" + integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" + integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" + integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" + integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" + integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.16.7": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz#d9eb649a54628a51701aef7e0ea3d17e2b9dd390" + integrity sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw== + dependencies: + "@babel/compat-data" "^7.17.0" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.16.7" + +"@babel/plugin-proposal-optional-catch-binding@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" + integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" + integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.16.11": + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" + integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.10" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-proposal-private-property-in-object@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce" + integrity sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" + integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -170,13 +422,34 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" @@ -191,7 +464,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== @@ -205,7 +478,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.8.3": +"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== @@ -233,7 +506,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.8.3": +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== @@ -247,6 +527,354 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-arrow-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" + integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-async-to-generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" + integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + +"@babel/plugin-transform-block-scoped-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" + integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-block-scoping@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" + integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-classes@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" + integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" + integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-destructuring@^7.16.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz#49dc2675a7afa9a5e4c6bdee636061136c3408d1" + integrity sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" + integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-duplicate-keys@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" + integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-exponentiation-operator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" + integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-for-of@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" + integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" + integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== + dependencies: + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" + integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-member-expression-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" + integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-modules-amd@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" + integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.16.8": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.9.tgz#274be1a2087beec0254d4abd4d86e52442e1e5b6" + integrity sha512-2TBFd/r2I6VlYn0YRTz2JdazS+FoUuQ2rIFHoAxtyP/0G3D82SBLaRq9rnUkpqlLg03Byfl/+M32mpxjO6KaPw== + dependencies: + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-simple-access" "^7.17.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.16.7": + version "7.17.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.17.8.tgz#81fd834024fae14ea78fbe34168b042f38703859" + integrity sha512-39reIkMTUVagzgA5x88zDYXPCMT6lcaRKs1+S9K6NKBPErbgO/w/kP8GlNQTC87b412ZTlmNgr3k2JrWgHH+Bw== + dependencies: + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" + integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" + integrity sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + +"@babel/plugin-transform-new-target@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" + integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-object-super@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" + integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + +"@babel/plugin-transform-parameters@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" + integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-property-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" + integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-regenerator@^7.16.7": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.17.9.tgz#0a33c3a61cf47f45ed3232903683a0afd2d3460c" + integrity sha512-Lc2TfbxR1HOyn/c6b4Y/b6NHoTb67n/IoWLxTu4kC7h4KQnWlhCq2S8Tx0t2SVvv5Uu87Hs+6JEJ5kt2tYGylQ== + dependencies: + regenerator-transform "^0.15.0" + +"@babel/plugin-transform-reserved-words@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" + integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-shorthand-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" + integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-spread@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" + integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + +"@babel/plugin-transform-sticky-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" + integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-template-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" + integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-typeof-symbol@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" + integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-unicode-escapes@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" + integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-unicode-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" + integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/preset-env@7.x": + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982" + integrity sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g== + dependencies: + "@babel/compat-data" "^7.16.8" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-option" "^7.16.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-async-generator-functions" "^7.16.8" + "@babel/plugin-proposal-class-properties" "^7.16.7" + "@babel/plugin-proposal-class-static-block" "^7.16.7" + "@babel/plugin-proposal-dynamic-import" "^7.16.7" + "@babel/plugin-proposal-export-namespace-from" "^7.16.7" + "@babel/plugin-proposal-json-strings" "^7.16.7" + "@babel/plugin-proposal-logical-assignment-operators" "^7.16.7" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7" + "@babel/plugin-proposal-numeric-separator" "^7.16.7" + "@babel/plugin-proposal-object-rest-spread" "^7.16.7" + "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-private-methods" "^7.16.11" + "@babel/plugin-proposal-private-property-in-object" "^7.16.7" + "@babel/plugin-proposal-unicode-property-regex" "^7.16.7" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.16.7" + "@babel/plugin-transform-async-to-generator" "^7.16.8" + "@babel/plugin-transform-block-scoped-functions" "^7.16.7" + "@babel/plugin-transform-block-scoping" "^7.16.7" + "@babel/plugin-transform-classes" "^7.16.7" + "@babel/plugin-transform-computed-properties" "^7.16.7" + "@babel/plugin-transform-destructuring" "^7.16.7" + "@babel/plugin-transform-dotall-regex" "^7.16.7" + "@babel/plugin-transform-duplicate-keys" "^7.16.7" + "@babel/plugin-transform-exponentiation-operator" "^7.16.7" + "@babel/plugin-transform-for-of" "^7.16.7" + "@babel/plugin-transform-function-name" "^7.16.7" + "@babel/plugin-transform-literals" "^7.16.7" + "@babel/plugin-transform-member-expression-literals" "^7.16.7" + "@babel/plugin-transform-modules-amd" "^7.16.7" + "@babel/plugin-transform-modules-commonjs" "^7.16.8" + "@babel/plugin-transform-modules-systemjs" "^7.16.7" + "@babel/plugin-transform-modules-umd" "^7.16.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.8" + "@babel/plugin-transform-new-target" "^7.16.7" + "@babel/plugin-transform-object-super" "^7.16.7" + "@babel/plugin-transform-parameters" "^7.16.7" + "@babel/plugin-transform-property-literals" "^7.16.7" + "@babel/plugin-transform-regenerator" "^7.16.7" + "@babel/plugin-transform-reserved-words" "^7.16.7" + "@babel/plugin-transform-shorthand-properties" "^7.16.7" + "@babel/plugin-transform-spread" "^7.16.7" + "@babel/plugin-transform-sticky-regex" "^7.16.7" + "@babel/plugin-transform-template-literals" "^7.16.7" + "@babel/plugin-transform-typeof-symbol" "^7.16.7" + "@babel/plugin-transform-unicode-escapes" "^7.16.7" + "@babel/plugin-transform-unicode-regex" "^7.16.7" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.16.8" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.5.0" + babel-plugin-polyfill-regenerator "^0.3.0" + core-js-compat "^3.20.2" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@^7.8.4": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" + integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -256,7 +884,7 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": +"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw== @@ -272,7 +900,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": +"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== @@ -734,7 +1362,7 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -babel-jest@^27.5.1: +babel-jest@27.x, babel-jest@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== @@ -748,6 +1376,13 @@ babel-jest@^27.5.1: graceful-fs "^4.2.9" slash "^3.0.0" +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" @@ -769,6 +1404,30 @@ babel-plugin-jest-hoist@^27.5.1: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" +babel-plugin-polyfill-corejs2@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" + integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.3.1" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" + integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + core-js-compat "^3.21.0" + +babel-plugin-polyfill-regenerator@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" + integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" @@ -820,7 +1479,7 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.17.5: +browserslist@^4.17.5, browserslist@^4.20.2: version "4.20.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== @@ -850,6 +1509,14 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -964,6 +1631,14 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" +core-js-compat@^3.20.2, core-js-compat@^3.21.0: + version "3.22.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.0.tgz#7ce17ab57c378be2c717c7c8ed8f82a50a25b3e4" + integrity sha512-WwA7xbfRGrk8BGaaHlakauVXrlYmAIkk8PNGb1FDQS+Rbrewc3pgFfwJFRw6psmJVAll7Px9UHRYE16oRQnwAQ== + dependencies: + browserslist "^4.20.2" + semver "7.0.0" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -1031,6 +1706,13 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1218,6 +1900,15 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -1260,6 +1951,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-symbols@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -1879,6 +2575,11 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -1919,6 +2620,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -2029,6 +2735,21 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -2168,6 +2889,54 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regenerator-transform@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" + integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== + dependencies: + "@babel/runtime" "^7.8.4" + +regexpu-core@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" + integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== + +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== + dependencies: + jsesc "~0.5.0" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -2190,7 +2959,7 @@ resolve.exports@^1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== -resolve@^1.20.0: +resolve@^1.14.2, resolve@^1.20.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== @@ -2223,6 +2992,11 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + semver@7.x, semver@^7.3.2: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" @@ -2230,7 +3004,7 @@ semver@7.x, semver@^7.3.2: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -2492,6 +3266,29 @@ typescript@4.x: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" From 5f5458d495fe09e5695aa75619e8d0a05aa6c589 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 23:29:25 -0400 Subject: [PATCH 47/62] chore: remove test for protected methods (should not do this) --- tests/deno/unit/mod/mock_test.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/tests/deno/unit/mod/mock_test.ts b/tests/deno/unit/mod/mock_test.ts index f34a0226..1bf2c115 100644 --- a/tests/deno/unit/mod/mock_test.ts +++ b/tests/deno/unit/mod/mock_test.ts @@ -19,24 +19,6 @@ Deno.test("Mock()", async (t) => { assertEquals(mock.is_mock, true); }, }); - - await t.step("can access protected property", () => { - const mock = Mock(TestObjectLotsOfDataMembers) - .create(); - assertEquals( - (mock as unknown as { [key: string]: string }).protected_property, - "I AM PROTECTED PROPERTY.", - ); - }); - - await t.step("can access protected method", () => { - const mock = Mock(TestObjectLotsOfDataMembers) - .create(); - assertEquals( - (mock as unknown as { [key: string]: () => string }).protectedMethod(), - "I AM A PROTECTED METHOD.", - ); - }); }); await t.step(".withConstructorArgs(...)", async (t) => { From b82f72c3b3996fbd94463397ed81510064bbc262 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 23:29:34 -0400 Subject: [PATCH 48/62] test: esm tests --- tests/esm/jest_assertions.ts | 7 + tests/esm/unit/mod/dummy.test.ts | 75 +++++ tests/esm/unit/mod/fake.test.ts | 361 +++++++++++++++++++++++ tests/esm/unit/mod/mock.test.ts | 482 +++++++++++++++++++++++++++++++ tests/esm/unit/mod/stub.test.ts | 45 +++ 5 files changed, 970 insertions(+) create mode 100644 tests/esm/jest_assertions.ts create mode 100644 tests/esm/unit/mod/dummy.test.ts create mode 100644 tests/esm/unit/mod/fake.test.ts create mode 100644 tests/esm/unit/mod/mock.test.ts create mode 100644 tests/esm/unit/mod/stub.test.ts diff --git a/tests/esm/jest_assertions.ts b/tests/esm/jest_assertions.ts new file mode 100644 index 00000000..d21c57ff --- /dev/null +++ b/tests/esm/jest_assertions.ts @@ -0,0 +1,7 @@ +export function assertEquals(actual: unknown, expected: unknown): void { + expect(actual).toStrictEqual(expected); +} + +export function assertThrows(actual: () => unknown, expected: new (message?: string) => Error, message: string): void { + expect(actual).toThrow(new expected(message)); +} \ No newline at end of file diff --git a/tests/esm/unit/mod/dummy.test.ts b/tests/esm/unit/mod/dummy.test.ts new file mode 100644 index 00000000..ed558fab --- /dev/null +++ b/tests/esm/unit/mod/dummy.test.ts @@ -0,0 +1,75 @@ +import { Dummy, Mock } from "../../../../lib/esm/mod.js"; +import { assertEquals } from "../../jest_assertions"; + +describe("Dummy()", () => { + it( + "can fill parameter lists", + (): void => { + const mockServiceOne = Mock(ServiceOne).create(); + const dummy3 = Dummy(ServiceThree); + + const resource = new Resource( + mockServiceOne, + Dummy(ServiceTwo), + dummy3, + ); + + resource.callServiceOne(); + assertEquals(mockServiceOne.calls.methodServiceOne, 1); + }); + + it( + "can be made without specifying constructor args", + (): void => { + const dummy = Dummy(Resource); + assertEquals(Object.getPrototypeOf(dummy), Resource); + }); +}); + +class Resource { + #service_one: ServiceOne; + #service_two: ServiceTwo; + #service_three: ServiceThree; + + constructor( + serviceOne: ServiceOne, + serviceTwo: ServiceTwo, + serviceThree: ServiceThree, + ) { + this.#service_one = serviceOne; + this.#service_two = serviceTwo; + this.#service_three = serviceThree; + } + + public callServiceOne() { + this.#service_one.methodServiceOne(); + } + + public callServiceTwo() { + this.#service_two.methodServiceTwo(); + } + + public callServiceThree() { + this.#service_three.methodServiceThree(); + } +} + +class ServiceOne { + public methodServiceOne() { + return "Method from ServiceOne was called."; + } +} + +class ServiceTwo { + public methodServiceTwo() { + return "Method from ServiceTwo was called."; + } +} + +class ServiceThree { + public methodServiceThree() { + return "Method from ServiceThree was called."; + } +} + +export {} diff --git a/tests/esm/unit/mod/fake.test.ts b/tests/esm/unit/mod/fake.test.ts new file mode 100644 index 00000000..5ce332bc --- /dev/null +++ b/tests/esm/unit/mod/fake.test.ts @@ -0,0 +1,361 @@ +import { Fake } from "../../../../lib/esm/mod"; +import { assertEquals, assertThrows } from "../../jest_assertions"; + +describe("Fake()", () => { + it( + "creates fake builder", + (): void => { + const fake = Fake(TestObjectOne); + assertEquals(fake.constructor.name, "FakeBuilder"); + }); + + describe(".create()", () => { + it( + "creates fake object", + (): void => { + const fake = Fake(TestObjectTwo).create(); + assertEquals(fake.name, undefined); + assertEquals(fake.is_fake, true); + }); + }); + + describe(".withConstructorArgs(...)", () => { + it( + "can take 1 arg", + (): void => { + const fake = Fake(TestObjectTwo) + .withConstructorArgs("some name") + .create(); + assertEquals(fake.name, "some name"); + assertEquals(fake.is_fake, true); + }); + + it( + "can take more than 1 arg", + (): void => { + const fake = Fake(TestObjectTwoMore) + .withConstructorArgs("some name", ["hello"]) + .create(); + assertEquals(fake.name, "some name"); + assertEquals(fake.array, ["hello"]); + assertEquals(fake.is_fake, true); + }); + }); + + describe(".method(...)", () => { + it( + "requires .willReturn(...) or .willThrow(...) to be chained", + (): void => { + const fake = Fake(TestObjectThree).create(); + assertEquals(fake.is_fake, true); + + // Original returns "World" + assertEquals(fake.test(), "World"); + + // Don't fully pre-program the method. This should cause an error during assertions. + fake.method("test"); + + try { + fake.test(); + } catch (error) { + assertEquals( + error.message, + `Pre-programmed method "test" does not have a return value.`, + ); + } + }); + + it( + ".willReturn(...) does not call original method and returns given value", + (): void => { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findAllUsers").willReturn("shortcut"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUsers(); + assertEquals(fakeServiceDoingShortcut.anotha_one_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_else_called, false); + + // Assert that the fake service can call original implementations + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUsers(); + assertEquals(fakeServiceNotDoingShortcut.anotha_one_called, true); + assertEquals(fakeServiceNotDoingShortcut.do_something_called, true); + assertEquals( + fakeServiceNotDoingShortcut.do_something_else_called, + true, + ); + }); + + it( + ".willReturn(...) can be performed more than once", + (): void => { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findUserById").willReturn("shortcut"); + fakeServiceDoingShortcut.method("findUserById").willReturn("shortcut2"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUser(1); + assertEquals(fakeServiceDoingShortcut.anotha_one_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_else_called, false); + + // Assert that the fake service can call original implementations + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUser(1); + assertEquals(fakeServiceNotDoingShortcut.anotha_one_called, true); + assertEquals(fakeServiceNotDoingShortcut.do_something_called, true); + assertEquals( + fakeServiceNotDoingShortcut.do_something_else_called, + true, + ); + }); + + it( + ".willThrow(...) does not call original method and throws error", + (): void => { + // Assert that a fake can make a class take a shortcut + const fakeServiceDoingShortcut = Fake(Repository).create(); + fakeServiceDoingShortcut.method("findAllUsers").willReturn("shortcut"); + const resourceWithShortcut = new Resource( + fakeServiceDoingShortcut, + ); + resourceWithShortcut.getUsers(); + assertEquals(fakeServiceDoingShortcut.anotha_one_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_called, false); + assertEquals(fakeServiceDoingShortcut.do_something_else_called, false); + + // Assert that the fake service can call original implementations + const fakeServiceNotDoingShortcut = Fake(Repository).create(); + const resourceWithoutShortcut = new Resource( + fakeServiceNotDoingShortcut, + ); + resourceWithoutShortcut.getUsers(); + assertEquals(fakeServiceNotDoingShortcut.anotha_one_called, true); + assertEquals(fakeServiceNotDoingShortcut.do_something_called, true); + assertEquals( + fakeServiceNotDoingShortcut.do_something_else_called, + true, + ); + }); + + it( + ".willReturn(fake) returns the fake object (basic)", + (): void => { + const fake = Fake(TestObjectFourBuilder).create(); + assertEquals(fake.is_fake, true); + + fake + .method("someComplexMethod") + .willReturn(fake); + + assertEquals(fake.someComplexMethod(), fake); + }); + + it( + ".willReturn(fake) returns the fake object (extra)", + (): void => { + // Assert that the original implementation sets properties + const fake1 = Fake(TestObjectFourBuilder).create(); + assertEquals(fake1.is_fake, true); + fake1.someComplexMethod(); + assertEquals(fake1.something_one, "one"); + assertEquals(fake1.something_two, "two"); + + // Assert that the fake implementation will not set properties + const fake2 = Fake(TestObjectFourBuilder).create(); + assertEquals(fake2.is_fake, true); + fake2 + .method("someComplexMethod") + .willReturn(fake2); + + assertEquals(fake2.someComplexMethod(), fake2); + assertEquals(fake2.something_one, undefined); + assertEquals(fake2.something_two, undefined); + + // Assert that we can also use setters + const fake3 = Fake(TestObjectFourBuilder).create(); + assertEquals(fake3.is_fake, true); + fake3.someComplexMethod(); + assertEquals(fake3.something_one, "one"); + assertEquals(fake3.something_two, "two"); + fake3.something_one = "you got changed"; + assertEquals(fake3.something_one, "you got changed"); + }); + + it( + ".willThrow() causes throwing RandomError (with constructor)", + (): void => { + const fake = Fake(TestObjectThree).create(); + assertEquals(fake.is_fake, true); + + // Original returns "World" + assertEquals(fake.test(), "World"); + + // Make the original method throw RandomError + fake + .method("test") + .willThrow(new RandomError("Random error message.")); + + assertThrows( + () => fake.test(), + RandomError, + "Random error message.", + ); + }); + + it( + ".willThrow() causes throwing RandomError2 (no constructor)", + (): void => { + const fake = Fake(TestObjectThree).create(); + assertEquals(fake.is_fake, true); + + // Original returns "World" + assertEquals(fake.test(), "World"); + + // Make the original method throw RandomError + fake + .method("test") + .willThrow(new RandomError2()); + + assertThrows( + () => fake.test(), + RandomError2, + "Some message not by the constructor.", + ); + }); + }); +}); + +//////////////////////////////////////////////////////////////////////////////// +// FILE MARKER - DATA ////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +class TestObjectOne { +} + +class TestObjectTwo { + public name: string; + constructor(name: string) { + this.name = name; + } +} + +class TestObjectTwoMore { + public name: string; + public array: string[]; + constructor(name: string, array: string[]) { + this.name = name; + this.array = array; + } +} + +class TestObjectThree { + public hello(): void { + return; + } + + public test(): string { + this.hello(); + this.hello(); + return "World"; + } +} + +class Resource { + #repository: Repository; + + constructor( + serviceOne: Repository, + ) { + this.#repository = serviceOne; + } + + public getUsers() { + this.#repository.findAllUsers(); + } + + public getUser(id: number) { + this.#repository.findUserById(id); + } +} + +class TestObjectFourBuilder { + #something_one?: string; + #something_two?: string; + + get something_one(): string | undefined { + return this.#something_one; + } + + set something_one(value: string | undefined) { + this.#something_one = value; + } + + get something_two(): string | undefined { + return this.#something_two; + } + + someComplexMethod(): this { + this.#setSomethingOne(); + this.#setSomethingTwo(); + return this; + } + + #setSomethingOne(): void { + this.#something_one = "one"; + } + + #setSomethingTwo(): void { + this.#something_two = "two"; + } +} + +class Repository { + public anotha_one_called = false; + public do_something_called = false; + public do_something_else_called = false; + + public findAllUsers(): string { + this.#doSomething(); + this.#doSomethingElse(); + this.#anothaOne(); + return "Finding all users"; + } + + public findUserById(id: number): string { + this.#doSomething(); + this.#doSomethingElse(); + this.#anothaOne(); + return `Finding user by id #${id}`; + } + + #anothaOne() { + this.anotha_one_called = true; + } + + #doSomething() { + this.do_something_called = true; + } + + #doSomethingElse() { + this.do_something_else_called = true; + } +} + +class RandomError extends Error {} +class RandomError2 extends Error { + public name = "RandomError2Name"; + public message = "Some message not by the constructor."; +} diff --git a/tests/esm/unit/mod/mock.test.ts b/tests/esm/unit/mod/mock.test.ts new file mode 100644 index 00000000..08f954ee --- /dev/null +++ b/tests/esm/unit/mod/mock.test.ts @@ -0,0 +1,482 @@ +import { Mock } from "../../../../lib/esm/mod"; +import { assertEquals, assertThrows } from "../../jest_assertions"; + +interface IRequestOptions { + headers?: Record; + method?: string; +} + +class Request { + public options: IRequestOptions; + public url: string; + public headers: Map; + public method: string; + + constructor( + url: string, + options: IRequestOptions + ) { + this.url = url; + this.options = options; + this.headers = this.createHeaders(options.headers ?? {}); + this.method = options.method ? options.method : "get"; + } + + createHeaders(headers: Record) { + const map = new Map(); + for (const header in headers) { + const value = headers[header]; + map.set(header, value); + } + return map; + } +} + +class TestObjectOne { +} + +class TestObjectTwo { + public name: string; + constructor(name: string) { + this.name = name; + } +} + +class TestObjectTwoMore { + public name: string; + public array: string[]; + constructor(name: string, array: string[]) { + this.name = name; + this.array = array; + } +} + +class TestObjectThree { + public hello(): void { + return; + } + + public test(): string { + this.hello(); + this.hello(); + return "World"; + } +} + +class TestObjectFourBuilder { + #something_one?: string; + #something_two?: string; + + get something_one(): string | undefined { + return this.#something_one; + } + + set something_one(value: string | undefined) { + this.#something_one = value; + } + + get something_two(): string | undefined { + return this.#something_two; + } + + someComplexMethod(): this { + this.#setSomethingOne(); + this.#setSomethingTwo(); + return this; + } + + #setSomethingOne(): void { + this.#something_one = "one"; + } + + #setSomethingTwo(): void { + this.#something_two = "two"; + } +} + +class RandomError extends Error {} +class RandomError2 extends Error { + public name = "RandomError2Name"; + public message = "Some message not by the constructor."; +} + +class MathService { + public add( + num1: number, + num2: number, + useNestedAdd = false, + ): number { + if (useNestedAdd) { + return this.nestedAdd(num1, num2); + } + return num1 + num2; + } + + public nestedAdd(num1: number, num2: number): number { + return num1 + num2; + } +} + +class TestObjectLotsOfDataMembers { + public name: string; + #age = 0; + protected math_service: MathService; + protected protected_property = "I AM PROTECTED PROPERTY."; + constructor(name: string, mathService: MathService) { + this.math_service = mathService; + this.name = name; + } + public sum( + num1: number, + num2: number, + useNestedAdd = false, + ): number { + const sum = this.math_service.add(num1, num2, useNestedAdd); + return sum; + } + protected protectedMethod() { + return "I AM A PROTECTED METHOD."; + } + + public get age() { + return this.#age; + } + + public set age(val: number) { + this.#age = val; + } +} + +class TestRequestHandler { + // deno-lint-ignore require-await + async handle(request: Request): Promise { + const method = request.method.toLowerCase(); + const contentType = request.headers.get("content-type"); + + if (method !== "post") { + return "Method is not post"; + } + + if (contentType !== "application/json") { + return "Content-Type is incorrect"; + } + + return "posted"; + } +} + +describe("Mock()", () => { + it( + "creates mock builder", + (): void => { + const mock = Mock(TestObjectOne); + assertEquals(mock.constructor.name, "MockBuilder"); + }); + + describe(".create()", () => { + it( + "creates mock object", + (): void => { + const mock = Mock(TestObjectTwo).create(); + assertEquals(mock.name, undefined); + assertEquals(mock.is_mock, true); + }); + }); + + describe(".withConstructorArgs(...)", () => { + it( + "can take 1 arg", + (): void => { + const mock = Mock(TestObjectTwo) + .withConstructorArgs("some name") + .create(); + assertEquals(mock.name, "some name"); + assertEquals(mock.is_mock, true); + }); + + it( + "can take more than 1 arg", + (): void => { + const mock = Mock(TestObjectTwoMore) + .withConstructorArgs("some name", ["hello"]) + .create(); + assertEquals(mock.name, "some name"); + assertEquals(mock.array, ["hello"]); + assertEquals(mock.is_mock, true); + + const mockMathService = Mock(MathService) + .create(); + const mockTestObject = Mock(TestObjectLotsOfDataMembers) + .withConstructorArgs("has mocked math service", mockMathService) + .create(); + assertEquals(mockMathService.calls.add, 0); + mockTestObject.sum(1, 1); + assertEquals(mockMathService.calls.add, 1); + }); + }); + + describe("method(...)", () => { + it( + "requires .willReturn(...) or .willThrow(...) to be chained", + (): void => { + const mock = Mock(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Don't fully pre-program the method. This should cause an error during assertions. + mock.method("test"); + + try { + mock.test(); + } catch (error) { + assertEquals( + error.message, + `Pre-programmed method "test" does not have a return value.`, + ); + } + assertEquals(mock.calls.test, 2); + assertEquals(mock.calls.hello, 2); + }); + + it( + ".willReturn(...) does not call original method and returns given value", + (): void => { + const mock = Mock(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Change original to return "Hello" + mock.method("test").willReturn("Hello"); + + // Should output "Hello" and make the following calls + assertEquals(mock.test(), "Hello"); + assertEquals(mock.calls.test, 2); + assertEquals(mock.calls.hello, 2); + }); + + it( + ".willReturn(...) can be performed more than once", + (): void => { + const mock = Mock(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Change original to return "Hello" + mock.method("test").willReturn("Hello"); + mock.method("test").willReturn("Hello!"); + + assertEquals(mock.test(), "Hello!"); + assertEquals(mock.calls.test, 2); + assertEquals(mock.calls.hello, 2); + }); + + it( + ".willReturn(...) returns specified value", + (): void => { + const mock = Mock(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Don't fully pre-program the method. This should cause an error during + // assertions. + mock + .method("test") + .willReturn({ + "something": "something", + }); + + assertEquals(mock.test(), { "something": "something" }); + assertEquals(mock.calls.test, 2); + assertEquals(mock.calls.hello, 2); + }); + + it( + ".willReturn(mock) returns the mock object (basic)", + (): void => { + const mock = Mock(TestObjectFourBuilder).create(); + assertEquals(mock.is_mock, true); + + mock + .method("someComplexMethod") + .willReturn(mock); + + assertEquals(mock.someComplexMethod(), mock); + assertEquals(mock.calls.someComplexMethod, 1); + }); + + it( + ".willReturn(mock) returns the mock object (extra)", + (): void => { + // Assert that the original implementation sets properties + const mock1 = Mock(TestObjectFourBuilder).create(); + assertEquals(mock1.is_mock, true); + mock1.someComplexMethod(); + assertEquals(mock1.something_one, "one"); + assertEquals(mock1.something_two, "two"); + assertEquals(mock1.calls.someComplexMethod, 1); + + // Assert that the mock implementation will not set properties + const mock2 = Mock(TestObjectFourBuilder).create(); + assertEquals(mock2.is_mock, true); + mock2 + .method("someComplexMethod") + .willReturn(mock2); + + assertEquals(mock2.someComplexMethod(), mock2); + assertEquals(mock2.something_one, undefined); + assertEquals(mock2.something_two, undefined); + assertEquals(mock2.calls.someComplexMethod, 1); + + // Assert that we can also use setters + const mock3 = Mock(TestObjectFourBuilder).create(); + assertEquals(mock3.is_mock, true); + mock3.someComplexMethod(); + assertEquals(mock3.something_one, "one"); + assertEquals(mock3.something_two, "two"); + mock3.something_one = "you got changed"; + assertEquals(mock3.something_one, "you got changed"); + assertEquals(mock3.calls.someComplexMethod, 1); + }); + + it( + ".willThrow() causes throwing RandomError (with constructor)", + (): void => { + const mock = Mock(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Make the original method throw RandomError + mock + .method("test") + .willThrow(new RandomError("Random error message.")); + + assertThrows( + () => mock.test(), + RandomError, + "Random error message.", + ); + assertEquals(mock.calls.test, 2); + }); + + it( + ".willThrow() causes throwing RandomError2 (no constructor)", + (): void => { + const mock = Mock(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + // Original returns "World" + assertEquals(mock.test(), "World"); + + // Make the original method throw RandomError + mock + .method("test") + .willThrow(new RandomError2()); + + assertThrows( + () => mock.test(), + RandomError2, + "Some message not by the constructor.", + ); + assertEquals(mock.calls.test, 2); + }); + + it( + ".expects(...).toBeCalled(...)", + (): void => { + const mock = Mock(TestObjectThree).create(); + assertEquals(mock.is_mock, true); + + mock.expects("hello").toBeCalled(2); + mock.test(); + mock.verifyExpectations(); + }); + }); + + // TODO(crookse) Put the below tests into one of the groups above this line + + describe("call count for outside nested function is increased", () => { + const mockMathService = Mock(MathService) + .create(); + const mockTestObject = Mock(TestObjectLotsOfDataMembers) + .withConstructorArgs("has mocked math service", mockMathService) + .create(); + assertEquals(mockMathService.calls.add, 0); + assertEquals(mockMathService.calls.nestedAdd, 0); + mockTestObject.sum(1, 1, true); + assertEquals(mockMathService.calls.add, 1); + assertEquals(mockMathService.calls.nestedAdd, 1); + }); + + describe("can mock getters and setters", () => { + const mock = Mock(TestObjectLotsOfDataMembers) + .create(); + mock.age = 999; + assertEquals(mock.age, 999); + }); + + describe("native request mock", () => { + it("handles async requests", async () => { + + const router = Mock(TestRequestHandler).create(); + + const reqPost = new Request("https://google.com", { + method: "post", + headers: { + "content-type": "application/json", + }, + }); + assertEquals(router.calls.handle, 0); + assertEquals(await router.handle(reqPost), "posted"); + assertEquals(router.calls.handle, 1); + + const reqPostNotJson = new Request("https://google.com", { + method: "post", + }); + assertEquals(router.calls.handle, 1); + assertEquals( + await router.handle(reqPostNotJson), + "Content-Type is incorrect", + ); + assertEquals(router.calls.handle, 2); + + const reqGet = new Request("https://google.com", { + method: "get", + }); + + assertEquals(router.calls.handle, 2); + assertEquals( + await router.handle(reqGet), + "Method is not post", + ); + assertEquals(router.calls.handle, 3); + }); + }); + + describe("sets the default value for getters", () => { + class Game { + } + + class PlayersEngine { + private game = new Game(); + get Game() { + return this.game; + } + set Game(val: Game) { + this.game = val; + } + } + + const mock = Mock(PlayersEngine).create(); + assertEquals(mock.Game instanceof Game, true); + }); +}); diff --git a/tests/esm/unit/mod/stub.test.ts b/tests/esm/unit/mod/stub.test.ts new file mode 100644 index 00000000..1f9edd4b --- /dev/null +++ b/tests/esm/unit/mod/stub.test.ts @@ -0,0 +1,45 @@ +import { Stub } from "../../../../lib/esm/mod"; +import { assertEquals } from "../../jest_assertions"; + +class Server { + public greeting = "hello"; + + public methodThatLogs() { + return "server is running!"; + } +} + +describe("Stub()", () => { + it("can stub a class property", () => { + const server = new Server(); + assertEquals(server.greeting, "hello"); + Stub(server, "greeting", "you got changed"); + assertEquals(server.greeting, "you got changed"); + Stub(server, "greeting", null); + assertEquals(server.greeting, null); + Stub(server, "greeting", true); + assertEquals(server.greeting, true); + const obj = { test: "hello" }; + Stub(server, "greeting", obj); + assertEquals(server.greeting, obj); + }); + + it("can stub a class method", () => { + const server = new Server(); + assertEquals(server.methodThatLogs(), "server is running!"); + Stub(server, "methodThatLogs"); + assertEquals(server.methodThatLogs(), "stubbed"); + Stub(server, "methodThatLogs", null); + assertEquals(server.methodThatLogs(), null); + Stub(server, "methodThatLogs", true); + assertEquals(server.methodThatLogs(), true); + const obj = { test: "hello" }; + Stub(server, "methodThatLogs", obj); + assertEquals(server.methodThatLogs(), obj); + }); + + it("can return a stubbed function", () => { + const stub = Stub(); + assertEquals(stub(), "stubbed"); + }); +}); From 1f11a366581bd11f517cdfb7b3a58c3506fe53ed Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Thu, 14 Apr 2022 23:36:18 -0400 Subject: [PATCH 49/62] chore: remove yarn.lock --- .gitignore | 3 + yarn.lock | 3445 ---------------------------------------------------- 2 files changed, 3 insertions(+), 3445 deletions(-) delete mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index 7103c86f..087ca4d6 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,6 @@ tmp/ # exceptions !.gitkeep + +# locks +yarn.lock diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 96f75f00..00000000 --- a/yarn.lock +++ /dev/null @@ -1,3445 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ampproject/remapping@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" - integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== - dependencies: - "@jridgewell/trace-mapping" "^0.3.0" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== - dependencies: - "@babel/highlight" "^7.16.7" - -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.8", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" - integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== - -"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.9.tgz#6bae81a06d95f4d0dec5bb9d74bbc1f58babdcfe" - integrity sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.9" - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helpers" "^7.17.9" - "@babel/parser" "^7.17.9" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.9" - "@babel/types" "^7.17.0" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" - -"@babel/generator@^7.17.9", "@babel/generator@^7.7.2": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.9.tgz#f4af9fd38fa8de143c29fce3f71852406fc1e2fc" - integrity sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ== - dependencies: - "@babel/types" "^7.17.0" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" - integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" - integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" - integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== - dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.17.5" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7", "@babel/helper-create-class-features-plugin@^7.17.6": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.9.tgz#71835d7fb9f38bd9f1378e40a4c0902fdc2ea49d" - integrity sha512-kUjip3gruz6AJKOq5i3nC6CoCEEF/oHH3cp6tOZhB+IyyyPyW0g1Gfsxn3mkk6S08pIA2y8GQh609v9G/5sHVQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-member-expression-to-functions" "^7.17.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - -"@babel/helper-create-regexp-features-plugin@^7.16.7": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" - integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - regexpu-core "^5.0.1" - -"@babel/helper-define-polyfill-provider@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" - integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== - dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - -"@babel/helper-environment-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" - integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-explode-assignable-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" - integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" - integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== - dependencies: - "@babel/template" "^7.16.7" - "@babel/types" "^7.17.0" - -"@babel/helper-hoist-variables@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" - integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-member-expression-to-functions@^7.16.7", "@babel/helper-member-expression-to-functions@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" - integrity sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw== - dependencies: - "@babel/types" "^7.17.0" - -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-module-transforms@^7.16.7", "@babel/helper-module-transforms@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" - integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" - "@babel/types" "^7.17.0" - -"@babel/helper-optimise-call-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" - integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" - integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== - -"@babel/helper-remap-async-to-generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" - integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-wrap-function" "^7.16.8" - "@babel/types" "^7.16.8" - -"@babel/helper-replace-supers@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" - integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-member-expression-to-functions" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/helper-simple-access@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" - integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== - dependencies: - "@babel/types" "^7.17.0" - -"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" - integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-split-export-declaration@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" - integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== - -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== - -"@babel/helper-wrap-function@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" - integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== - dependencies: - "@babel/helper-function-name" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.8" - "@babel/types" "^7.16.8" - -"@babel/helpers@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" - integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== - dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.9" - "@babel/types" "^7.17.0" - -"@babel/highlight@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" - integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" - integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" - integrity sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9" - integrity sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-proposal-optional-chaining" "^7.16.7" - -"@babel/plugin-proposal-async-generator-functions@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" - integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-remap-async-to-generator" "^7.16.8" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" - integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-proposal-class-static-block@^7.16.7": - version "7.17.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz#164e8fd25f0d80fa48c5a4d1438a6629325ad83c" - integrity sha512-X/tididvL2zbs7jZCeeRJ8167U/+Ac135AM6jCAx6gYXDUviZV5Ku9UDvWS2NCuWlFjIRXklYhwo6HhAC7ETnA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.17.6" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-proposal-dynamic-import@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" - integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" - integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" - integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" - integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" - integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-numeric-separator@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" - integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.16.7": - version "7.17.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz#d9eb649a54628a51701aef7e0ea3d17e2b9dd390" - integrity sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw== - dependencies: - "@babel/compat-data" "^7.17.0" - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.16.7" - -"@babel/plugin-proposal-optional-catch-binding@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" - integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" - integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@^7.16.11": - version "7.16.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" - integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.10" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-proposal-private-property-in-object@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce" - integrity sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" - integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" - integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-arrow-functions@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" - integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-async-to-generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" - integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== - dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-remap-async-to-generator" "^7.16.8" - -"@babel/plugin-transform-block-scoped-functions@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" - integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-block-scoping@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" - integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-classes@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" - integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" - integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-destructuring@^7.16.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.7.tgz#49dc2675a7afa9a5e4c6bdee636061136c3408d1" - integrity sha512-XVh0r5yq9sLR4vZ6eVZe8FKfIcSgaTBxVBRSYokRj2qksf6QerYnTxz9/GTuKTH/n/HwLP7t6gtlybHetJ/6hQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" - integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-duplicate-keys@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" - integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-exponentiation-operator@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" - integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-for-of@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" - integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-function-name@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" - integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== - dependencies: - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" - integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-member-expression-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" - integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-modules-amd@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" - integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g== - dependencies: - "@babel/helper-module-transforms" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-commonjs@^7.16.8": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.9.tgz#274be1a2087beec0254d4abd4d86e52442e1e5b6" - integrity sha512-2TBFd/r2I6VlYn0YRTz2JdazS+FoUuQ2rIFHoAxtyP/0G3D82SBLaRq9rnUkpqlLg03Byfl/+M32mpxjO6KaPw== - dependencies: - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-systemjs@^7.16.7": - version "7.17.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.17.8.tgz#81fd834024fae14ea78fbe34168b042f38703859" - integrity sha512-39reIkMTUVagzgA5x88zDYXPCMT6lcaRKs1+S9K6NKBPErbgO/w/kP8GlNQTC87b412ZTlmNgr3k2JrWgHH+Bw== - dependencies: - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-umd@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" - integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ== - dependencies: - "@babel/helper-module-transforms" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" - integrity sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - -"@babel/plugin-transform-new-target@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" - integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-object-super@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" - integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - -"@babel/plugin-transform-parameters@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" - integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-property-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" - integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-regenerator@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.17.9.tgz#0a33c3a61cf47f45ed3232903683a0afd2d3460c" - integrity sha512-Lc2TfbxR1HOyn/c6b4Y/b6NHoTb67n/IoWLxTu4kC7h4KQnWlhCq2S8Tx0t2SVvv5Uu87Hs+6JEJ5kt2tYGylQ== - dependencies: - regenerator-transform "^0.15.0" - -"@babel/plugin-transform-reserved-words@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" - integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-shorthand-properties@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" - integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-spread@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" - integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - -"@babel/plugin-transform-sticky-regex@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" - integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-template-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" - integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-typeof-symbol@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" - integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-unicode-escapes@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" - integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/plugin-transform-unicode-regex@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" - integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/preset-env@7.x": - version "7.16.11" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982" - integrity sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g== - dependencies: - "@babel/compat-data" "^7.16.8" - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.7" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.7" - "@babel/plugin-proposal-async-generator-functions" "^7.16.8" - "@babel/plugin-proposal-class-properties" "^7.16.7" - "@babel/plugin-proposal-class-static-block" "^7.16.7" - "@babel/plugin-proposal-dynamic-import" "^7.16.7" - "@babel/plugin-proposal-export-namespace-from" "^7.16.7" - "@babel/plugin-proposal-json-strings" "^7.16.7" - "@babel/plugin-proposal-logical-assignment-operators" "^7.16.7" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7" - "@babel/plugin-proposal-numeric-separator" "^7.16.7" - "@babel/plugin-proposal-object-rest-spread" "^7.16.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" - "@babel/plugin-proposal-optional-chaining" "^7.16.7" - "@babel/plugin-proposal-private-methods" "^7.16.11" - "@babel/plugin-proposal-private-property-in-object" "^7.16.7" - "@babel/plugin-proposal-unicode-property-regex" "^7.16.7" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.16.7" - "@babel/plugin-transform-async-to-generator" "^7.16.8" - "@babel/plugin-transform-block-scoped-functions" "^7.16.7" - "@babel/plugin-transform-block-scoping" "^7.16.7" - "@babel/plugin-transform-classes" "^7.16.7" - "@babel/plugin-transform-computed-properties" "^7.16.7" - "@babel/plugin-transform-destructuring" "^7.16.7" - "@babel/plugin-transform-dotall-regex" "^7.16.7" - "@babel/plugin-transform-duplicate-keys" "^7.16.7" - "@babel/plugin-transform-exponentiation-operator" "^7.16.7" - "@babel/plugin-transform-for-of" "^7.16.7" - "@babel/plugin-transform-function-name" "^7.16.7" - "@babel/plugin-transform-literals" "^7.16.7" - "@babel/plugin-transform-member-expression-literals" "^7.16.7" - "@babel/plugin-transform-modules-amd" "^7.16.7" - "@babel/plugin-transform-modules-commonjs" "^7.16.8" - "@babel/plugin-transform-modules-systemjs" "^7.16.7" - "@babel/plugin-transform-modules-umd" "^7.16.7" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.8" - "@babel/plugin-transform-new-target" "^7.16.7" - "@babel/plugin-transform-object-super" "^7.16.7" - "@babel/plugin-transform-parameters" "^7.16.7" - "@babel/plugin-transform-property-literals" "^7.16.7" - "@babel/plugin-transform-regenerator" "^7.16.7" - "@babel/plugin-transform-reserved-words" "^7.16.7" - "@babel/plugin-transform-shorthand-properties" "^7.16.7" - "@babel/plugin-transform-spread" "^7.16.7" - "@babel/plugin-transform-sticky-regex" "^7.16.7" - "@babel/plugin-transform-template-literals" "^7.16.7" - "@babel/plugin-transform-typeof-symbol" "^7.16.7" - "@babel/plugin-transform-unicode-escapes" "^7.16.7" - "@babel/plugin-transform-unicode-regex" "^7.16.7" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.16.8" - babel-plugin-polyfill-corejs2 "^0.3.0" - babel-plugin-polyfill-corejs3 "^0.5.0" - babel-plugin-polyfill-regenerator "^0.3.0" - core-js-compat "^3.20.2" - semver "^6.3.0" - -"@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/runtime@^7.8.4": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" - integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.16.7", "@babel/template@^7.3.3": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" - integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.9" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.9" - "@babel/types" "^7.17.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" - integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - to-fast-properties "^2.0.0" - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@cspotcode/source-map-consumer@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" - integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== - -"@cspotcode/source-map-support@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" - integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== - dependencies: - "@cspotcode/source-map-consumer" "0.8.0" - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" - integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - -"@jest/core@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" - integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== - dependencies: - "@jest/console" "^27.5.1" - "@jest/reporters" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.8.1" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^27.5.1" - jest-config "^27.5.1" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-resolve-dependencies "^27.5.1" - jest-runner "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - jest-watcher "^27.5.1" - micromatch "^4.0.4" - rimraf "^3.0.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" - integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== - dependencies: - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - -"@jest/fake-timers@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" - integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== - dependencies: - "@jest/types" "^27.5.1" - "@sinonjs/fake-timers" "^8.0.1" - "@types/node" "*" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-util "^27.5.1" - -"@jest/globals@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" - integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/types" "^27.5.1" - expect "^27.5.1" - -"@jest/reporters@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" - integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-haste-map "^27.5.1" - jest-resolve "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - slash "^3.0.0" - source-map "^0.6.0" - string-length "^4.0.1" - terminal-link "^2.0.0" - v8-to-istanbul "^8.1.0" - -"@jest/source-map@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" - integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.2.9" - source-map "^0.6.0" - -"@jest/test-result@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" - integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== - dependencies: - "@jest/console" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" - integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== - dependencies: - "@jest/test-result" "^27.5.1" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-runtime "^27.5.1" - -"@jest/transform@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" - integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^27.5.1" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-regex-util "^27.5.1" - jest-util "^27.5.1" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - -"@jest/types@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" - integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - -"@jridgewell/resolve-uri@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" - integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" - integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== - -"@jridgewell/trace-mapping@^0.3.0": - version "0.3.4" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" - integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^8.0.1": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" - integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@tsconfig/node10@^1.0.7": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" - integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== - -"@tsconfig/node12@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" - integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== - -"@tsconfig/node14@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" - integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== - -"@tsconfig/node16@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" - integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== - -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.1.19" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" - integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.0.tgz#7a9b80f712fe2052bc20da153ff1e552404d8e4b" - integrity sha512-r8aveDbd+rzGP+ykSdF3oPuTVRWRfbBiHl0rVDM2yNEmSMXfkObQLV46b4RnCv3Lra51OlfnZhkkFaDl2MIRaA== - dependencies: - "@babel/types" "^7.3.0" - -"@types/graceful-fs@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/jest@27.x": - version "27.4.1" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" - integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== - dependencies: - jest-matcher-utils "^27.0.0" - pretty-format "^27.0.0" - -"@types/node@*": - version "17.0.24" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.24.tgz#20ba1bf69c1b4ab405c7a01e950c4f446b05029f" - integrity sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g== - -"@types/node@16.x": - version "16.11.27" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.27.tgz#5da19383bdbeda99bc0d09cfbb88cab7297ebc51" - integrity sha512-C1pD3kgLoZ56Uuy5lhfOxie4aZlA3UMGLX9rXteq4WitEZH6Rl80mwactt9QG0w0gLFlN/kLBTFnGXtDVWvWQw== - -"@types/prettier@^2.1.5": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.0.tgz#efcbd41937f9ae7434c714ab698604822d890759" - integrity sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw== - -"@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== - -"@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== - -"@types/yargs@^16.0.0": - version "16.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== - dependencies: - "@types/yargs-parser" "*" - -abab@^2.0.3, abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== - dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - -acorn-walk@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^7.1.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.2.4, acorn@^8.4.1: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -anymatch@^3.0.3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -babel-jest@27.x, babel-jest@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" - integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== - dependencies: - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^27.5.1" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" - integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.0.0" - "@types/babel__traverse" "^7.0.6" - -babel-plugin-polyfill-corejs2@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" - integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== - dependencies: - "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.3.1" - semver "^6.1.1" - -babel-plugin-polyfill-corejs3@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" - integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" - core-js-compat "^3.21.0" - -babel-plugin-polyfill-regenerator@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" - integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" - -babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - -babel-preset-jest@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" - integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== - dependencies: - babel-plugin-jest-hoist "^27.5.1" - babel-preset-current-node-syntax "^1.0.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browserslist@^4.17.5, browserslist@^4.20.2: - version "4.20.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" - integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== - dependencies: - caniuse-lite "^1.0.30001317" - electron-to-chromium "^1.4.84" - escalade "^3.1.1" - node-releases "^2.0.2" - picocolors "^1.0.0" - -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001317: - version "1.0.30001332" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" - integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -ci-info@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" - integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== - -cjs-module-lexer@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= - -collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -core-js-compat@^3.20.2, core-js-compat@^3.21.0: - version "3.22.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.0.tgz#7ce17ab57c378be2c717c7c8ed8f82a50a25b3e4" - integrity sha512-WwA7xbfRGrk8BGaaHlakauVXrlYmAIkk8PNGb1FDQS+Rbrewc3pgFfwJFRw6psmJVAll7Px9UHRYE16oRQnwAQ== - dependencies: - browserslist "^4.20.2" - semver "7.0.0" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - -debug@4, debug@^4.1.0, debug@^4.1.1: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decimal.js@^10.2.1: - version "10.3.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" - integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== - -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= - -deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -diff-sequences@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" - integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== - dependencies: - webidl-conversions "^5.0.0" - -electron-to-chromium@^1.4.84: - version "1.4.108" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.108.tgz#380b01ff68e958d2b9fdf4572e054020a506c568" - integrity sha512-/36KkMuL6+WTrodVlOjtHhH9Ro7BgRaQrh0bfKckwDtdRSjTBuZCOddeXxzK1PkwphoeTxGUFVT9xnmvQ7xEdw== - -emittery@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" - integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -esprima@^4.0.0, esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= - -expect@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" - integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== - dependencies: - "@jest/types" "^27.5.1" - jest-get-type "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== - dependencies: - bser "2.1.1" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== - dependencies: - whatwg-encoding "^1.0.5" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-core-module@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" - integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== - dependencies: - has "^1.0.3" - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== - -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" - integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - -istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.1.3: - version "3.1.4" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" - integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -jest-changed-files@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" - integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== - dependencies: - "@jest/types" "^27.5.1" - execa "^5.0.0" - throat "^6.0.1" - -jest-circus@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" - integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - throat "^6.0.1" - -jest-cli@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" - integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== - dependencies: - "@jest/core" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - import-local "^3.0.2" - jest-config "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - prompts "^2.0.1" - yargs "^16.2.0" - -jest-config@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" - integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== - dependencies: - "@babel/core" "^7.8.0" - "@jest/test-sequencer" "^27.5.1" - "@jest/types" "^27.5.1" - babel-jest "^27.5.1" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.1" - graceful-fs "^4.2.9" - jest-circus "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-get-type "^27.5.1" - jest-jasmine2 "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runner "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^27.5.1" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-diff@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" - integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== - dependencies: - chalk "^4.0.0" - diff-sequences "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-docblock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" - integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== - dependencies: - detect-newline "^3.0.0" - -jest-each@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" - integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== - dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - jest-get-type "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - -jest-environment-jsdom@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" - integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - jsdom "^16.6.0" - -jest-environment-node@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" - integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - -jest-get-type@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" - integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== - -jest-haste-map@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" - integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== - dependencies: - "@jest/types" "^27.5.1" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^27.5.1" - jest-serializer "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - micromatch "^4.0.4" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.3.2" - -jest-jasmine2@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" - integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - throat "^6.0.1" - -jest-leak-detector@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" - integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== - dependencies: - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" - integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== - dependencies: - chalk "^4.0.0" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-message-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" - integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.5.1" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" - integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - -jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== - -jest-regex-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" - integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== - -jest-resolve-dependencies@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" - integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== - dependencies: - "@jest/types" "^27.5.1" - jest-regex-util "^27.5.1" - jest-snapshot "^27.5.1" - -jest-resolve@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" - integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== - dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-pnp-resolver "^1.2.2" - jest-util "^27.5.1" - jest-validate "^27.5.1" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" - -jest-runner@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" - integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== - dependencies: - "@jest/console" "^27.5.1" - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.8.1" - graceful-fs "^4.2.9" - jest-docblock "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-haste-map "^27.5.1" - jest-leak-detector "^27.5.1" - jest-message-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runtime "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - source-map-support "^0.5.6" - throat "^6.0.1" - -jest-runtime@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" - integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/globals" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - execa "^5.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-serializer@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" - integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.9" - -jest-snapshot@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" - integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== - dependencies: - "@babel/core" "^7.7.2" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.0.0" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^27.5.1" - graceful-fs "^4.2.9" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - jest-haste-map "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - natural-compare "^1.4.0" - pretty-format "^27.5.1" - semver "^7.3.2" - -jest-util@^27.0.0, jest-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" - integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" - integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== - dependencies: - "@jest/types" "^27.5.1" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^27.5.1" - leven "^3.1.0" - pretty-format "^27.5.1" - -jest-watcher@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" - integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== - dependencies: - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - jest-util "^27.5.1" - string-length "^4.0.1" - -jest-worker@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@27.x: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" - integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== - dependencies: - "@jest/core" "^27.5.1" - import-local "^3.0.2" - jest-cli "^27.5.1" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsdom@^16.6.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" - integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.6" - xml-name-validator "^3.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json5@2.x, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - -lodash.memoize@4.x: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - -lodash@^4.7.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@1.x, make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@^3.0.4: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -node-releases@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" - integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -nwsapi@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse5@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pirates@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -pretty-format@^27.0.0, pretty-format@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" - integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== - dependencies: - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^17.0.1" - -prompts@^2.0.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -psl@^1.1.33: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - -regenerate-unicode-properties@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" - integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== - dependencies: - regenerate "^1.4.2" - -regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regenerator-transform@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" - integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== - dependencies: - "@babel/runtime" "^7.8.4" - -regexpu-core@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" - integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== - dependencies: - regenerate "^1.4.2" - regenerate-unicode-properties "^10.0.1" - regjsgen "^0.6.0" - regjsparser "^0.8.2" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.0.0" - -regjsgen@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" - integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== - -regjsparser@^0.8.2: - version "0.8.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" - integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== - dependencies: - jsesc "~0.5.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== - -resolve@^1.14.2, resolve@^1.20.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== - dependencies: - is-core-module "^2.8.1" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -rimraf@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - -semver@7.x, semver@^7.3.2: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -source-map-support@^0.5.6: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -stack-utils@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" - integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== - dependencies: - escape-string-regexp "^2.0.0" - -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-hyperlinks@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" - integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== - -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.1.2" - -tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== - dependencies: - punycode "^2.1.1" - -ts-jest@27.x: - version "27.1.4" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.4.tgz#84d42cf0f4e7157a52e7c64b1492c46330943e00" - integrity sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^27.0.0" - json5 "2.x" - lodash.memoize "4.x" - make-error "1.x" - semver "7.x" - yargs-parser "20.x" - -ts-node@10.x: - version "10.7.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" - integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== - dependencies: - "@cspotcode/source-map-support" "0.7.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.0" - yn "3.1.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typescript@4.x: - version "4.6.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" - integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== - -unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" - integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== - -unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" - integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - -unicode-match-property-value-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" - integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== - -unicode-property-aliases-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" - integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== - -universalify@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -v8-compile-cache-lib@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" - integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== - -v8-to-istanbul@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" - integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - source-map "^0.7.3" - -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== - dependencies: - xml-name-validator "^3.0.0" - -walker@^1.0.7: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - -webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== - -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - -whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - -whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" - integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== - dependencies: - lodash "^4.7.0" - tr46 "^2.1.0" - webidl-conversions "^6.1.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -ws@^7.4.6: - version "7.5.7" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" - integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== - -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@20.x, yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== From 631c18aaa9d36b79e3f7d92cf51bfced3fc39b28 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 06:58:53 -0400 Subject: [PATCH 50/62] ci: add node unit tests --- .github/workflows/master.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 33e64ac2..2b89a701 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -21,8 +21,14 @@ jobs: - name: Install Deno uses: denoland/setup-deno@v1 - - name: Unit - run: deno test tests/unit + - name: Unit Tests (Deno) + run: deno test tests/ + + - name: Unit Tests (Node) + run: | + yarn install + yarn build + yarn test linter: # Only one OS is required since fmt is cross platform From 6b1006e2fc1945fdc53ba7949b1b0a0500c4d967 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 06:59:06 -0400 Subject: [PATCH 51/62] chore: deno fmt --- tests/cjs/unit/mod/fake.test.js | 15 ++-- tests/cjs/unit/mod/mock.test.js | 148 +++++++++++++++++-------------- tests/deps.ts | 5 +- tests/esm/jest_assertions.ts | 8 +- tests/esm/unit/mod/dummy.test.ts | 8 +- tests/esm/unit/mod/fake.test.ts | 38 +++++--- tests/esm/unit/mod/mock.test.ts | 44 +++++---- 7 files changed, 159 insertions(+), 107 deletions(-) diff --git a/tests/cjs/unit/mod/fake.test.js b/tests/cjs/unit/mod/fake.test.js index 8b280510..04eda05c 100644 --- a/tests/cjs/unit/mod/fake.test.js +++ b/tests/cjs/unit/mod/fake.test.js @@ -47,7 +47,9 @@ describe("Fake()", () => { try { fake.test(); } catch (error) { - expect(error.message).toBe(`Pre-programmed method "test" does not have a return value.`); + expect(error.message).toBe( + `Pre-programmed method "test" does not have a return value.`, + ); } }); @@ -173,7 +175,9 @@ describe("Fake()", () => { .method("test") .willThrow(new RandomError("Random error message.")); - expect(() => fake.test()).toThrow(new RandomError("Random error message.")); + expect(() => fake.test()).toThrow( + new RandomError("Random error message."), + ); }); it(".willThrow() causes throwing RandomError2 (no constructor)", () => { @@ -188,7 +192,9 @@ describe("Fake()", () => { .method("test") .willThrow(new RandomError2()); - expect(() => fake.test()).toThrow(new RandomError2("Some message not by the constructor.")); + expect(() => fake.test()).toThrow( + new RandomError2("Some message not by the constructor."), + ); }); }); }); @@ -242,7 +248,7 @@ class Resource { } class TestObjectFourBuilder { - someComplexMethod() { + someComplexMethod() { this.setSomethingOne(); this.setSomethingTwo(); return this; @@ -296,4 +302,3 @@ class RandomError2 extends Error { name = "RandomError2Name"; message = "Some message not by the constructor."; } - diff --git a/tests/cjs/unit/mod/mock.test.js b/tests/cjs/unit/mod/mock.test.js index 11b99ea5..d16fd56f 100644 --- a/tests/cjs/unit/mod/mock.test.js +++ b/tests/cjs/unit/mod/mock.test.js @@ -3,7 +3,7 @@ const { Mock } = require("../../../../lib/cjs/mod"); class Request { constructor( url, - options = {} + options = {}, ) { this.url = url; this.options = options; @@ -114,9 +114,9 @@ class TestRequestHandler { const method = request.method.toLowerCase(); const contentType = request.headers.get("content-type"); - console.log(request.headers) - console.log(request.headers) - console.log(request.headers) + console.log(request.headers); + console.log(request.headers); + console.log(request.headers); if (method !== "post") { return "Method is not post"; @@ -136,7 +136,8 @@ describe("Mock()", () => { () => { const mock = Mock(TestObjectOne); expect(mock.constructor.name).toBe("MockBuilder"); - }); + }, + ); describe(".create()", () => { it( @@ -145,7 +146,8 @@ describe("Mock()", () => { const mock = Mock(TestObjectTwo).create(); expect(mock.name).toBe(undefined); expect(mock.is_mock).toBe(true); - }); + }, + ); }); describe(".withConstructorArgs(...)", () => { @@ -157,7 +159,8 @@ describe("Mock()", () => { .create(); expect(mock.name).toBe("some name"); expect(mock.is_mock).toBe(true); - }); + }, + ); it( "can take more than 1 arg", @@ -177,7 +180,8 @@ describe("Mock()", () => { expect(mockMathService.calls.add).toBe(0); mockTestObject.sum(1, 1); expect(mockMathService.calls.add).toBe(1); - }); + }, + ); }); describe("method(...)", () => { @@ -196,26 +200,29 @@ describe("Mock()", () => { try { mock.test(); } catch (error) { - expect(error.message).toBe(`Pre-programmed method "test" does not have a return value.`); + expect(error.message).toBe( + `Pre-programmed method "test" does not have a return value.`, + ); } expect(mock.calls.test).toBe(2); expect(mock.calls.hello).toBe(2); - }); + }, + ); - it(".willReturn(...) does not call original method and returns given value",() => { - const mock = Mock(TestObjectThree).create(); - expect(mock.is_mock).toBe(true); + it(".willReturn(...) does not call original method and returns given value", () => { + const mock = Mock(TestObjectThree).create(); + expect(mock.is_mock).toBe(true); - // Original returns "World" - expect(mock.test()).toBe("World"); + // Original returns "World" + expect(mock.test()).toBe("World"); - // Change original to return "Hello" - mock.method("test").willReturn("Hello"); + // Change original to return "Hello" + mock.method("test").willReturn("Hello"); - // Should output "Hello" and make the following calls - expect(mock.test()).toBe("Hello"); - expect(mock.calls.test).toBe(2); - expect(mock.calls.hello).toBe(2); + // Should output "Hello" and make the following calls + expect(mock.test()).toBe("Hello"); + expect(mock.calls.test).toBe(2); + expect(mock.calls.hello).toBe(2); }); it( @@ -234,7 +241,8 @@ describe("Mock()", () => { expect(mock.test()).toBe("Hello!"); expect(mock.calls.test).toBe(2); expect(mock.calls.hello).toBe(2); - }); + }, + ); it( ".willReturn(...) returns specified value", @@ -250,56 +258,57 @@ describe("Mock()", () => { mock .method("test") .willReturn({ - "something": undefined + "something": undefined, }); expect(mock.test()).toStrictEqual({ "something": undefined }); expect(mock.calls.test).toBe(2); expect(mock.calls.hello).toBe(2); - }); + }, + ); it(".willReturn(mock) returns the mock object (basic)", () => { - const mock = Mock(TestObjectFourBuilder).create(); - expect(mock.is_mock).toBe(true); + const mock = Mock(TestObjectFourBuilder).create(); + expect(mock.is_mock).toBe(true); - mock - .method("someComplexMethod") - .willReturn(mock); + mock + .method("someComplexMethod") + .willReturn(mock); - expect(mock.someComplexMethod()).toBe(mock); - expect(mock.calls.someComplexMethod).toBe(1); + expect(mock.someComplexMethod()).toBe(mock); + expect(mock.calls.someComplexMethod).toBe(1); }); it(".willReturn(mock) returns the mock object (extra)", () => { - // Assert that the original implementation sets properties - const mock1 = Mock(TestObjectFourBuilder).create(); - expect(mock1.is_mock).toBe(true); - mock1.someComplexMethod(); - expect(mock1.something_one).toBe("one"); - expect(mock1.something_two).toBe("two"); - expect(mock1.calls.someComplexMethod).toBe(1); - - // Assert that the mock implementation will not set properties - const mock2 = Mock(TestObjectFourBuilder).create(); - expect(mock2.is_mock).toBe(true); - mock2 - .method("someComplexMethod") - .willReturn(mock2); - - expect(mock2.someComplexMethod()).toBe(mock2); - expect(mock2.something_one).toBe(undefined); - expect(mock2.something_two).toBe(undefined); - expect(mock2.calls.someComplexMethod).toBe(1); - - // Assert that we can also use setters - const mock3 = Mock(TestObjectFourBuilder).create(); - expect(mock3.is_mock).toBe(true); - mock3.someComplexMethod(); - expect(mock3.something_one).toBe("one"); - expect(mock3.something_two).toBe("two"); - mock3.something_one = "you got changed"; - expect(mock3.something_one).toBe("you got changed"); - expect(mock3.calls.someComplexMethod).toBe(1); + // Assert that the original implementation sets properties + const mock1 = Mock(TestObjectFourBuilder).create(); + expect(mock1.is_mock).toBe(true); + mock1.someComplexMethod(); + expect(mock1.something_one).toBe("one"); + expect(mock1.something_two).toBe("two"); + expect(mock1.calls.someComplexMethod).toBe(1); + + // Assert that the mock implementation will not set properties + const mock2 = Mock(TestObjectFourBuilder).create(); + expect(mock2.is_mock).toBe(true); + mock2 + .method("someComplexMethod") + .willReturn(mock2); + + expect(mock2.someComplexMethod()).toBe(mock2); + expect(mock2.something_one).toBe(undefined); + expect(mock2.something_two).toBe(undefined); + expect(mock2.calls.someComplexMethod).toBe(1); + + // Assert that we can also use setters + const mock3 = Mock(TestObjectFourBuilder).create(); + expect(mock3.is_mock).toBe(true); + mock3.someComplexMethod(); + expect(mock3.something_one).toBe("one"); + expect(mock3.something_two).toBe("two"); + mock3.something_one = "you got changed"; + expect(mock3.something_one).toBe("you got changed"); + expect(mock3.calls.someComplexMethod).toBe(1); }); it( @@ -317,10 +326,11 @@ describe("Mock()", () => { .willThrow(new RandomError("Random error message.")); expect( - () => mock.test() + () => mock.test(), ).toThrow(new RandomError("Random error message.")); expect(mock.calls.test).toBe(2); - }); + }, + ); it( ".willThrow() causes throwing RandomError2 (no constructor)", @@ -336,9 +346,12 @@ describe("Mock()", () => { .method("test") .willThrow(new RandomError2()); - expect(() => mock.test()).toThrow(new RandomError2("Some message not by the constructor.")); + expect(() => mock.test()).toThrow( + new RandomError2("Some message not by the constructor."), + ); expect(mock.calls.test).toBe(2); - }); + }, + ); it( ".expects(...).toBeCalled(...)", @@ -349,7 +362,8 @@ describe("Mock()", () => { mock.expects("hello").toBeCalled(2); mock.test(); mock.verifyExpectations(); - }); + }, + ); }); // TODO(crookse) Put the below tests into one of the groups above this line @@ -383,9 +397,9 @@ describe("Mock()", () => { "content-type": "application/json", }, }); - console.log("testasdfasfasdf") + console.log("testasdfasfasdf"); console.log(reqPost.headers); - console.log("testasdfasfasdf") + console.log("testasdfasfasdf"); expect(router.calls.handle).toBe(0); expect(router.handle(reqPost)).toBe("posted"); expect(router.calls.handle).toBe(1); diff --git a/tests/deps.ts b/tests/deps.ts index 769ff5ee..81d6d28d 100644 --- a/tests/deps.ts +++ b/tests/deps.ts @@ -1 +1,4 @@ -export { assertEquals, assertThrows } from "https://deno.land/std@0.135.0/testing/asserts.ts"; +export { + assertEquals, + assertThrows, +} from "https://deno.land/std@0.135.0/testing/asserts.ts"; diff --git a/tests/esm/jest_assertions.ts b/tests/esm/jest_assertions.ts index d21c57ff..78587464 100644 --- a/tests/esm/jest_assertions.ts +++ b/tests/esm/jest_assertions.ts @@ -2,6 +2,10 @@ export function assertEquals(actual: unknown, expected: unknown): void { expect(actual).toStrictEqual(expected); } -export function assertThrows(actual: () => unknown, expected: new (message?: string) => Error, message: string): void { +export function assertThrows( + actual: () => unknown, + expected: new (message?: string) => Error, + message: string, +): void { expect(actual).toThrow(new expected(message)); -} \ No newline at end of file +} diff --git a/tests/esm/unit/mod/dummy.test.ts b/tests/esm/unit/mod/dummy.test.ts index ed558fab..3ded1079 100644 --- a/tests/esm/unit/mod/dummy.test.ts +++ b/tests/esm/unit/mod/dummy.test.ts @@ -16,14 +16,16 @@ describe("Dummy()", () => { resource.callServiceOne(); assertEquals(mockServiceOne.calls.methodServiceOne, 1); - }); + }, + ); it( "can be made without specifying constructor args", (): void => { const dummy = Dummy(Resource); assertEquals(Object.getPrototypeOf(dummy), Resource); - }); + }, + ); }); class Resource { @@ -72,4 +74,4 @@ class ServiceThree { } } -export {} +export {}; diff --git a/tests/esm/unit/mod/fake.test.ts b/tests/esm/unit/mod/fake.test.ts index 5ce332bc..0cdb8afa 100644 --- a/tests/esm/unit/mod/fake.test.ts +++ b/tests/esm/unit/mod/fake.test.ts @@ -7,7 +7,8 @@ describe("Fake()", () => { (): void => { const fake = Fake(TestObjectOne); assertEquals(fake.constructor.name, "FakeBuilder"); - }); + }, + ); describe(".create()", () => { it( @@ -16,7 +17,8 @@ describe("Fake()", () => { const fake = Fake(TestObjectTwo).create(); assertEquals(fake.name, undefined); assertEquals(fake.is_fake, true); - }); + }, + ); }); describe(".withConstructorArgs(...)", () => { @@ -28,7 +30,8 @@ describe("Fake()", () => { .create(); assertEquals(fake.name, "some name"); assertEquals(fake.is_fake, true); - }); + }, + ); it( "can take more than 1 arg", @@ -39,7 +42,8 @@ describe("Fake()", () => { assertEquals(fake.name, "some name"); assertEquals(fake.array, ["hello"]); assertEquals(fake.is_fake, true); - }); + }, + ); }); describe(".method(...)", () => { @@ -63,10 +67,11 @@ describe("Fake()", () => { `Pre-programmed method "test" does not have a return value.`, ); } - }); + }, + ); it( - ".willReturn(...) does not call original method and returns given value", + ".willReturn(...) does not call original method and returns given value", (): void => { // Assert that a fake can make a class take a shortcut const fakeServiceDoingShortcut = Fake(Repository).create(); @@ -91,7 +96,8 @@ describe("Fake()", () => { fakeServiceNotDoingShortcut.do_something_else_called, true, ); - }); + }, + ); it( ".willReturn(...) can be performed more than once", @@ -120,7 +126,8 @@ describe("Fake()", () => { fakeServiceNotDoingShortcut.do_something_else_called, true, ); - }); + }, + ); it( ".willThrow(...) does not call original method and throws error", @@ -148,7 +155,8 @@ describe("Fake()", () => { fakeServiceNotDoingShortcut.do_something_else_called, true, ); - }); + }, + ); it( ".willReturn(fake) returns the fake object (basic)", @@ -161,7 +169,8 @@ describe("Fake()", () => { .willReturn(fake); assertEquals(fake.someComplexMethod(), fake); - }); + }, + ); it( ".willReturn(fake) returns the fake object (extra)", @@ -192,7 +201,8 @@ describe("Fake()", () => { assertEquals(fake3.something_two, "two"); fake3.something_one = "you got changed"; assertEquals(fake3.something_one, "you got changed"); - }); + }, + ); it( ".willThrow() causes throwing RandomError (with constructor)", @@ -213,7 +223,8 @@ describe("Fake()", () => { RandomError, "Random error message.", ); - }); + }, + ); it( ".willThrow() causes throwing RandomError2 (no constructor)", @@ -234,7 +245,8 @@ describe("Fake()", () => { RandomError2, "Some message not by the constructor.", ); - }); + }, + ); }); }); diff --git a/tests/esm/unit/mod/mock.test.ts b/tests/esm/unit/mod/mock.test.ts index 08f954ee..ef5ef7db 100644 --- a/tests/esm/unit/mod/mock.test.ts +++ b/tests/esm/unit/mod/mock.test.ts @@ -14,7 +14,7 @@ class Request { constructor( url: string, - options: IRequestOptions + options: IRequestOptions, ) { this.url = url; this.options = options; @@ -171,7 +171,8 @@ describe("Mock()", () => { (): void => { const mock = Mock(TestObjectOne); assertEquals(mock.constructor.name, "MockBuilder"); - }); + }, + ); describe(".create()", () => { it( @@ -180,7 +181,8 @@ describe("Mock()", () => { const mock = Mock(TestObjectTwo).create(); assertEquals(mock.name, undefined); assertEquals(mock.is_mock, true); - }); + }, + ); }); describe(".withConstructorArgs(...)", () => { @@ -192,7 +194,8 @@ describe("Mock()", () => { .create(); assertEquals(mock.name, "some name"); assertEquals(mock.is_mock, true); - }); + }, + ); it( "can take more than 1 arg", @@ -212,7 +215,8 @@ describe("Mock()", () => { assertEquals(mockMathService.calls.add, 0); mockTestObject.sum(1, 1); assertEquals(mockMathService.calls.add, 1); - }); + }, + ); }); describe("method(...)", () => { @@ -238,10 +242,11 @@ describe("Mock()", () => { } assertEquals(mock.calls.test, 2); assertEquals(mock.calls.hello, 2); - }); + }, + ); it( - ".willReturn(...) does not call original method and returns given value", + ".willReturn(...) does not call original method and returns given value", (): void => { const mock = Mock(TestObjectThree).create(); assertEquals(mock.is_mock, true); @@ -256,7 +261,8 @@ describe("Mock()", () => { assertEquals(mock.test(), "Hello"); assertEquals(mock.calls.test, 2); assertEquals(mock.calls.hello, 2); - }); + }, + ); it( ".willReturn(...) can be performed more than once", @@ -274,7 +280,8 @@ describe("Mock()", () => { assertEquals(mock.test(), "Hello!"); assertEquals(mock.calls.test, 2); assertEquals(mock.calls.hello, 2); - }); + }, + ); it( ".willReturn(...) returns specified value", @@ -296,7 +303,8 @@ describe("Mock()", () => { assertEquals(mock.test(), { "something": "something" }); assertEquals(mock.calls.test, 2); assertEquals(mock.calls.hello, 2); - }); + }, + ); it( ".willReturn(mock) returns the mock object (basic)", @@ -310,7 +318,8 @@ describe("Mock()", () => { assertEquals(mock.someComplexMethod(), mock); assertEquals(mock.calls.someComplexMethod, 1); - }); + }, + ); it( ".willReturn(mock) returns the mock object (extra)", @@ -344,7 +353,8 @@ describe("Mock()", () => { mock3.something_one = "you got changed"; assertEquals(mock3.something_one, "you got changed"); assertEquals(mock3.calls.someComplexMethod, 1); - }); + }, + ); it( ".willThrow() causes throwing RandomError (with constructor)", @@ -366,7 +376,8 @@ describe("Mock()", () => { "Random error message.", ); assertEquals(mock.calls.test, 2); - }); + }, + ); it( ".willThrow() causes throwing RandomError2 (no constructor)", @@ -388,7 +399,8 @@ describe("Mock()", () => { "Some message not by the constructor.", ); assertEquals(mock.calls.test, 2); - }); + }, + ); it( ".expects(...).toBeCalled(...)", @@ -399,7 +411,8 @@ describe("Mock()", () => { mock.expects("hello").toBeCalled(2); mock.test(); mock.verifyExpectations(); - }); + }, + ); }); // TODO(crookse) Put the below tests into one of the groups above this line @@ -426,7 +439,6 @@ describe("Mock()", () => { describe("native request mock", () => { it("handles async requests", async () => { - const router = Mock(TestRequestHandler).create(); const reqPost = new Request("https://google.com", { From b6656b04ff71ff3fefc567fb8cdbac0a6c5077c0 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:06:19 -0400 Subject: [PATCH 52/62] ci: fix unit test runs for deno --- .github/workflows/master.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 2b89a701..6173a8de 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -22,7 +22,7 @@ jobs: uses: denoland/setup-deno@v1 - name: Unit Tests (Deno) - run: deno test tests/ + run: deno test tests/deno - name: Unit Tests (Node) run: | From 580c2b075efcc4913974f0080a659f41634eb34b Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:07:45 -0400 Subject: [PATCH 53/62] fix: tsconfig to point to include conversion workspace dir --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 6ab8d8bb..e4b8592b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,6 @@ "esModuleInterop": true, "moduleResolution": "node" }, - "include": ["./tmp/**/*.ts"], + "include": ["./tmp/conversion_workspace/**/*.ts"], "exclude": ["./tests/**/*"] } From e2b82d726f54e0ca869edc1e5c3ba98b0a93e265 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:09:13 -0400 Subject: [PATCH 54/62] chore: deno fmt --- console/build_esm_lib.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/console/build_esm_lib.ts b/console/build_esm_lib.ts index 49608e68..23cddcd1 100644 --- a/console/build_esm_lib.ts +++ b/console/build_esm_lib.ts @@ -16,7 +16,9 @@ let file: any; while (!file) { try { - file = await Deno.lstat("tmp/conversion_workspace/src/fake/fake_builder.ts"); + file = await Deno.lstat( + "tmp/conversion_workspace/src/fake/fake_builder.ts", + ); } catch (error) { } } @@ -33,12 +35,12 @@ for (const index in filesToRewrite) { // Step 3: Remove all .ts extensions from the import/export statements const newImportStatements = importStatements?.map((statement: string) => { - return statement.replace(/\.ts";/, `";`); - }); + return statement.replace(/\.ts";/, `";`); + }); const newExportStatements = exportStatements?.map((statement: string) => { - return statement.replace(/\.ts";/, `";`); - }); + return statement.replace(/\.ts";/, `";`); + }); // Step 4: Replace the original contents with the new contents if (newImportStatements) { From 899c3646819bdd2aaabd033c98a2924c7a73d821 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:11:52 -0400 Subject: [PATCH 55/62] chore: alphabetize scripts; add script to check build --- console/build_esm_lib.ts | 11 ----------- package.json | 5 +++-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/console/build_esm_lib.ts b/console/build_esm_lib.ts index 23cddcd1..6a683a74 100644 --- a/console/build_esm_lib.ts +++ b/console/build_esm_lib.ts @@ -12,17 +12,6 @@ const filesToRewrite = [ "tmp/conversion_workspace/mod.ts", ]; -let file: any; - -while (!file) { - try { - file = await Deno.lstat( - "tmp/conversion_workspace/src/fake/fake_builder.ts", - ); - } catch (error) { - } -} - for (const index in filesToRewrite) { const file = filesToRewrite[index]; diff --git a/package.json b/package.json index 4d2660c3..492e0007 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,11 @@ "author": "Drash Land", "license": "MIT", "scripts": { - "test": "jest tests", + "build": ". console/build_esm_lib && yarn build:cjs && yarn build:esm", "build:cjs": "tsc --project tsconfig.cjs.json", "build:esm": "tsc --project tsconfig.esm.json", - "build": ". console/build_esm_lib && yarn build:cjs && yarn build:esm" + "check": "rm -rf node_modules/ && rm yarn.lock && yarn install && yarn build && yarn test", + "test": "jest tests" }, "devDependencies": { "@babel/preset-env": "7.x", From 8ee187879d85283ed626ce814ca8bcc445755fc9 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:12:51 -0400 Subject: [PATCH 56/62] chore: deno fmt node config files --- babel.config.js | 2 +- jest.config.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/babel.config.js b/babel.config.js index 9ea84edd..721e8b82 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1 +1 @@ -module.exports = {presets: ['@babel/preset-env']} +module.exports = { presets: ["@babel/preset-env"] }; diff --git a/jest.config.ts b/jest.config.ts index e11f801b..4b1f85bb 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,5 +1,5 @@ /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ -import type { Config } from "@jest/types" +import type { Config } from "@jest/types"; const config: Config.InitialOptions = { preset: "ts-jest", @@ -7,8 +7,8 @@ const config: Config.InitialOptions = { verbose: true, moduleFileExtensions: ["ts", "js"], transform: { - '^.+\\.(ts|tsx)?$': 'ts-jest', + "^.+\\.(ts|tsx)?$": "ts-jest", "^.+\\.(js|jsx)$": "babel-jest", - } -} -export default config + }, +}; +export default config; From 12544566ff692702b4906e509e62b1564219d299 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:17:51 -0400 Subject: [PATCH 57/62] ci: install node.. duh --- .github/workflows/master.yml | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 6173a8de..63394dd3 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -9,7 +9,7 @@ on: - main jobs: - tests: + tests_deno: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] @@ -21,15 +21,36 @@ jobs: - name: Install Deno uses: denoland/setup-deno@v1 - - name: Unit Tests (Deno) + - name: Unit Tests run: deno test tests/deno - - name: Unit Tests (Node) + tests_node: + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + # We only support until EOL + node: ['10', '12', '14', '15', '16', '17'] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2 + + - name: Install Node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + + - name: Install deps + run: yarn install + + - name: Build CJS and ESM run: | - yarn install yarn build yarn test + - name: Unit Test + run: yarn test + linter: # Only one OS is required since fmt is cross platform runs-on: ubuntu-latest From f6db265312468ae05e4d13ee6fbd7f5e0ccada16 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:19:51 -0400 Subject: [PATCH 58/62] ci: remove node 10 and 12 --- .github/workflows/master.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 63394dd3..3f134571 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -30,7 +30,8 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macos-latest] # We only support until EOL - node: ['10', '12', '14', '15', '16', '17'] + # See https://nodejs.org/en/about/releases/ + node: ['14', '15', '16', '17'] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 From b677420ed645870ebb65e7ebda78db3817959e16 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:21:42 -0400 Subject: [PATCH 59/62] ci: add deno to tests_node (required for building cjs and esm) --- .github/workflows/master.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 3f134571..fa81998d 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -36,6 +36,10 @@ jobs: steps: - uses: actions/checkout@v2 + # We need deno because the "Build CJS and ESM" step runs `deno run` + - name: Install Deno + uses: denoland/setup-deno@v1 + - name: Install Node uses: actions/setup-node@v2 with: From 567de91737f5e96d4648a42ec9db91d885cc5df8 Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:28:27 -0400 Subject: [PATCH 60/62] ci: fix scripts to work in powershell --- console/build_esm_lib | 0 package.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 console/build_esm_lib diff --git a/console/build_esm_lib b/console/build_esm_lib old mode 100644 new mode 100755 diff --git a/package.json b/package.json index 492e0007..30d6f3e5 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "author": "Drash Land", "license": "MIT", "scripts": { - "build": ". console/build_esm_lib && yarn build:cjs && yarn build:esm", + "build": "console/build_esm_lib && yarn build:cjs && yarn build:esm", "build:cjs": "tsc --project tsconfig.cjs.json", "build:esm": "tsc --project tsconfig.esm.json", "check": "rm -rf node_modules/ && rm yarn.lock && yarn install && yarn build && yarn test", From a9b4bbe2085627c65788583dcf8ce09f4d0905ca Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 07:34:53 -0400 Subject: [PATCH 61/62] chore: fix ci to work with windows; remove console log statements --- .github/workflows/master.yml | 9 +++++++-- package.json | 1 + src/fake/fake_builder.ts | 2 -- src/mock/mock_builder.ts | 2 -- tests/cjs/unit/mod/mock.test.js | 7 ------- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index fa81998d..873bfec1 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -48,10 +48,15 @@ jobs: - name: Install deps run: yarn install - - name: Build CJS and ESM + - name: Build CJS and ESM (*nix) + if: matrix.os != 'windows-latest' run: | yarn build - yarn test + + - name: Build CJS and ESM (windows) + if: matrix.os == 'windows-latest' + run: | + yarn build:windows - name: Unit Test run: yarn test diff --git a/package.json b/package.json index 30d6f3e5..8d4ed42a 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "license": "MIT", "scripts": { "build": "console/build_esm_lib && yarn build:cjs && yarn build:esm", + "build:windows": "bash console/build_esm_lib && yarn build:cjs && yarn build:esm", "build:cjs": "tsc --project tsconfig.cjs.json", "build:esm": "tsc --project tsconfig.esm.json", "check": "rm -rf node_modules/ && rm yarn.lock && yarn install && yarn build && yarn test", diff --git a/src/fake/fake_builder.ts b/src/fake/fake_builder.ts index c2c2df97..c3818088 100644 --- a/src/fake/fake_builder.ts +++ b/src/fake/fake_builder.ts @@ -223,8 +223,6 @@ export class FakeBuilder { // original does not. const bound = methodToCall.bind(fake); - // console.log(`calling bound()`); - // Use `return` because the original function could return a value return bound(...args); }, diff --git a/src/mock/mock_builder.ts b/src/mock/mock_builder.ts index 382e7704..612fbdfc 100644 --- a/src/mock/mock_builder.ts +++ b/src/mock/mock_builder.ts @@ -228,8 +228,6 @@ export class MockBuilder { // original does not. const bound = methodToCall.bind(mock); - // console.log(`calling bound()`); - // Use `return` because the original function could return a value return bound(...args); }, diff --git a/tests/cjs/unit/mod/mock.test.js b/tests/cjs/unit/mod/mock.test.js index d16fd56f..004b91bd 100644 --- a/tests/cjs/unit/mod/mock.test.js +++ b/tests/cjs/unit/mod/mock.test.js @@ -114,10 +114,6 @@ class TestRequestHandler { const method = request.method.toLowerCase(); const contentType = request.headers.get("content-type"); - console.log(request.headers); - console.log(request.headers); - console.log(request.headers); - if (method !== "post") { return "Method is not post"; } @@ -397,9 +393,6 @@ describe("Mock()", () => { "content-type": "application/json", }, }); - console.log("testasdfasfasdf"); - console.log(reqPost.headers); - console.log("testasdfasfasdf"); expect(router.calls.handle).toBe(0); expect(router.handle(reqPost)).toBe("posted"); expect(router.calls.handle).toBe(1); From b0c5c75b394de8b06e701f8999fc32a12a12d7fc Mon Sep 17 00:00:00 2001 From: Eric Crooks Date: Sat, 16 Apr 2022 10:06:31 -0400 Subject: [PATCH 62/62] ci: add yarn publish --- .github/workflows/release.yml | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7f7aef31..668f8510 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,7 +2,67 @@ name: Release on: release: types: [published] + jobs: + + npm: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + token: ${{ secrets.CI_USER_PAT }} + + # We need deno because the "Build CJS and ESM" step runs `deno run` + - name: Install Deno + uses: denoland/setup-deno@v1 + + # Setup .npmrc file to publish to npm + - name: Install Node + uses: actions/setup-node@v2 + with: + registry-url: 'https://registry.npmjs.org' + scope: '@drashland' + + - name: Install deps + run: yarn install + + - name: Build CJS and ESM + run: yarn build + + - name: Publish + run: yarn publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTOMATION_TOKEN }} + + github: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + token: ${{ secrets.CI_USER_PAT }} + + # We need deno because the "Build CJS and ESM" step runs `deno run` + - name: Install Deno + uses: denoland/setup-deno@v1 + + # Setup .npmrc file to publish to github + - name: Install Node + uses: actions/setup-node@v2 + with: + registry-url: 'https://npm.pkg.github.com' + scope: '@drashland' + + - name: Install deps + run: yarn install + + - name: Build CJS and ESM + run: yarn build + + - name: Publish + run: yarn publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + publish-egg: runs-on: ubuntu-latest steps: