1
0
mirror of https://github.com/alrayyes/my-opinionated-gatsby-starter synced 2023-11-14 15:56:29 +00:00

Added jest tests

This commit is contained in:
Ryan Kes 2020-06-04 15:50:51 +02:00
parent 43dbd82a88
commit d8cb872fcf
31 changed files with 2569 additions and 68 deletions

View File

@ -1,12 +1,14 @@
{
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"plugins": ["@typescript-eslint", "jest"],
"extends": [
"react-app",
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"prettier/@typescript-eslint"
"plugin:prettier/recommended",
"prettier/@typescript-eslint",
"plugin:jest/recommended"
],
"rules": {
"react/prop-types": "off"

View File

@ -1,4 +1,4 @@
.cache
package.json
package-lock.json
public
node_modules/
public/
.cache/
coverage/

1
__mocks__/file-mock.ts Normal file
View File

@ -0,0 +1 @@
module.exports = "test-file-stub"

28
__mocks__/gatsby.ts Normal file
View File

@ -0,0 +1,28 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
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
({
activeClassName,
activeStyle,
getProps,
innerRef,
partiallyActive,
ref,
replace,
to,
...rest
}) =>
React.createElement("a", {
...rest,
href: to,
})
),
StaticQuery: jest.fn(),
useStaticQuery: jest.fn(),
}

6
jest-preprocess.js Normal file
View File

@ -0,0 +1,6 @@
const babelOptions = {
presets: ["babel-preset-gatsby", "@babel/preset-typescript"],
}
// eslint-disable-next-line @typescript-eslint/no-var-requires
module.exports = require("babel-jest").createTransformer(babelOptions)

183
jest.config.js Normal file
View File

@ -0,0 +1,183 @@
// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html
module.exports = {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Stop running tests after `n` failures
// bail: 0,
// The directory where Jest should store its cached dependency information
// cacheDirectory: "/tmp/jest_rs",
// Automatically clear mock calls and instances between every test
clearMocks: true,
// Indicates whether the coverage information should be collected while executing the test
// collectCoverage: false,
// An array of glob patterns indicating a set of files for which coverage information should be collected
// collectCoverageFrom: undefined,
// The directory where Jest should output its coverage files
coverageDirectory: "coverage",
// An array of regexp pattern strings used to skip coverage collection
// coveragePathIgnorePatterns: [
// "/node_modules/"
// ],
// A list of reporter names that Jest uses when writing coverage reports
coverageReporters: ["json", "lcov", "text", "clover", "cobertura"],
// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: undefined,
// A path to a custom dependency extractor
// dependencyExtractor: undefined,
// Make calling deprecated APIs throw helpful error messages
// errorOnDeprecated: false,
// Force coverage collection from ignored files using an array of glob patterns
// forceCoverageMatch: [],
// A path to a module which exports an async function that is triggered once before all test suites
// globalSetup: undefined,
// A path to a module which exports an async function that is triggered once after all test suites
// globalTeardown: undefined,
// A set of global variables that need to be available in all test environments
globals: {
__PATH_PREFIX__: ``,
},
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [
// "node_modules"
// ],
// An array of file extensions your modules use
// moduleFileExtensions: [
// "js",
// "json",
// "jsx",
// "ts",
// "tsx",
// "node"
// ],
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
moduleNameMapper: {
".+\\.(css|styl|less|sass|scss)$": `identity-obj-proxy`,
".+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": `<rootDir>/__mocks__/file-mock.ts`,
},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
// Activates notifications for test results
// notify: false,
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",
// A preset that is used as a base for Jest's configuration
// preset: undefined,
// Run tests from one or more projects
// projects: undefined,
// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
// Automatically reset mock state between every test
// resetMocks: false,
// Reset the module registry before running each individual test
// resetModules: false,
// A path to a custom resolver
// resolver: undefined,
// Automatically restore mock state between every test
// restoreMocks: false,
// The root directory that Jest should scan for tests and modules within
// rootDir: undefined,
// A list of paths to directories that Jest should use to search for files in
// roots: [
// "<rootDir>"
// ],
// Allows you to use a custom runner instead of Jest's default test runner
// runner: "jest-runner",
// The paths to modules that run some code to configure or set up the testing environment before each test
setupFiles: [`<rootDir>/loadershim.js`],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
//snapshotSerializers: ["jest-emotion"],
// The test environment that will be used for testing
testEnvironment: "node",
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
// Adds a location field to test results
// testLocationInResults: false,
// The glob patterns Jest uses to detect test files
// testMatch: [
// "**/__tests__/**/*.[jt]s?(x)",
// "**/?(*.)+(spec|test).[tj]s?(x)"
// ],
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
testPathIgnorePatterns: [`node_modules`, `\\.cache`, `<rootDir>.*/public`],
// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
// This option allows the use of a custom results processor
// testResultsProcessor: undefined,
// This option allows use of a custom test runner
// testRunner: "jasmine2",
// This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
// testURL: "http://localhost",
// Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
// timers: "real",
// A map from regular expressions to paths to transformers
transform: {
"^.+\\.[jt]sx?$": `<rootDir>/jest-preprocess.js`,
},
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
transformIgnorePatterns: [`node_modules/(?!(gatsby|gatsby-plugin-mdx)/)`],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
// verbose: undefined,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],
// Whether to use watchman for file crawling
// watchman: true,
}

3
loadershim.js Normal file
View File

@ -0,0 +1,3 @@
global.___loader = {
enqueue: jest.fn(),
}

View File

@ -18,24 +18,32 @@
"react-helmet": "^6.0.0"
},
"devDependencies": {
"@types/node": "^14.0.6",
"@babel/preset-typescript": "^7.10.1",
"@types/react": "^16.9.35",
"@types/react-dom": "^16.9.8",
"@types/react-helmet": "^6.0.0",
"@types/react-test-renderer": "^16.9.2",
"@typescript-eslint/eslint-plugin": "^3.1.0",
"@typescript-eslint/parser": "^3.1.0",
"eslint": "^7.1.0",
"eslint-config-prettier": "^6.11.0",
"eslint-config-react-app": "^5.2.1",
"eslint-loader": "^4.0.2",
"eslint-plugin-flowtype": "^5.1.3",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jest": "^23.13.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-react": "^7.20.0",
"eslint-plugin-react-hooks": "^4.0.4",
"gatsby-plugin-eslint": "^2.0.8",
"husky": ">=4",
"identity-obj-proxy": "^3.0.0",
"jest": "^26.0.1",
"jest-emotion": "^10.0.32",
"lint-staged": ">=10",
"prettier": "^2.0.5",
"react-test-renderer": "^16.13.1",
"typescript": "^3.9.3"
},
"keywords": [

11
src/@types/pages/using-typescript.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
export interface UsingTypescriptDataInterface {
data: {
site: {
buildTime: string
}
}
}
export interface UsingTypescriptInterface extends UsingTypescriptDataInterface {
path: string
}

View File

@ -0,0 +1,42 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Header renders correctly 1`] = `
<header
style={
Object {
"background": "rebeccapurple",
"marginBottom": "1.45rem",
}
}
>
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "1.45rem 1.0875rem",
}
}
>
<h1
style={
Object {
"margin": 0,
}
}
>
<a
href="/"
style={
Object {
"color": "white",
"textDecoration": "none",
}
}
>
Default Starter
</a>
</h1>
</div>
</header>
`;

View File

@ -0,0 +1,111 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Header renders correctly 1`] = `
<div
className=" gatsby-image-wrapper"
style={
Object {
"maxHeight": null,
"maxWidth": null,
"overflow": "hidden",
"position": "relative",
}
}
>
<div
aria-hidden={true}
style={
Object {
"paddingBottom": "100%",
"width": "100%",
}
}
/>
<img
alt=""
aria-hidden={true}
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsSAAALEgHS3X78AAACYklEQVQ4y42Uy28SQRjA+dM8efDmwYN6qF6qiSY+Y/WgQRMibY00TaWNBSRSCraYQtHl/bR0KyxQWCgWWAqU8izl/Sq7rLNsRHlVJpvJtzPfb77nDIOcZHSoqZSrp4+KtXIziubaLRysMCZiCYqOoVnhjNEi8RcztdxxeTzc6VBfT+5O2Vhpb+vw4wMdZ0ppWvP9xzLeJoDNThf2W+Nz1+XzNxQubSToSKKW+BDc+WOnkshhSVgeCiGpViZMEg1oxc26Knt+ae3bEtJTZwzE1kXLccG0+sOOlrcvZXvsczPkITfsa20vwIKnhsh+BnjUarT74Gb13CY7KBVJMv3z4N1NszQYsMWM62HNrCis/GxXn0iYls23uz5LPBcv0bH8hUH2XRoM85ySXv7JBtO87jMIvWq+H5GoYIHCLA1ZxD6Qap3Ak8IKfW7TJ50lK6uP9E6RgndHaODtCJ6Z5RyHfnE7j6gRbcKlCYNSt+rtETHTpUGgEP8FYmdNqd/Mo7aiVWTfuH2L9xASvfxxlqr01EYkrJszvNkgW9bH0OuFr+99m+y9IOeyU6zIp/Hubp/yMEztlzFPwOhdvq+nIoS1JNn4t2sugCmVsDvPe2KKolnZLCxhOcAKQRDDXTQaVi46lqYhIBwHTrl3oWqhMRDtaJge37lOBMKo4tfbqhVX0J7snTsWps8uZWuoOQY6CcjpSIF55UvmqNgr5wUwtV1IVdnXtnSfPEB2qjDNqnvczRl0m+j6Jn5lXb6nAQJqinmN0ZEBj03YLzghY8PnTRz80o/GRJZpOLCb0PM9BN7pvUEjx28V00WUg9jIVwAAAABJRU5ErkJggg=="
style={
Object {
"height": "100%",
"left": 0,
"objectFit": "cover",
"objectPosition": "center",
"opacity": 1,
"position": "absolute",
"top": 0,
"transitionDelay": "500ms",
"width": "100%",
}
}
/>
<noscript
dangerouslySetInnerHTML={
Object {
"__html": "<picture><source type='image/webp' srcset=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/61e93/gatsby-astronaut.webp 200w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/1f5c5/gatsby-astronaut.webp 400w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/58556/gatsby-astronaut.webp 800w\\" sizes=\\"(max-width: 800px) 100vw, 800px\\" /><source srcset=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/69585/gatsby-astronaut.png 200w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/497c6/gatsby-astronaut.png 400w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png 800w\\" sizes=\\"(max-width: 800px) 100vw, 800px\\" /><img loading=\\"lazy\\" sizes=\\"(max-width: 800px) 100vw, 800px\\" srcset=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/69585/gatsby-astronaut.png 200w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/497c6/gatsby-astronaut.png 400w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png 800w\\" src=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png\\" alt=\\"\\" style=\\"position:absolute;top:0;left:0;opacity:1;width:100%;height:100%;object-fit:cover;object-position:center\\"/></picture>",
}
}
/>
</div>
`;
exports[`Image renders correctly 1`] = `
<div
className=" gatsby-image-wrapper"
style={
Object {
"maxHeight": null,
"maxWidth": null,
"overflow": "hidden",
"position": "relative",
}
}
>
<div
aria-hidden={true}
style={
Object {
"paddingBottom": "100%",
"width": "100%",
}
}
/>
<img
alt=""
aria-hidden={true}
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsSAAALEgHS3X78AAACYklEQVQ4y42Uy28SQRjA+dM8efDmwYN6qF6qiSY+Y/WgQRMibY00TaWNBSRSCraYQtHl/bR0KyxQWCgWWAqU8izl/Sq7rLNsRHlVJpvJtzPfb77nDIOcZHSoqZSrp4+KtXIziubaLRysMCZiCYqOoVnhjNEi8RcztdxxeTzc6VBfT+5O2Vhpb+vw4wMdZ0ppWvP9xzLeJoDNThf2W+Nz1+XzNxQubSToSKKW+BDc+WOnkshhSVgeCiGpViZMEg1oxc26Knt+ae3bEtJTZwzE1kXLccG0+sOOlrcvZXvsczPkITfsa20vwIKnhsh+BnjUarT74Gb13CY7KBVJMv3z4N1NszQYsMWM62HNrCis/GxXn0iYls23uz5LPBcv0bH8hUH2XRoM85ySXv7JBtO87jMIvWq+H5GoYIHCLA1ZxD6Qap3Ak8IKfW7TJ50lK6uP9E6RgndHaODtCJ6Z5RyHfnE7j6gRbcKlCYNSt+rtETHTpUGgEP8FYmdNqd/Mo7aiVWTfuH2L9xASvfxxlqr01EYkrJszvNkgW9bH0OuFr+99m+y9IOeyU6zIp/Hubp/yMEztlzFPwOhdvq+nIoS1JNn4t2sugCmVsDvPe2KKolnZLCxhOcAKQRDDXTQaVi46lqYhIBwHTrl3oWqhMRDtaJge37lOBMKo4tfbqhVX0J7snTsWps8uZWuoOQY6CcjpSIF55UvmqNgr5wUwtV1IVdnXtnSfPEB2qjDNqnvczRl0m+j6Jn5lXb6nAQJqinmN0ZEBj03YLzghY8PnTRz80o/GRJZpOLCb0PM9BN7pvUEjx28V00WUg9jIVwAAAABJRU5ErkJggg=="
style={
Object {
"height": "100%",
"left": 0,
"objectFit": "cover",
"objectPosition": "center",
"opacity": 1,
"position": "absolute",
"top": 0,
"transitionDelay": "500ms",
"width": "100%",
}
}
/>
<noscript
dangerouslySetInnerHTML={
Object {
"__html": "<picture><source type='image/webp' srcset=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/61e93/gatsby-astronaut.webp 200w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/1f5c5/gatsby-astronaut.webp 400w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/58556/gatsby-astronaut.webp 800w\\" sizes=\\"(max-width: 800px) 100vw, 800px\\" /><source srcset=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/69585/gatsby-astronaut.png 200w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/497c6/gatsby-astronaut.png 400w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png 800w\\" sizes=\\"(max-width: 800px) 100vw, 800px\\" /><img loading=\\"lazy\\" sizes=\\"(max-width: 800px) 100vw, 800px\\" srcset=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/69585/gatsby-astronaut.png 200w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/497c6/gatsby-astronaut.png 400w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png 800w\\" src=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png\\" alt=\\"\\" style=\\"position:absolute;top:0;left:0;opacity:1;width:100%;height:100%;object-fit:cover;object-position:center\\"/></picture>",
}
}
/>
</div>
`;

View File

@ -0,0 +1,68 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Layout renders correctly 1`] = `
Array [
<header
style={
Object {
"background": "rebeccapurple",
"marginBottom": "1.45rem",
}
}
>
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "1.45rem 1.0875rem",
}
}
>
<h1
style={
Object {
"margin": 0,
}
}
>
<a
href="/"
style={
Object {
"color": "white",
"textDecoration": "none",
}
}
>
Gatsby Default Starter
</a>
</h1>
</div>
</header>,
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "0 1.0875rem 1.45rem",
}
}
>
<main>
children
</main>
<footer>
©
2020
, Built with
<a
href="https://www.gatsbyjs.org"
>
Gatsby
</a>
</footer>
</div>,
]
`;

View File

@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Layout renders correctly 1`] = `null`;

View File

@ -0,0 +1,12 @@
import renderer from "react-test-renderer"
import Header from "./header"
import React from "react"
describe("Header", () => {
it("renders correctly", () => {
const tree = renderer
.create(<Header siteTitle="Default Starter" />)
.toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -0,0 +1,39 @@
import renderer from "react-test-renderer"
import React from "react"
import Image from "./image"
import * as Gatsby from "gatsby"
import { ImageDataInterface } from "../@types/components/image"
const useStaticQuery = jest.spyOn(Gatsby, "useStaticQuery")
describe("Image", () => {
beforeEach(() => {
const data: ImageDataInterface = {
placeholderImage: {
childImageSharp: {
fluid: {
base64:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsSAAALEgHS3X78AAACYklEQVQ4y42Uy28SQRjA+dM8efDmwYN6qF6qiSY+Y/WgQRMibY00TaWNBSRSCraYQtHl/bR0KyxQWCgWWAqU8izl/Sq7rLNsRHlVJpvJtzPfb77nDIOcZHSoqZSrp4+KtXIziubaLRysMCZiCYqOoVnhjNEi8RcztdxxeTzc6VBfT+5O2Vhpb+vw4wMdZ0ppWvP9xzLeJoDNThf2W+Nz1+XzNxQubSToSKKW+BDc+WOnkshhSVgeCiGpViZMEg1oxc26Knt+ae3bEtJTZwzE1kXLccG0+sOOlrcvZXvsczPkITfsa20vwIKnhsh+BnjUarT74Gb13CY7KBVJMv3z4N1NszQYsMWM62HNrCis/GxXn0iYls23uz5LPBcv0bH8hUH2XRoM85ySXv7JBtO87jMIvWq+H5GoYIHCLA1ZxD6Qap3Ak8IKfW7TJ50lK6uP9E6RgndHaODtCJ6Z5RyHfnE7j6gRbcKlCYNSt+rtETHTpUGgEP8FYmdNqd/Mo7aiVWTfuH2L9xASvfxxlqr01EYkrJszvNkgW9bH0OuFr+99m+y9IOeyU6zIp/Hubp/yMEztlzFPwOhdvq+nIoS1JNn4t2sugCmVsDvPe2KKolnZLCxhOcAKQRDDXTQaVi46lqYhIBwHTrl3oWqhMRDtaJge37lOBMKo4tfbqhVX0J7snTsWps8uZWuoOQY6CcjpSIF55UvmqNgr5wUwtV1IVdnXtnSfPEB2qjDNqnvczRl0m+j6Jn5lXb6nAQJqinmN0ZEBj03YLzghY8PnTRz80o/GRJZpOLCb0PM9BN7pvUEjx28V00WUg9jIVwAAAABJRU5ErkJggg==",
aspectRatio: 1,
src:
"/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png",
srcSet:
"/static/6d91c86c0fde632ba4cd01062fd9ccfa/69585/gatsby-astronaut.png 200w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/497c6/gatsby-astronaut.png 400w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png 800w",
srcSetWebp:
"/static/6d91c86c0fde632ba4cd01062fd9ccfa/61e93/gatsby-astronaut.webp 200w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/1f5c5/gatsby-astronaut.webp 400w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/58556/gatsby-astronaut.webp 800w",
srcWebp:
"/static/6d91c86c0fde632ba4cd01062fd9ccfa/58556/gatsby-astronaut.webp",
sizes: "(max-width: 800px) 100vw, 800px",
},
},
},
}
useStaticQuery.mockImplementation(() => data)
})
it("renders correctly", () => {
const tree = renderer.create(<Image />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -0,0 +1,26 @@
import renderer from "react-test-renderer"
import React from "react"
import * as Gatsby from "gatsby"
import Layout from "./layout"
import { LayoutDataInterface } from "../@types/components/layout"
const useStaticQuery = jest.spyOn(Gatsby, "useStaticQuery")
describe("Layout", () => {
beforeEach(() => {
const data: LayoutDataInterface = {
site: {
siteMetadata: {
title: "Gatsby Default Starter",
},
},
}
useStaticQuery.mockImplementation(() => data)
})
it("renders correctly", () => {
const tree = renderer.create(<Layout>children</Layout>).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -0,0 +1,72 @@
import renderer from "react-test-renderer"
import React from "react"
import * as Gatsby from "gatsby"
import SEO from "./seo"
import { SEODataInterface } from "../@types/components/seo"
import { Helmet } from "react-helmet"
const useStaticQuery = jest.spyOn(Gatsby, "useStaticQuery")
describe("SEO", () => {
beforeEach(() => {
const data: SEODataInterface = {
site: {
siteMetadata: {
title: "Gatsby Default Starter",
description:
"Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.",
author: "@gatsbyjs",
},
},
}
useStaticQuery.mockImplementation(() => data)
})
it("renders correctly with passed title", () => {
renderer.create(<SEO title={"test title"} />)
const helmet = Helmet.peek()
expect(helmet.title.toString()).toEqual(
`<title data-react-helmet="true">test title | Gatsby Default Starter</title>`
)
expect(helmet.meta.toString()).toEqual(
`<meta data-react-helmet="true" name="description" content="Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need."/><meta data-react-helmet="true" property="og:title" content="test title"/><meta data-react-helmet="true" property="og:description" content="Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need."/><meta data-react-helmet="true" property="og:type" content="website"/><meta data-react-helmet="true" name="twitter:card" content="summary"/><meta data-react-helmet="true" name="twitter:creator" content="@gatsbyjs"/><meta data-react-helmet="true" name="twitter:title" content="test title"/><meta data-react-helmet="true" name="twitter:description" content="Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need."/>`
)
})
it("renders correctly with passed description", () => {
renderer.create(
<SEO title={"test title"} description={"test description"} />
)
const helmet = Helmet.peek()
expect(helmet.meta.toString()).toEqual(
`<meta data-react-helmet="true" name="description" content="test description"/><meta data-react-helmet="true" property="og:title" content="test title"/><meta data-react-helmet="true" property="og:description" content="test description"/><meta data-react-helmet="true" property="og:type" content="website"/><meta data-react-helmet="true" name="twitter:card" content="summary"/><meta data-react-helmet="true" name="twitter:creator" content="@gatsbyjs"/><meta data-react-helmet="true" name="twitter:title" content="test title"/><meta data-react-helmet="true" name="twitter:description" content="test description"/>`
)
})
it("renders correctly with passed lang", () => {
renderer.create(<SEO title={"test title"} lang={"nl"} />)
const helmet = Helmet.peek()
expect(helmet.htmlAttributes.toString()).toEqual(`lang="nl"`)
})
it("renders correctly with passed meta tags", () => {
renderer.create(
<SEO
title={"test title"}
meta={[
{ name: "test name", content: "test name content" },
{ property: "test property", content: "test property content" },
]}
/>
)
const helmet = Helmet.peek()
expect(helmet.meta.toString()).toEqual(
`<meta data-react-helmet="true" name="description" content="Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need."/><meta data-react-helmet="true" property="og:title" content="test title"/><meta data-react-helmet="true" property="og:description" content="Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need."/><meta data-react-helmet="true" property="og:type" content="website"/><meta data-react-helmet="true" name="twitter:card" content="summary"/><meta data-react-helmet="true" name="twitter:creator" content="@gatsbyjs"/><meta data-react-helmet="true" name="twitter:title" content="test title"/><meta data-react-helmet="true" name="twitter:description" content="Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need."/><meta data-react-helmet="true" name="test name" content="test name content"/><meta data-react-helmet="true" property="test property" content="test property content"/>`
)
})
})

28
src/pages/404.test.tsx Normal file
View File

@ -0,0 +1,28 @@
import React from "react"
import renderer from "react-test-renderer"
import * as Gatsby from "gatsby"
import NotFoundPage from "./404"
import { SEODataInterface } from "../@types/components/seo"
const useStaticQuery = jest.spyOn(Gatsby, "useStaticQuery")
describe("NotFoundPage", () => {
beforeEach(() => {
const data: SEODataInterface = {
site: {
siteMetadata: {
title: "Gatsby Default Starter",
description:
"Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.",
author: "@gatsbyjs",
},
},
}
useStaticQuery.mockImplementation(() => data)
})
it("renders correctly", () => {
expect(renderer.create(<NotFoundPage />).toJSON()).toMatchSnapshot()
})
})

View File

@ -2,9 +2,8 @@ import React from "react"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { PageProps } from "gatsby"
const NotFoundPage: React.FC<PageProps> = () => (
const NotFoundPage: React.FC = () => (
<Layout>
<SEO title="404: Not found" />
<h1>NOT FOUND</h1>

View File

@ -0,0 +1,73 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NotFoundPage renders correctly 1`] = `
Array [
<header
style={
Object {
"background": "rebeccapurple",
"marginBottom": "1.45rem",
}
}
>
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "1.45rem 1.0875rem",
}
}
>
<h1
style={
Object {
"margin": 0,
}
}
>
<a
href="/"
style={
Object {
"color": "white",
"textDecoration": "none",
}
}
>
Gatsby Default Starter
</a>
</h1>
</div>
</header>,
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "0 1.0875rem 1.45rem",
}
}
>
<main>
<h1>
NOT FOUND
</h1>
<p>
You just hit a route that doesn't exist... the sadness.
</p>
</main>
<footer>
©
2020
, Built with
<a
href="https://www.gatsbyjs.org"
>
Gatsby
</a>
</footer>
</div>,
]
`;

View File

@ -0,0 +1,149 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`IndexPage renders correctly 1`] = `
Array [
<header
style={
Object {
"background": "rebeccapurple",
"marginBottom": "1.45rem",
}
}
>
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "1.45rem 1.0875rem",
}
}
>
<h1
style={
Object {
"margin": 0,
}
}
>
<a
href="/"
style={
Object {
"color": "white",
"textDecoration": "none",
}
}
>
Gatsby Default Starter
</a>
</h1>
</div>
</header>,
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "0 1.0875rem 1.45rem",
}
}
>
<main>
<h1>
Hi people
</h1>
<p>
Welcome to your new Gatsby site.
</p>
<p>
Now go build something great.
</p>
<div
style={
Object {
"marginBottom": "1.45rem",
"maxWidth": "300px",
}
}
>
<div
className=" gatsby-image-wrapper"
style={
Object {
"maxHeight": null,
"maxWidth": null,
"overflow": "hidden",
"position": "relative",
}
}
>
<div
aria-hidden={true}
style={
Object {
"paddingBottom": "100%",
"width": "100%",
}
}
/>
<img
alt=""
aria-hidden={true}
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsSAAALEgHS3X78AAACYklEQVQ4y42Uy28SQRjA+dM8efDmwYN6qF6qiSY+Y/WgQRMibY00TaWNBSRSCraYQtHl/bR0KyxQWCgWWAqU8izl/Sq7rLNsRHlVJpvJtzPfb77nDIOcZHSoqZSrp4+KtXIziubaLRysMCZiCYqOoVnhjNEi8RcztdxxeTzc6VBfT+5O2Vhpb+vw4wMdZ0ppWvP9xzLeJoDNThf2W+Nz1+XzNxQubSToSKKW+BDc+WOnkshhSVgeCiGpViZMEg1oxc26Knt+ae3bEtJTZwzE1kXLccG0+sOOlrcvZXvsczPkITfsa20vwIKnhsh+BnjUarT74Gb13CY7KBVJMv3z4N1NszQYsMWM62HNrCis/GxXn0iYls23uz5LPBcv0bH8hUH2XRoM85ySXv7JBtO87jMIvWq+H5GoYIHCLA1ZxD6Qap3Ak8IKfW7TJ50lK6uP9E6RgndHaODtCJ6Z5RyHfnE7j6gRbcKlCYNSt+rtETHTpUGgEP8FYmdNqd/Mo7aiVWTfuH2L9xASvfxxlqr01EYkrJszvNkgW9bH0OuFr+99m+y9IOeyU6zIp/Hubp/yMEztlzFPwOhdvq+nIoS1JNn4t2sugCmVsDvPe2KKolnZLCxhOcAKQRDDXTQaVi46lqYhIBwHTrl3oWqhMRDtaJge37lOBMKo4tfbqhVX0J7snTsWps8uZWuoOQY6CcjpSIF55UvmqNgr5wUwtV1IVdnXtnSfPEB2qjDNqnvczRl0m+j6Jn5lXb6nAQJqinmN0ZEBj03YLzghY8PnTRz80o/GRJZpOLCb0PM9BN7pvUEjx28V00WUg9jIVwAAAABJRU5ErkJggg=="
style={
Object {
"height": "100%",
"left": 0,
"objectFit": "cover",
"objectPosition": "center",
"opacity": 1,
"position": "absolute",
"top": 0,
"transitionDelay": "500ms",
"width": "100%",
}
}
/>
<noscript
dangerouslySetInnerHTML={
Object {
"__html": "<picture><source type='image/webp' srcset=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/61e93/gatsby-astronaut.webp 200w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/1f5c5/gatsby-astronaut.webp 400w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/58556/gatsby-astronaut.webp 800w\\" sizes=\\"(max-width: 800px) 100vw, 800px\\" /><source srcset=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/69585/gatsby-astronaut.png 200w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/497c6/gatsby-astronaut.png 400w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png 800w\\" sizes=\\"(max-width: 800px) 100vw, 800px\\" /><img loading=\\"lazy\\" sizes=\\"(max-width: 800px) 100vw, 800px\\" srcset=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/69585/gatsby-astronaut.png 200w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/497c6/gatsby-astronaut.png 400w,
/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png 800w\\" src=\\"/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png\\" alt=\\"\\" style=\\"position:absolute;top:0;left:0;opacity:1;width:100%;height:100%;object-fit:cover;object-position:center\\"/></picture>",
}
}
/>
</div>
</div>
<a
href="/page-2/"
>
Go to page 2
</a>
<br />
<a
href="/using-typescript/"
>
Go to "Using TypeScript"
</a>
</main>
<footer>
©
2020
, Built with
<a
href="https://www.gatsbyjs.org"
>
Gatsby
</a>
</footer>
</div>,
]
`;

View File

@ -0,0 +1,78 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SecondPage renders correctly 1`] = `
Array [
<header
style={
Object {
"background": "rebeccapurple",
"marginBottom": "1.45rem",
}
}
>
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "1.45rem 1.0875rem",
}
}
>
<h1
style={
Object {
"margin": 0,
}
}
>
<a
href="/"
style={
Object {
"color": "white",
"textDecoration": "none",
}
}
>
Gatsby Default Starter
</a>
</h1>
</div>
</header>,
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "0 1.0875rem 1.45rem",
}
}
>
<main>
<h1>
Hi from the second page
</h1>
<p>
Welcome to page 2
</p>
<a
href="/"
>
Go back to the homepage
</a>
</main>
<footer>
©
2020
, Built with
<a
href="https://www.gatsbyjs.org"
>
Gatsby
</a>
</footer>
</div>,
]
`;

View File

@ -0,0 +1,119 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NotFoundPage renders correctly 1`] = `
Array [
<header
style={
Object {
"background": "rebeccapurple",
"marginBottom": "1.45rem",
}
}
>
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "1.45rem 1.0875rem",
}
}
>
<h1
style={
Object {
"margin": 0,
}
}
>
<a
href="/"
style={
Object {
"color": "white",
"textDecoration": "none",
}
}
>
Gatsby Default Starter
</a>
</h1>
</div>
</header>,
<div
style={
Object {
"margin": "0 auto",
"maxWidth": 960,
"padding": "0 1.0875rem 1.45rem",
}
}
>
<main>
<h1>
Gatsby supports TypeScript by default!
</h1>
<p>
This means that you can create and write
<em>
.ts/.tsx
</em>
files for your pages, components etc. Please note that the
<em>
gatsby-*.js
</em>
files (like gatsby-node.js) currently don't support TypeScript yet.
</p>
<p>
For type checking you'll want to install
<em>
typescript
</em>
via npm and run
<em>
tsc --init
</em>
to create a
<em>
.tsconfig
</em>
file.
</p>
<p>
You're currently on the page "
/path
" which was built on
2020-06-04T09:48:20.000Z
.
</p>
<p>
To learn more, head over to our
<a
href="https://www.gatsbyjs.org/docs/typescript/"
>
documentation about TypeScript
</a>
.
</p>
<a
href="/"
>
Go back to the homepage
</a>
</main>
<footer>
©
2020
, Built with
<a
href="https://www.gatsbyjs.org"
>
Gatsby
</a>
</footer>
</div>,
]
`;

49
src/pages/index.test.tsx Normal file
View File

@ -0,0 +1,49 @@
import React from "react"
import renderer from "react-test-renderer"
import * as Gatsby from "gatsby"
import IndexPage from "./index"
import { SEODataInterface } from "../@types/components/seo"
import { ImageDataInterface } from "../@types/components/image"
interface DataInterface extends SEODataInterface, ImageDataInterface {}
const useStaticQuery = jest.spyOn(Gatsby, "useStaticQuery")
describe("IndexPage", () => {
beforeEach(() => {
const data: DataInterface = {
site: {
siteMetadata: {
title: "Gatsby Default Starter",
description:
"Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.",
author: "@gatsbyjs",
},
},
placeholderImage: {
childImageSharp: {
fluid: {
base64:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsSAAALEgHS3X78AAACYklEQVQ4y42Uy28SQRjA+dM8efDmwYN6qF6qiSY+Y/WgQRMibY00TaWNBSRSCraYQtHl/bR0KyxQWCgWWAqU8izl/Sq7rLNsRHlVJpvJtzPfb77nDIOcZHSoqZSrp4+KtXIziubaLRysMCZiCYqOoVnhjNEi8RcztdxxeTzc6VBfT+5O2Vhpb+vw4wMdZ0ppWvP9xzLeJoDNThf2W+Nz1+XzNxQubSToSKKW+BDc+WOnkshhSVgeCiGpViZMEg1oxc26Knt+ae3bEtJTZwzE1kXLccG0+sOOlrcvZXvsczPkITfsa20vwIKnhsh+BnjUarT74Gb13CY7KBVJMv3z4N1NszQYsMWM62HNrCis/GxXn0iYls23uz5LPBcv0bH8hUH2XRoM85ySXv7JBtO87jMIvWq+H5GoYIHCLA1ZxD6Qap3Ak8IKfW7TJ50lK6uP9E6RgndHaODtCJ6Z5RyHfnE7j6gRbcKlCYNSt+rtETHTpUGgEP8FYmdNqd/Mo7aiVWTfuH2L9xASvfxxlqr01EYkrJszvNkgW9bH0OuFr+99m+y9IOeyU6zIp/Hubp/yMEztlzFPwOhdvq+nIoS1JNn4t2sugCmVsDvPe2KKolnZLCxhOcAKQRDDXTQaVi46lqYhIBwHTrl3oWqhMRDtaJge37lOBMKo4tfbqhVX0J7snTsWps8uZWuoOQY6CcjpSIF55UvmqNgr5wUwtV1IVdnXtnSfPEB2qjDNqnvczRl0m+j6Jn5lXb6nAQJqinmN0ZEBj03YLzghY8PnTRz80o/GRJZpOLCb0PM9BN7pvUEjx28V00WUg9jIVwAAAABJRU5ErkJggg==",
aspectRatio: 1,
src:
"/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png",
srcSet:
"/static/6d91c86c0fde632ba4cd01062fd9ccfa/69585/gatsby-astronaut.png 200w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/497c6/gatsby-astronaut.png 400w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png 800w",
srcSetWebp:
"/static/6d91c86c0fde632ba4cd01062fd9ccfa/61e93/gatsby-astronaut.webp 200w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/1f5c5/gatsby-astronaut.webp 400w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/58556/gatsby-astronaut.webp 800w",
srcWebp:
"/static/6d91c86c0fde632ba4cd01062fd9ccfa/58556/gatsby-astronaut.webp",
sizes: "(max-width: 800px) 100vw, 800px",
},
},
},
}
useStaticQuery.mockImplementation(() => data)
})
it("renders correctly", () => {
expect(renderer.create(<IndexPage />).toJSON()).toMatchSnapshot()
})
})

View File

@ -1,11 +1,11 @@
import React from "react"
import { Link, PageProps } from "gatsby"
import { Link } from "gatsby"
import Layout from "../components/layout"
import Image from "../components/image"
import SEO from "../components/seo"
const IndexPage: React.FC<PageProps> = () => (
const IndexPage: React.FC = () => (
<Layout>
<SEO title="Home" />
<h1>Hi people</h1>

28
src/pages/page-2.test.tsx Normal file
View File

@ -0,0 +1,28 @@
import React from "react"
import renderer from "react-test-renderer"
import * as Gatsby from "gatsby"
import { SEODataInterface } from "../@types/components/seo"
import SecondPage from "./page-2"
const useStaticQuery = jest.spyOn(Gatsby, "useStaticQuery")
describe("SecondPage", () => {
beforeEach(() => {
const data: SEODataInterface = {
site: {
siteMetadata: {
title: "Gatsby Default Starter",
description:
"Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.",
author: "@gatsbyjs",
},
},
}
useStaticQuery.mockImplementation(() => data)
})
it("renders correctly", () => {
expect(renderer.create(<SecondPage />).toJSON()).toMatchSnapshot()
})
})

View File

@ -1,10 +1,10 @@
import React from "react"
import { Link, PageProps } from "gatsby"
import { Link } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"
const SecondPage: React.FC<PageProps> = () => (
const SecondPage: React.FC = () => (
<Layout>
<SEO title="Page two" />
<h1>Hi from the second page</h1>

View File

@ -0,0 +1,41 @@
import React from "react"
import renderer from "react-test-renderer"
import UsingTypescript from "./using-typescript"
import { UsingTypescriptDataInterface } from "../@types/pages/using-typescript"
import { SEODataInterface } from "../@types/components/seo"
import * as Gatsby from "gatsby"
const useStaticQuery = jest.spyOn(Gatsby, "useStaticQuery")
describe("NotFoundPage", () => {
beforeEach(() => {
const data: SEODataInterface = {
site: {
siteMetadata: {
title: "Gatsby Default Starter",
description:
"Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.",
author: "@gatsbyjs",
},
},
}
useStaticQuery.mockImplementation(() => data)
})
it("renders correctly", () => {
const data: UsingTypescriptDataInterface = {
data: {
site: {
buildTime: "2020-06-04T09:48:20.000Z",
},
},
}
expect(
renderer
.create(<UsingTypescript data={data.data} path={"/path"} />)
.toJSON()
).toMatchSnapshot()
})
})

View File

@ -1,17 +1,15 @@
// If you don't want to use TypeScript you can delete this file!
import React from "react"
import { PageProps, Link, graphql } from "gatsby"
import { Link, graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { UsingTypescriptInterface } from "../@types/pages/using-typescript"
type DataProps = {
site: {
buildTime: string
}
}
const UsingTypescript: React.FC<PageProps<DataProps>> = ({ data, path }) => (
const UsingTypescript: React.FC<UsingTypescriptInterface> = ({
data,
path,
}) => (
<Layout>
<SEO title="Using TypeScript" />
<h1>Gatsby supports TypeScript by default!</h1>

View File

@ -19,7 +19,7 @@
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
"noEmit": true /* Do not emit outputs. */,
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
@ -35,7 +35,7 @@
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
"noUnusedLocals": true /* Report errors on unused locals. */,
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
@ -66,6 +66,6 @@
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true,
/* Disallow inconsistently-cased references to the same file. */
"jsx": "react"
"jsx": "preserve"
}
}

1412
yarn.lock

File diff suppressed because it is too large Load Diff