Skip to content

Commit

Permalink
Adding end-to-end tests for basic react usage. Resolves #67. (#77)
Browse files Browse the repository at this point in the history
* Beginnings of e2e tests

* Progress

* Adding end-to-end tests for basic react usage. Resolves #67.

* Self review

* Fixing linking

* Fixing tests

* Readme

* Adding typescript react test
  • Loading branch information
joeldenning authored Apr 11, 2020
1 parent 8c80eac commit ef30ac5
Show file tree
Hide file tree
Showing 15 changed files with 3,003 additions and 71 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
.DS_Store
.DS_Store
tests/fixtures
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ Note that create-single-spa can run in the current directory by default, but you

### Tests

`yarn test`
There are two kinds of tests - end-to-end (e2e) and package-specific tests. The package-specific tests reside inside of each package and can be run with `yarn test:packages`. The end-to-end tests can be run with `yarn test:e2e`. To run both, you can run `yarn test`.

Note that the end-to-end tests run create-single-spa several times to create several "fixture" directories, which takes a fair amount of time. To avoid having to recreate the fixtures every test run, the tests will reuse an existing fixtures directory if one is present. This means you only have to create the fixtures once. To clean out a specific fixture so that it is recreated, simply delete the directory. To clean out all fixtures, you can run `yarn clean-tests`.
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
testEnvironment: "node",
// Fun times waiting on yarn / npm install inside of CI
testTimeout: 180000,
testRegex: "tests\\/e2e\\/.+test.js",
watchPathIgnorePatterns: ["<rootDir>/tests/fixtures/"],
};
14 changes: 12 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
{
"name": "root",
"devDependencies": {
"@types/jest": "^25.2.1",
"concurrently": "^5.1.0",
"husky": "^4.2.3",
"jest": "^25.3.0",
"jest-cli": "^25.3.0",
"lerna": "^3.15.0",
"mkdirp": "^1.0.4",
"nixt": "^0.5.1",
"prettier": "^2.0.4",
"pretty-quick": "^2.0.1"
"pretty-quick": "^2.0.1",
"rimraf": "^3.0.2"
},
"scripts": {
"bootstrap": "lerna bootstrap",
"test": "lerna run test",
"clean-tests": "rimraf tests/fixtures",
"test": "yarn clean-tests && concurrently -n w: 'yarn:test:*'",
"test:packages": "lerna run test",
"test:e2e": "jest",
"lint": "lerna run lint",
"publish-all": "lerna publish",
"format": "prettier './**/*' --write"
Expand Down
4 changes: 4 additions & 0 deletions packages/generator-single-spa/src/generator-single-spa.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ module.exports = class SingleSpaGenerator extends Generator {
if (args.length > 0 && !this.options.dir) {
this.options.dir = args[0];
}

Object.keys(this.options).forEach((optionKey) => {
if (this.options[optionKey] === "false") this.options[optionKey] = false;
});
}
async chooseDestinationDir() {
if (!this.options.dir) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ module.exports = class SingleSpaReactGenerator extends Generator {
type: Boolean,
default: false,
});
this.option("orgName", {
type: String,
});
this.option("projectName", {
type: String,
});
}
async createPackageJson() {
this.packageManager = this.options.packageManager;

if (!this.packageManager) {
this.packageManager = (
if (!this.options.packageManager) {
this.options.packageManager = (
await this.prompt([
{
type: "list",
Expand All @@ -31,8 +35,8 @@ module.exports = class SingleSpaReactGenerator extends Generator {
).packageManager;
}

if (!this.typescript) {
this.typescript = (
if (!this.options.hasOwnProperty("typescript")) {
this.options.typescript = (
await this.prompt([
{
type: "confirm",
Expand All @@ -49,13 +53,13 @@ module.exports = class SingleSpaReactGenerator extends Generator {
{ encoding: "utf-8" }
);
const packageJsonStr = ejs.render(packageJsonTemplate, {
packageManager: this.packageManager,
typescript: this.typescript,
packageManager: this.options.packageManager,
typescript: this.options.typescript,
});

const packageJson = JSON.parse(packageJsonStr);

if (this.typescript) {
if (this.options.typescript) {
// Will be added as a dependency via ts-package.json
delete packageJson.devDependencies["@types/jest"];
// Will be replaced by eslint-config-ts-react-important-stuff
Expand All @@ -64,89 +68,93 @@ module.exports = class SingleSpaReactGenerator extends Generator {

this.fs.extendJSON(this.destinationPath("package.json"), packageJson);

if (this.typescript) {
if (this.options.typescript) {
this.fs.extendJSON(
this.destinationPath("package.json"),
this.fs.readJSON(this.templatePath("ts-package.json"))
);
}
}
async copyOtherFiles() {
const templateOptions = await this.prompt([
{
type: "input",
name: "orgName",
message: "Organization name (use lowercase and dashes)",
},
{
type: "input",
name: "projectName",
message: "Project name (use lowercase and dashes)",
},
]);
templateOptions.typescript = this.typescript;
this.orgName = templateOptions.orgName;
this.projectName = templateOptions.projectName;
if (!this.options.orgName) {
this.options.orgName = await this.prompt([
{
type: "input",
name: "orgName",
message: "Organization name (use lowercase and dashes)",
},
]).orgName;
}

if (!this.options.projectName) {
this.options.projectName = await this.prompt([
{
type: "input",
name: "projectName",
message: "Project name (use lowercase and dashes)",
},
]);
}

const srcFileExtension = this.typescript ? "tsx" : "js";
const srcFileExtension = this.options.typescript ? "tsx" : "js";

this.fs.copyTpl(
this.templatePath("jest.config.js"),
this.destinationPath("jest.config.js"),
templateOptions
this.options
);
this.fs.copyTpl(
this.templatePath(".babelrc.ejs"),
this.destinationPath(".babelrc"),
templateOptions
this.options
);
this.fs.copyTpl(
this.templatePath(".eslintrc.ejs"),
this.destinationPath(".eslintrc"),
templateOptions
this.options
);
this.fs.copyTpl(
this.templatePath("../../common-templates/gitignore"), // this is relative to /templates
this.destinationPath(".gitignore"),
templateOptions
this.options
);
this.fs.copyTpl(
this.templatePath(".prettierignore"),
this.destinationPath(".prettierignore"),
templateOptions
this.options
);
this.fs.copyTpl(
this.templatePath("webpack.config.js"),
this.destinationPath("webpack.config.js"),
templateOptions
this.options
);
this.fs.copyTpl(
this.templatePath("src/root.component.js"),
this.destinationPath(`src/root.component.${srcFileExtension}`),
templateOptions
this.options
);
this.fs.copyTpl(
this.templatePath("src/root.component.test.js"),
this.destinationPath(`src/root.component.test.${srcFileExtension}`),
templateOptions
this.options
);
this.fs.copyTpl(
this.templatePath("src/set-public-path.js"),
this.destinationPath(`src/set-public-path.${srcFileExtension}`),
templateOptions
this.options
);
this.fs.copyTpl(
this.templatePath("src/main.js"),
this.destinationPath(
`src/${templateOptions.orgName}-${templateOptions.projectName}.${srcFileExtension}`
`src/${this.options.orgName}-${this.options.projectName}.${srcFileExtension}`
),
templateOptions
this.options
);
if (this.typescript) {
if (this.options.typescript) {
this.fs.copyTpl(
this.templatePath("tsconfig.json"),
this.destinationPath("tsconfig.json"),
templateOptions
this.options
);
}

Expand All @@ -161,13 +169,13 @@ module.exports = class SingleSpaReactGenerator extends Generator {
}
install() {
this.installDependencies({
npm: this.packageManager === "npm",
yarn: this.packageManager === "yarn",
npm: this.options.packageManager === "npm",
yarn: this.options.packageManager === "yarn",
bower: false,
});
}
finished() {
this.on(`${this.packageManager}Install:end`, () => {
this.on(`${this.options.packageManager}Install:end`, () => {
const coloredFinalInstructions = chalk.bgWhite.black;
console.log(coloredFinalInstructions("Project setup complete!"));
console.log(
Expand All @@ -177,8 +185,8 @@ module.exports = class SingleSpaReactGenerator extends Generator {
);
console.log(
coloredFinalInstructions(
`1. Run '${this.packageManager} start${
this.packageManager === "npm" ? " --" : ""
`1. Run '${this.options.packageManager} start${
this.options.packageManager === "npm" ? " --" : ""
} --https --port 8500'`
)
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.gitignore
.prettierignore
yarn.lock
package-lock.json
package-lock.json
dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
yarn.lock
package-lock.json
LICENSE
*.ejs
*.ejs
dist
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.gitignore
.prettierignore
yarn.lock
package-lock.json
package-lock.json
dist
4 changes: 4 additions & 0 deletions packages/webpack-config-single-spa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,9 @@
"clean-webpack-plugin": "^3.0.0",
"unused-files-webpack-plugin": "^3.4.0",
"webpack-bundle-analyzer": "^3.6.0"
},
"optionalDependencies": {
"fork-ts-checker-webpack-plugin": "^4.1.3",
"typescript": "^3.8.3"
}
}
Loading

0 comments on commit ef30ac5

Please sign in to comment.