diff --git a/packages/contentful-extension-scripts/lib/index.js b/packages/contentful-extension-scripts/lib/index.js index e04c6bc..884721c 100755 --- a/packages/contentful-extension-scripts/lib/index.js +++ b/packages/contentful-extension-scripts/lib/index.js @@ -11,7 +11,7 @@ const spawn = require('cross-spawn'); const args = process.argv.slice(2); const scriptIndex = args.findIndex( - x => x === 'build' || x === 'start' || x === 'help' + x => x === 'build' || x === 'start' || x === 'help' || x === 'test' ); const script = scriptIndex === -1 ? args[0] : args[scriptIndex]; const nodeArgs = scriptIndex > 0 ? args.slice(0, scriptIndex) : []; @@ -19,6 +19,7 @@ const nodeArgs = scriptIndex > 0 ? args.slice(0, scriptIndex) : []; switch (script) { case 'build': case 'start': + case 'test': case 'help': { const result = spawn.sync( 'node', diff --git a/packages/contentful-extension-scripts/package.json b/packages/contentful-extension-scripts/package.json index e2be34f..d23a803 100644 --- a/packages/contentful-extension-scripts/package.json +++ b/packages/contentful-extension-scripts/package.json @@ -33,14 +33,20 @@ "url": "https://github.com/contentful/create-contentful-extension/issues" }, "dependencies": { + "identity-obj-proxy": "3.0.0", "chalk": "2.4.2", "cross-spawn": "6.0.5", "fs-extra": "7.0.1", "htmlnano": "0.2.3", + "babel-jest": "^24.8.0", + "jest": "^24.8.0", + "jest-watch-typeahead": "^0.3.1", + "ts-jest": "^24.0.2", "parcel-bundler": "1.12.3", "parcel-plugin-url-loader": "1.3.1", "posthtml": "0.11.4", "posthtml-inline-assets": "3.0.0", + "typescript": "^3.5.2", "yargs": "13.2.4" }, "scripts": { diff --git a/packages/contentful-extension-scripts/scripts/test.js b/packages/contentful-extension-scripts/scripts/test.js new file mode 100644 index 0000000..4c3f514 --- /dev/null +++ b/packages/contentful-extension-scripts/scripts/test.js @@ -0,0 +1,30 @@ +// Do this as the first thing so that any code reading it knows the right env. +process.env.BABEL_ENV = 'test'; +process.env.NODE_ENV = 'test'; +const createJestConfig = require('./utils/createJestConfig'); +const paths = require('./utils/paths'); +const fs = require('fs'); +const jest = require('jest'); + +const argv = process.argv.slice(2); + +let appPackageJson = {}; + +try { + appPackageJson = fs.readJSONSync(paths.packageJson); +} catch (e) { + // do nothing +} + +process.on('unhandledRejection', err => { + throw err; +}); + +argv.push( + '--config', + JSON.stringify( + Object.assign({}, createJestConfig(), appPackageJson.jest || {}) + ) +); + +jest.run(argv); diff --git a/packages/contentful-extension-scripts/scripts/utils/createJestConfig.js b/packages/contentful-extension-scripts/scripts/utils/createJestConfig.js new file mode 100644 index 0000000..be7e889 --- /dev/null +++ b/packages/contentful-extension-scripts/scripts/utils/createJestConfig.js @@ -0,0 +1,33 @@ +const paths = require('./paths'); + +module.exports = function createJestConfig() { + const config = { + verbose: true, + transform: { + '.+\\.(js|jsx)?$': require.resolve('babel-jest'), + '^.+\\.(ts|tsx)?$': require.resolve('ts-jest/dist'), + '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': require.resolve( + './jestFileTransform.js' + ), + }, + transformIgnorePatterns: [ + '[/\\\\]node_modules[/\\\\].+\\.(js|jsx|tsx|ts)$', + ], + moduleNameMapper: { + '\\.(css|less|scss)$': require.resolve('identity-obj-proxy'), + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], + collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'], + coverageReporters: ['lcov'], + testMatch: ['/**/*.(spec|test).{ts,tsx,js,jsx}'], + testURL: 'http://localhost', + rootDir: paths.root, + coverageDirectory: paths.coverage, + watchPlugins: [ + require.resolve('jest-watch-typeahead/filename'), + require.resolve('jest-watch-typeahead/testname'), + ], + }; + + return config; +}; diff --git a/packages/contentful-extension-scripts/scripts/utils/getPackageJson.js b/packages/contentful-extension-scripts/scripts/utils/getPackageJson.js new file mode 100644 index 0000000..e69de29 diff --git a/packages/contentful-extension-scripts/scripts/utils/jestFileTransform.js b/packages/contentful-extension-scripts/scripts/utils/jestFileTransform.js new file mode 100644 index 0000000..dd9fda3 --- /dev/null +++ b/packages/contentful-extension-scripts/scripts/utils/jestFileTransform.js @@ -0,0 +1,11 @@ +'use strict'; + +const path = require('path'); + +// This is a custom Jest transformer turning file imports into filenames. +module.exports = { + process(src, filename) { + const assetFilename = JSON.stringify(path.basename(filename)); + return `module.exports = ${assetFilename};`; + }, +}; diff --git a/packages/contentful-extension-scripts/scripts/utils/paths.js b/packages/contentful-extension-scripts/scripts/utils/paths.js index 493c63e..7870499 100644 --- a/packages/contentful-extension-scripts/scripts/utils/paths.js +++ b/packages/contentful-extension-scripts/scripts/utils/paths.js @@ -5,7 +5,10 @@ const appDirectory = fs.realpathSync(process.cwd()); const resolveApp = relativePath => path.resolve(appDirectory, relativePath); module.exports = { + packageJson: resolveApp('package.json'), + root: resolveApp('.'), src: resolveApp('src'), build: resolveApp('build'), cache: resolveApp('.cache'), + coverage: resolveApp('.coverage'), }; diff --git a/packages/contentful-extension-scripts/scripts/utils/showHelp.js b/packages/contentful-extension-scripts/scripts/utils/showHelp.js index 9ba8181..8d280f5 100644 --- a/packages/contentful-extension-scripts/scripts/utils/showHelp.js +++ b/packages/contentful-extension-scripts/scripts/utils/showHelp.js @@ -13,6 +13,11 @@ module.exports = () => { console.log(chalk.cyan(` npm run build`)); console.log(' Bundles the extension for production.'); console.log(); + console.log(chalk.cyan(` npm run test`)); + console.log( + ' Run jest runner in watch mode. Passes through all flats directly to Jest' + ); + console.log(); console.log(chalk.cyan(` npm run configure`)); console.log( ' Asks which space and environment you want to use for development and deployment.' diff --git a/packages/contentful-extension-scripts/scripts/utils/updatePackageJsonFile.js b/packages/contentful-extension-scripts/scripts/utils/updatePackageJsonFile.js index dd296b1..747f169 100644 --- a/packages/contentful-extension-scripts/scripts/utils/updatePackageJsonFile.js +++ b/packages/contentful-extension-scripts/scripts/utils/updatePackageJsonFile.js @@ -3,6 +3,8 @@ module.exports = (pkg, { version, language, type }) => { pkg.scripts = { start: 'contentful-extension-scripts start', build: 'contentful-extension-scripts build', + test: 'contentful-extension-scripts test --env=jsdom --watch', + 'test:coverage': 'contentful-extension-scripts test --env=jsdom --coverage', deploy: 'npm run build && contentful extension update --force', configure: 'contentful space use && contentful space environment use', login: 'contentful login', @@ -16,12 +18,13 @@ module.exports = (pkg, { version, language, type }) => { '@babel/preset-env': '7.3.4', '@babel/preset-react': '7.0.0', '@contentful/contentful-extension-scripts': version, + '@testing-library/react': '8.0.4', cssnano: '4.1.10', - 'contentful-cli': '0.28.0', + 'contentful-cli': '0.33.1', }; pkg.dependencies = { '@contentful/forma-36-fcss': '^0.0.20', - '@contentful/forma-36-react-components': '^3.11.2', + '@contentful/forma-36-react-components': '^3.11.3', '@contentful/forma-36-tokens': '^0.3.0', 'contentful-ui-extensions-sdk': '3.9.0', 'prop-types': '^15.7.2', @@ -48,10 +51,11 @@ module.exports = (pkg, { version, language, type }) => { if (language === 'typescript') { pkg.devDependencies = Object.assign({}, pkg.devDependencies, { + typescript: '3.5.2', + '@types/jest': '24.0.15', '@types/react': '^16.8.17', '@types/react-dom': '^16.8.4', '@types/webpack-env': '1.13.9', - typescript: '3.5.2', }); } diff --git a/packages/contentful-extension-scripts/template/common/.babelrc b/packages/contentful-extension-scripts/template/common/.babelrc index 4a33b13..ae7d146 100644 --- a/packages/contentful-extension-scripts/template/common/.babelrc +++ b/packages/contentful-extension-scripts/template/common/.babelrc @@ -3,8 +3,7 @@ [ "@babel/preset-env", { - "useBuiltIns": false, - "modules": false + "useBuiltIns": false } ], [ diff --git a/packages/contentful-extension-scripts/template/common/.contentfulrc.json b/packages/contentful-extension-scripts/template/common/.contentfulrc.json index 212698e..5193c21 100644 --- a/packages/contentful-extension-scripts/template/common/.contentfulrc.json +++ b/packages/contentful-extension-scripts/template/common/.contentfulrc.json @@ -1,5 +1,6 @@ { - "cmaToken": "", + "managementToken": "", "activeSpaceId": "", - "activeEnvironmentId": "" + "activeEnvironmentId": "", + "host": "api.contentful.com" } diff --git a/packages/contentful-extension-scripts/template/common/gitignore b/packages/contentful-extension-scripts/template/common/gitignore index cf562b5..4815f06 100644 --- a/packages/contentful-extension-scripts/template/common/gitignore +++ b/packages/contentful-extension-scripts/template/common/gitignore @@ -15,6 +15,9 @@ yarn-error.log* # Dependency directories node_modules/ +# Coverage +.coverage + # Build build/* !/build/index.html diff --git a/packages/contentful-extension-scripts/template/javascript-entry/src/index.js b/packages/contentful-extension-scripts/template/javascript-entry/src/index.js index fd2734a..89572f6 100644 --- a/packages/contentful-extension-scripts/template/javascript-entry/src/index.js +++ b/packages/contentful-extension-scripts/template/javascript-entry/src/index.js @@ -12,7 +12,7 @@ import { } from '@contentful/forma-36-react-components'; import { init, locations } from 'contentful-ui-extensions-sdk'; import '@contentful/forma-36-react-components/dist/styles.css'; -import '@contentful/forma-36-fcss'; +import '@contentful/forma-36-fcss/dist/styles.css'; import './index.css'; /** @@ -25,7 +25,7 @@ import './index.css'; * See https://github.com/contentful/create-contentful-extension/blob/master/docs/examples/entry-editor-content-model.json for details. */ -class App extends React.Component { +export class App extends React.Component { constructor(props) { super(props); @@ -71,11 +71,16 @@ class App extends React.Component { Title Body -