From 524b0a74c6fe39b9fb7667524109006d5055dc05 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 22 Aug 2020 09:15:05 +0200 Subject: [PATCH] Migrated first component and test to typescript --- jest.config.js | 4 +-- package-lock.json | 34 +++++++++++++++++++ package.json | 3 ++ src/App.js | 44 ------------------------- src/App.tsx | 39 ++++++++++++++++++++++ src/container/{index.js => index.ts} | 10 +++--- src/visits/helpers/OpenMapModalBtn.scss | 2 +- test/{App.test.js => App.test.tsx} | 11 ++++--- 8 files changed, 91 insertions(+), 56 deletions(-) delete mode 100644 src/App.js create mode 100644 src/App.tsx rename src/container/{index.js => index.ts} (81%) rename test/{App.test.js => App.test.tsx} (69%) diff --git a/jest.config.js b/jest.config.js index f698a928..0387f86d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -17,9 +17,9 @@ module.exports = { testEnvironment: 'jsdom', testURL: 'http://localhost', transform: { - '^.+\\.(js|jsx|mjs)$': '/node_modules/babel-jest', + '^.+\\.(ts|tsx|js|jsx|mjs)$': '/node_modules/babel-jest', '^.+\\.css$': '/config/jest/cssTransform.js', - '^(?!.*\\.(js|jsx|mjs|css|json)$)': '/config/jest/fileTransform.js', + '^(?!.*\\.(ts|tsx|js|jsx|mjs|css|json)$)': '/config/jest/fileTransform.js', }, transformIgnorePatterns: [ '[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$', diff --git a/package-lock.json b/package-lock.json index 31584ce3..63d74a88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2022,12 +2022,31 @@ "@babel/types": "^7.3.0" } }, + "@types/cheerio": { + "version": "0.22.21", + "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.21.tgz", + "integrity": "sha512-aGI3DfswwqgKPiEOTaiHV2ZPC9KEhprpgEbJnv0fZl3SGX0cGgEva1126dGrMC6AJM6v/aihlUgJn9M5DbDZ/Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/enzyme": { + "version": "3.10.5", + "resolved": "https://registry.npmjs.org/@types/enzyme/-/enzyme-3.10.5.tgz", + "integrity": "sha512-R+phe509UuUYy9Tk0YlSbipRpfVtIzb/9BHn5pTEtjJTF5LXvUjrIQcZvNyANNEyFrd2YGs196PniNT1fgvOQA==", + "dev": true, + "requires": { + "@types/cheerio": "*", + "@types/react": "*" + } + }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -2264,6 +2283,15 @@ "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", "dev": true }, + "@types/ramda": { + "version": "0.27.14", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.27.14.tgz", + "integrity": "sha512-vbw/VAtEJeSJ6Z61QT+epirlnBeJiJIO7ndK1BJ0fKswnfbiTNga/jBG6R3OnBaFYx+UJv6Iv7ZfWDFSsSzNqA==", + "dev": true, + "requires": { + "ts-toolbelt": "^6.3.3" + } + }, "@types/react": { "version": "16.9.46", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.46.tgz", @@ -19465,6 +19493,12 @@ "integrity": "sha512-1J/vefLC+BWSo+qe8OnJQfWTYRS6ingxjwqmHMqaMxXMj7kFtKLgAaYW3JeX3mktjgUL+etlU8/B4VUAUI9QGw==", "dev": true }, + "ts-toolbelt": { + "version": "6.15.5", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", + "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==", + "dev": true + }, "tsconfig-paths": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", diff --git a/package.json b/package.json index 50cdcf77..99762489 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,9 @@ "@stryker-mutator/javascript-mutator": "^3.2.4", "@stryker-mutator/jest-runner": "^3.2.4", "@svgr/webpack": "^4.3.3", + "@types/enzyme": "^3.10.5", + "@types/jest": "^26.0.10", + "@types/ramda": "^0.27.14", "@types/react": "^16.9.46", "@types/react-dom": "^16.9.8", "@types/react-redux": "^7.1.9", diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 3a8716eb..00000000 --- a/src/App.js +++ /dev/null @@ -1,44 +0,0 @@ -import React, { useEffect } from 'react'; -import PropTypes from 'prop-types'; -import { Route, Switch } from 'react-router-dom'; -import NotFound from './common/NotFound'; -import './App.scss'; - -const propTypes = { - fetchServers: PropTypes.func, - servers: PropTypes.object, -}; - -const App = (MainHeader, Home, MenuLayout, CreateServer, EditServer, Settings) => { - const AppComp = ({ fetchServers, servers }) => { - // On first load, try to fetch the remote servers if the list is empty - useEffect(() => { - if (Object.keys(servers).length === 0) { - fetchServers(); - } - }, []); - - return ( -
- - -
- - - - - - - - -
-
- ); - }; - - AppComp.propTypes = propTypes; - - return AppComp; -}; - -export default App; diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 00000000..81311fd2 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,39 @@ +import React, { useEffect, FC } from 'react'; +import { Route, Switch } from 'react-router-dom'; +import NotFound from './common/NotFound'; +import './App.scss'; + +interface AppProps { + fetchServers: Function; + servers: Record; +} + +const App = (MainHeader: FC, Home: FC, MenuLayout: FC, CreateServer: FC, EditServer: FC, Settings: FC) => ( + { fetchServers, servers }: AppProps, +) => { + // On first load, try to fetch the remote servers if the list is empty + useEffect(() => { + if (Object.keys(servers).length === 0) { + fetchServers(); + } + }, []); + + return ( +
+ + +
+ + + + + + + + +
+
+ ); +}; + +export default App; diff --git a/src/container/index.js b/src/container/index.ts similarity index 81% rename from src/container/index.js rename to src/container/index.ts index 38ec382f..ae20ae63 100644 --- a/src/container/index.js +++ b/src/container/index.ts @@ -1,4 +1,4 @@ -import Bottle from 'bottlejs'; +import Bottle, { IContainer } from 'bottlejs'; import { withRouter } from 'react-router-dom'; import { connect as reduxConnect } from 'react-redux'; import { pick } from 'ramda'; @@ -12,17 +12,19 @@ import provideUtilsServices from '../utils/services/provideServices'; import provideMercureServices from '../mercure/services/provideServices'; import provideSettingsServices from '../settings/services/provideServices'; +type ActionMap = Record; + const bottle = new Bottle(); const { container } = bottle; -const lazyService = (container, serviceName) => (...args) => container[serviceName](...args); -const mapActionService = (map, actionName) => ({ +const lazyService = (container: IContainer, serviceName: string) => (...args: any[]) => container[serviceName](...args); +const mapActionService = (map: ActionMap, actionName: string): ActionMap => ({ ...map, // Wrap actual action service in a function so that it is lazily created the first time it is called [actionName]: lazyService(container, actionName), }); -const connect = (propsFromState, actionServiceNames = []) => +const connect = (propsFromState: string[], actionServiceNames: string[] = []) => reduxConnect( propsFromState ? pick(propsFromState) : null, actionServiceNames.reduce(mapActionService, {}), diff --git a/src/visits/helpers/OpenMapModalBtn.scss b/src/visits/helpers/OpenMapModalBtn.scss index 1da946fe..007802ae 100644 --- a/src/visits/helpers/OpenMapModalBtn.scss +++ b/src/visits/helpers/OpenMapModalBtn.scss @@ -1,4 +1,4 @@ -.open-map-modal-btn__btn { +.open-map-modal-btn__btn.open-map-modal-btn__btn { padding: 0; margin-right: 1rem; } diff --git a/test/App.test.js b/test/App.test.tsx similarity index 69% rename from test/App.test.js rename to test/App.test.tsx index ef67971c..fe50f068 100644 --- a/test/App.test.js +++ b/test/App.test.tsx @@ -1,17 +1,18 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { shallow, ShallowWrapper } from 'enzyme'; import { Route } from 'react-router-dom'; import { identity } from 'ramda'; import appFactory from '../src/App'; describe('', () => { - let wrapper; - const MainHeader = () => ''; + let wrapper: ShallowWrapper; + const MainHeader = () => null; + const DummyComponent = () => null; beforeEach(() => { - const App = appFactory(MainHeader, identity, identity, identity, identity); + const App = appFactory(MainHeader, DummyComponent, DummyComponent, DummyComponent, DummyComponent, DummyComponent); - wrapper = shallow(); + wrapper = shallow(); }); afterEach(() => wrapper.unmount());