coryhouse / react-slingshot

React + Redux starter kit / boilerplate with Babel, hot reloading, testing, linting and a working example app built in
MIT License
9.74k stars 2.95k forks source link

tests throw error when loading images in components #102

Closed jonahlau closed 8 years ago

jonahlau commented 8 years ago

I'm having trouble running tests on component files where I load image using file loader. The images load fine and webpack builds properly with no issues when the environment is not test. This can be reproduced in the starter kit out of the box by requiring an image (e.g. const img = require('./image.png')) in src/components/AboutPage.js and then running npm test.

Is there a recommended approach on how to include images so tests run properly? Thanks for your help in advance!

I get this error when the tests are run:

SyntaxError: /Users/jonathan/Documents/development/react-slingshot/src/components/logo.png: Unexpected character '�' (1:0)
> 1 | �PNG
    | ^
  2 |
  3 |
  4 | IHDRK8Nz�tEXtSoftwareAdobe ImageReadyq�e<xiTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.5-c021 79.155772, 2014/01/13-19:44:00        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpMM:OriginalDocumentID="xmp.did:1137358d-5c79-4cc7-a595-c6968251149a" xmpMM:DocumentID="xmp.did:753CB9F0E9B311E5B5BEF0A4346D0307" xmpMM:InstanceID="xmp.iid:753CB9EFE9B311E5B5BEF0A4346D0307" xmp:CreatorTool="Adobe Photoshop CC 2014 (Macintosh)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:a733f891-b46a-4482-ae4c-3f48a7eb83f0" stRef:documentID="xmp.did:1137358d-5c79-4cc7-a595-c6968251149a"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>�+@IDATx��\�e�~{�'l�9���T$IYEAD8�DO�ALx�yz�3AEA<уSQ8�J�
                                                                                                           +iٜs�I�}�5˰��, �w����33;�_�W_�[o�W������Ѻ��?�OYW��=?�Kh�K|��I����,#Y�s��Lz�/β�x������Io>�3����a�U$�|N�'�n3�cM\s��$W�d�<��$a�~0�:��I�l$�#IG���F�F��C$KI�I����&YK2��AY&��$�H��g��<CR�Vu�_=����8&�
                                                                              �k�u�$)g%>���,+I"���&�~$�$���{`Sɓl1{H���
@r�į�X��غ^��_O2�?EYRIBI�X9�yrϑ$��"��q�{������U� � �[Q/'ɛ�8!$���OI^'9N2엢,A9�Ar��8$�A��
                                                                                                �����\K2���c
    at Parser.pp.raise (/Users/jonathan/Documents/development/react-slingshot/node_modules/babylon/index.js:1378:13)
    at Parser.getTokenFromCode (/Users/jonathan/Documents/development/react-slingshot/node_modules/babylon/index.js:5250:10)
    at Parser.readToken (/Users/jonathan/Documents/development/react-slingshot/node_modules/babylon/index.js:4887:19)
    at Parser.<anonymous> (/Users/jonathan/Documents/development/react-slingshot/node_modules/babylon/index.js:4338:20)
    at Parser.readToken (/Users/jonathan/Documents/development/react-slingshot/node_modules/babylon/index.js:3632:22)
    at Parser.nextToken (/Users/jonathan/Documents/development/react-slingshot/node_modules/babylon/index.js:4877:19)
    at Parser.parse (/Users/jonathan/Documents/development/react-slingshot/node_modules/babylon/index.js:1348:10)
    at Object.parse (/Users/jonathan/Documents/development/react-slingshot/node_modules/babylon/index.js:45:50)
    at File.parse (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/index.js:479:24)
    at File.parseCode (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/index.js:568:20)
    at /Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/node_modules/babel-core/lib/transformation/pipeline.js:48:12
    at File.wrap (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/node_modules/babel-core/lib/transformation/file/index.js:528:16)
    at Pipeline.transform (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/node_modules/babel-core/lib/transformation/pipeline.js:46:17)
    at Object.transformFileSync (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/node_modules/babel-core/lib/api/node.js:124:10)
    at compile (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/lib/node.js:98:20)
    at loader (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/lib/node.js:126:14)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/lib/node.js:136:7)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at Object.<anonymous> (AboutPage.js:5:11)
    at Module._compile (module.js:435:26)
    at loader (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/lib/node.js:126:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/lib/node.js:136:7)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at Object.<anonymous> (AboutPage.spec.js:3:1)
    at Module._compile (module.js:435:26)
    at loader (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/lib/node.js:126:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/jonathan/Documents/development/react-slingshot/node_modules/babel-register/lib/node.js:136:7)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at /Users/jonathan/Documents/development/react-slingshot/node_modules/mocha/lib/mocha.js:216:27
    at Array.forEach (native)
    at Mocha.loadFiles (/Users/jonathan/Documents/development/react-slingshot/node_modules/mocha/lib/mocha.js:213:14)
    at Mocha.run (/Users/jonathan/Documents/development/react-slingshot/node_modules/mocha/lib/mocha.js:453:10)
    at loadAndRun (/Users/jonathan/Documents/development/react-slingshot/node_modules/mocha/bin/_mocha:349:22)
    at rerun (/Users/jonathan/Documents/development/react-slingshot/node_modules/mocha/bin/_mocha:376:5)
    at /Users/jonathan/Documents/development/react-slingshot/node_modules/mocha/bin/_mocha:384:7
    at StatWatcher.<anonymous> (/Users/jonathan/Documents/development/react-slingshot/node_modules/mocha/lib/utils.js:173:9)
    at emitTwo (events.js:87:13)
    at StatWatcher.emit (events.js:172:7)
    at StatWatcher._handle.onchange (fs.js:1290:10)
coryhouse commented 8 years ago

When working with Mocha and Webpack, the problem is: How do we handle Webpack-specific features that Mocha doesn’t understand like required images and CSS?

Option 1: Bundle with Webpack first. Setup a dedicated Webpack config for testing. Utilize the null-loader for any features that Mocha doesn’t understand. Create an entry point for your tests where you list all the test files. Related StackOverflow Post.

The downsides: You have to create and maintain a file that lists all your files under test. I haven't tried this, but I also suspect debugging tests would be trickier since the line numbers provided by Mocha would be compiled source.

Option 2: Disable individual features ad-hoc. For example, we're already disabling imported CSS using ignore-styles. Note how that is passed to Mocha on the command line in the test script.

The downside: You have to find a way around each Webpack-specific feature you use, one-by-one.

I definitely want to avoid option 1 because listing all tests is an ongoing hassle and may lead to tests not being run (because someone forgot to add them to the index file). Option 2, in contrast, is merely a one time hassle. I'm currently looking for a way to disable required images. This looks promising. As does this.

jonahlau commented 8 years ago

Thanks for the quick response. I just tried option 2 and it worked like a charm.

I definitely agree that specifying the file types to ignore on a case by case basis in option 2 definitely seems less error-prone than option 1. If you have a team of developers working on the same project, like you said, one would very likely end up with someone forgetting to "register" their tests and they end up not being run.

One way is to pass to the --compilers option a standard list of image file types that all return null in a mocha.opts file? If there are missing image file types, they can just be added to the list.

coryhouse commented 8 years ago

Great to hear! It worked for me as well (coincidentally I hit the same issue today). Check out my latest commit for my fix.

Thanks for reporting!