mirror of
https://github.com/kremalicious/blog.git
synced 2025-02-14 21:10:25 +01:00
setup testing
This commit is contained in:
parent
fde55614a0
commit
1a0a5d5b24
@ -17,7 +17,8 @@
|
|||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"node": true,
|
"node": true,
|
||||||
"es6": true
|
"es6": true,
|
||||||
|
"jest": true
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"quotes": ["error", "single"],
|
"quotes": ["error", "single"],
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,3 +6,4 @@ public
|
|||||||
.cache
|
.cache
|
||||||
src/components/svg
|
src/components/svg
|
||||||
plugins/gatsby-redirect-from
|
plugins/gatsby-redirect-from
|
||||||
|
coverage
|
||||||
|
@ -18,10 +18,19 @@ before_install:
|
|||||||
- sudo apt-get install python3-pip
|
- sudo apt-get install python3-pip
|
||||||
- sudo -H pip3 install --upgrade pip
|
- sudo -H pip3 install --upgrade pip
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
# https://docs.codeclimate.com/docs/travis-ci-test-coverage
|
||||||
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
||||||
|
- chmod +x ./cc-test-reporter
|
||||||
|
- ./cc-test-reporter before-build
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- npm test
|
- npm test
|
||||||
- travis_wait 60 npm run build
|
- travis_wait 60 npm run build
|
||||||
|
|
||||||
|
after_script:
|
||||||
|
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- pip install --user awscli
|
- pip install --user awscli
|
||||||
- export PATH=$PATH:$HOME/.local/bin
|
- export PATH=$PATH:$HOME/.local/bin
|
||||||
|
21
README.md
21
README.md
@ -10,6 +10,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://travis-ci.com/kremalicious/blog"><img src="https://travis-ci.com/kremalicious/blog.svg?branch=master" /></a>
|
<a href="https://travis-ci.com/kremalicious/blog"><img src="https://travis-ci.com/kremalicious/blog.svg?branch=master" /></a>
|
||||||
<a href="https://codeclimate.com/github/kremalicious/blog/maintainability"><img src="https://api.codeclimate.com/v1/badges/4e86c791349cd12368cd/maintainability" /></a>
|
<a href="https://codeclimate.com/github/kremalicious/blog/maintainability"><img src="https://api.codeclimate.com/v1/badges/4e86c791349cd12368cd/maintainability" /></a>
|
||||||
|
<a href="https://codeclimate.com/github/kremalicious/blog/test_coverage"><img src="https://api.codeclimate.com/v1/badges/4e86c791349cd12368cd/test_coverage" /></a>
|
||||||
<a href="https://greenkeeper.io/"><img src="https://badges.greenkeeper.io/kremalicious/blog.svg" /></a>
|
<a href="https://greenkeeper.io/"><img src="https://badges.greenkeeper.io/kremalicious/blog.svg" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -28,6 +29,7 @@
|
|||||||
- [🍬 Typekit component](#-typekit-component)
|
- [🍬 Typekit component](#-typekit-component)
|
||||||
- [✨ Development](#-development)
|
- [✨ Development](#-development)
|
||||||
- [🔮 Linting](#-linting)
|
- [🔮 Linting](#-linting)
|
||||||
|
- [👩🔬 Testing](#-testing)
|
||||||
- [🎈 Add a new post](#-add-a-new-post)
|
- [🎈 Add a new post](#-add-a-new-post)
|
||||||
- [🚚 Deployment](#-deployment)
|
- [🚚 Deployment](#-deployment)
|
||||||
- [🏛 Licenses](#-licenses)
|
- [🏛 Licenses](#-licenses)
|
||||||
@ -139,7 +141,6 @@ All SVG assets under `src/images/` will be converted to React components with th
|
|||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
import { ReactComponent as Logo } from './components/svg/Logo'
|
import { ReactComponent as Logo } from './components/svg/Logo'
|
||||||
|
|
||||||
;<Logo />
|
;<Logo />
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -185,6 +186,24 @@ npm run format
|
|||||||
npm run format:css
|
npm run format:css
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 👩🔬 Testing
|
||||||
|
|
||||||
|
Test suite is setup with [Jest](https://jestjs.io) and [react-testing-library](https://github.com/kentcdodds/react-testing-library).
|
||||||
|
|
||||||
|
To run all tests, including all linting tests:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
All test files live beside the respective component. Testing setup, fixtures, and mocks can be found in `./jest.config.js` and `./jest` folder.
|
||||||
|
|
||||||
|
For local development, run the test watcher:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run test:watch
|
||||||
|
```
|
||||||
|
|
||||||
### 🎈 Add a new post
|
### 🎈 Add a new post
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
19
jest.config.js
Normal file
19
jest.config.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
module.exports = {
|
||||||
|
transform: {
|
||||||
|
'^.+\\.jsx?$': '<rootDir>/jest/jest-preprocess.js'
|
||||||
|
},
|
||||||
|
moduleNameMapper: {
|
||||||
|
'.+\\.(css|styl|less|sass|scss)$': 'identity-obj-proxy',
|
||||||
|
'.+\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
|
||||||
|
'<rootDir>/jest/__mocks__/file-mock.js',
|
||||||
|
'\\.svg': '<rootDir>/jest/__mocks__/svgr-mock.js'
|
||||||
|
},
|
||||||
|
testPathIgnorePatterns: ['node_modules', '.cache', 'public', 'coverage'],
|
||||||
|
transformIgnorePatterns: ['node_modules/(?!(gatsby)/)'],
|
||||||
|
globals: {
|
||||||
|
__PATH_PREFIX__: ''
|
||||||
|
},
|
||||||
|
testURL: 'http://localhost',
|
||||||
|
setupFiles: ['<rootDir>/jest/loadershim.js'],
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/jest/setup-test-env.js']
|
||||||
|
}
|
1
jest/__mocks__/file-mock.js
Normal file
1
jest/__mocks__/file-mock.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = 'test-file-stub'
|
28
jest/__mocks__/gatsby.js
Normal file
28
jest/__mocks__/gatsby.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const React = require('react')
|
||||||
|
const gatsby = jest.requireActual('gatsby')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
...gatsby,
|
||||||
|
graphql: jest.fn(),
|
||||||
|
Link: jest.fn().mockImplementation(
|
||||||
|
// these props are invalid for an `a` tag
|
||||||
|
({
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
activeClassName,
|
||||||
|
activeStyle,
|
||||||
|
getProps,
|
||||||
|
innerRef,
|
||||||
|
ref,
|
||||||
|
replace,
|
||||||
|
to,
|
||||||
|
/* eslint-enable no-unused-vars */
|
||||||
|
...rest
|
||||||
|
}) =>
|
||||||
|
React.createElement('a', {
|
||||||
|
...rest,
|
||||||
|
href: to
|
||||||
|
})
|
||||||
|
),
|
||||||
|
StaticQuery: jest.fn(),
|
||||||
|
useStaticQuery: jest.fn()
|
||||||
|
}
|
1
jest/__mocks__/svgr-mock.js
Normal file
1
jest/__mocks__/svgr-mock.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = { ReactComponent: 'svg' }
|
5
jest/jest-preprocess.js
Normal file
5
jest/jest-preprocess.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const babelOptions = {
|
||||||
|
presets: ['babel-preset-gatsby']
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = require('babel-jest').createTransformer(babelOptions)
|
3
jest/loadershim.js
Normal file
3
jest/loadershim.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
global.___loader = {
|
||||||
|
enqueue: jest.fn()
|
||||||
|
}
|
4
jest/setup-test-env.js
Normal file
4
jest/setup-test-env.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import 'jest-dom/extend-expect'
|
||||||
|
|
||||||
|
// this is basically: afterEach(cleanup)
|
||||||
|
import 'react-testing-library/cleanup-after-each'
|
11
jest/testRender.js
Normal file
11
jest/testRender.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { render } from 'react-testing-library'
|
||||||
|
|
||||||
|
const testRender = component => {
|
||||||
|
it('renders without crashing', () => {
|
||||||
|
const { container } = render(component)
|
||||||
|
|
||||||
|
expect(container.firstChild).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default testRender
|
58
package.json
58
package.json
@ -22,7 +22,8 @@
|
|||||||
"lint:md": "markdownlint './**/*.{md,markdown}' --ignore './{node_modules,public,.cache,.git}/**/*'",
|
"lint:md": "markdownlint './**/*.{md,markdown}' --ignore './{node_modules,public,.cache,.git}/**/*'",
|
||||||
"lint:yaml": "prettier '**/*.{yml,yaml}' --list-different",
|
"lint:yaml": "prettier '**/*.{yml,yaml}' --list-different",
|
||||||
"lint": "run-p --continue-on-error lint:js lint:css lint:yaml lint:md",
|
"lint": "run-p --continue-on-error lint:js lint:css lint:yaml lint:md",
|
||||||
"test": "npm run lint",
|
"test": "npm run lint && jest --coverage",
|
||||||
|
"test:watch": "npm run lint && jest --coverage --watch",
|
||||||
"deploy": "./scripts/deploy.sh",
|
"deploy": "./scripts/deploy.sh",
|
||||||
"new": "babel-node ./scripts/new.js"
|
"new": "babel-node ./scripts/new.js"
|
||||||
},
|
},
|
||||||
@ -33,36 +34,36 @@
|
|||||||
"dms2dec": "^1.1.0",
|
"dms2dec": "^1.1.0",
|
||||||
"fast-exif": "^1.0.1",
|
"fast-exif": "^1.0.1",
|
||||||
"fraction.js": "^4.0.12",
|
"fraction.js": "^4.0.12",
|
||||||
"gatsby": "^2.3.22",
|
"gatsby": "^2.4.2",
|
||||||
"gatsby-image": "^2.0.38",
|
"gatsby-image": "^2.0.41",
|
||||||
"gatsby-plugin-catch-links": "^2.0.13",
|
"gatsby-plugin-catch-links": "^2.0.13",
|
||||||
"gatsby-plugin-favicon": "^3.1.5",
|
"gatsby-plugin-favicon": "^3.1.6",
|
||||||
"gatsby-plugin-feed": "^2.1.0",
|
"gatsby-plugin-feed": "^2.2.0",
|
||||||
"gatsby-plugin-lunr": "^1.4.0",
|
"gatsby-plugin-lunr": "^1.5.0",
|
||||||
"gatsby-plugin-matomo": "^0.7.0",
|
"gatsby-plugin-matomo": "^0.7.0",
|
||||||
"gatsby-plugin-meta-redirect": "^1.1.1",
|
"gatsby-plugin-meta-redirect": "^1.1.1",
|
||||||
"gatsby-plugin-offline": "^2.0.25",
|
"gatsby-plugin-offline": "^2.1.0",
|
||||||
"gatsby-plugin-react-helmet": "^3.0.11",
|
"gatsby-plugin-react-helmet": "^3.0.12",
|
||||||
"gatsby-plugin-sass": "^2.0.11",
|
"gatsby-plugin-sass": "^2.0.11",
|
||||||
"gatsby-plugin-sharp": "^2.0.34",
|
"gatsby-plugin-sharp": "^2.0.36",
|
||||||
"gatsby-plugin-sitemap": "^2.0.12",
|
"gatsby-plugin-sitemap": "^2.1.0",
|
||||||
"gatsby-plugin-svgr": "^2.0.2",
|
"gatsby-plugin-svgr": "^2.0.2",
|
||||||
"gatsby-plugin-webpack-size": "^0.0.3",
|
"gatsby-plugin-webpack-size": "^0.0.3",
|
||||||
"gatsby-redirect-from": "^0.1.1",
|
"gatsby-redirect-from": "^0.1.1",
|
||||||
"gatsby-remark-autolink-headers": "^2.0.16",
|
"gatsby-remark-autolink-headers": "^2.0.16",
|
||||||
"gatsby-remark-copy-linked-files": "^2.0.11",
|
"gatsby-remark-copy-linked-files": "^2.0.12",
|
||||||
"gatsby-remark-highlights": "^1.3.4",
|
"gatsby-remark-highlights": "^1.3.4",
|
||||||
"gatsby-remark-images": "^3.0.10",
|
"gatsby-remark-images": "^3.0.11",
|
||||||
"gatsby-remark-smartypants": "^2.0.9",
|
"gatsby-remark-smartypants": "^2.0.9",
|
||||||
"gatsby-source-filesystem": "^2.0.29",
|
"gatsby-source-filesystem": "^2.0.33",
|
||||||
"gatsby-source-graphql": "^2.0.18",
|
"gatsby-source-graphql": "^2.0.18",
|
||||||
"gatsby-transformer-remark": "^2.3.8",
|
"gatsby-transformer-remark": "^2.3.12",
|
||||||
"gatsby-transformer-sharp": "^2.1.18",
|
"gatsby-transformer-sharp": "^2.1.19",
|
||||||
"graphql": "^14.2.0",
|
"graphql": "^14.2.1",
|
||||||
"intersection-observer": "^0.6.0",
|
"intersection-observer": "^0.6.0",
|
||||||
"js-scrypt": "^0.2.0",
|
"js-scrypt": "^0.2.0",
|
||||||
"load-script": "^1.0.0",
|
"load-script": "^1.0.0",
|
||||||
"node-sass": "^4.11.0",
|
"node-sass": "^4.12.0",
|
||||||
"nord": "^0.2.1",
|
"nord": "^0.2.1",
|
||||||
"pigeon-maps": "^0.12.1",
|
"pigeon-maps": "^0.12.1",
|
||||||
"pigeon-marker": "^0.3.4",
|
"pigeon-marker": "^0.3.4",
|
||||||
@ -70,7 +71,7 @@
|
|||||||
"react-blockies": "^1.4.1",
|
"react-blockies": "^1.4.1",
|
||||||
"react-clipboard.js": "^2.0.7",
|
"react-clipboard.js": "^2.0.7",
|
||||||
"react-dom": "^16.8.6",
|
"react-dom": "^16.8.6",
|
||||||
"react-helmet": "^5.2.0",
|
"react-helmet": "^5.2.1",
|
||||||
"react-modal": "^3.8.1",
|
"react-modal": "^3.8.1",
|
||||||
"react-pose": "^4.0.8",
|
"react-pose": "^4.0.8",
|
||||||
"react-qr-svg": "^2.2.1",
|
"react-qr-svg": "^2.2.1",
|
||||||
@ -80,31 +81,36 @@
|
|||||||
"remark-react": "^5.0.1",
|
"remark-react": "^5.0.1",
|
||||||
"slugify": "^1.3.4",
|
"slugify": "^1.3.4",
|
||||||
"terser": "^3.17.0",
|
"terser": "^3.17.0",
|
||||||
"web3": "^1.0.0-beta.51"
|
"web3": "^1.0.0-beta.54"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/node": "^7.2.2",
|
"@babel/node": "^7.2.2",
|
||||||
"@babel/preset-env": "^7.4.2",
|
"@babel/preset-env": "^7.4.4",
|
||||||
"@svgr/webpack": "^4.2.0",
|
"@svgr/webpack": "^4.2.0",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
|
"babel-jest": "^24.7.1",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^5.16.0",
|
||||||
"eslint-config-prettier": "^4.1.0",
|
"eslint-config-prettier": "^4.2.0",
|
||||||
"eslint-loader": "^2.1.2",
|
"eslint-loader": "^2.1.2",
|
||||||
"eslint-plugin-graphql": "^3.0.3",
|
"eslint-plugin-graphql": "^3.0.3",
|
||||||
"eslint-plugin-jsx-a11y": "^6.2.1",
|
"eslint-plugin-jsx-a11y": "^6.2.1",
|
||||||
"eslint-plugin-prettier": "^3.0.1",
|
"eslint-plugin-prettier": "^3.0.1",
|
||||||
"eslint-plugin-react": "^7.12.4",
|
"eslint-plugin-react": "^7.13.0",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^7.0.1",
|
||||||
|
"identity-obj-proxy": "^3.0.0",
|
||||||
|
"jest": "^24.7.1",
|
||||||
|
"jest-dom": "^3.1.4",
|
||||||
"markdownlint-cli": "^0.15.0",
|
"markdownlint-cli": "^0.15.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"ora": "^3.2.0",
|
"ora": "^3.4.0",
|
||||||
"pify": "^4.0.1",
|
"pify": "^4.0.1",
|
||||||
"prettier": "^1.17.0",
|
"prettier": "^1.17.0",
|
||||||
"prettier-stylelint": "^0.4.2",
|
"prettier-stylelint": "^0.4.2",
|
||||||
"stylelint": "^10.0.0",
|
"react-testing-library": "^7.0.0",
|
||||||
"stylelint-config-css-modules": "^1.3.0",
|
"stylelint": "^10.0.1",
|
||||||
|
"stylelint-config-css-modules": "^1.4.0",
|
||||||
"stylelint-config-standard": "^18.3.0",
|
"stylelint-config-standard": "^18.3.0",
|
||||||
"stylelint-scss": "^3.5.4",
|
"stylelint-scss": "^3.6.1",
|
||||||
"why-did-you-update": "^1.0.6"
|
"why-did-you-update": "^1.0.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
9
src/components/atoms/Container.test.jsx
Normal file
9
src/components/atoms/Container.test.jsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import React from 'react'
|
||||||
|
// import { render } from 'react-testing-library'
|
||||||
|
import testRender from '../../../jest/testRender'
|
||||||
|
|
||||||
|
import Container from './Container'
|
||||||
|
|
||||||
|
describe('Container', () => {
|
||||||
|
testRender(<Container>Hello</Container>)
|
||||||
|
})
|
@ -1,70 +1,8 @@
|
|||||||
import React, { Fragment, PureComponent } from 'react'
|
import React, { PureComponent } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import Map from 'pigeon-maps'
|
import ExifMap from './ExifMap'
|
||||||
import Marker from 'pigeon-marker'
|
|
||||||
import styles from './Exif.module.scss'
|
import styles from './Exif.module.scss'
|
||||||
|
|
||||||
const MAPBOX_ACCESS_TOKEN =
|
|
||||||
'pk.eyJ1Ijoia3JlbWFsaWNpb3VzIiwiYSI6ImNqbTE2NHpkYjJmNm8zcHF4eDVqZzk3ejEifQ.1uwPzM6MSTgL2e1Hxcmuqw'
|
|
||||||
|
|
||||||
const retina =
|
|
||||||
typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : ''
|
|
||||||
|
|
||||||
const mapbox = (mapboxId, accessToken) => (x, y, z) =>
|
|
||||||
`https://api.mapbox.com/styles/v1/mapbox/${mapboxId}/tiles/256/${z}/${x}/${y}${retina}?access_token=${accessToken}`
|
|
||||||
|
|
||||||
const providers = {
|
|
||||||
osm: (x, y, z) => {
|
|
||||||
const s = String.fromCharCode(97 + ((x + y + z) % 3))
|
|
||||||
return `https://${s}.tile.openstreetmap.org/${z}/${x}/${y}.png`
|
|
||||||
},
|
|
||||||
wikimedia: (x, y, z) =>
|
|
||||||
`https://maps.wikimedia.org/osm-intl/${z}/${x}/${y}${retina}.png`,
|
|
||||||
stamen: (x, y, z) =>
|
|
||||||
`https://stamen-tiles.a.ssl.fastly.net/terrain/${z}/${x}/${y}${retina}.jpg`,
|
|
||||||
streets: mapbox('streets-v10', MAPBOX_ACCESS_TOKEN),
|
|
||||||
satellite: mapbox('satellite-streets-v10', MAPBOX_ACCESS_TOKEN),
|
|
||||||
outdoors: mapbox('outdoors-v10', MAPBOX_ACCESS_TOKEN),
|
|
||||||
light: mapbox('light-v9', MAPBOX_ACCESS_TOKEN),
|
|
||||||
dark: mapbox('dark-v9', MAPBOX_ACCESS_TOKEN)
|
|
||||||
}
|
|
||||||
|
|
||||||
class ExifMap extends PureComponent {
|
|
||||||
state = { zoom: 12 }
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
gps: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
zoomIn = () => {
|
|
||||||
this.setState({
|
|
||||||
zoom: Math.min(this.state.zoom + 4, 20)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { latitude, longitude } = this.props.gps
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Map
|
|
||||||
center={[latitude, longitude]}
|
|
||||||
zoom={this.state.zoom}
|
|
||||||
height={160}
|
|
||||||
attribution={false}
|
|
||||||
provider={providers['light']}
|
|
||||||
metaWheelZoom={true}
|
|
||||||
metaWheelZoomWarning={'META+wheel to zoom'}
|
|
||||||
>
|
|
||||||
<Marker
|
|
||||||
anchor={[latitude, longitude]}
|
|
||||||
payload={1}
|
|
||||||
onClick={this.zoomIn}
|
|
||||||
/>
|
|
||||||
</Map>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class Exif extends PureComponent {
|
export default class Exif extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
exif: PropTypes.object
|
exif: PropTypes.object
|
||||||
@ -82,7 +20,7 @@ export default class Exif extends PureComponent {
|
|||||||
} = this.props.exif
|
} = this.props.exif
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<>
|
||||||
<aside className={styles.exif}>
|
<aside className={styles.exif}>
|
||||||
<div className={styles.data}>
|
<div className={styles.data}>
|
||||||
{model && <span title="Camera model">{model}</span>}
|
{model && <span title="Camera model">{model}</span>}
|
||||||
@ -94,7 +32,7 @@ export default class Exif extends PureComponent {
|
|||||||
</div>
|
</div>
|
||||||
<div className={styles.map}>{gps && <ExifMap gps={gps} />}</div>
|
<div className={styles.map}>{gps && <ExifMap gps={gps} />}</div>
|
||||||
</aside>
|
</aside>
|
||||||
</Fragment>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
src/components/atoms/Exif.test.jsx
Normal file
19
src/components/atoms/Exif.test.jsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import React from 'react'
|
||||||
|
// import { render } from 'react-testing-library'
|
||||||
|
import testRender from '../../../jest/testRender'
|
||||||
|
|
||||||
|
import Exif from './Exif'
|
||||||
|
|
||||||
|
const exif = {
|
||||||
|
iso: '500',
|
||||||
|
model: 'Canon',
|
||||||
|
fstop: '7.2',
|
||||||
|
shutterspeed: '200',
|
||||||
|
focalLength: '200',
|
||||||
|
exposure: '200',
|
||||||
|
gps: { latitude: '52.4792516', longitude: '13.431609' }
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Exif', () => {
|
||||||
|
testRender(<Exif exif={exif} />)
|
||||||
|
})
|
65
src/components/atoms/ExifMap.jsx
Normal file
65
src/components/atoms/ExifMap.jsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import React, { PureComponent } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import Map from 'pigeon-maps'
|
||||||
|
import Marker from 'pigeon-marker'
|
||||||
|
|
||||||
|
const MAPBOX_ACCESS_TOKEN =
|
||||||
|
'pk.eyJ1Ijoia3JlbWFsaWNpb3VzIiwiYSI6ImNqbTE2NHpkYjJmNm8zcHF4eDVqZzk3ejEifQ.1uwPzM6MSTgL2e1Hxcmuqw'
|
||||||
|
|
||||||
|
const retina =
|
||||||
|
typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : ''
|
||||||
|
|
||||||
|
const mapbox = (mapboxId, accessToken) => (x, y, z) =>
|
||||||
|
`https://api.mapbox.com/styles/v1/mapbox/${mapboxId}/tiles/256/${z}/${x}/${y}${retina}?access_token=${accessToken}`
|
||||||
|
|
||||||
|
const providers = {
|
||||||
|
// osm: (x, y, z) => {
|
||||||
|
// const s = String.fromCharCode(97 + ((x + y + z) % 3))
|
||||||
|
// return `https://${s}.tile.openstreetmap.org/${z}/${x}/${y}.png`
|
||||||
|
// },
|
||||||
|
// wikimedia: (x, y, z) =>
|
||||||
|
// `https://maps.wikimedia.org/osm-intl/${z}/${x}/${y}${retina}.png`,
|
||||||
|
// stamen: (x, y, z) =>
|
||||||
|
// `https://stamen-tiles.a.ssl.fastly.net/terrain/${z}/${x}/${y}${retina}.jpg`,
|
||||||
|
// streets: mapbox('streets-v10', MAPBOX_ACCESS_TOKEN),
|
||||||
|
// satellite: mapbox('satellite-streets-v10', MAPBOX_ACCESS_TOKEN),
|
||||||
|
// outdoors: mapbox('outdoors-v10', MAPBOX_ACCESS_TOKEN),
|
||||||
|
light: mapbox('light-v9', MAPBOX_ACCESS_TOKEN),
|
||||||
|
dark: mapbox('dark-v9', MAPBOX_ACCESS_TOKEN)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ExifMap extends PureComponent {
|
||||||
|
state = { zoom: 12 }
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
gps: PropTypes.object
|
||||||
|
}
|
||||||
|
|
||||||
|
zoomIn = () => {
|
||||||
|
this.setState({
|
||||||
|
zoom: Math.min(this.state.zoom + 4, 20)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { latitude, longitude } = this.props.gps
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Map
|
||||||
|
center={[latitude, longitude]}
|
||||||
|
zoom={this.state.zoom}
|
||||||
|
height={160}
|
||||||
|
attribution={false}
|
||||||
|
provider={providers['light']}
|
||||||
|
metaWheelZoom={true}
|
||||||
|
metaWheelZoomWarning={'META+wheel to zoom'}
|
||||||
|
>
|
||||||
|
<Marker
|
||||||
|
anchor={[latitude, longitude]}
|
||||||
|
payload={1}
|
||||||
|
onClick={this.zoomIn}
|
||||||
|
/>
|
||||||
|
</Map>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
9
src/components/atoms/Hamburger.test.jsx
Normal file
9
src/components/atoms/Hamburger.test.jsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import React from 'react'
|
||||||
|
// import { render } from 'react-testing-library'
|
||||||
|
import testRender from '../../../jest/testRender'
|
||||||
|
|
||||||
|
import Hamburger from './Hamburger'
|
||||||
|
|
||||||
|
describe('Hamburger', () => {
|
||||||
|
testRender(<Hamburger />)
|
||||||
|
})
|
9
src/components/atoms/Input.test.jsx
Normal file
9
src/components/atoms/Input.test.jsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import React from 'react'
|
||||||
|
// import { render } from 'react-testing-library'
|
||||||
|
import testRender from '../../../jest/testRender'
|
||||||
|
|
||||||
|
import Input from './Input'
|
||||||
|
|
||||||
|
describe('Input', () => {
|
||||||
|
testRender(<Input />)
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user