diff --git a/jest.setup.js b/jest.setup.js index 306452c..b7dea2b 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -4,3 +4,5 @@ // Used for __tests__/testing-library.js // Learn more: https://github.com/testing-library/jest-dom import '@testing-library/jest-dom/extend-expect'; + +import 'reflect-metadata'; diff --git a/package.json b/package.json index cc1a4b8..ea180c9 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,9 @@ "clsx": "1.1.1", "next": "12.1.4", "react": "18.0.0", - "react-dom": "18.0.0" + "react-dom": "18.0.0", + "reflect-metadata": "0.1.13", + "tsyringe": "4.6.0" }, "devDependencies": { "@next/bundle-analyzer": "12.1.4", diff --git a/src/components/pages/index-page/Bar.ts b/src/components/pages/index-page/Bar.ts new file mode 100644 index 0000000..225d449 --- /dev/null +++ b/src/components/pages/index-page/Bar.ts @@ -0,0 +1,11 @@ +import { singleton } from 'tsyringe'; +import { Foo } from './Foo'; + +@singleton() +export class Bar { + constructor(public foo: Foo) {} + + get subHeader(): string { + return this.foo.subHeader; + } +} diff --git a/src/components/pages/index-page/Foo.ts b/src/components/pages/index-page/Foo.ts new file mode 100644 index 0000000..2a0e078 --- /dev/null +++ b/src/components/pages/index-page/Foo.ts @@ -0,0 +1,3 @@ +export class Foo { + subHeader = 'Foo Sub Header'; +} diff --git a/src/components/pages/index-page/IndexPage.test.tsx b/src/components/pages/index-page/IndexPage.test.tsx index 258519d..ba9a4d7 100644 --- a/src/components/pages/index-page/IndexPage.test.tsx +++ b/src/components/pages/index-page/IndexPage.test.tsx @@ -1,10 +1,45 @@ import { render, screen } from '@testing-library/react'; import { IndexPage } from './IndexPage'; +import { Foo } from './Foo'; +import { Bar } from './Bar'; +import { container } from 'tsyringe'; + +class NewFoo { + subHeader = 'Test Sub Header'; +} + +class NextGenFoo { + subHeader = '789'; +} + +// https://vhiairrassary.com/engineer/2020-07-18-overriding-singletons-from-tsyringe-within-jest-tests/ describe('IndexPage', () => { - test('renders the page', () => { - render(); + let store: Bar; + + beforeEach(() => { + store = container.createChildContainer().register(Foo, NewFoo).resolve(Bar); + + container.clearInstances(); + }); + + test('renders the about button', () => { + render(); expect(screen.getByTestId('IndexPage_about-button')).toContainHTML('About'); }); + + test('renders the sub header', () => { + render(); + + expect(screen.getByTestId('IndexPage_sub-header')).toContainHTML('Test Sub Header'); + }); + + test('renders the sub s', () => { + const storeOverride = container.createChildContainer().register(Foo, NextGenFoo).resolve(Bar); + + render(); + + expect(screen.getByTestId('IndexPage_sub-header')).toContainHTML('789'); + }); }); diff --git a/src/components/pages/index-page/IndexPage.tsx b/src/components/pages/index-page/IndexPage.tsx index 551e923..5ee4398 100644 --- a/src/components/pages/index-page/IndexPage.tsx +++ b/src/components/pages/index-page/IndexPage.tsx @@ -1,9 +1,12 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import Link from 'next/link'; import { Routes } from '../../../constants/Routes'; +import { container } from 'tsyringe'; +import { Bar } from './Bar'; interface IProps { testId?: string; + store: Bar; } export const IndexPage: React.FC = (props) => { @@ -20,6 +23,7 @@ export const IndexPage: React.FC = (props) => { 👋 +

{props.store.subHeader}

About diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index a810f3c..a1722be 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,5 +1,6 @@ import '../css/main.css'; +import 'reflect-metadata'; import React from 'react'; import { AppProps } from 'next/app'; import Head from 'next/head'; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 2b483f4..49219df 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,14 +1,18 @@ -import React from 'react'; +import React, { useState } from 'react'; import { MainLayout } from '../components/shared/main-layout/MainLayout'; import { IndexPage } from '../components/pages/index-page/IndexPage'; import { NextPage } from 'next'; +import { container } from 'tsyringe'; +import { Bar } from '../components/pages/index-page/Bar'; interface IProps {} const IndexRoute: NextPage = (props) => { + const [store] = useState(() => container.resolve(Bar)); + return ( - + ); }; diff --git a/tsconfig.json b/tsconfig.json index 25de0c9..692a6cd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,7 +18,9 @@ "paths": { "environments": ["environments"] }, - "incremental": true + "incremental": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules", "./tools"] diff --git a/yarn.lock b/yarn.lock index 8679732..b4dbe25 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3903,6 +3903,11 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +reflect-metadata@0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + regenerator-runtime@^0.13.4: version "0.13.9" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" @@ -4416,7 +4421,7 @@ tsconfig-paths@^3.11.0, tsconfig-paths@^3.9.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^1.8.1: +tslib@^1.8.1, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -4428,6 +4433,13 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tsyringe@4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/tsyringe/-/tsyringe-4.6.0.tgz#14915d3d7f0db35e1cf7269bdbf7c440713c8d07" + integrity sha512-BMQAZamSfEmIQzH8WJeRu1yZGQbPSDuI9g+yEiKZFIcO46GPZuMOC2d0b52cVBdw1d++06JnDSIIZvEnogMdAw== + dependencies: + tslib "^1.9.3" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"