-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BREAKING CHANGE: whole interface is different, refer to README.
- Loading branch information
Showing
66 changed files
with
735 additions
and
1,953 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,6 @@ | ||
.DS_Store | ||
/.idea | ||
*.iml | ||
/coverage | ||
/work | ||
/node_modules | ||
*.configbean | ||
/pids | ||
/log | ||
.cache | ||
.beans | ||
/static | ||
*.marko.js | ||
*.dust.js | ||
*.log | ||
.telemetry.json | ||
/tmp | ||
/reports | ||
jshint.xml | ||
jshint.html | ||
mocha.xunit | ||
*.marko.js | ||
.coverage | ||
yarn.lock | ||
coverage | ||
node_modules | ||
yarn* | ||
.vscode | ||
.reports | ||
marko-modules-mocking-map.json |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,14 @@ | ||
language: node_js | ||
node_js: | ||
- "6.10.2" | ||
- "8.11.2" | ||
env: | ||
- CXX=g++-4.8 | ||
addons: | ||
apt: | ||
sources: | ||
- ubuntu-toolchain-r-test | ||
packages: | ||
- g++-4.8 | ||
cache: | ||
directories: | ||
- llvm-3.8.0 | ||
before_install: | ||
- | ||
if [ "${TRAVIS_OS_NAME}" = "linux" ]; then | ||
if [ -z "$(ls -A llvm-$LLVM_VERSION)" ]; then | ||
wget -O llvm-$LLVM_VERSION.tar.xz http://llvm.org/releases/$LLVM_VERSION/clang+llvm-$LLVM_VERSION-x86_64-linux-gnu-ubuntu-14.04.tar.xz; | ||
mkdir llvm-$LLVM_VERSION; | ||
xzcat llvm-$LLVM_VERSION.tar.xz | tar -xvf - --strip 1 -C llvm-$LLVM_VERSION; | ||
fi; | ||
llvm-$LLVM_VERSION/bin/llvm-config --version; | ||
export LLVM_CONFIG="llvm-$LLVM_VERSION/bin/llvm-config"; | ||
fi | ||
deploy: | ||
on: | ||
tags: true | ||
branch: master | ||
- NODE_ENV=test | ||
before_script: | ||
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter | ||
- chmod +x ./cc-test-reporter | ||
- ./cc-test-reporter before-build | ||
script: | ||
- npm run lint | ||
- npm run test -- --coverage | ||
after_script: | ||
- ./cc-test-reporter after-build -t lcov --exit-code $TRAVIS_TEST_RESULT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,232 +1,72 @@ | ||
# marko-tester [![Build Status](https://travis-ci.org/oxala/marko-tester.svg?branch=master)](https://travis-ci.org/oxala/marko-tester) | ||
[![Build Status](https://travis-ci.org/oxala/marko-tester.svg?branch=master)](https://travis-ci.org/oxala/marko-tester) [![Test Coverage](https://api.codeclimate.com/v1/badges/46c76b421392b0cdc6e1/test_coverage)](https://codeclimate.com/github/oxala/marko-tester/test_coverage) | ||
# marko-tester | ||
A utility that helps you test marko components within the JEST framework. | ||
|
||
Test library to assist with testing marko 4 (and marko 4 legacy) UI components and more. | ||
|
||
## Usage | ||
|
||
### Start using marko-tester with: | ||
|
||
``` | ||
yarn add marko-tester --dev | ||
``` | ||
|
||
### CLI | ||
|
||
Once you've installed marko-tester, you can start using the `markotester` alias with the path to your source folder. There are few arguments you can pass if needed: | ||
|
||
- `--no-coverage` if you don't want to generate coverage report | ||
- `--no-mocha` if you want to execute only linting | ||
- `--no-lint` if you don't want lint checks | ||
- `--lint-es5` if you want to lint code with es5 rules by default | ||
- `--fix-lint` if you want to automatically fix your linting issues | ||
- `--fix-fixtures` if you want to automatically replace failing fixtures with actual render result | ||
- `--fix` combines `--fix-lint` and `--fix-fixtures` together | ||
|
||
``` | ||
markotester source --no-coverage | ||
markotester source --no-coverage --no-lint | ||
markotester source --fix-lint | ||
markotester source --fix-fixtures | ||
``` | ||
|
||
`package.json` example: | ||
## Requirements | ||
Your project needs to have `jest@^23` and `marko@^4.5` installed. | ||
Within your regular JEST configuration, you need to specify a transform for `*.marko` files: | ||
|
||
``` | ||
"scripts": { | ||
"lint": "yarn test --lint --no-mocha", | ||
"test": "markotester src --no-lint --no-coverage", | ||
"coverage": "yarn test --coverage" | ||
... | ||
"transform": { | ||
... | ||
"^.+\\.marko$": "<rootDir>/node_modules/marko-jest/preprocessor.js" | ||
} | ||
``` | ||
|
||
### File structure | ||
|
||
``` | ||
app | ||
|- source | ||
| |- components | ||
| | |- phone-frame | ||
| | | +- test | ||
| | | |- fixtures | ||
| | | | |- default.html | ||
| | | | |- default.json | ||
| | | | |- empty.js | ||
| | | | +- empty.html | ||
| | | +- index.spec.js | ||
| | |- component.js | ||
| | +- index.marko | ||
| +- pages | ||
| | +- mobile-preview | ||
| | |- test | ||
| | | |- fixtures | ||
| | | | |- default.html | ||
| | | | +- default.json | ||
| | | +- index.spec.js | ||
| | |- index.js | ||
| | +- index.marko | ||
| +- services | ||
| |- test | ||
| | +- amazing-service.spec.js | ||
| +- amazing-service.js | ||
+- .marko-tester.js | ||
``` | ||
|
||
### Configuration file | ||
|
||
You can find an example configuration file in the root folder of `marko-tester` (default confirugation): | ||
## Configuration | ||
In the global JEST object, you can pass a `tester` configuration: | ||
|
||
``` | ||
{ | ||
"components": [], | ||
"taglibExcludeDirs": [], | ||
"taglibExcludePackages": [], | ||
"excludedAttributes": [], | ||
"lassoPlugins": [], | ||
"coverage": { | ||
"reporters": [ | ||
"text-summary", | ||
"html", | ||
"json-summary" | ||
], | ||
"dest": ".reports", | ||
"excludes": [ | ||
"**/*.marko.js" | ||
] | ||
"global": { | ||
... | ||
"tester": { | ||
"fixturesDir": "inputs", | ||
"shallow": false | ||
} | ||
}; | ||
} | ||
``` | ||
|
||
* **components** - An array of patterns for files that should be loaded into jsdom page by lasso. | ||
* **taglibExcludeDirs** - An array of paths relative to the root of your project folders that contain `marko.json`. This is used to isolate your tests so the nested components won't be renderer. | ||
* **taglibExcludePackages** - An array of module names. This is used to isolate your tests so the nested components won't be renderer. | ||
* **excludedAttributes** - An array of HTML attributes that can be different every test execution (e.g `data-widget` which marko dynamically changes based on package version). | ||
* **lassoPlugins** - An array of lasso plugins to require and attach to lasso configuration during client test execution. | ||
* **coverage.reporters** - An array of reporters for istanbul to use. | ||
* **coverage.dest** - The target destination folder where reports will be written. | ||
* **coverage.excludes** - An array of file patterns to exclude from istanbul reports. | ||
|
||
### Automatic component/fixtures search and fixtures test | ||
- fixturesDir - The folder name where you have fixtures to render the component with. _(Default: "fixtures")_ | ||
|
||
Marko-tester will try to automatically find your component renderer and/or fixtures to test. For the renderer, marko-tester will go up one level from your spec file and search for `index.marko` (or the file specified in `w-bind` for legacy components). | ||
- shallow - You can turn off shallow rendering by passing `false` here. That way marko won't isolate any component test. _(Default: true)_ | ||
|
||
Fixtures will be automatically found if they are inside the `fixtures` folder on the same level as your spec file. | ||
|
||
If fixtures and renderer would be found, and spec file exists for the component,fixture test would be automatically performed. | ||
## Usage | ||
`marko-tester` exposes a `getComponent` method for you to use. Pass a relative test file path to a marko component and you will receive a `render` method and `fixtures` method/object. By default, `getComponent` will run JEST SnapShot tests for the fixtures of the component. | ||
|
||
### Render comparison based on specific input (fixtures test) | ||
- `render` is a method that renders a component with a given input and mounts it to `document.body`. The mounted component instance is returned. | ||
|
||
The rendering test works by giving your template the input to use for rendering and then comparing output with the specified HTML. | ||
- `fixtures` is an object by default. It contains all the fixtures that are found within the fixture folder of this component. If a `withoutFixtures` option is passed to the `getComponent` method, `fixtures` will be a method that will run JEST SnapShot tests for your fixture. You will still be able to get fixture content by the filename: `fixtures[FixtureFileName]`. | ||
|
||
The JSON file and HTML file comprising a test should follow the pattern below (check the `fixtures` folder in File Structure section): | ||
### Example | ||
You can find examples in the `tests` folder. The boilerplate looks like this: | ||
|
||
``` | ||
{test-case}.html | ||
{test-case}.json | ||
{another-test-case}.html | ||
{another-test-case}.js | ||
``` | ||
const { getComponent } = require('marko-tester'); | ||
const { render } = getComponent('../index.marko'); | ||
### Component client-side testing | ||
describe('When component is rendered', () => { | ||
let component; | ||
The client test works by instantiating a marko-widget and testing the functionality against it. For that browser environment is needed, for those purposes marko-tester uses jsdom to render the lasso-generated page and expose window object. | ||
|
||
During client testing, `marko-tester` gives you a few methods to utilize: | ||
|
||
* **describe.page** - Will create an empty page, giving you access to window and document objects. This method is available right after test case declaration. | ||
* **describe.component** - Used to build the page with the component constructor in it. At this point, the `marko.component` attribute will be exposed to the mocha context giving you access to your widget's instance. This method is available right after test case declaration. | ||
|
||
``` | ||
'use strict'; | ||
// First describe in spec files will be read by marko-tester to initialize test environment; | ||
// By default the describe string will be the path to autodiscovered renderer or `index.js` in the directory above; | ||
// If you specify a string for first describe, your text will be appended to the path of the directory above; | ||
describe(({ expect, sinon, fixtures }) => { | ||
// list of the params that are being returned in the callback: | ||
// expect - chai's expect; | ||
// sinon - library to spy and stub; | ||
// fixtures - will give you a list of attached test fixtures to current component; | ||
// mockRequire - exposes 'mock-require' npm module; | ||
describe.component(({ marko, modRequire }) => { | ||
// list of the params that are being returned in the callback: | ||
// modRequire - a helper function to require modules on a browser level; | ||
// marko - marko context that contains the component instance under `marko.component`; | ||
let mockHello; | ||
beforeEach(() => { | ||
mockHello = 'world'; | ||
marko.component.hello = mockHello; | ||
}); | ||
afterEach(() => { | ||
delete marko.component.hello; | ||
}); | ||
it('should have hello attribute', () => { | ||
expect(marko.compomnent.hello).to.be.equal(mockHello); | ||
}); | ||
beforeEach(() => { | ||
component = render(fixtures.default); | ||
}); | ||
}); | ||
``` | ||
|
||
By default, running `describe.component` will build the component using the `default` fixture (if there is one). If you wish to build the component using a different fixture, you can pass an option to do that before the callback: | ||
|
||
``` | ||
describe.component({ | ||
fixture: {} | ||
}, ({ marko }) => { ... }); | ||
``` | ||
|
||
### Few additional features | ||
|
||
1. `describe.component` and `describe.page` commands are just patched describe functions. That's why the `only` and `skip` operators can be used with these commands (e.g `describe.component.only()`, `describe.page.skip()`). | ||
2. If you want to mock require during client-side testing - you can do that using options for `testComponent` method. There as a key you can pass relative path to the necessary file that will be required. And the mock of that file as a value. Keep in mind that mocked require will only exist within this `buildComponent`.<br> | ||
``` | ||
describe.component({ | ||
mock: { | ||
require: { | ||
'../dep': { hello: 'world' }, | ||
some_node_module: { world: 'hello' } | ||
}, | ||
component: { | ||
'nested-component': { world: 'hello' } | ||
}, | ||
components: { | ||
'hello-worlds': [{ worlds: 'hello' }] | ||
} | ||
}, | ||
}, ({ marko }) => { ... }); | ||
``` | ||
afterEach(() => { | ||
component.destroy(); | ||
}); | ||
3. You can also use a different file layout if necessary. When your template has a top-level element of `tbody`, `tr`, or something else that expects a `table` element as a parent, you can add the `layout` parameter and set it to `table`. This will ensure JSDOM renders your component correctly. | ||
``` | ||
describe.component({ | ||
fixture: fixtures.basic, | ||
layout: 'table' | ||
}, ({ marko }) => { ... }); | ||
...your assertions... | ||
}); | ||
``` | ||
|
||
## Code style (linting) | ||
|
||
Apart from testing, consistent styling is another important part of keeping high quality code. For that particular reason, `marko-tester` comes with an `eslint` and `stylelint` checks built-in. It will check the style of your code when you execute the `markotester` command. | ||
|
||
It uses legacy (es5) **airbnb** configuration for ESLint and **standard** configuration for Stylelint (checkine both *less* and *css* files). | ||
|
||
## References | ||
|
||
* [Marko](http://markojs.com) | ||
* [Mocha](https://mochajs.org) | ||
* [Sinon](http://sinonjs.org/docs/) | ||
* [Expect](http://chaijs.com/api/bdd/) | ||
* [rewire](https://github.com/jhnns/rewire) | ||
* [mock-require](https://github.com/boblauer/mock-require) | ||
* [ESLint](http://eslint.org) | ||
* [eslint-airbnb-config](https://github.com/airbnb/javascript/tree/es5-deprecated/es5) | ||
* [eslint-config-ebay](https://github.com/darkwebdev/eslint-config-ebay) | ||
* [Stylelint](https://github.com/stylelint/stylelint) | ||
* [stylelint-config-standard](https://github.com/stylelint/stylelint-config-standard) | ||
* [Istanbul](https://github.com/gotwarlost/istanbul) | ||
* [jest](https://jestjs.io) | ||
|
||
## Thanks | ||
* [Dylan Piercey](https://github.com/DylanPiercey) | ||
* [Abiyasa Suhardi](https://github.com/abiyasa) | ||
|
||
## Licence | ||
MIT |
Oops, something went wrong.