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() {