diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..4cc0a8e --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,77 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + if: "!contains(github.event.head_commit.message, '[skip ci]')" + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: 12 + - uses: actions/cache@v2 + with: + path: ~/.pnpm-store + key: ${{ runner.os }}-build-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-build- + - run: | + npm -g install pnpm@5.16 + pnpm set verify-store-integrity false + - run: pnpm install + - run: pnpm run test:coverage + - uses: codecov/codecov-action@v1 + - run: mv "$(pnpm pack | tail -n 1)" pkg.tgz + - uses: actions/upload-artifact@v2 + with: + name: package-art + path: pkg.tgz + test_example: + needs: test + runs-on: ubuntu-20.04 + defaults: + run: + working-directory: example + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: 12 + - uses: actions/download-artifact@v2 + with: + name: package-art + path: example + - run: npm install pkg.tgz --only=development --no-package-lock + - uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-build-example-${{ hashFiles('**/example/package.json') }} + restore-keys: | + ${{ runner.os }}-build-example-npm- + - run: npm install + - run: npm run build -- --prefix-paths + - if: github.event_name == 'push' + uses: actions/upload-artifact@v2 + with: + name: example-art + path: example/public + deploy_example: + if: github.event_name == 'push' + needs: test_example + runs-on: ubuntu-20.04 + steps: + - uses: actions/download-artifact@v2 + with: + name: example-art + path: public + - uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: public + force_orphan: true diff --git a/src/__tests__/__fixtures__/pluginOptionsSchema.js b/src/__tests__/__fixtures__/pluginOptionsSchema.js new file mode 100644 index 0000000..9b8bec6 --- /dev/null +++ b/src/__tests__/__fixtures__/pluginOptionsSchema.js @@ -0,0 +1,39 @@ +export default [ + { + title: 'should invalidate unknown options', + options: { + unknown: 5, + foo: { + bar: true, + }, + } + }, + { + title: 'should invalidate options with incorrect data types', + options: { + enabled: 5, + report: [], + purgecss: { + defaultExtractor: '', + safelist: true, + blocklist: [{}] + }, + } + }, + { + title: 'should validate correct options', + options: { + enabled: true, + report: false, + reportConsole: true, + purgecss: { + allowSymbols: false, + rejected: false, + defaultExtractor: s => s, + fontFace: false, + keyframes: true, + variables: true + } + } + } +] diff --git a/src/__tests__/__snapshots__/bootstrap.js.snap b/src/__tests__/__snapshots__/bootstrap.js.snap new file mode 100644 index 0000000..70ef4f2 --- /dev/null +++ b/src/__tests__/__snapshots__/bootstrap.js.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`onPreBootstrap correctly initializes custom options 1`] = ` +Object { + "_pathPrefix": "", + "_plugin": "gatsby-plugin-postbuild", + "_public": "/virtual/project/public", + "_root": "/virtual/project", + "enabled": true, + "purgecss": Object { + "allowSymbols": true, + "fontFace": false, + "keyframes": false, + "rejected": false, + "variables": false, + }, + "report": false, + "reportConsole": true, +} +`; + +exports[`onPreBootstrap correctly initializes default options 1`] = ` +Object { + "_pathPrefix": "", + "_plugin": "gatsby-plugin-postbuild", + "_public": "/virtual/project/public", + "_root": "/virtual/project", + "enabled": true, + "purgecss": Object { + "allowSymbols": false, + "fontFace": false, + "keyframes": false, + "rejected": true, + "variables": false, + }, + "report": true, + "reportConsole": true, +} +`; diff --git a/src/__tests__/__snapshots__/pluginOptionsSchema.js.snap b/src/__tests__/__snapshots__/pluginOptionsSchema.js.snap new file mode 100644 index 0000000..a09f36b --- /dev/null +++ b/src/__tests__/__snapshots__/pluginOptionsSchema.js.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`pluginOptionsSchema should invalidate options with incorrect data types 1`] = `false`; + +exports[`pluginOptionsSchema should invalidate options with incorrect data types 2`] = ` +Array [ + "\\"enabled\\" must be a boolean", + "\\"report\\" must be a boolean", + "\\"purgecss.defaultExtractor\\" must be of type function", + "\\"purgecss.safelist\\" must be one of [object, array]", + "\\"purgecss.blocklist[0]\\" must be a string", +] +`; + +exports[`pluginOptionsSchema should invalidate unknown options 1`] = `false`; + +exports[`pluginOptionsSchema should invalidate unknown options 2`] = ` +Array [ + "\\"unknown\\" is not allowed", + "\\"foo\\" is not allowed", +] +`; + +exports[`pluginOptionsSchema should validate correct options 1`] = `true`; + +exports[`pluginOptionsSchema should validate correct options 2`] = `Array []`; diff --git a/src/__tests__/bootstrap.js b/src/__tests__/bootstrap.js new file mode 100644 index 0000000..b41a097 --- /dev/null +++ b/src/__tests__/bootstrap.js @@ -0,0 +1,22 @@ +import fs from 'fs' +import { options } from '../util' +import { mountOptions } from '../../test/utils' +jest.mock('fs') + +describe('onPreBootstrap', () => { + it('correctly initializes default options', () => { + expect(() => mountOptions()).not.toThrow() + expect(options).toMatchSnapshot() + }) + + it('correctly initializes custom options', () => { + expect(() => mountOptions({ + report: false, + purgecss: { + allowSymbols: true, + rejected: false + } + })).not.toThrow() + expect(options).toMatchSnapshot() + }) +}) diff --git a/src/__tests__/pluginOptionsSchema.js b/src/__tests__/pluginOptionsSchema.js new file mode 100644 index 0000000..a4a643b --- /dev/null +++ b/src/__tests__/pluginOptionsSchema.js @@ -0,0 +1,17 @@ +import { testPluginOptionsSchema } from 'gatsby-plugin-utils' +import { pluginOptionsSchema } from '../' +import testCases from './__fixtures__/pluginOptionsSchema' + +describe('pluginOptionsSchema', () => { + for (const { title, options } of testCases) { + it(title, async () => { + const { isValid, errors } = await testPluginOptionsSchema( + pluginOptionsSchema, + options + ) + + expect(isValid).toMatchSnapshot() + expect(errors).toMatchSnapshot() + }) + } +})