Skip to content

Commit 46b88e6

Browse files
authored
Set up jest (#69)
* πŸ›  install jest * πŸ§ͺ add an example test * πŸ›  run tests in CI * πŸ› add missing GitHub actions property runs-on * πŸ› add checkout step to test job * πŸ› install dependencies before running test script * πŸ›  set up jest for gatsby + typescript * πŸ§ͺ stub example mocks + tests * 🧹 extract utility function * πŸ›  lock upgraded node version
1 parent 8454821 commit 46b88e6

File tree

13 files changed

+3219
-394
lines changed

13 files changed

+3219
-394
lines changed

β€Ž.github/workflows/ci.ymlβ€Ž

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,13 @@ jobs:
1515
run: npm run lint
1616
- name: Format all files
1717
run: npm run format
18+
19+
test:
20+
name: Test
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v1
24+
- name: Install dependencies
25+
run: npm install
26+
- name: Run tests
27+
run: npm run test

β€Ž.nvmrcβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v12.6.0
1+
v13.2.0

β€Ž__mocks__/file-mock.jsβ€Ž

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// See: https://www.gatsbyjs.org/docs/unit-testing/#2-creating-a-configuration-file-for-jest
2+
3+
module.exports = 'test-file-stub'

β€Ž__mocks__/gatsby.jsβ€Ž

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// See: https://www.gatsbyjs.org/docs/unit-testing/#3-useful-mocks-to-complete-your-testing-environment
2+
3+
const React = require('react')
4+
const gatsby = jest.requireActual('gatsby')
5+
6+
module.exports = {
7+
...gatsby,
8+
graphql: jest.fn(),
9+
Link: jest.fn().mockImplementation(
10+
// these props are invalid for an `a` tag
11+
({
12+
activeClassName,
13+
activeStyle,
14+
getProps,
15+
innerRef,
16+
partiallyActive,
17+
ref,
18+
replace,
19+
to,
20+
...rest
21+
}) =>
22+
React.createElement('a', {
23+
...rest,
24+
href: to,
25+
})
26+
),
27+
StaticQuery: jest.fn(),
28+
useStaticQuery: jest.fn(),
29+
}

β€Ž__mocks__/tutorials.jsβ€Ž

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
3+
TODO: mock tutorials as they come from YAML
4+
TODO: mock tutorials as they come from gatsby-node
5+
6+
*/
7+
8+
module.exports = {
9+
tutorials: [
10+
{
11+
authors: ['Owlypixel'],
12+
date: 'Nov 22, 2019',
13+
fields: {
14+
authorsAsString: 'owlypixel',
15+
formatsAsString: 'text',
16+
topicsAsString: 'themes mdx guitar',
17+
},
18+
formats: ['text'],
19+
link: 'https://owlypixel.com/building-gatsbyjs-theme-from-scratch/',
20+
source: 'owlypixel.com',
21+
title: 'How to Build a GatsbyJS Guitar-Chords-MDX Theme From Scratch',
22+
topics: ['guitar', 'mdx', 'themes'],
23+
},
24+
],
25+
}

β€Žgatsby-node.jsβ€Ž

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
// 1. Generate string versions of tutorial array fields for faster search
22
///////////////////////////////////////////////////////////////////////////////////
33

4+
// TODO: unit test this utility
5+
function convertArrayToString(array) {
6+
return array ? array.join(` `).toLowerCase() : ``
7+
}
8+
49
exports.onCreateNode = ({ node, actions }) => {
510
const { createNodeField } = actions
611

712
if (node.internal.type === 'TutorialsYaml') {
813
createNodeField({
914
node,
1015
name: `formatsAsString`,
11-
value: node.formats ? node.formats.join(` `).toLowerCase() : ``,
16+
value: convertArrayToString(node.formats),
1217
})
1318

1419
createNodeField({
1520
node,
1621
name: `topicsAsString`,
17-
value: node.topics ? node.topics.join(` `).toLowerCase() : ``,
22+
value: convertArrayToString(node.topics),
1823
})
1924

2025
createNodeField({
2126
node,
2227
name: `authorsAsString`,
23-
value: node.authors ? node.authors.join(` `).toLowerCase() : ``,
28+
value: convertArrayToString(node.authors),
2429
})
2530
}
2631
}
@@ -90,6 +95,8 @@ exports.createPages = async ({ graphql, reporter }) => {
9095
const { tutorialsWithDates, tutorialsWithoutDates } = result.data
9196
const tutorials = [...tutorialsWithDates.nodes, ...tutorialsWithoutDates.nodes]
9297

98+
// TODO: extract repeated patterns into utilities and test them...
99+
93100
// Create a sorted list of all unique formats
94101
const formatArrays = tutorials.map(tutorial => tutorial.formats)
95102
const formats = [

β€Žjest-preprocess.jsβ€Ž

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// See: https://www.gatsbyjs.org/docs/unit-testing/#2-creating-a-configuration-file-for-jest
2+
3+
const babelOptions = {
4+
presets: ['babel-preset-gatsby'],
5+
}
6+
7+
module.exports = require('babel-jest').createTransformer(babelOptions)

β€Žjest.config.jsβ€Ž

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// See: https://www.gatsbyjs.org/docs/unit-testing/
2+
3+
module.exports = {
4+
transform: {
5+
'^.+\\.tsx?$': 'ts-jest',
6+
'^.+\\.jsx?$': '<rootDir>/jest-preprocess.js',
7+
},
8+
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.([tj]sx?)$',
9+
moduleNameMapper: {
10+
'.+\\.(css|styl|less|sass|scss)$': 'identity-obj-proxy',
11+
'.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
12+
'<rootDir>/__mocks__/file-mock.js',
13+
},
14+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
15+
testEnvironment: 'jest-environment-jsdom',
16+
testPathIgnorePatterns: ['node_modules', '.cache', 'public'],
17+
transformIgnorePatterns: ['node_modules/(?!(gatsby)/)'],
18+
globals: {
19+
__PATH_PREFIX__: '',
20+
},
21+
setupFiles: ['<rootDir>/loadershim.js'],
22+
}

β€Žloadershim.jsβ€Ž

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
global.___loader = {
2+
enqueue: jest.fn(),
3+
}

0 commit comments

Comments
Β (0)