-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
df9b0ac
commit 5314d0c
Showing
7 changed files
with
423 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ test-results.json | |
package-lock.json | ||
yarn.lock | ||
|
||
gatsby* | ||
/gatsby* | ||
!index.js | ||
yarn.lock | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { onClientEntry } from '../gatsby-browser'; | ||
import GSCMock from '../.cache/GlobalStyleComponent'; | ||
import themeMock from '../.cache/GlobalStylePropsTheme'; | ||
import otherMock from '../.cache/GlobalStylePropsOther'; | ||
|
||
jest.mock( | ||
`../.cache/GlobalStyleComponent`, | ||
() => { | ||
return { | ||
globalStyle: { | ||
renderStyles: jest.fn(), | ||
elementId: 'GlobalStyle', | ||
}, | ||
}; | ||
}, | ||
{ virtual: true } | ||
); | ||
|
||
jest.mock( | ||
`../.cache/GlobalStylePropsTheme`, | ||
() => { | ||
return { typography: { fontFamily: 'Roboto' } }; | ||
}, | ||
{ virtual: true } | ||
); | ||
|
||
jest.mock( | ||
`../.cache/GlobalStylePropsOther`, | ||
() => { | ||
return { light: true }; | ||
}, | ||
{ virtual: true } | ||
); | ||
|
||
describe(`onClientEntry`, () => { | ||
beforeEach(() => { | ||
process.env.BUILD_STAGE = `develop`; | ||
}); | ||
|
||
afterAll(() => { | ||
delete process.env.BUILD_STAGE; | ||
}); | ||
|
||
beforeEach(() => { | ||
// Completely restes mock back to initial value, including all information | ||
// stored in mockFn.mock.calls and mockFn.mock.instances arrays, | ||
// as well as any mocked return values or implementations. | ||
// Replaces mockFn.mock (not just mockFn.mock.calls and mockFn.mock.instances) | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
it(`should inject CSS rules`, () => { | ||
// onClientEntry comes from a different copy of gatsby-browser, | ||
// compared to the other tests. This is due to jest.resetModules(). | ||
onClientEntry(); | ||
|
||
expect(GSCMock.globalStyle.renderStyles).toHaveBeenCalledWith( | ||
expect.objectContaining({ theme: themeMock, ...otherMock }) | ||
); | ||
}); | ||
|
||
it('should not run if BUILD_STAGE is not develop', () => { | ||
process.env.BUILD_STAGE = `build-html`; | ||
onClientEntry(); | ||
expect(GSCMock.globalStyle.renderStyles).not.toHaveBeenCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import path from 'path'; | ||
import rimraf from 'rimraf'; | ||
import os from 'os'; | ||
import * as gatsbyNode from '../gatsby-node'; | ||
|
||
const onPreBootstrapMock = jest.spyOn(gatsbyNode, 'onPreBootstrap'); | ||
|
||
const rootDir = path.join(__dirname, '../..'); | ||
const store = { store: { getState: () => ({ program: { directory: rootDir } }) } }; | ||
|
||
jest.mock('os', () => { | ||
return { | ||
platform: jest.fn(() => 'win32'), | ||
}; | ||
}); | ||
|
||
let options; | ||
let emptyOptions; | ||
|
||
describe('gatsby-node.js', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
|
||
options = { | ||
pathToConfigModule: `src/styles/GlobalStyleComponent`, | ||
props: { | ||
theme: `src/styles/theme`, | ||
other: { | ||
light: true, | ||
}, | ||
}, | ||
}; | ||
|
||
emptyOptions = { | ||
pathToConfigModule: ``, | ||
props: {}, | ||
}; | ||
}); | ||
|
||
afterAll(done => { | ||
rimraf(path.join(rootDir, `/src/.cache`), () => { | ||
done(); | ||
}); | ||
}); | ||
|
||
it('Can create cache when none exist', done => { | ||
const dir = path.join(rootDir, `/src/.cache`); | ||
rimraf(dir, () => { | ||
onPreBootstrapMock(store, emptyOptions); | ||
expect(onPreBootstrapMock).toHaveBeenCalledWith(store, emptyOptions); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('can create cache when options are passed in', () => { | ||
onPreBootstrapMock(store, options); | ||
expect(onPreBootstrapMock).toHaveBeenCalledWith(store, options); | ||
}); | ||
|
||
it('options can use absolute paths', () => { | ||
const configDir = path.join(rootDir, `src/styles/GlobalStyleComponent`); | ||
const themeDir = path.join(rootDir, `src/styles/theme`); | ||
options.pathToConfigModule = configDir; | ||
options.props.theme = themeDir; | ||
onPreBootstrapMock(store, options); | ||
expect(onPreBootstrapMock).toHaveBeenCalledWith(store, options); | ||
}); | ||
|
||
it('can run on different platforms', () => { | ||
os.platform.mockReturnValue('linux'); | ||
onPreBootstrapMock(store, options); | ||
expect(onPreBootstrapMock).toHaveBeenCalledWith(store, options); | ||
}); | ||
|
||
it('can create cache when no options are passed in', () => { | ||
onPreBootstrapMock(store, emptyOptions); | ||
expect(onPreBootstrapMock).toHaveBeenCalledWith(store, emptyOptions); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import React from 'react'; | ||
import { onPreRenderHTML, onRenderBody } from '../gatsby-ssr'; | ||
|
||
jest.mock( | ||
`../.cache/GlobalStyleComponent`, | ||
() => { | ||
return { | ||
globalStyle: { | ||
ReactStyleComponent: () => <style />, | ||
elementId: 'GlobalStyle', | ||
}, | ||
}; | ||
}, | ||
{ virtual: true } | ||
); | ||
|
||
jest.mock( | ||
`../.cache/GlobalStylePropsTheme`, | ||
() => { | ||
return { typography: { fontFamily: 'Roboto' } }; | ||
}, | ||
{ virtual: true } | ||
); | ||
|
||
jest.mock( | ||
`../.cache/GlobalStylePropsOther`, | ||
() => { | ||
return { light: true }; | ||
}, | ||
{ virtual: true } | ||
); | ||
|
||
// Clone and merge array of multiple arrays into one flat array (flattens array) | ||
const clone = arr => [...arr]; | ||
|
||
describe(`onRenderBody`, () => { | ||
const setup = (options = {}, env = `build-html`) => { | ||
process.env.BUILD_STAGE = env; | ||
const api = { | ||
setHeadComponents: jest.fn(), | ||
}; | ||
onRenderBody(api, options); | ||
return api; | ||
}; | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
afterAll(() => { | ||
delete process.env.BUILD_STAGE; | ||
}); | ||
|
||
it(`invokes setHeadComponents with array containing GlobalStyleComponent`, () => { | ||
const api = setup(); | ||
|
||
expect(api.setHeadComponents).toHaveBeenCalledWith([ | ||
expect.objectContaining({ key: expect.stringContaining('GlobalStyle') }), | ||
]); | ||
}); | ||
|
||
it(`only invokes setHeadComponents if BUILD_STAGE is build-html`, () => { | ||
const api = setup({}, `develop`); | ||
|
||
expect(api.setHeadComponents).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
describe(`onPreRenderHTML`, () => { | ||
const setup = (components = []) => { | ||
const api = { | ||
getHeadComponents: jest.fn(() => components), | ||
replaceHeadComponents: jest.fn(), | ||
}; | ||
onPreRenderHTML(api); | ||
return api; | ||
}; | ||
|
||
it(`reorders GlobalStyle first`, () => { | ||
const spies = setup([ | ||
{ | ||
key: `link-1234`, | ||
}, | ||
{ | ||
key: `link-preload`, | ||
}, | ||
{ | ||
key: `GlobalStyle`, | ||
}, | ||
]); | ||
|
||
expect(spies.replaceHeadComponents).toHaveBeenCalledTimes(1); | ||
expect(spies.replaceHeadComponents).toHaveBeenCalledWith( | ||
expect.arrayContaining([ | ||
{ | ||
key: `GlobalStyle`, | ||
}, | ||
]) | ||
); | ||
}); | ||
|
||
it(`leaves non-GlobalStyle head components as-is`, () => { | ||
const components = [ | ||
{ | ||
key: `link-1234`, | ||
}, | ||
{ | ||
key: `link-preload`, | ||
}, | ||
{ | ||
key: `_____01234_____`, | ||
}, | ||
]; | ||
|
||
const spies = setup(clone(components)); | ||
|
||
// Check that it did not reorder when GlobalStyle was not in list | ||
// Component list Clone which we ran reorder on, should be identical to original component list | ||
expect(spies.replaceHeadComponents).toHaveBeenCalledWith(components); | ||
}); | ||
|
||
it(`does not fail when head components include null`, () => { | ||
const components = [ | ||
{ | ||
key: `link-1234`, | ||
}, | ||
{ | ||
key: `link-preload`, | ||
}, | ||
{ | ||
key: `_____01234_____`, | ||
}, | ||
null, | ||
]; | ||
|
||
const spies = setup(clone(components)); | ||
|
||
expect(spies.replaceHeadComponents).toHaveBeenCalledWith(components); | ||
expect(spies.replaceHeadComponents).toHaveReturned(); | ||
}); | ||
}); | ||
|
||
/* | ||
describe(`onRenderBody`, () => { | ||
it(`injects theme if theme is passed`); | ||
it(`uses default theme if no theme is passed.`); | ||
it(`injects other props if any are passed`); | ||
}); | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Hot reload gatsby-plugin-global-styles in development | ||
|
||
import GlobalStyleComponent from './.cache/GlobalStyleComponent'; | ||
import GlobalStylePropsTheme from './.cache/GlobalStylePropsTheme'; | ||
import GlobalStylePropsOther from './.cache/GlobalStylePropsOther'; | ||
|
||
// eslint-disable-next-line import/prefer-default-export | ||
export const onClientEntry = () => { | ||
if (process.env.BUILD_STAGE === `develop`) { | ||
GlobalStyleComponent.globalStyle.renderStyles({ | ||
theme: GlobalStylePropsTheme, | ||
...GlobalStylePropsOther, | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import os from 'os'; | ||
|
||
// Write out the GlobalStyleComponent module to .cache. | ||
// Happens before webpack starts compiling page. | ||
// .cache is available when gatsby-browser.js and gatsby-ssr.js runs. | ||
|
||
// eslint-disable-next-line import/prefer-default-export | ||
export const onPreBootstrap = ({ store }, pluginOptions) => { | ||
const { program } = store.getState(); | ||
|
||
let module; | ||
if (pluginOptions.pathToConfigModule) { | ||
module = `import GlobalStyleComponent from "${ | ||
path.isAbsolute(pluginOptions.pathToConfigModule) | ||
? pluginOptions.pathToConfigModule | ||
: path.join(program.directory, pluginOptions.pathToConfigModule) | ||
}"; | ||
export default GlobalStyleComponent; | ||
`; | ||
|
||
if (os.platform() === `win32`) { | ||
module = module.split(`\\`).join(`\\\\`); | ||
} | ||
} else { | ||
module = `import createGlobalStyle from 'global-styles'; | ||
const GlobalStyleComponent = createGlobalStyle\`\`; | ||
export default GlobalStyleComponent; | ||
`; | ||
} | ||
|
||
const dir = `${__dirname}/.cache`; | ||
|
||
if (!fs.existsSync(dir)) { | ||
fs.mkdirSync(dir); | ||
} | ||
|
||
fs.writeFileSync(`${dir}/GlobalStyleComponent.js`, module); | ||
|
||
// Write Props.theme to cache. | ||
if (pluginOptions.props.theme) { | ||
module = `import theme from "${ | ||
path.isAbsolute(pluginOptions.props.theme) | ||
? pluginOptions.props.theme | ||
: path.join(program.directory, pluginOptions.props.theme) | ||
}"; | ||
export default theme; | ||
`; | ||
|
||
if (os.platform() === `win32`) { | ||
module = module.split(`\\`).join(`\\\\`); | ||
} | ||
} else { | ||
module = `const defaultTheme = { typography: { fontFamily: 'Arial' } }; | ||
export default defaultTheme; | ||
`; | ||
} | ||
|
||
fs.writeFileSync(`${dir}/GlobalStylePropsTheme.js`, module); | ||
|
||
// Write Props.other to cache. | ||
if (pluginOptions.props.other) { | ||
module = `const otherProps = ${JSON.stringify(pluginOptions.props.other)}; | ||
export default otherProps; | ||
`; | ||
} else { | ||
module = `const emptyOtherProps = {}; | ||
export default emptyOtherProps; | ||
`; | ||
} | ||
|
||
fs.writeFileSync(`${dir}/GlobalStylePropsOther.js`, module); | ||
}; |
Oops, something went wrong.