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

Can't use JSX in test files (but can in imported ones) #458

Closed
tomazzaman opened this issue Jan 19, 2016 · 19 comments
Closed

Can't use JSX in test files (but can in imported ones) #458

tomazzaman opened this issue Jan 19, 2016 · 19 comments

Comments

@tomazzaman
Copy link

Here's the test file I'm trying to run:

import test from 'ava';
import React from 'react';
import { createRenderer } from 'react-addons-test-utils';
import FieldError from '../../../js/components/form/FieldError.js';

test('FieldError shows when the error is in array', t => {
  const renderer = createRenderer();

  const errors = [{ attribute: 'email', code: '123' }];
  renderer.render(
    <FieldError resource="user" attribute="email" code="123" errors={ errors }>
      Error message
    </FieldError>
  );
  const resuslt = renderer.getRenderOutput();

  t.same(result, '<span class="form__error">Error message</span>');
});

The command I'm using:

$ NODE_ENV=development node ./node_modules/.bin/ava client/test/components/form/FieldError.spec.js

I get a syntax error on the line with JSX:

SyntaxError: /Users/Tomaz/Projects/MyProject/client/test/components/form/FieldError.spec.js: Unexpected token (11:4)
    at Parser.pp.raise (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:1413:13)
    at Parser.pp.unexpected (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:2895:8)
    at Parser.pp.parseExprAtom (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:746:12)
    at Parser.pp.parseExprSubscripts (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:501:19)
    at Parser.pp.parseMaybeUnary (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:481:19)
    at Parser.pp.parseExprOps (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:412:19)
    at Parser.pp.parseMaybeConditional (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:394:19)
    at Parser.pp.parseMaybeAssign (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:357:19)
    at Parser.pp.parseExprListItem (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:1224:16)
    at Parser.pp.parseCallExpressionArguments (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:577:20)
    at Parser.pp.parseSubscripts (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:540:29)
    at Parser.pp.parseExprSubscripts (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:511:15)
    at Parser.pp.parseMaybeUnary (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:481:19)
    at Parser.pp.parseExprOps (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:412:19)
    at Parser.pp.parseMaybeConditional (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:394:19)
    at Parser.pp.parseMaybeAssign (/Users/Tomaz/Projects/MyProject/node_modules/babylon/index.js:357:19)
From previous event:
    at Api.run (/Users/Tomaz/Projects/MyProject/node_modules/ava/api.js:148:4)
    at Object.<anonymous> (/Users/Tomaz/Projects/MyProject/node_modules/ava/cli.js:110:5)
    at Module._compile (module.js:398:26)
    at Object.Module._extensions..js (module.js:405:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:430:10)
    at startup (node.js:141:18)
    at node.js:980:3

My .babelrc:

{
  "presets": ["react", "es2015", "stage-0"],
  "env": {
    "development": {
      "plugins": [
        ["react-transform", {
          "transforms": [{
            "transform": "react-transform-hmr",
            "imports": ["react"],
            "locals": ["module"]
          }, {
            "transform": "react-transform-catch-errors",
            "imports": ["react", "redbox-react"]
          }]
        }]
      ]
    }
  }
}

I've tried running the command with babel-node, but the result is the same.

Not sure what else to try (apart from avoiding JSX in tests all together)

@vadimdemedes
Copy link
Contributor

JSX is not yet supported in AVA's tests.

As a workaround, you can separate <FieldError> component in a separate file, which you can compile yourself via babel. Then, import the already compiled component and do something like:

renderer.render(React.createElement(FieldError, props));

@tomazzaman
Copy link
Author

Yep, that's what I'm doing now, here's a working test:

import test from 'ava';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import FieldError from '../../../js/components/form/FieldError.js';

test('FieldError shows when the error is in array', assert => {
  const errors = [{ attribute: 'email', code: '123' }];

  const field = React.createElement(FieldError, {
    errors,
    attribute: 'email',
    code: '123',
  }, 'Error message');

  const result = ReactDOMServer.renderToStaticMarkup(field);

  assert.same(result, '<span class="form__error">Error message</span>');
});

@vadimdemedes
Copy link
Contributor

Would be great to describe this workaround in a "Testing with React" recipe (#446).

@tomazzaman Do you have some free time to contribute a recipe for React? No worries if not ;)

@tomazzaman
Copy link
Author

Sure, I'd be more than happy, just let me know what to do, I'm quite a noob on contributing on GH :)

@vadimdemedes
Copy link
Contributor

No probs, you'll love it! So, here's what you'll need to do:

  1. Check out our Contributing guide, especially "Submitting a pull request" part.
  2. Fork the ava repository to your account.
  3. Clone tomazzaman/ava repository.
  4. Create a new git branch with a short descriptive name of your work (e.g. react-recipe).
  5. Create a new markdown file for your React recipe in docs/recipes (e.g. docs/recipes/react.md).
  6. Write the recipe. You can check out recipes submitted by other contributors for inspiration - Add a code coverage recipe #444 and add endpoint testing example to FAQ #402
  7. After you review your recipe and think it's ready to go, commit & push this branch to your repository
  8. Now go to https://github.com/tomazzaman/ava and you'll see GitHub offering to send a pull request of your branch. Here's the official guide on sending pull requests - https://help.github.com/articles/using-pull-requests/.

Let me know if you need any help ;)

@tomazzaman
Copy link
Author

Will do! Thanks for the step-by-step guide! I'll get on it once kids are in bed :)

@mattkrick
Copy link
Contributor

That's weird, FWIW JSX works natively in my tests, not sure what the difference is: https://github.com/mattkrick/redux-socket-cluster/blob/master/__tests__/index-tests.js#L46

@wyze
Copy link

wyze commented Jan 19, 2016

@mattkrick JSX works on 0.9.x as it reads in the .babelrc, but reading in the .babelrc file was removed in 0.10.

@mattkrick
Copy link
Contributor

ohhhh good to know. you just saved me a future headache, cheers

@tomazzaman
Copy link
Author

@vdemedes I have another recipe that doesn't necessarily include AVA but I think it could be very useful for the users so I was wondering whether you'd be interested in publishing it here. I first planned a blog post, but I think it'll get bigger exposure here. It's about integration testing.

@benji6
Copy link

benji6 commented Jan 21, 2016

Can I check whether AVA plans to add support for JSX again in the future or whether I should be keeping all my tests in plain JS?

@vadimdemedes
Copy link
Contributor

@tomazzaman Could you send me a draft I can read?

@benji6 I don't think we had this discussion among core team members, but as for me personally I would like to add native JSX support in future. At the moment, feel free to use the workaround described in this thread.

@tomazzaman
Copy link
Author

@vdemedes see this gist. It's not complete, I'd explain what this script does in much more detail and why some decisions were made.

@vadimdemedes
Copy link
Contributor

@tomazzaman Not sure about this, as it's out of AVA's scope in my opinion. There are many ways to do integration testing, and I don't feel that we can have one universal recipe for it. Let's see what others think anyway ;) /cc @sindresorhus @jamestalmage

@tomazzaman
Copy link
Author

Okay, no problem, I do have some other piece of code I'd like to share though; A basic continuous runner that keeps the process open for instant feedback. I can turn this into a recipe as well.

import path from 'path';
import childProcess from 'child_process';
import program from 'commander';
import chokidar from 'chokidar';
import { isMatch } from 'micromatch';
const AVA = require.resolve('ava/cli.js');

program
  .version('0.0.1')
  .option('-c, --coverage', 'Include code coverage')
  .option('-s, --single-run', 'Exit the process after first run')
  .parse(process.argv);

let commandArray = [AVA];
if (program.coverage) {
  const NYC = path.resolve('node_modules/nyc/bin/nyc.js');
  commandArray = [NYC, '--cache', '--reporter=text', '--reporter=html'].concat(commandArray);
}

const sourcesGlob = 'client/js/**/*.js';
const testsGlob = 'client/test/**/*.spec.js';

const watcher = chokidar.watch([sourcesGlob, testsGlob]);

watcher.on('add', function add(filepath) {
  this.sourceFiles = this.sourceFiles || [];
  this.testFiles = this.testFiles || commandArray;

  if (isMatch(filepath, sourcesGlob)) {
    this.sourceFiles.push(filepath);
  } else if (isMatch(filepath, testsGlob)) {
    this.testFiles.push(filepath);
  }
});

watcher.on('ready', function ready() {
  runSuite(this.testFiles);
});

watcher.on('change', function change(filepath) {
  runSuite(this.testFiles);
});

function runSuite(testFiles) {
  console.log('Running tests...');
  const command = testFiles.concat('--color');

  const runner = childProcess.execFile(process.execPath, command, (error) => {
    const exitCode = error ? error.code : 0;
    if (program.singleRun) process.exit(exitCode);
  });

  runner.stdout.pipe(process.stdout);
  runner.stderr.pipe(process.stderr);
}

@sindresorhus
Copy link
Member

Not sure about this, as it's out of AVA's scope in my opinion.

I agree.

A basic continuous runner that keeps the process open for instant feedback. I can turn this into a recipe as well.

I think it would be better as a pull request for #70.

@tomazzaman
Copy link
Author

@sindresorhus I'll have a go during the weekend

@sindresorhus
Copy link
Member

@tomazzaman \o/ :)

MoOx added a commit to MoOx/phenomic that referenced this issue Feb 9, 2016
We can't use jsx in test
avajs/ava#458
@novemberborn
Copy link
Member

Let's move the JSX recipe discussion to #446.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants