Generating a test based on source examples
mik01aj opened this issue · 15 comments
It would be cool if we could have a task to run all the code examples from the docs and check that they don't throw exceptions both when used with ReactDOM.render
and ReactDOMServer.renderToString
. I'd like to put it in npm test
task for my project and have it checked with CI.
We just need to get the examples using examples.loader
, and do it for all the code
chunks.
I would even implement it myself, but I can't figure out how. I thought I could write something similar to mocha-loader, but I just don't get what's going on there (it's a pitch loader, whatever that really means).
Or maybe enhanced-require (unmaintained 😞) in Node would help? I have no idea.
Webpack docs about usage in Node.js might be useful.
I do not argue that we need a feature like this in react-styleguidist, but I'd like to have this for my project, and imho having a recipe how to do this could be also useful for others.
Not sure I can help you much with this. And I agree that it’s not in the scope of this project. But if you need the examples loader I can extract it to a separate package.
But leaving that bug aside, I was able to run a test for one component using this code (mochatest.js
):
require('testdom')('<html><body></body></html>');
var React = require('react');
var TestUtils = require('react-addons-test-utils');
var _ = require('lodash');
var babel = require('babel-core');
var babelConfig = require('./package.json').babel;
global.React = React; // needed for all examples
describe('Button', function() {
global.Button = require('./ui/Button');
// var markdownContent = require('./ui/Button/examples.md');
var markdownContent = require('./examples'); // because of https://github.com/istarkov/babel-plugin-webpack-loaders/issues/98
var codeChunks = _.filter(markdownContent, {type: 'code'});
_.forEach(codeChunks, (chunk, index) => {
it(`should work as in example ${index}`, function () {
var transformedCode = babel.transform(chunk.content, babelConfig).code;
var vDom = chunk.evalInContext(transformedCode, _.noop); // noop for setState
TestUtils.renderIntoDocument(vDom);
});
});
});
I also needed a bit of webpack config for it - webpack.test.config.js
:
module.exports = {
output: {
libraryTarget: 'commonjs2', // Needed for babel-plugin-webpack-loaders
},
module: {
loaders: [
{
test: /\.scss$/,
loader: 'style!css!postcss!resolve-url!sass',
},
{
test: /\.md$/,
loader: 'react-styleguidist/loaders/examples',
},
{test: /\.(png|jpg|gif|eot|woff|woff2|ttf|svg)$/, loader: 'url?limit=8192'},
],
},
resolve: {
extensions: ['', '.js', '.jsx'],
},
};
I run the tests with:
BABEL_DISABLE_CACHE=1 NODE_ENV=test `npm bin`/mocha --compilers js:babel-register mochatest.js
Result:
@sapegin I made some more progress, but I need to change one thing in styleguidist: instead of:
require('styleguide!')
we would do:
require('styleguide!' + pathToConfigFile)
Then it would be possible to reuse that loader. Otherwise it always looks for the config path in process.argv
...
If you could change this for me, it would be great! :)
@sapegin I tried, but it's difficult because the config is needed pretty much everywhere. I believe it should be passed explicitly to every "part", rather than required
by each module. I could add a flag to override the logic of finding and loading the config, but this feels ugly.
Maybe the server
and build
could call some config.init(argv)
at the beginning. I don't see any better way since we need to pass the config to other loaders too (like props.loader
), and we even can't serialize the config (to pass it as a loader query param) because it contains JS functions.
That’s difficult but important task. But I’m still not sure about the best (or at least good) way to solve it.
Passing the config (not just a file path) explicitly would be the best but seems impossible with loaders. But we can start with just a file name, it’s better than nothing anyway.
Better than nothing, don’t know how to improve it ;-)
So I added one more commit and finally got it working.
https://gist.github.com/mik01aj/5b0be7da5453b84a8a2a51b57611c2c7
So, to sum up, I was able to setup the code for my project (code in gist) but it's hacky as it uses some undocumented APIs (setting globals manually, chunk.evalInContext
, component.nameFallbak
typo, etc). If more people want it, we could refactor styleguidist so that it's easier to do this kind of tests.
Cool! I’d suggest to close it now until anyone wants more.
FYI: I updated my gist for v3.0.