Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A CLI for running specific tests suites, like bootstrap CLI #1752

Merged
merged 8 commits into from
Aug 28, 2017
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- run:
name: "Install root dependencies"
command: |
yarn
yarn install
- save_cache:
key: root-dependencies-{{ checksum "package.json" }}
paths:
Expand Down Expand Up @@ -59,7 +59,7 @@ jobs:
- run:
name: "Install root dependencies"
command: |
yarn
yarn install
- run:
name: "Bootstrapping"
command: |
Expand All @@ -83,7 +83,7 @@ jobs:
- run:
name: "Install root dependencies"
command: |
yarn
yarn install
- run:
name: "Bootstrapping packages"
command: |
Expand All @@ -103,7 +103,7 @@ jobs:
- run:
name: "Install root dependencies"
command: |
yarn
yarn install
- run:
name: "Bootstrapping"
command: |
Expand All @@ -123,7 +123,7 @@ jobs:
- run:
name: "Install root dependencies"
command: |
yarn
yarn install
- run:
name: "Linting"
command: |
Expand All @@ -139,15 +139,15 @@ jobs:
- run:
name: "Install root dependencies"
command: |
yarn
yarn install
- run:
name: "Bootstrapping"
command: |
yarn bootstrap -- --core --reactnative
- run:
name: "Unit testing"
command: |
yarn test -- --coverage -i
yarn test -- --all --coverage --runInBand
yarn coverage
deploy:
<<: *defaults
Expand Down
55 changes: 40 additions & 15 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,44 @@ No software is bug free. So, if you got an issue, follow these steps:

To test your project against the current latest version of storybook, you can clone the repository and link it with `yarn`. Try following these steps:

1. Download the latest version of this project, and build it:
#### 1. Download the latest version of this project, and build it:

```sh
git clone https://github.com/storybooks/storybook.git
cd storybook
yarn install
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @Hypnosphi opted to use the shorthand yarn notation. We should keep it consistent

yarn bootstrap
```

The bootstrap command will ask which sections of the codebase you want to bootstrap. Unless you're going to work with ReactNative or the Documentation, you can keep the default.

You can also pick directly from CLI:

```sh
git clone https://github.com/storybooks/storybook.git
cd storybook
yarn
yarn bootstrap -- --core
```

#### 2a. Run unit tests

You can use one of the example projects in `examples/` to develop on.

This command will list all the suites and options for running tests.

2. Link `storybook` and any other required dependencies:
```sh
yarn test
```

_Note that in order to run the tests fro ReactNative, you must have bootstrapped with ReactNative enabled_

You can also pick suites from CLI:

```sh
yarn test -- --core
```

In order to run ALL unit tests, you must have bootstrapped the react-native

#### 2b. Link `storybook` and any other required dependencies:

If you want to test your own existing project using the github version of storybook, you need to `link` the packages you use in your project.

```sh
cd app/react
Expand All @@ -54,11 +81,12 @@ A good way to do that is using the example `cra-kitchen-sink` app embedded in th
# Download and build this repository:
git clone https://github.com/storybooks/storybook.git
cd storybook
yarn
yarn bootstrap -- --core
yarn install
yarn bootstrap

# make changes to try and reproduce the problem, such as adding components + stories
yarn start
cd examples/cra-kitchen-sink
yarn storybook

# see if you can see the problem, if so, commit it:
git checkout "branch-describing-issue"
Expand Down Expand Up @@ -194,12 +222,9 @@ First, build the release:
git checkout master
git status

# clean out extra files
# clean out extra files & build all the packages
# WARNING: destructive if you have extra files lying around!
git clean -fdx && yarn

# build all the packages
yarn bootstrap -- --all
yarn bootstrap -- --reset --all
```

From here there are different procedures for prerelease (e.g. alpha/beta/rc) and proper release.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"lint:js": "eslint --cache --cache-location=.cache/eslint --ext .js,.jsx,.json",
"lint:md": "remark",
"publish": "lerna publish",
"test": "jest --projects ./ ./examples/react-native-vanilla"
"test": "./scripts/test.js"
},
"devDependencies": {
"babel-cli": "^6.24.1",
Expand Down
145 changes: 145 additions & 0 deletions scripts/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#!/usr/bin/env node
const inquirer = require('inquirer');
const program = require('commander');
const childProcess = require('child_process');
const chalk = require('chalk');
const log = require('npmlog');

log.heading = 'storybook';
const prefix = 'test';
log.addLevel('aborted', 3001, { fg: 'red', bold: true });

const spawn = command =>
childProcess.spawnSync(`${command}`, {
shell: true,
stdio: 'inherit',
});

const main = program.version('3.0.0').option('--all', `Test everything ${chalk.gray('(all)')}`);

const createProject = ({ defaultValue, option, name, projectLocation }) => ({
value: false,
defaultValue: defaultValue || false,
option: option || undefined,
name: name || 'unnamed task',
projectLocation,
});
const createOption = ({ defaultValue, option, name, extraParam }) => ({
value: false,
defaultValue: defaultValue || false,
option: option || undefined,
name: name || 'unnamed task',
extraParam,
});

const tasks = {
core: createProject({
name: `Core & React & Vue ${chalk.gray('(core)')}`,
defaultValue: true,
option: '--core',
projectLocation: './',
}),
'react-native-vanilla': createProject({
name: `React-Native example ${chalk.gray('(react-native-vanilla)')}`,
defaultValue: true,
option: '--reactnative',
projectLocation: './examples/react-native-vanilla',
}),
// 'crna-kitchen-sink': createProject({
// name: `React-Native-App example ${chalk.gray('(crna-kitchen-sink)')} ${chalk.red(
// '[not implemented yet]'
// )}`,
// defaultValue: false,
// option: '--reactnativeapp',
// projectLocation: './examples/crna-kitchen-sink',
// }),
watchmode: createOption({
name: `Run in watch-mode ${chalk.gray('(watchmode)')}`,
defaultValue: false,
option: '--watch',
extraParam: '--watch',
}),
coverage: createOption({
name: `Output coverage reports ${chalk.gray('(coverage)')}`,
defaultValue: false,
option: '--coverage',
extraParam: '--coverage',
}),
runInBand: createOption({
name: `Run all tests serially in the current process ${chalk.gray('(runInBand)')}`,
defaultValue: false,
option: '--runInBand',
extraParam: '--runInBand',
}),
};

const getProjects = list => {
const filtered = list.filter(key => key.projectLocation);
if (filtered.length > 0) {
return filtered.map(key => key.projectLocation);
}

// if list would have been empty, we run with default projects
return Object.keys(tasks)
.map(key => tasks[key])
.filter(key => key.projectLocation && key.defaultValue)
.map(key => key.projectLocation);
};

const getExtraParams = list => list.filter(key => key.extraParam).map(key => key.extraParam);

Object.keys(tasks)
.reduce((acc, key) => acc.option(tasks[key].option, tasks[key].name), main)
.parse(process.argv);

Object.keys(tasks).forEach(key => {
tasks[key].value =
program[tasks[key].option.replace('--', '')] || (program.all && tasks[key].projectLocation);
});

let selection;
if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) {
selection = inquirer
.prompt([
{
type: 'checkbox',
message: 'Select which tests to run',
name: 'todo',
choices: Object.keys(tasks)
.map(key => tasks[key])
.filter(key => key.projectLocation)
.map(key => ({
name: key.name,
checked: key.defaultValue,
}))
.concat(new inquirer.Separator())
.concat(
Object.keys(tasks).map(key => tasks[key]).filter(key => key.extraParam).map(key => ({
name: key.name,
checked: key.defaultValue,
}))
),
},
])
.then(({ todo }) =>
todo.map(name => tasks[Object.keys(tasks).find(i => tasks[i].name === name)])
);
} else {
selection = Promise.resolve(
Object.keys(tasks).map(key => tasks[key]).filter(item => item.value === true)
);
}

selection
.then(list => {
if (list.length === 0) {
log.warn(prefix, 'Nothing to test');
} else {
spawn(`jest --projects ${getProjects(list).join(' ')} ${getExtraParams(list).join(' ')}`);
process.stdout.write('\x07');
}
})
.catch(e => {
log.aborted(prefix, chalk.red(e.message));
log.silly(prefix, e);
});