From 05b1115533ad722f467cdde98257ef2e72dd0f33 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Sun, 26 May 2019 22:20:16 +0200 Subject: [PATCH] add tests --- gatsby-node.js | 13 ++- jest/__fixtures__/repos.json | 102 ++++++++++++++++++ package.json | 1 + src/components/atoms/LinkIcon.jsx | 3 + src/components/molecules/Repository.jsx | 5 +- src/components/molecules/Repository.test.jsx | 40 +++++++ .../organisms/Repositories.test.jsx | 11 ++ src/pages/__tests__/index.test.jsx | 10 +- src/pages/index.jsx | 3 +- 9 files changed, 180 insertions(+), 8 deletions(-) create mode 100644 jest/__fixtures__/repos.json create mode 100644 src/components/molecules/Repository.test.jsx create mode 100644 src/components/organisms/Repositories.test.jsx diff --git a/gatsby-node.js b/gatsby-node.js index c42b4ef..a5dbc8e 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -8,6 +8,8 @@ const axios = require('axios') const fs = require('fs') const yaml = require('js-yaml') const reposYaml = yaml.load(fs.readFileSync('./content/repos.yml', 'utf8')) +const { performance } = require('perf_hooks') +const chalk = require('chalk') function truncate(n, useWordBoundary) { if (this.length <= n) { @@ -37,11 +39,18 @@ async function getGithubRepos(data) { let repos exports.onPreBootstrap = async () => { + const t0 = performance.now() + try { repos = await getGithubRepos(reposYaml[0]) - console.log(`success getGithubRepos: ${repos.length} repos`) + const t1 = performance.now() + const ms = t1 - t0 + const s = ((ms / 1000) % 60).toFixed(3) + console.log( + chalk.green('success ') + `getGithubRepos: ${repos.length} repos - ${s} s` + ) } catch (error) { - console.error(error.message) + throw Error(error.message) } } diff --git a/jest/__fixtures__/repos.json b/jest/__fixtures__/repos.json new file mode 100644 index 0000000..609c8f7 --- /dev/null +++ b/jest/__fixtures__/repos.json @@ -0,0 +1,102 @@ +[ + { + "id": 133283555, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzMyODM1NTU=", + "name": "portfolio", + "full_name": "kremalicious/portfolio", + "private": false, + "owner": { + "login": "kremalicious", + "id": 90316, + "node_id": "MDQ6VXNlcjkwMzE2", + "avatar_url": "https://avatars1.githubusercontent.com/u/90316?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kremalicious", + "html_url": "https://github.com/kremalicious", + "followers_url": "https://api.github.com/users/kremalicious/followers", + "following_url": "https://api.github.com/users/kremalicious/following{/other_user}", + "gists_url": "https://api.github.com/users/kremalicious/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kremalicious/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kremalicious/subscriptions", + "organizations_url": "https://api.github.com/users/kremalicious/orgs", + "repos_url": "https://api.github.com/users/kremalicious/repos", + "events_url": "https://api.github.com/users/kremalicious/events{/privacy}", + "received_events_url": "https://api.github.com/users/kremalicious/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/kremalicious/portfolio", + "description": "👔 Portfolio thingy, built with Gatsby", + "fork": false, + "url": "https://api.github.com/repos/kremalicious/portfolio", + "forks_url": "https://api.github.com/repos/kremalicious/portfolio/forks", + "keys_url": "https://api.github.com/repos/kremalicious/portfolio/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/kremalicious/portfolio/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/kremalicious/portfolio/teams", + "hooks_url": "https://api.github.com/repos/kremalicious/portfolio/hooks", + "issue_events_url": "https://api.github.com/repos/kremalicious/portfolio/issues/events{/number}", + "events_url": "https://api.github.com/repos/kremalicious/portfolio/events", + "assignees_url": "https://api.github.com/repos/kremalicious/portfolio/assignees{/user}", + "branches_url": "https://api.github.com/repos/kremalicious/portfolio/branches{/branch}", + "tags_url": "https://api.github.com/repos/kremalicious/portfolio/tags", + "blobs_url": "https://api.github.com/repos/kremalicious/portfolio/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/kremalicious/portfolio/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/kremalicious/portfolio/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/kremalicious/portfolio/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/kremalicious/portfolio/statuses/{sha}", + "languages_url": "https://api.github.com/repos/kremalicious/portfolio/languages", + "stargazers_url": "https://api.github.com/repos/kremalicious/portfolio/stargazers", + "contributors_url": "https://api.github.com/repos/kremalicious/portfolio/contributors", + "subscribers_url": "https://api.github.com/repos/kremalicious/portfolio/subscribers", + "subscription_url": "https://api.github.com/repos/kremalicious/portfolio/subscription", + "commits_url": "https://api.github.com/repos/kremalicious/portfolio/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/kremalicious/portfolio/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/kremalicious/portfolio/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/kremalicious/portfolio/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/kremalicious/portfolio/contents/{+path}", + "compare_url": "https://api.github.com/repos/kremalicious/portfolio/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/kremalicious/portfolio/merges", + "archive_url": "https://api.github.com/repos/kremalicious/portfolio/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/kremalicious/portfolio/downloads", + "issues_url": "https://api.github.com/repos/kremalicious/portfolio/issues{/number}", + "pulls_url": "https://api.github.com/repos/kremalicious/portfolio/pulls{/number}", + "milestones_url": "https://api.github.com/repos/kremalicious/portfolio/milestones{/number}", + "notifications_url": "https://api.github.com/repos/kremalicious/portfolio/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/kremalicious/portfolio/labels{/name}", + "releases_url": "https://api.github.com/repos/kremalicious/portfolio/releases{/id}", + "deployments_url": "https://api.github.com/repos/kremalicious/portfolio/deployments", + "created_at": "2018-05-13T23:53:31Z", + "updated_at": "2019-05-26T19:34:49Z", + "pushed_at": "2019-05-26T19:35:10Z", + "git_url": "git://github.com/kremalicious/portfolio.git", + "ssh_url": "git@github.com:kremalicious/portfolio.git", + "clone_url": "https://github.com/kremalicious/portfolio.git", + "svn_url": "https://github.com/kremalicious/portfolio", + "homepage": "https://matthiaskretschmann.com", + "size": 135135, + "stargazers_count": 55, + "watchers_count": 55, + "language": "JavaScript", + "has_issues": true, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 5, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 1, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 5, + "open_issues": 1, + "watchers": 55, + "default_branch": "master" + } +] diff --git a/package.json b/package.json index 66d5054..1781454 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "babel-eslint": "^10.0.1", "babel-jest": "^24.7.1", "babel-preset-gatsby": "^0.1.11", + "chalk": "^2.4.2", "eslint": "^5.16.0", "eslint-config-prettier": "^4.2.0", "eslint-loader": "^2.1.2", diff --git a/src/components/atoms/LinkIcon.jsx b/src/components/atoms/LinkIcon.jsx index 9acfad8..cf2c9bc 100644 --- a/src/components/atoms/LinkIcon.jsx +++ b/src/components/atoms/LinkIcon.jsx @@ -10,6 +10,7 @@ import { ReactComponent as Dribbble } from '../../images/dribbble.svg' import { ReactComponent as Email } from '../../images/email.svg' import { ReactComponent as Blog } from '../../images/blog.svg' import { ReactComponent as Twitter } from '../../images/twitter.svg' +import { ReactComponent as Star } from '../../images/star.svg' const LinkIcon = ({ title, type, ...props }) => { let typeOrTitle = type ? type : title @@ -39,6 +40,8 @@ const LinkIcon = ({ title, type, ...props }) => { return case 'Twitter': return + case 'star': + return default: return null } diff --git a/src/components/molecules/Repository.jsx b/src/components/molecules/Repository.jsx index 9982930..ecb6ebc 100644 --- a/src/components/molecules/Repository.jsx +++ b/src/components/molecules/Repository.jsx @@ -1,8 +1,7 @@ import React from 'react' import PropTypes from 'prop-types' -import { ReactComponent as Star } from '../../images/star.svg' -import styles from './Repository.module.scss' import LinkIcon from '../atoms/LinkIcon' +import styles from './Repository.module.scss' const Repository = ({ repo }) => { const { name, description, html_url, homepage, stargazers_count } = repo @@ -32,7 +31,7 @@ const Repository = ({ repo }) => { - {stargazers_count} + {stargazers_count}

diff --git a/src/components/molecules/Repository.test.jsx b/src/components/molecules/Repository.test.jsx new file mode 100644 index 0000000..ee256c2 --- /dev/null +++ b/src/components/molecules/Repository.test.jsx @@ -0,0 +1,40 @@ +import React from 'react' +import { render } from 'react-testing-library' +import Repository from './Repository' +import repos from '../../../jest/__fixtures__/repos.json' + +describe('Repository', () => { + it('renders correctly', () => { + const { container } = render() + expect(container.firstChild).toBeInTheDocument() + }) + + it('uses html_url as main link for portfolio & blog', () => { + const repo1 = { + name: 'portfolio', + html_url: 'html_url' + } + + const { container } = render() + expect(container.querySelector('h1 > a').getAttribute('href')).toBe( + repo1.html_url + ) + }) + + it('renders homepage link when provided', () => { + const repo = { + name: 'Hello', + homepage: 'hello' + } + + const { container } = render() + expect(container.querySelectorAll('p:last-child a').length).toBe(3) + }) + + it('renders no link without homepage', () => { + const repo = { name: 'Hello' } + + const { container } = render() + expect(container.querySelectorAll('p:last-child a').length).toBe(2) + }) +}) diff --git a/src/components/organisms/Repositories.test.jsx b/src/components/organisms/Repositories.test.jsx new file mode 100644 index 0000000..916cd35 --- /dev/null +++ b/src/components/organisms/Repositories.test.jsx @@ -0,0 +1,11 @@ +import React from 'react' +import { render } from 'react-testing-library' +import Repositories from './Repositories' +import repos from '../../../jest/__fixtures__/repos.json' + +describe('Repositories', () => { + it('renders correctly', () => { + const { container } = render() + expect(container.firstChild).toBeInTheDocument() + }) +}) diff --git a/src/pages/__tests__/index.test.jsx b/src/pages/__tests__/index.test.jsx index a08e405..1230658 100644 --- a/src/pages/__tests__/index.test.jsx +++ b/src/pages/__tests__/index.test.jsx @@ -16,8 +16,16 @@ describe('Home', () => { ...projectImageFiles } + const pageContext = { + repos: [ + { + name: 'Hello' + } + ] + } + it('renders correctly from data file values', () => { - const { container } = render() + const { container } = render() expect(container.firstChild).toBeInTheDocument() }) }) diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 598b016..a93844e 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -21,8 +21,7 @@ function getImageCount(images, slug) { export default class Home extends PureComponent { static propTypes = { data: PropTypes.object.isRequired, - pageContext: PropTypes.object.isRequired, - location: PropTypes.object.isRequired + pageContext: PropTypes.object.isRequired } render() {