Skip to content
This repository was archived by the owner on Jan 16, 2022. It is now read-only.

Commit 1d705da

Browse files
priscilawebdevjuanpicado
authored andcommitted
feat: version Component - Replaced classes by func. comp (#129)
* refactor: replaced classes by func comp * fix: fixed space margin * refactor: changed display logic * fix: fixed types * fix: fixed Version test * fix: fixed version style
1 parent 1a74c08 commit 1d705da

File tree

7 files changed

+146
-111
lines changed

7 files changed

+146
-111
lines changed

src/components/Versions/Versions.test.tsx

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,39 @@
11
import React from 'react';
22
import { mount } from 'enzyme';
33
import { MemoryRouter } from 'react-router';
4+
import { DetailContext, DetailContextProps } from '../../pages/Version';
45

56
import Versions, { LABEL_CURRENT_TAGS, LABEL_VERSION_HISTORY } from './Versions';
67
import data from './__partials__/data.json';
78

89
import { render, cleanup } from '@testing-library/react';
910

10-
const mockPackageMeta = jest.fn(() => ({
11+
const detailContextValue: Partial<DetailContextProps> = {
1112
packageName: 'foo',
1213
packageMeta: data,
13-
}));
14+
};
1415

15-
jest.mock('../../pages/Version', () => ({
16-
DetailContextConsumer: component => {
17-
return component.children({ ...mockPackageMeta() });
18-
},
19-
}));
16+
const ComponentToBeRendered: React.FC<{ contextValue: Partial<DetailContextProps> }> = ({ contextValue }) => (
17+
<MemoryRouter>
18+
<DetailContext.Provider value={contextValue}>
19+
<Versions />
20+
</DetailContext.Provider>
21+
</MemoryRouter>
22+
);
2023

2124
describe('<Version /> component', () => {
22-
beforeEach(() => {
23-
jest.resetModules();
24-
});
25-
2625
afterEach(() => {
2726
cleanup();
2827
});
2928

3029
// FIXME: this test is not deterministic (writes `N days ago` in the snapshot, where N is random number)
3130
test.skip('should render the component in default state', () => {
32-
const wrapper = mount(
33-
<MemoryRouter>
34-
<Versions />
35-
</MemoryRouter>
36-
);
31+
const wrapper = mount(<ComponentToBeRendered contextValue={detailContextValue} />);
3732
expect(wrapper.html()).toMatchSnapshot();
3833
});
3934

4035
test('should render versions', () => {
41-
const { getByText } = render(
42-
<MemoryRouter>
43-
<Versions />
44-
</MemoryRouter>
45-
);
36+
const { getByText } = render(<ComponentToBeRendered contextValue={detailContextValue} />);
4637

4738
expect(getByText(LABEL_VERSION_HISTORY)).toBeTruthy();
4839
expect(getByText(LABEL_CURRENT_TAGS)).toBeTruthy();
@@ -53,18 +44,7 @@ describe('<Version /> component', () => {
5344
});
5445

5546
test('should not render versions', () => {
56-
const request = {
57-
packageName: 'foo',
58-
};
59-
60-
// @ts-ignore
61-
mockPackageMeta.mockImplementation(() => request);
62-
63-
const { queryByText } = render(
64-
<MemoryRouter>
65-
<Versions />
66-
</MemoryRouter>
67-
);
47+
const { queryByText } = render(<ComponentToBeRendered contextValue={{ packageName: detailContextValue.packageName }} />);
6848

6949
expect(queryByText(LABEL_VERSION_HISTORY)).toBeFalsy();
7050
expect(queryByText(LABEL_CURRENT_TAGS)).toBeFalsy();
Lines changed: 33 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,46 @@
1-
import React, { ReactElement } from 'react';
2-
import List from '@material-ui/core/List';
3-
import { Link as RouterLink } from 'react-router-dom';
4-
import Link from '@material-ui/core/Link';
5-
import ListItem from '@material-ui/core/ListItem';
1+
import React, { useContext } from 'react';
62

7-
import { DetailContextConsumer } from '../../pages/Version';
8-
import { formatDateDistance } from '../../utils/package';
9-
import { DIST_TAGS } from '../../../lib/constants';
3+
import { DetailContext } from '../../pages/Version';
4+
5+
import { Heading } from './styles';
106

11-
import { Heading, Spacer, ListItemText } from './styles';
7+
import VersionsTagList from './VersionsTagList';
8+
import VersionsHistoryList from './VersionsHistoryList';
9+
10+
import { DIST_TAGS } from '../../../lib/constants';
1211

1312
export const NOT_AVAILABLE = 'Not available';
1413
export const LABEL_CURRENT_TAGS = 'Current Tags';
1514
export const LABEL_VERSION_HISTORY = 'Version History';
1615

17-
class Versions extends React.PureComponent {
18-
public render(): ReactElement<HTMLDivElement> {
19-
return (
20-
<DetailContextConsumer>
21-
{context => {
22-
const { packageMeta, packageName } = context;
16+
const Versions: React.FC = () => {
17+
const detailContext = useContext(DetailContext);
2318

24-
if (!packageMeta) {
25-
return null;
26-
}
19+
const { packageMeta, packageName } = detailContext;
2720

28-
return this.renderContent(packageMeta, packageName);
29-
}}
30-
</DetailContextConsumer>
31-
);
21+
if (!packageMeta) {
22+
return null;
3223
}
3324

34-
public renderPackageList = (packages: {}, timeMap: Record<string, {}>, packageName): ReactElement<HTMLDivElement> => {
35-
return (
36-
<List dense={true}>
37-
{Object.keys(packages)
38-
.reverse()
39-
.map(version => (
40-
<ListItem className="version-item" key={version}>
41-
<Link component={RouterLink} to={`/-/web/detail/${packageName}/v/${version}`}>
42-
<ListItemText>{version}</ListItemText>
43-
</Link>
44-
<Spacer />
45-
<ListItemText>{timeMap[version] ? `${formatDateDistance(timeMap[version])} ago` : NOT_AVAILABLE}</ListItemText>
46-
</ListItem>
47-
))}
48-
</List>
49-
);
50-
};
51-
52-
public renderTagList = (packages: {}): ReactElement<HTMLDivElement> => {
53-
return (
54-
<List dense={true}>
55-
{Object.keys(packages)
56-
.reverse()
57-
.map(tag => (
58-
<ListItem className="version-item" key={tag}>
59-
<ListItemText>{tag}</ListItemText>
60-
<Spacer />
61-
<ListItemText>{packages[tag]}</ListItemText>
62-
</ListItem>
63-
))}
64-
</List>
65-
);
66-
};
67-
68-
public renderContent(packageMeta, packageName): ReactElement<HTMLDivElement> {
69-
const { versions = {}, time: timeMap = {}, [DIST_TAGS]: distTags = {} } = packageMeta;
70-
71-
return (
72-
<>
73-
{distTags && (
74-
<>
75-
<Heading variant="subtitle1">{LABEL_CURRENT_TAGS}</Heading>
76-
{this.renderTagList(distTags)}
77-
</>
78-
)}
79-
{versions && (
80-
<>
81-
<Heading variant="subtitle1">{LABEL_VERSION_HISTORY}</Heading>
82-
{this.renderPackageList(versions, timeMap, packageName)}
83-
</>
84-
)}
85-
</>
86-
);
87-
}
88-
}
25+
// @ts-ignore - Property 'dist-tags' does not exist on type 'PackageMetaInterface'
26+
const { versions = {}, time = {}, [DIST_TAGS]: distTags = {} } = packageMeta;
27+
28+
return (
29+
<>
30+
{distTags && Object.keys(distTags).length > 0 && (
31+
<>
32+
<Heading variant="subtitle1">{LABEL_CURRENT_TAGS}</Heading>
33+
<VersionsTagList tags={distTags} />
34+
</>
35+
)}
36+
{versions && Object.keys(versions).length > 0 && packageName && (
37+
<>
38+
<Heading variant="subtitle1">{LABEL_VERSION_HISTORY}</Heading>
39+
<VersionsHistoryList packageName={packageName} time={time} versions={versions} />
40+
</>
41+
)}
42+
</>
43+
);
44+
};
8945

9046
export default Versions;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
import List from '@material-ui/core/List';
3+
import Link from '@material-ui/core/Link';
4+
import ListItem from '@material-ui/core/ListItem';
5+
import { Link as RouterLink } from 'react-router-dom';
6+
import { Spacer, ListItemText } from './styles';
7+
8+
import { Versions, Time } from '../../../types/packageMeta';
9+
import { formatDateDistance } from '../../utils/package';
10+
11+
export const NOT_AVAILABLE = 'Not available';
12+
13+
interface Props {
14+
versions: Versions;
15+
packageName: string;
16+
time: Time;
17+
}
18+
19+
const VersionsHistoryList: React.FC<Props> = ({ versions, packageName, time }) => (
20+
<List dense={true}>
21+
{Object.keys(versions)
22+
.reverse()
23+
.map(version => (
24+
<ListItem className="version-item" key={version}>
25+
<Link component={RouterLink} to={`/-/web/detail/${packageName}/v/${version}`}>
26+
<ListItemText>{version}</ListItemText>
27+
</Link>
28+
<Spacer />
29+
<ListItemText>{time[version] ? `${formatDateDistance(time[version])} ago` : NOT_AVAILABLE}</ListItemText>
30+
</ListItem>
31+
))}
32+
</List>
33+
);
34+
35+
export default VersionsHistoryList;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
import List from '@material-ui/core/List';
3+
import ListItem from '@material-ui/core/ListItem';
4+
import { Spacer, ListItemText } from './styles';
5+
6+
import { DistTags } from '../../../types/packageMeta';
7+
8+
interface Props {
9+
tags: DistTags;
10+
}
11+
12+
const VersionsTagList: React.FC<Props> = ({ tags }) => (
13+
<List dense={true}>
14+
{Object.keys(tags)
15+
.reverse()
16+
.map(tag => (
17+
<ListItem className="version-item" key={tag}>
18+
<ListItemText>{tag}</ListItemText>
19+
<Spacer />
20+
<ListItemText>{tags[tag]}</ListItemText>
21+
</ListItem>
22+
))}
23+
</List>
24+
);
25+
26+
export default VersionsTagList;

src/components/Versions/__snapshots__/Versions.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/components/Versions/styles.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const Spacer = styled('div')({
1414
borderBottom: '1px dotted rgba(0, 0, 0, 0.2)',
1515
whiteSpace: 'nowrap',
1616
height: '0.5em',
17+
margin: '0 16px',
1718
});
1819

1920
export const ListItemText = styled(MuiListItemText)({

types/packageMeta.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
export interface PackageMetaInterface {
2+
versions?: Versions;
3+
distTags?: DistTags;
4+
time?: Time;
25
latest: {
36
name: string;
47
dist: {
@@ -14,3 +17,37 @@ interface LicenseInterface {
1417
type: string;
1518
url: string;
1619
}
20+
21+
export interface DistTags {
22+
[key: string]: string;
23+
}
24+
25+
export interface Time {
26+
[key: string]: string;
27+
}
28+
29+
export interface Versions {
30+
[key: string]: Version;
31+
}
32+
33+
export interface Version {
34+
name: string;
35+
version: string;
36+
author?: string | Author;
37+
maintainers?: Maintainer[];
38+
description?: string;
39+
license?: string;
40+
main?: string;
41+
keywords?: string[];
42+
}
43+
44+
interface Author {
45+
name?: string;
46+
email?: string;
47+
url?: string;
48+
}
49+
50+
interface Maintainer {
51+
email?: string;
52+
name?: string;
53+
}

0 commit comments

Comments
 (0)