diff --git a/.circleci/config.yml b/.circleci/config.yml index cff7048af7b10..2a8842c08ba70 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -205,12 +205,16 @@ jobs: unit_tests_node10: executor: node + environment: + FORCE_COLOR: 0 <<: *test_template unit_tests_node12: executor: name: node image: "12" + environment: + FORCE_COLOR: 0 <<: *test_template unit_tests_www: diff --git a/packages/gatsby-recipes/README.md b/packages/gatsby-recipes/README.md index cc1142911eceb..20e9f0373e780 100644 --- a/packages/gatsby-recipes/README.md +++ b/packages/gatsby-recipes/README.md @@ -134,7 +134,9 @@ Soon will support options. #### `` +```jsx +``` ##### props diff --git a/packages/gatsby-recipes/src/providers/fs/__snapshots__/file.test.js.snap b/packages/gatsby-recipes/src/providers/fs/__snapshots__/file.test.js.snap new file mode 100644 index 0000000000000..9bb3a5175fed4 --- /dev/null +++ b/packages/gatsby-recipes/src/providers/fs/__snapshots__/file.test.js.snap @@ -0,0 +1,225 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`file resource e2e file resource test: File create 1`] = ` +Object { + "_message": "Wrote file file.txt", + "content": "Hello, world!", + "id": "file.txt", + "path": "file.txt", +} +`; + +exports[`file resource e2e file resource test: File create plan 1`] = ` +Object { + "currentState": "", + "describe": "Write file.txt", + "diff": "- Original - 0 ++ Modified + 1 + ++ Hello, world!", + "newState": "Hello, world!", +} +`; + +exports[`file resource e2e file resource test: File destroy 1`] = ` +Object { + "_message": "Wrote file file.txt", + "content": "Hello, world!1", + "id": "file.txt", + "path": "file.txt", +} +`; + +exports[`file resource e2e file resource test: File update 1`] = ` +Object { + "_message": "Wrote file file.txt", + "content": "Hello, world!1", + "id": "file.txt", + "path": "file.txt", +} +`; + +exports[`file resource e2e file resource test: File update plan 1`] = ` +Object { + "currentState": "Hello, world!", + "describe": "Write file.txt", + "diff": "- Original - 1 ++ Modified + 1 + +- Hello, world! ++ Hello, world!1", + "newState": "Hello, world!1", +} +`; + +exports[`file resource e2e remote file resource test: File create 1`] = ` +Object { + "_message": "Wrote file file.txt", + "content": "query { + allGatsbyPlugin { + nodes { + name + options + resolvedOptions + package { + version + } + ... on GatsbyTheme { + files { + nodes { + path + } + } + shadowedFiles { + nodes { + path + } + } + } + } + } +}", + "id": "file.txt", + "path": "file.txt", +} +`; + +exports[`file resource e2e remote file resource test: File create plan 1`] = ` +Object { + "currentState": "", + "describe": "Write file.txt", + "diff": "- Original - 0 ++ Modified + 24 + ++ query { ++ allGatsbyPlugin { ++ nodes { ++ name ++ options ++ resolvedOptions ++ package { ++ version ++ } ++ ... on GatsbyTheme { ++ files { ++ nodes { ++ path ++ } ++ } ++ shadowedFiles { ++ nodes { ++ path ++ } ++ } ++ } ++ } ++ } ++ }", + "newState": "query { + allGatsbyPlugin { + nodes { + name + options + resolvedOptions + package { + version + } + ... on GatsbyTheme { + files { + nodes { + path + } + } + shadowedFiles { + nodes { + path + } + } + } + } + } +}", +} +`; + +exports[`file resource e2e remote file resource test: File destroy 1`] = ` +Object { + "_message": "Wrote file file.txt", + "content": "https://gist.githubusercontent.com/KyleAMathews/3d763491e5c4c6396e1a6a626b2793ce/raw/545120bfecbe7b0f97f6f021801bc8b6370b5b41/gistfile2.txt", + "id": "file.txt", + "path": "file.txt", +} +`; + +exports[`file resource e2e remote file resource test: File update 1`] = ` +Object { + "_message": "Wrote file file.txt", + "content": "https://gist.githubusercontent.com/KyleAMathews/3d763491e5c4c6396e1a6a626b2793ce/raw/545120bfecbe7b0f97f6f021801bc8b6370b5b41/gistfile2.txt", + "id": "file.txt", + "path": "file.txt", +} +`; + +exports[`file resource e2e remote file resource test: File update plan 1`] = ` +Object { + "currentState": "query { + allGatsbyPlugin { + nodes { + name + options + resolvedOptions + package { + version + } + ... on GatsbyTheme { + files { + nodes { + path + } + } + shadowedFiles { + nodes { + path + } + } + } + } + } +}", + "describe": "Write file.txt", + "diff": "- Original - 23 ++ Modified + 3 + +- query { +- allGatsbyPlugin { +- nodes { +- name +- options +- resolvedOptions +- package { +- version +- } +- ... on GatsbyTheme { +- files { +- nodes { +- path +- } +- } +- shadowedFiles { +- nodes { +- path +- } +- } +- } +- } +- } ++ const options = { ++ key: process.env.WHATEVER ++ + }", + "newState": "const options = { + key: process.env.WHATEVER + +}", +} +`; diff --git a/packages/gatsby-recipes/src/providers/gatsby/__snapshots__/plugin.test.js.snap b/packages/gatsby-recipes/src/providers/gatsby/__snapshots__/plugin.test.js.snap new file mode 100644 index 0000000000000..3278b248d12e3 --- /dev/null +++ b/packages/gatsby-recipes/src/providers/gatsby/__snapshots__/plugin.test.js.snap @@ -0,0 +1,412 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`gatsby-plugin resource e2e plugin resource test with hello world starter: GatsbyPlugin create 1`] = ` +Object { + "_message": "Installed gatsby-plugin-foo in gatsby-config.js", + "id": "gatsby-plugin-foo", + "name": "gatsby-plugin-foo", +} +`; + +exports[`gatsby-plugin resource e2e plugin resource test with hello world starter: GatsbyPlugin create plan 1`] = ` +Object { + "currentState": "/** + * Configure your Gatsby site with this file. + * + * See: https://www.gatsbyjs.org/docs/gatsby-config/ + */ +module.exports = { + /* Your site config here */ + plugins: [], +} +", + "describe": "Install gatsby-plugin-foo in gatsby-config.js", + "diff": "- Original - 1 ++ Modified + 1 + +@@ -5,6 +5,6 @@ + */ + module.exports = { + /* Your site config here */ +- plugins: [], ++ plugins: [\\"gatsby-plugin-foo\\"], + } +", + "id": "gatsby-plugin-foo", + "name": "gatsby-plugin-foo", + "newState": "/** + * Configure your Gatsby site with this file. + * + * See: https://www.gatsbyjs.org/docs/gatsby-config/ + */ +module.exports = { + /* Your site config here */ + plugins: [\\"gatsby-plugin-foo\\"], +} +", +} +`; + +exports[`gatsby-plugin resource e2e plugin resource test with hello world starter: GatsbyPlugin destroy 1`] = `undefined`; + +exports[`gatsby-plugin resource e2e plugin resource test with hello world starter: GatsbyPlugin update 1`] = ` +Object { + "_message": "Installed gatsby-plugin-foo in gatsby-config.js", + "id": "gatsby-plugin-foo", + "name": "gatsby-plugin-foo", +} +`; + +exports[`gatsby-plugin resource e2e plugin resource test with hello world starter: GatsbyPlugin update plan 1`] = ` +Object { + "currentState": "/** + * Configure your Gatsby site with this file. + * + * See: https://www.gatsbyjs.org/docs/gatsby-config/ + */ +module.exports = { + /* Your site config here */ + plugins: [\\"gatsby-plugin-foo\\"], +} +", + "describe": "Install gatsby-plugin-foo in gatsby-config.js", + "diff": "Compared values have no visual difference.", + "id": "gatsby-plugin-foo", + "name": "gatsby-plugin-foo", + "newState": "/** + * Configure your Gatsby site with this file. + * + * See: https://www.gatsbyjs.org/docs/gatsby-config/ + */ +module.exports = { + /* Your site config here */ + plugins: [\\"gatsby-plugin-foo\\"], +} +", +} +`; + +exports[`gatsby-plugin resource e2e plugin resource test: GatsbyPlugin create 1`] = ` +Object { + "_message": "Installed gatsby-plugin-foo in gatsby-config.js", + "id": "gatsby-plugin-foo", + "name": "gatsby-plugin-foo", +} +`; + +exports[`gatsby-plugin resource e2e plugin resource test: GatsbyPlugin create plan 1`] = ` +Object { + "currentState": "const redish = \`#c5484d\` +module.exports = { + siteMetadata: { + title: \`Bricolage\`, + author: \`Kyle Mathews\`, + homeCity: \`San Francisco\`, + }, + plugins: [ + { + resolve: \`gatsby-source-filesystem\`, + options: { + path: \`\${__dirname}/src/pages\`, + name: \`pages\`, + }, + }, + \`gatsby-transformer-sharp\`, + \`gatsby-plugin-emotion\`, + { + resolve: \`gatsby-plugin-typography\`, + options: { + pathToConfigModule: \`src/utils/typography\`, + }, + }, + { + resolve: \`gatsby-transformer-remark\`, + options: { + plugins: [ + { + resolve: \`gatsby-remark-images\`, + options: { + maxWidth: 590, + }, + }, + { + resolve: \`gatsby-remark-responsive-iframe\`, + options: { + wrapperStyle: \`margin-bottom: 1.0725rem\`, + }, + }, + \`gatsby-remark-prismjs\`, + \`gatsby-remark-copy-linked-files\`, + \`gatsby-remark-smartypants\`, + ], + }, + }, + \`gatsby-plugin-sharp\`, + { + resolve: \`gatsby-plugin-google-analytics\`, + options: { + trackingId: \`UA-774017-3\`, + }, + }, + { + resolve: \`gatsby-plugin-manifest\`, + options: { + name: \`Bricolage\`, + short_name: \`Bricolage\`, + icon: \`static/logo.png\`, + start_url: \`/\`, + background_color: redish, + theme_color: redish, + display: \`minimal-ui\`, + }, + }, + \`gatsby-plugin-offline\`, // \`gatsby-plugin-preact\`, + \`gatsby-plugin-react-helmet\`, + ], +} +", + "describe": "Install gatsby-plugin-foo in gatsby-config.js", + "diff": "- Original - 0 ++ Modified + 1 + +@@ -64,6 +64,7 @@ + }, + \`gatsby-plugin-offline\`, // \`gatsby-plugin-preact\`, + \`gatsby-plugin-react-helmet\`, ++ \\"gatsby-plugin-foo\\", + ], + } +", + "id": "gatsby-plugin-foo", + "name": "gatsby-plugin-foo", + "newState": "const redish = \`#c5484d\` +module.exports = { + siteMetadata: { + title: \`Bricolage\`, + author: \`Kyle Mathews\`, + homeCity: \`San Francisco\`, + }, + plugins: [ + { + resolve: \`gatsby-source-filesystem\`, + options: { + path: \`\${__dirname}/src/pages\`, + name: \`pages\`, + }, + }, + \`gatsby-transformer-sharp\`, + \`gatsby-plugin-emotion\`, + { + resolve: \`gatsby-plugin-typography\`, + options: { + pathToConfigModule: \`src/utils/typography\`, + }, + }, + { + resolve: \`gatsby-transformer-remark\`, + options: { + plugins: [ + { + resolve: \`gatsby-remark-images\`, + options: { + maxWidth: 590, + }, + }, + { + resolve: \`gatsby-remark-responsive-iframe\`, + options: { + wrapperStyle: \`margin-bottom: 1.0725rem\`, + }, + }, + \`gatsby-remark-prismjs\`, + \`gatsby-remark-copy-linked-files\`, + \`gatsby-remark-smartypants\`, + ], + }, + }, + \`gatsby-plugin-sharp\`, + { + resolve: \`gatsby-plugin-google-analytics\`, + options: { + trackingId: \`UA-774017-3\`, + }, + }, + { + resolve: \`gatsby-plugin-manifest\`, + options: { + name: \`Bricolage\`, + short_name: \`Bricolage\`, + icon: \`static/logo.png\`, + start_url: \`/\`, + background_color: redish, + theme_color: redish, + display: \`minimal-ui\`, + }, + }, + \`gatsby-plugin-offline\`, // \`gatsby-plugin-preact\`, + \`gatsby-plugin-react-helmet\`, + \\"gatsby-plugin-foo\\", + ], +} +", +} +`; + +exports[`gatsby-plugin resource e2e plugin resource test: GatsbyPlugin destroy 1`] = `undefined`; + +exports[`gatsby-plugin resource e2e plugin resource test: GatsbyPlugin update 1`] = ` +Object { + "_message": "Installed gatsby-plugin-foo in gatsby-config.js", + "id": "gatsby-plugin-foo", + "name": "gatsby-plugin-foo", +} +`; + +exports[`gatsby-plugin resource e2e plugin resource test: GatsbyPlugin update plan 1`] = ` +Object { + "currentState": "const redish = \`#c5484d\` +module.exports = { + siteMetadata: { + title: \`Bricolage\`, + author: \`Kyle Mathews\`, + homeCity: \`San Francisco\`, + }, + plugins: [ + { + resolve: \`gatsby-source-filesystem\`, + options: { + path: \`\${__dirname}/src/pages\`, + name: \`pages\`, + }, + }, + \`gatsby-transformer-sharp\`, + \`gatsby-plugin-emotion\`, + { + resolve: \`gatsby-plugin-typography\`, + options: { + pathToConfigModule: \`src/utils/typography\`, + }, + }, + { + resolve: \`gatsby-transformer-remark\`, + options: { + plugins: [ + { + resolve: \`gatsby-remark-images\`, + options: { + maxWidth: 590, + }, + }, + { + resolve: \`gatsby-remark-responsive-iframe\`, + options: { + wrapperStyle: \`margin-bottom: 1.0725rem\`, + }, + }, + \`gatsby-remark-prismjs\`, + \`gatsby-remark-copy-linked-files\`, + \`gatsby-remark-smartypants\`, + ], + }, + }, + \`gatsby-plugin-sharp\`, + { + resolve: \`gatsby-plugin-google-analytics\`, + options: { + trackingId: \`UA-774017-3\`, + }, + }, + { + resolve: \`gatsby-plugin-manifest\`, + options: { + name: \`Bricolage\`, + short_name: \`Bricolage\`, + icon: \`static/logo.png\`, + start_url: \`/\`, + background_color: redish, + theme_color: redish, + display: \`minimal-ui\`, + }, + }, + \`gatsby-plugin-offline\`, // \`gatsby-plugin-preact\`, + \`gatsby-plugin-react-helmet\`, + \\"gatsby-plugin-foo\\", + ], +} +", + "describe": "Install gatsby-plugin-foo in gatsby-config.js", + "diff": "Compared values have no visual difference.", + "id": "gatsby-plugin-foo", + "name": "gatsby-plugin-foo", + "newState": "const redish = \`#c5484d\` +module.exports = { + siteMetadata: { + title: \`Bricolage\`, + author: \`Kyle Mathews\`, + homeCity: \`San Francisco\`, + }, + plugins: [ + { + resolve: \`gatsby-source-filesystem\`, + options: { + path: \`\${__dirname}/src/pages\`, + name: \`pages\`, + }, + }, + \`gatsby-transformer-sharp\`, + \`gatsby-plugin-emotion\`, + { + resolve: \`gatsby-plugin-typography\`, + options: { + pathToConfigModule: \`src/utils/typography\`, + }, + }, + { + resolve: \`gatsby-transformer-remark\`, + options: { + plugins: [ + { + resolve: \`gatsby-remark-images\`, + options: { + maxWidth: 590, + }, + }, + { + resolve: \`gatsby-remark-responsive-iframe\`, + options: { + wrapperStyle: \`margin-bottom: 1.0725rem\`, + }, + }, + \`gatsby-remark-prismjs\`, + \`gatsby-remark-copy-linked-files\`, + \`gatsby-remark-smartypants\`, + ], + }, + }, + \`gatsby-plugin-sharp\`, + { + resolve: \`gatsby-plugin-google-analytics\`, + options: { + trackingId: \`UA-774017-3\`, + }, + }, + { + resolve: \`gatsby-plugin-manifest\`, + options: { + name: \`Bricolage\`, + short_name: \`Bricolage\`, + icon: \`static/logo.png\`, + start_url: \`/\`, + background_color: redish, + theme_color: redish, + display: \`minimal-ui\`, + }, + }, + \`gatsby-plugin-offline\`, // \`gatsby-plugin-preact\`, + \`gatsby-plugin-react-helmet\`, + \\"gatsby-plugin-foo\\", + ], +} +", +} +`; diff --git a/packages/gatsby-recipes/src/providers/gatsby/__snapshots__/shadow-file.test.js.snap b/packages/gatsby-recipes/src/providers/gatsby/__snapshots__/shadow-file.test.js.snap new file mode 100644 index 0000000000000..409570ebc6b99 --- /dev/null +++ b/packages/gatsby-recipes/src/providers/gatsby/__snapshots__/shadow-file.test.js.snap @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Shadow File resource e2e shadow file resource test: GatsbyShadowFile create 1`] = ` +Object { + "_message": "Shadowed src/gatsby-theme-blog/components/author.js from gatsby-theme-blog", + "contents": "import React from 'react' + +export default () =>

F. Scott Fitzgerald

+", + "id": "src/gatsby-theme-blog/components/author.js", + "path": "src/gatsby-theme-blog/components/author.js", + "theme": "gatsby-theme-blog", +} +`; + +exports[`Shadow File resource e2e shadow file resource test: GatsbyShadowFile create plan 1`] = ` +Object { + "currentState": Object {}, + "describe": "Shadow src/components/author.js from the theme gatsby-theme-blog", + "diff": "- Original - 0 ++ Modified + 4 + ++ import React from 'react' ++ ++ export default () =>

F. Scott Fitzgerald

++", + "id": "src/gatsby-theme-blog/components/author.js", + "newState": Object { + "contents": "import React from 'react' + +export default () =>

F. Scott Fitzgerald

+", + "id": "src/gatsby-theme-blog/components/author.js", + "path": "src/components/author.js", + "theme": "gatsby-theme-blog", + }, + "path": "src/components/author.js", + "theme": "gatsby-theme-blog", +} +`; + +exports[`Shadow File resource e2e shadow file resource test: GatsbyShadowFile destroy 1`] = ` +Object { + "_message": "Shadowed src/gatsby-theme-blog/components/author.js from gatsby-theme-blog", + "contents": "import React from 'react' + +export default () =>

F. Scott Fitzgerald

+", + "id": "src/gatsby-theme-blog/components/author.js", + "path": "src/gatsby-theme-blog/components/author.js", + "theme": "gatsby-theme-blog", +} +`; + +exports[`Shadow File resource e2e shadow file resource test: GatsbyShadowFile update 1`] = ` +Object { + "_message": "Shadowed src/gatsby-theme-blog/components/author.js from gatsby-theme-blog", + "contents": "import React from 'react' + +export default () =>

F. Scott Fitzgerald

+", + "id": "src/gatsby-theme-blog/components/author.js", + "path": "src/gatsby-theme-blog/components/author.js", + "theme": "gatsby-theme-blog", +} +`; + +exports[`Shadow File resource e2e shadow file resource test: GatsbyShadowFile update plan 1`] = ` +Object { + "currentState": Object { + "_message": "Shadowed src/gatsby-theme-blog/components/author.js from gatsby-theme-blog", + "contents": "import React from 'react' + +export default () =>

F. Scott Fitzgerald

+", + "id": "src/gatsby-theme-blog/components/author.js", + "path": "src/gatsby-theme-blog/components/author.js", + "theme": "gatsby-theme-blog", + }, + "describe": "Shadow src/components/author.js from the theme gatsby-theme-blog", + "diff": "Compared values have no visual difference.", + "id": "src/gatsby-theme-blog/components/author.js", + "newState": Object { + "contents": "import React from 'react' + +export default () =>

F. Scott Fitzgerald

+", + "id": "src/gatsby-theme-blog/components/author.js", + "path": "src/components/author.js", + "theme": "gatsby-theme-blog", + }, + "path": "src/components/author.js", + "theme": "gatsby-theme-blog", +} +`; diff --git a/packages/gatsby-recipes/src/providers/gatsby/shadow-file.js b/packages/gatsby-recipes/src/providers/gatsby/shadow-file.js index 651d01a4f12a4..a4a03041a6aad 100644 --- a/packages/gatsby-recipes/src/providers/gatsby/shadow-file.js +++ b/packages/gatsby-recipes/src/providers/gatsby/shadow-file.js @@ -2,34 +2,60 @@ const path = require(`path`) const fs = require(`fs-extra`) const Joi = require(`@hapi/joi`) +const { slash } = require(`gatsby-core-utils`) + const resourceSchema = require(`../resource-schema`) const getDiff = require(`../utils/get-diff`) const fileExists = filePath => fs.existsSync(filePath) const relativePathForShadowedFile = ({ theme, filePath }) => { // eslint-disable-next-line - const [_src, ...filePathParts] = filePath.split(path.sep) + const [_src, ...filePathParts] = filePath.split(`/`) const relativePath = path.join(`src`, theme, path.join(...filePathParts)) - return relativePath + return slash(relativePath) } +exports.relativePathForShadowedFile = relativePathForShadowedFile + +const createPathToThemeFile = ({ root, theme, filePath }) => { + // eslint-disable-next-line + const fullPath = path.join(root, `node_modules`, theme, filePath) + return slash(fullPath) +} +exports.createPathToThemeFile = createPathToThemeFile + +const splitId = id => { + // Remove src + // eslint-disable-next-line + const [_src, ...filePathParts] = id.split(`/`) + let theme + let filePath + // Check if npm package is scoped + if (filePathParts[0][0] === `@`) { + theme = path.join(filePathParts[0], filePathParts[1]) + filePath = path.join(...filePathParts.slice(2)) + } else { + theme = filePathParts[0] + filePath = path.join(...filePathParts.slice(1)) + } + return { + theme: slash(theme), + filePath: slash(filePath), + } +} +exports.splitId = splitId + const create = async ({ root }, { theme, path: filePath }) => { const id = relativePathForShadowedFile({ filePath, theme }) - const relativePathInTheme = filePath.replace(theme + path.sep, ``) - const fullFilePathToShadow = path.join( - root, - `node_modules`, - theme, - relativePathInTheme - ) + const fullFilePathToShadow = createPathToThemeFile({ root, theme, filePath }) const contents = await fs.readFile(fullFilePathToShadow, `utf8`) - const fullPath = path.join(root, id) + const shadowedFilePath = path.join(root, id) - await fs.ensureFile(fullPath) - await fs.writeFile(fullPath, contents) + await fs.ensureFile(shadowedFilePath) + await fs.writeFile(shadowedFilePath, contents) const result = await read({ root }, id) return result @@ -37,15 +63,15 @@ const create = async ({ root }, { theme, path: filePath }) => { const read = async ({ root }, id) => { // eslint-disable-next-line - const [_src, theme, ..._filePathParts] = id.split(path.sep) + const { theme, filePath } = splitId(id) - const fullPath = path.join(root, id) + const shadowedFilePath = path.join(root, id) - if (!fileExists(fullPath)) { + if (!fileExists(shadowedFilePath)) { return undefined } - const contents = await fs.readFile(fullPath, `utf8`) + const contents = await fs.readFile(shadowedFilePath, `utf8`) const resource = { id, @@ -87,21 +113,13 @@ module.exports.plan = async ({ root }, { theme, path: filePath, id }) => { let currentResource = `` if (!id) { // eslint-disable-next-line - const [_src, ...filePathParts] = filePath.split(path.sep) - id = path.join(`src`, theme, path.join(...filePathParts)) + id = relativePathForShadowedFile({ theme, filePath }) } currentResource = (await read({ root }, id)) || {} // eslint-disable-next-line - const [_src, _theme, ...shadowPathParts] = id.split(path.sep) - const fullFilePathToShadow = path.join( - root, - `node_modules`, - theme, - `src`, - path.join(...shadowPathParts) - ) + const fullFilePathToShadow = path.join(root, `node_modules`, theme, filePath) const newContents = await fs.readFile(fullFilePathToShadow, `utf8`) const newResource = { diff --git a/packages/gatsby-recipes/src/providers/gatsby/shadow-file.test.js b/packages/gatsby-recipes/src/providers/gatsby/shadow-file.test.js new file mode 100644 index 0000000000000..4c7314902f137 --- /dev/null +++ b/packages/gatsby-recipes/src/providers/gatsby/shadow-file.test.js @@ -0,0 +1,107 @@ +const path = require(`path`) +const rimraf = require(`rimraf`) + +const resourceTestHelper = require(`../resource-test-helper`) + +const root = path.join(__dirname, `fixtures`) + +const cleanup = () => { + rimraf.sync(path.join(root, `src`)) +} + +beforeEach(() => { + cleanup() +}) + +afterEach(() => { + cleanup() +}) + +describe(`Shadow File resource`, () => { + test(`e2e shadow file resource test`, async () => { + await resourceTestHelper({ + resourceModule: shadowFile, + resourceName: `GatsbyShadowFile`, + context: { root }, + initialObject: { + theme: `gatsby-theme-blog`, + path: `src/components/author.js`, + }, + partialUpdate: { + theme: `gatsby-theme-blog`, + path: `src/components/author.js`, + }, + }) + }) +}) + +const shadowFile = require(`./shadow-file`) +const { + relativePathForShadowedFile, + createPathToThemeFile, + splitId, +} = require(`./shadow-file.js`) + +describe(`shadow-file create relative path for theme file`, () => { + it(`should create the corect path for a non-scoped npm package`, () => { + expect( + relativePathForShadowedFile({ + theme: `foo-theme`, + filePath: `src/foo.js`, + }) + ).toEqual(`src/foo-theme/foo.js`) + }) + it(`should create the corect path for a scoped npm package`, () => { + expect( + relativePathForShadowedFile({ + theme: `@bar/foo-theme`, + filePath: `src/foo.js`, + }) + ).toEqual(`src/@bar/foo-theme/foo.js`) + }) +}) + +// TODO restore e2e tests by running results through slash +describe(`shadow-file create full path to theme file`, () => { + it(`should create the corect path for a non-scoped npm package`, () => { + expect( + createPathToThemeFile({ + root: `/sup/`, + theme: `foo-theme`, + filePath: `src/foo.js`, + }) + ).toEqual(`/sup/node_modules/foo-theme/src/foo.js`) + }) + it(`should create the corect path for a scoped npm package`, () => { + expect( + createPathToThemeFile({ + root: `/sup/`, + theme: `@bar/foo-theme`, + filePath: `src/foo.js`, + }) + ).toEqual(`/sup/node_modules/@bar/foo-theme/src/foo.js`) + }) +}) + +describe(`shadow-file should split the id correctly`, () => { + it(`should split the id correctly for a non-scoped npm package`, () => { + expect(splitId(`src/foo/bar.js`)).toEqual({ + theme: `foo`, + filePath: `bar.js`, + }) + expect(splitId(`src/foo/bar/index.js`)).toEqual({ + theme: `foo`, + filePath: `bar/index.js`, + }) + }) + it(`should split the id correctly for a scoped npm package`, () => { + expect(splitId(`src/@foo/theme-name/bar.js`)).toEqual({ + theme: `@foo/theme-name`, + filePath: `bar.js`, + }) + expect(splitId(`src/@foo/theme-name/bar/index.js`)).toEqual({ + theme: `@foo/theme-name`, + filePath: `bar/index.js`, + }) + }) +}) diff --git a/packages/gatsby-recipes/src/providers/git/__snapshots__/ignore.test.js.snap b/packages/gatsby-recipes/src/providers/git/__snapshots__/ignore.test.js.snap new file mode 100644 index 0000000000000..3efdbdde8856a --- /dev/null +++ b/packages/gatsby-recipes/src/providers/git/__snapshots__/ignore.test.js.snap @@ -0,0 +1,53 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`git ignore resource e2e test: GitIgnore create 1`] = ` +Object { + "_message": "Added .cache to gitignore", + "id": ".cache", + "name": ".cache", +} +`; + +exports[`git ignore resource e2e test: GitIgnore create plan 1`] = ` +Object { + "currentState": "node_modules +", + "describe": "Add .cache to gitignore", + "diff": "- Original - 1 ++ Modified + 1 + + node_modules +- ++ .cache", + "newState": "node_modules +.cache", +} +`; + +exports[`git ignore resource e2e test: GitIgnore destroy 1`] = ` +Object { + "id": ".cache", + "name": ".cache", +} +`; + +exports[`git ignore resource e2e test: GitIgnore update 1`] = ` +Object { + "_message": "Added .cache to gitignore", + "id": ".cache", + "name": ".cache", +} +`; + +exports[`git ignore resource e2e test: GitIgnore update plan 1`] = ` +Object { + "currentState": "node_modules +.cache +", + "describe": "Add .cache to gitignore", + "diff": "", + "newState": "node_modules +.cache +", +} +`; diff --git a/packages/gatsby-recipes/src/providers/npm/__snapshots__/package-json.test.js.snap b/packages/gatsby-recipes/src/providers/npm/__snapshots__/package-json.test.js.snap index a1381dde52ea4..9bea9147e6617 100644 --- a/packages/gatsby-recipes/src/providers/npm/__snapshots__/package-json.test.js.snap +++ b/packages/gatsby-recipes/src/providers/npm/__snapshots__/package-json.test.js.snap @@ -1,5 +1,61 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`packageJson resource e2e package resource test: PackageJson create 1`] = ` +Object { + "id": "husky", + "name": "husky", + "value": "{ + \\"hooks\\": {} +}", +} +`; + +exports[`packageJson resource e2e package resource test: PackageJson create plan 1`] = ` +Object { + "currentState": "{}", + "describe": "Add husky to package.json", + "diff": "", + "id": "husky", + "name": "husky", + "newState": "{ + \\"husky\\": { + \\"hooks\\": {} + } +}", +} +`; + +exports[`packageJson resource e2e package resource test: PackageJson destroy 1`] = `undefined`; + +exports[`packageJson resource e2e package resource test: PackageJson update 1`] = ` +Object { + "id": "husky", + "name": "husky", + "value": "{ + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } +}", +} +`; + +exports[`packageJson resource e2e package resource test: PackageJson update plan 1`] = ` +Object { + "currentState": "{}", + "describe": "Add husky to package.json", + "diff": "", + "id": "husky", + "name": "husky", + "newState": "{ + \\"husky\\": { + \\"hooks\\": { + \\"pre-commit\\": \\"lint-staged\\" + } + } +}", +} +`; + exports[`packageJson resource handles object values 1`] = ` Object { "id": "husky", diff --git a/packages/gatsby-recipes/src/providers/npm/__snapshots__/package.test.js.snap b/packages/gatsby-recipes/src/providers/npm/__snapshots__/package.test.js.snap index 7273096bcf7ff..6d07fa4c173ce 100644 --- a/packages/gatsby-recipes/src/providers/npm/__snapshots__/package.test.js.snap +++ b/packages/gatsby-recipes/src/providers/npm/__snapshots__/package.test.js.snap @@ -1,5 +1,48 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`npm package resource e2e npm package resource test: NPMPackage create 1`] = ` +Object { + "_message": "Installed NPM package is-sorted@1.0.0", + "id": "is-sorted", + "name": "is-sorted", + "version": "1.0.0", +} +`; + +exports[`npm package resource e2e npm package resource test: NPMPackage create plan 1`] = ` +Object { + "currentState": undefined, + "describe": "Install is-sorted@1.0.0", + "newState": "is-sorted@1.0.0", +} +`; + +exports[`npm package resource e2e npm package resource test: NPMPackage destroy 1`] = ` +Object { + "_message": "Installed NPM package is-sorted@1.0.2", + "id": "is-sorted", + "name": "is-sorted", + "version": "1.0.2", +} +`; + +exports[`npm package resource e2e npm package resource test: NPMPackage update 1`] = ` +Object { + "_message": "Installed NPM package is-sorted@1.0.2", + "id": "is-sorted", + "name": "is-sorted", + "version": "1.0.2", +} +`; + +exports[`npm package resource e2e npm package resource test: NPMPackage update plan 1`] = ` +Object { + "currentState": "is-sorted@1.0.0", + "describe": "Install is-sorted@1.0.2", + "newState": "is-sorted@1.0.2", +} +`; + exports[`package manager client commands generates the correct commands for npm 1`] = ` Array [ "install", diff --git a/packages/gatsby-recipes/src/providers/npm/__snapshots__/script.test.js.snap b/packages/gatsby-recipes/src/providers/npm/__snapshots__/script.test.js.snap new file mode 100644 index 0000000000000..0d0a5883178ca --- /dev/null +++ b/packages/gatsby-recipes/src/providers/npm/__snapshots__/script.test.js.snap @@ -0,0 +1,57 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`npm script resource e2e script resource test: NPMScript create 1`] = ` +Object { + "_message": "Wrote script apple to your package.json", + "command": "foot", + "id": "apple", + "name": "apple", +} +`; + +exports[`npm script resource e2e script resource test: NPMScript create plan 1`] = ` +Object { + "currentState": "", + "describe": "Add new command to your package.json", + "diff": "- Original - 1 ++ Modified + 3 + + Object { + \\"name\\": \\"test\\", +- \\"scripts\\": Object {}, ++ \\"scripts\\": Object { ++ \\"apple\\": \\"foot\\", ++ }, + }", + "newState": "\\"apple\\": \\"foot\\"", +} +`; + +exports[`npm script resource e2e script resource test: NPMScript destroy 1`] = `undefined`; + +exports[`npm script resource e2e script resource test: NPMScript update 1`] = ` +Object { + "_message": "Wrote script apple to your package.json", + "command": "foot2", + "id": "apple", + "name": "apple", +} +`; + +exports[`npm script resource e2e script resource test: NPMScript update plan 1`] = ` +Object { + "currentState": "\\"apple\\": \\"foot\\"", + "describe": "Add new command to your package.json", + "diff": "- Original - 1 ++ Modified + 1 + + Object { + \\"name\\": \\"test\\", + \\"scripts\\": Object { +- \\"apple\\": \\"foot\\", ++ \\"apple\\": \\"foot2\\", + }, + }", + "newState": "\\"apple\\": \\"foot2\\"", +} +`; diff --git a/packages/gatsby-recipes/src/providers/npm/package-json.js b/packages/gatsby-recipes/src/providers/npm/package-json.js index 3a3f58f4e09d6..67e820a85f45f 100644 --- a/packages/gatsby-recipes/src/providers/npm/package-json.js +++ b/packages/gatsby-recipes/src/providers/npm/package-json.js @@ -58,9 +58,10 @@ exports.schema = schema exports.validate = validate module.exports.plan = async ({ root }, { id, name, value }) => { + const parsedValue = typeof value === `string` ? JSON.parse(value) : value const key = id || name const currentState = readPackageJson(root) - const newState = { ...currentState, [key]: value } + const newState = { ...currentState, [key]: parsedValue } return { id: key, diff --git a/packages/gatsby-recipes/src/providers/resource-test-helper.js b/packages/gatsby-recipes/src/providers/resource-test-helper.js index af52709889299..b9adaf6dbaf40 100644 --- a/packages/gatsby-recipes/src/providers/resource-test-helper.js +++ b/packages/gatsby-recipes/src/providers/resource-test-helper.js @@ -1,5 +1,5 @@ -// const resourceSchema = require(`./resource-schema`) -// const Joi = require(`@hapi/joi`) +const resourceSchema = require(`./resource-schema`) +const Joi = require(`@hapi/joi`) module.exports = async ({ resourceModule: resource, @@ -12,9 +12,6 @@ module.exports = async ({ const createPlan = await resource.plan(context, initialObject) expect(createPlan).toBeTruthy() - // Temporary short circuit while we figure out snapshots - return undefined - /* expect(createPlan).toMatchSnapshot(`${resourceName} create plan`) // Test creating the resource @@ -49,5 +46,4 @@ module.exports = async ({ createResponse.id ) expect(postDestroyReadResponse).toBeUndefined() -*/ }