testing code transpiled for es6
Asked Answered
L

2

10

I'm preparing to write some tests with Qunit for a Backbone app that is written for ES6 with babel.js applied to it so that it can run in contemporary browsers. To ensure that I have qunit set up properly and all the paths properly specified, I first tested an Backbone model written in ES5 and everything worked as expected. However, I then included bundle.js (which contains the results of my ES6 code with babel.js applied to it) into my tests/index.html, and wrote

 test ( "Code transformed by babel.js contained in bundle.js can be tested", function(){
    expect(1);
    var es6model = new ES6Model();
    equal( es6model.get("defaultproperty"), "defaultstring", "defaultproperty should be defaultstring");
 })

and it's telling me ES6Model is not defined.

Question: is there something about code transformed by babeljs that would make it more challenging to be tested using Qunit?

In addition to all the complex js that babel writes at the top of the file, the code in bundle.js looks like this

var Model = Backbone.Model;
var View = Backbone.View;
var Collection = Backbone.Collection;
var Router = Backbone.Router;
var LocalStorage = Backbone.LocalStorage;

var ES6Model = (function (Model) {
    function ES6Model() {
        _classCallCheck(this, ES6Model);

        if (Model != null) {
            Model.apply(this, arguments);
        }
    }

    _inherits(ES6Model, Model);

    _prototypeProperties(Gopher, null, {
        defaults: {
            value: function defaults() {

                return {
                    defaultproperty: "defaultstring"

                };
            },
            writable: true,
            configurable: true
        }
    });

    return ES6Model;
})(Model);

Update

I include all the code created by babel.js in a file called bundle.js and include that in my index.html like I would any other js file, and it runs without issue, which is why I assumed I could test it like any other js code. However, it should be noted (as the commenter pointed out) that the code created by babel.js is contained in a module..this is how bundle.js begins with the model I'm trying to test coming after

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";

Update

I am using browserify to apply babel to the various files of my ES6 code which creates a bundle. To run the tests, I do npm run test and to compile the bundle, I try both of these (one of them uses modules --ignore) but neither of them work

"scripts": {

    "test": "./node_modules/karma/bin/karma start --log-level debug",
    "build-js": "browserify app/app.js app/views.js app/models.js  app/d3charts.js -t babelify > app/bundle.js",
    "t-build": "browserify app/app.js app/views.js app/models.js app/d3charts.js -t [babelify --modules ignore] > app/test/test-bundle.js"
  },

(The application is a Backbone.js app).

This is my karma config file. I don't have any further configuration (so I'm guessing my inclusion of karma-require is a waste but maybe necessary...)

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['qunit'],
    plugins: ['karma-qunit', 'karma-phantomjs-launcher', 'karma-requirejs'],

    files : [
      'app/test/jquery.js',     
      'app/test/d3.js',
      'app/test/json2.js',
      'app/test/underscore.js',
      'app/test/backbone.js',
      'app/backbone.localStorage.js',

      'app/test/test-bundle.js',
      'app/test/tests.js'

    ],


    reporters: ['progress'],

    // web server port
    port: 8080,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    // See https://mcmap.net/q/415943/-how-to-make-travis-execute-angular-tests-on-chrome-quot-please-set-env-variable-chrome_bin-quot
    customLaunchers: {
        Chrome_sandbox: {
            base: 'Chrome',
            flags: ['--no-sandbox']
        }
    }
  });
};
Lightless answered 27/2, 2015 at 0:40 Comment(2)
Probably "all that complex js at the top of the file" sets up a module scope in which ES6Model is contained. How do you include and call it in a normal page, does that work?Floccose
@Floccose lol. I include all the code created by babel.js in a file called bundle.js and include that just as I would any other js file, and it runs without issue, that's why I assumed there wouldn't be any issues testing it like ordinary js. But yes, you are right, it does seem to create a module scope as bundle.js starts like this (function e(t,n,r){function s(o,u){if(!n[o])...Lightless
R
3

For reference they way to do this with traceur is to compile the traceur-runtime.js file into the code (see https://github.com/google/traceur-compiler/issues/777 - a similar variable not defined error).

E.g.

traceur --out out/src/yourcode.js --script lib/traceur-runtime.js --script test/yourcode.js

(see Compiling Offline https://github.com/google/traceur-compiler/wiki/Compiling-Offline).

Revivify answered 28/2, 2015 at 5:36 Comment(1)
Another solution here using a launcher file groups.google.com/forum/#!topic/traceur-compiler-discuss/…Revivify
T
1

Import the Babel-generated module into your test before executing (recommended)

You'll need to include a module loader (e.g. SystemJS) to handle the imports. Babel has excellent documentation for its module system.

It looks something like this:

System.import( 'path/to/ES6Module' )
  .then( function( ES6Module ) {
    // … Run your tests on ES6Module here
  });

Note: System.import() returns a Promise, so your test suite will need to support asynchronous operations.


Tell Babel to skip module generation (simpler)

You can tell Babel not to wrap your code in a module using the --modules ignore flag. This allows your code to set up global variables, immediately available to your unit tests. Global variables are not recommended (especially in production systems), but they are simpler to apply.

Tinstone answered 28/6, 2015 at 3:7 Comment(6)
I tried --modules ignore and while it got me past the initial issue that made me post this question, it didn't fix every problem. For example, my ES6 app is made up of several files, and the import statements between those files didn't seem to be respected i.e. some of the functions imported from one of the file were still not visible in the tests.Lightless
@Lightless that is exactly what --modules ignore is supposed to do, so it might be good to try SystemJS insteadTinstone
after I wrote my comment, I realized maybe I didn't express myself clearly. I use browserify to apply babel to my ES6 code,and I pass it the --modules ignore flag. this puts all the ES6 code in the bundle.js file. While you say that's what --modules ignore is "supposed to do", I can still see functions in the bundle.js file from the various files that went into creating the bundle.js file, so either --modules ignore didn't do its thing, or I don't understand what you mean. Either way, when I write tests, even if the functions are in the bundle.js, the test code can't see themLightless
Ah, that is a difference…instead of explaining your setup, could you share your browserify configuration and which test suite you're using?Tinstone
I updated the OP with the lines from package.json that I use to create the bundle and also to run the tests. Also added the karma config file. Appreciate any help you can provide.Lightless
@Lightless thanks for the extra context. Maybe try this link: derickbailey.com/2014/06/18/…Tinstone

© 2022 - 2024 — McMap. All rights reserved.