diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 162ac03b..79e22d61 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - node-version: [12.x, 14.x] + node-version: [14.x] env: NPM_EMAIL: '' diff --git a/package.json b/package.json index a4a43d9b..400b70ca 100644 --- a/package.json +++ b/package.json @@ -27,13 +27,13 @@ "@babel/preset-typescript": "7.18.x", "@babel/types": "7.20.x", "@johanblumenberg/ts-mockito": "1.x.x", - "@testing-library/react": "^12.1.2", + "@testing-library/react": "14.x.x", "@testing-library/react-hooks": "^7.0.2", "@types/hoist-non-react-statics": "^3.3.1", - "@types/jest": "26.x.x", + "@types/jest": "29.5.x", "@types/lodash": "^4.14.176", - "@types/react": "^17.0.34", - "@types/react-dom": "^17.0.11", + "@types/react": "18.2.x", + "@types/react-dom": "18.2.x", "@types/react-test-renderer": "17.0.1", "@typescript-eslint/eslint-plugin": "^5.3.0", "@typescript-eslint/parser": "^5.3.0", @@ -46,10 +46,11 @@ "eslint-plugin-react": "^7.26.1", "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-unused-imports": "2.x.x", - "jest": "27.x.x", + "jest": "29.5.x", + "jest-environment-jsdom": "^29.5.0", "lodash": "^4.17.21", - "react": "17.0.2", - "react-dom": "17.0.2", + "react": "18.2.x", + "react-dom": "18.2.x", "setimmediate": "^1.0.5", "typescript": "^4.5.4" }, @@ -78,4 +79,4 @@ "url": "https://github.com/wix-incubator/react-obsidian/issues" }, "homepage": "https://github.com/wix-incubator/react-obsidian#readme" -} \ No newline at end of file +} diff --git a/src/graph/registry/GraphRegistry.ts b/src/graph/registry/GraphRegistry.ts index 98be84bd..95a595c3 100644 --- a/src/graph/registry/GraphRegistry.ts +++ b/src/graph/registry/GraphRegistry.ts @@ -63,8 +63,8 @@ export class GraphRegistry { } clear(graph: Graph) { - const Graph = this.instanceToConstructor.get(graph)!; - if (this.isSingleton(Graph)) return; + const Graph = this.instanceToConstructor.get(graph); + if (!Graph || this.isSingleton(Graph)) return; this.instanceToConstructor.delete(graph); this.constructorToInstance.get(Graph)!.delete(graph); this.nameToInstance.delete(graph.name); diff --git a/src/injectors/hooks/HookInjector.test.ts b/src/injectors/hooks/HookInjector.test.ts index af3aeb26..3bace991 100644 --- a/src/injectors/hooks/HookInjector.test.ts +++ b/src/injectors/hooks/HookInjector.test.ts @@ -1,4 +1,4 @@ -import { renderHook } from '@testing-library/react-hooks'; +import { renderHook } from '@testing-library/react'; import { useState } from 'react'; import StringProvider from '../../../test/fixtures/StringProvider'; import Subgraph from '../../../test/fixtures/Subgraph'; diff --git a/src/injectors/hooks/InjectHook.test.ts b/src/injectors/hooks/InjectHook.test.ts index 4b5f8ad4..1efe7b47 100644 --- a/src/injectors/hooks/InjectHook.test.ts +++ b/src/injectors/hooks/InjectHook.test.ts @@ -1,4 +1,4 @@ -import { renderHook } from '@testing-library/react-hooks'; +import { renderHook } from '@testing-library/react'; import MainGraph from '../../../test/fixtures/MainGraph'; import Subgraph from '../../../test/fixtures/Subgraph'; import { DependenciesOf } from '../../types'; diff --git a/src/observable/useObserver.test.ts b/src/observable/useObserver.test.ts index 9875f91c..5c58cbb9 100644 --- a/src/observable/useObserver.test.ts +++ b/src/observable/useObserver.test.ts @@ -1,4 +1,4 @@ -import { act, renderHook } from '@testing-library/react-hooks'; +import { act, renderHook } from '@testing-library/react'; import _ from 'lodash'; import { Observable } from './Observable'; import { useObserver } from './useObserver'; diff --git a/test/integration/reactStrictMode.test.tsx b/test/integration/reactStrictMode.test.tsx new file mode 100644 index 00000000..e7ddd5e8 --- /dev/null +++ b/test/integration/reactStrictMode.test.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { DependenciesOf, injectComponent } from '../../src'; +import { LifecycleBoundGraph } from '../fixtures/LifecycleBoundGraph'; + +describe('React Strict Mode', () => { + it('should render without crashing', () => { + const { container } = render(, { + wrapper: React.StrictMode, + }); + expect(container.textContent).toBe('A string passed via props: foo'); + }); +}); + +const Component = ({ computedFromProps }: DependenciesOf) => { + return <>{computedFromProps}; +}; + +const InjectedComponent = injectComponent<{ stringFromProps: string }>(Component, LifecycleBoundGraph); diff --git a/transformers/babel-plugin-obsidian/__snapshots__/index.test.ts.snap b/transformers/babel-plugin-obsidian/__snapshots__/index.test.ts.snap index ff85d907..ed5eb6f8 100644 --- a/transformers/babel-plugin-obsidian/__snapshots__/index.test.ts.snap +++ b/transformers/babel-plugin-obsidian/__snapshots__/index.test.ts.snap @@ -4,7 +4,7 @@ exports[`Provider Arguments Transformer Adds method name to provider arguments ( "var _dec, _class; function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; } let MainGraph = (_dec = Provides({ - name: \\"someString\\" + name: "someString" }), (_class = class MainGraph { someString({ stringProvider: stringProvider, @@ -12,16 +12,16 @@ let MainGraph = (_dec = Provides({ }) { return stringProvider.theString + emptyString; } -}, (_applyDecoratedDescriptor(_class.prototype, \\"someString\\", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, \\"someString\\"), _class.prototype)), _class));" +}, (_applyDecoratedDescriptor(_class.prototype, "someString", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "someString"), _class.prototype)), _class));" `; exports[`Provider Arguments Transformer Adds property name to @Inject arguments @Inject -> @Inject("myDependency") 1`] = ` "var _dec, _class, _descriptor; function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; } function _initializerWarningHelper(descriptor, context) { throw new Error('Decorating class property failed. Please ensure that ' + 'transform-class-properties is enabled and runs after the decorators transform.'); } -let MainGraph = (_dec = Inject(\\"someString\\"), (_class = class MainGraph { +let MainGraph = (_dec = Inject("someString"), (_class = class MainGraph { someString = _initializerWarningHelper(_descriptor, this); -}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, \\"someString\\", [_dec], { +}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, "someString", [_dec], { configurable: true, enumerable: true, writable: true, @@ -33,9 +33,9 @@ exports[`Provider Arguments Transformer Adds property name to @LateInject argume "var _dec, _class, _descriptor; function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; } function _initializerWarningHelper(descriptor, context) { throw new Error('Decorating class property failed. Please ensure that ' + 'transform-class-properties is enabled and runs after the decorators transform.'); } -let MainGraph = (_dec = LateInject(\\"someString\\"), (_class = class MainGraph { +let MainGraph = (_dec = LateInject("someString"), (_class = class MainGraph { someString = _initializerWarningHelper(_descriptor, this); -}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, \\"someString\\", [_dec], { +}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, "someString", [_dec], { configurable: true, enumerable: true, writable: true, @@ -54,16 +54,16 @@ let MainGraph = (_dec = Provides({ }) { return stringProvider.theString; } -}, (_applyDecoratedDescriptor(_class.prototype, \\"someString\\", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, \\"someString\\"), _class.prototype)), _class));" +}, (_applyDecoratedDescriptor(_class.prototype, "someString", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "someString"), _class.prototype)), _class));" `; exports[`Provider Arguments Transformer Does not add property name to @Inject if name is provided by the user 1`] = ` "var _dec, _class, _descriptor; function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; } function _initializerWarningHelper(descriptor, context) { throw new Error('Decorating class property failed. Please ensure that ' + 'transform-class-properties is enabled and runs after the decorators transform.'); } -let MainGraph = (_dec = Inject(\\"someString\\"), (_class = class MainGraph { +let MainGraph = (_dec = Inject("someString"), (_class = class MainGraph { someString = _initializerWarningHelper(_descriptor, this); -}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, \\"someString\\", [_dec], { +}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, "someString", [_dec], { configurable: true, enumerable: true, writable: true, @@ -75,9 +75,9 @@ exports[`Provider Arguments Transformer Does not add property name to @LateInjec "var _dec, _class, _descriptor; function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; } function _initializerWarningHelper(descriptor, context) { throw new Error('Decorating class property failed. Please ensure that ' + 'transform-class-properties is enabled and runs after the decorators transform.'); } -let MainGraph = (_dec = LateInject(\\"someString\\"), (_class = class MainGraph { +let MainGraph = (_dec = LateInject("someString"), (_class = class MainGraph { someString = _initializerWarningHelper(_descriptor, this); -}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, \\"someString\\", [_dec], { +}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, "someString", [_dec], { configurable: true, enumerable: true, writable: true, @@ -89,17 +89,17 @@ exports[`Provider Arguments Transformer handles providers that have no arguments "var _dec, _class; function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; } let MainGraph = (_dec = Provides({ - name: \\"someString\\" + name: "someString" }), (_class = class MainGraph { someString() { return 'someString'; } -}, (_applyDecoratedDescriptor(_class.prototype, \\"someString\\", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, \\"someString\\"), _class.prototype)), _class));" +}, (_applyDecoratedDescriptor(_class.prototype, "someString", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "someString"), _class.prototype)), _class));" `; exports[`Provider Arguments Transformer saves constructor argument name in Inject - @Inject -> @Inject(arg) 1`] = ` "class MainGraph { - constructor(@Inject(\\"arg\\") + constructor(@Inject("arg") arg) {} }" `;