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

Generating a test based on source examples #34

Closed
mik01aj opened this issue Nov 12, 2015 · 15 comments
Closed

Generating a test based on source examples #34

mik01aj opened this issue Nov 12, 2015 · 15 comments

Comments

@mik01aj
Copy link
Collaborator

mik01aj commented Nov 12, 2015

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.

@sapegin
Copy link
Member

sapegin commented Nov 16, 2015

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.

@mik01aj
Copy link
Collaborator Author

mik01aj commented Jun 3, 2016

I tried to build something, but I had to stop here.

@mik01aj
Copy link
Collaborator Author

mik01aj commented Jun 3, 2016

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:

image

@mik01aj
Copy link
Collaborator Author

mik01aj commented Jun 3, 2016

@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
Copy link
Member

sapegin commented Jun 5, 2016

@mik01aj You have push access ;-) I’ll make a new release.

@mik01aj
Copy link
Collaborator Author

mik01aj commented Jun 6, 2016

@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.

screenshot 2016-06-06 09 37 41

@mik01aj
Copy link
Collaborator Author

mik01aj commented Jun 6, 2016

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.

@sapegin
Copy link
Member

sapegin commented Jun 6, 2016

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.

@mik01aj
Copy link
Collaborator Author

mik01aj commented Jun 6, 2016

@sapegin please have a look at a4e9cf2. This is the simple solution (not a nice one)

@sapegin
Copy link
Member

sapegin commented Jun 6, 2016

Better than nothing, don’t know how to improve it ;-)

@mik01aj
Copy link
Collaborator Author

mik01aj commented Jun 6, 2016

So I added one more commit and finally got it working.

https://gist.github.com/mik01aj/5b0be7da5453b84a8a2a51b57611c2c7

image

@mik01aj
Copy link
Collaborator Author

mik01aj commented Jun 6, 2016

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.

@sapegin
Copy link
Member

sapegin commented Jun 6, 2016

Cool! I’d suggest to close it now until anyone wants more.

@mik01aj mik01aj closed this as completed Jun 6, 2016
@mik01aj
Copy link
Collaborator Author

mik01aj commented Jul 7, 2016

FYI: I updated my gist for v3.0.

@sapegin
Copy link
Member

sapegin commented Sep 20, 2016

I’m working on Node API and thinking about removing this hack. But I want to preserve functionality you need. Check #183 for details.

@sapegin sapegin mentioned this issue Sep 20, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants