From 5cb47ed49ef424ba37970c555b5c5e9e3c5d2516 Mon Sep 17 00:00:00 2001 From: Andrew Hughson Date: Thu, 31 Oct 2019 21:17:16 +0000 Subject: [PATCH] fix: convert Engine component to hooks (#233) * refactor: convert Engine component to hooks * inline engine test data only used by one test * remove from engines tests * remove confusing test abstraction * change tests to not use mutations --- src/components/Engines/Engines.test.tsx | 78 +++++++++------------ src/components/Engines/Engines.tsx | 92 ++++++++++--------------- types/packageMeta.ts | 4 ++ 3 files changed, 73 insertions(+), 101 deletions(-) diff --git a/src/components/Engines/Engines.test.tsx b/src/components/Engines/Engines.test.tsx index 3286854..1521549 100644 --- a/src/components/Engines/Engines.test.tsx +++ b/src/components/Engines/Engines.test.tsx @@ -1,71 +1,61 @@ import React from 'react'; import { mount } from 'enzyme'; +import { DetailContext } from '../../pages/Version'; +import { PackageMetaInterface } from '../../../types/packageMeta'; + import Engine from './Engines'; jest.mock('./img/node.png', () => ''); jest.mock('../Install/img/npm.svg', () => ''); -const mockPackageMeta: jest.Mock = jest.fn(() => ({ +const mockPackageMeta = (engines?: PackageMetaInterface['latest']['engines']): PackageMetaInterface => ({ latest: { - homepage: 'https://verdaccio.tld', - bugs: { - url: 'https://verdaccio.tld/bugs', - }, + name: 'verdaccio', + version: '0.0.0', dist: { - tarball: 'https://verdaccio.tld/download', + fileCount: 1, + unpackedSize: 1, }, + ...(engines && { engines }), }, -})); - -jest.mock('../../pages/Version', () => ({ - DetailContextConsumer: component => { - return component.children({ packageMeta: mockPackageMeta() }); - }, -})); + _uplinks: {}, +}); describe(' component', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - test('should render the component in default state', () => { - const packageMeta = { - latest: { - engines: { - node: '>= 0.1.98', - npm: '>3', - }, - }, - }; + const packageMeta = mockPackageMeta({ + node: '>= 0.1.98', + npm: '>3', + }); - mockPackageMeta.mockImplementation(() => packageMeta); - - const wrapper = mount(); + const wrapper = mount( + + + + ); expect(wrapper.html()).toMatchSnapshot(); }); test('should render the component when there is no engine key in package meta', () => { - const packageMeta = { - latest: {}, - }; + const packageMeta = mockPackageMeta(); - mockPackageMeta.mockImplementation(() => packageMeta); - - const wrapper = mount(); - expect(wrapper.html()).toEqual(''); + const wrapper = mount( + + + + ); + expect(wrapper.html()).toBeNull(); }); test('should render the component when there is no keys in engine in package meta', () => { - const packageMeta = { - latest: { - engines: {}, - }, - }; + const packageMeta = mockPackageMeta({}); - mockPackageMeta.mockImplementation(() => packageMeta); - - const wrapper = mount(); - expect(wrapper.html()).toEqual(''); + const wrapper = mount( + + + + ); + expect(wrapper.html()).toBeNull(); }); }); diff --git a/src/components/Engines/Engines.tsx b/src/components/Engines/Engines.tsx index bfb9486..4def60f 100644 --- a/src/components/Engines/Engines.tsx +++ b/src/components/Engines/Engines.tsx @@ -1,6 +1,6 @@ -import React, { Component, ReactElement } from 'react'; +import React, { useContext } from 'react'; -import { VersionPageConsumerProps, DetailContextConsumer } from '../../pages/Version'; +import { DetailContext } from '../../pages/Version'; import Avatar from '../../muiComponents/Avatar'; import List from '../../muiComponents/List'; import npm from '../Install/img/npm.svg'; @@ -8,66 +8,44 @@ import ListItemText from '../../muiComponents/ListItemText'; import Grid from '../../muiComponents/Grid'; import { StyledText, EngineListItem } from './styles'; -// @ts-ignore import node from './img/node.png'; -const ICONS = { - 'node-JS': , - 'NPM-version': , -}; +const Engine: React.FC = () => { + const { packageMeta } = useContext(DetailContext); -class Engine extends Component { - public render(): ReactElement { - return ( - - {context => { - return this.renderEngine(context as VersionPageConsumerProps); - }} - - ); + const engines = packageMeta && packageMeta.latest && packageMeta.latest.engines; + + if (!engines || (!engines.node && !engines.npm)) { + return null; } - private renderEngine = ({ packageMeta }): ReactElement | null => { - const { engines } = packageMeta.latest; - if (!engines) { - return null; - } + /* eslint-disable react/jsx-max-depth */ + return ( + + {engines.node && ( + + {'node JS'}}> + + + + + + + )} - const engineDict = { - 'node-JS': engines.node, - 'NPM-version': engines.npm, - }; - - const accumulator: React.ReactNode[] = []; - const items = Object.keys(engineDict).reduce((markup, text, key) => { - const heading = engineDict[text]; - if (heading) { - markup.push( - - {this.renderListItems(heading, text)} - - ); - } - return markup; - }, accumulator); - - if (items.length < 1) { - return null; - } - - return {items}; - }; - - private renderListItems = (heading: string, text: string) => { - return ( - {text.split('-').join(' ')}}> - - {ICONS[text]} - - - - ); - }; -} + {engines.npm && ( + + {'NPM version'}}> + + + + + + + )} + + ); + /* eslint-enable react/jsx-max-depth */ +}; export default Engine; diff --git a/types/packageMeta.ts b/types/packageMeta.ts index 1c29080..67a6303 100644 --- a/types/packageMeta.ts +++ b/types/packageMeta.ts @@ -9,6 +9,10 @@ export interface PackageMetaInterface { fileCount: number; unpackedSize: number; }; + engines?: { + node?: string; + npm?: string; + }; license?: Partial | string; version: string; };