Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to use helper classes within unit tests of a bundled aurelia app. RequireJS Configuration?

Summary

Using the aurelia cli and the default tasks that are included, I am unable to leverage helper classes that are located within the test folder in my unit tests.

Details

Starting with the sample app created with au new, I have a contrived helper class located within 'test/util/helper.ts':

export class Helper {
    Property : string;
}

This class is imported by the test/unit/app.spec.ts file:

import {App} from '../../src/app';
import {Helper} from "../util/helper";

describe('the app', () => {
  it('says hello', () => {
    let h = new Helper();
    h.Property = "Testing";
    expect(h.Property).toBe("Testing");
    expect(new App().message).toBe('Hello World!');
  });
});

Approach #1 - Bundling I have modified the aurelia.json file in a few places:

  • Change the source of the typescript compiler to include files under the test folder

    "transpiler": {
       "id": "typescript",
       "displayName": "TypeScript",
       "fileExtension": ".ts",
       "dtsSource": [
         "./typings/**/*.d.ts",
         "./custom_typings/**/*.d.ts"
       ],
       "source": ["src\\**\\*.ts","test\\**\\*.ts"]
    },
    
  • Modify the app-bundle to exclude any file from the test folder

      {
        "name": "app-bundle.js",
        "source": {
          "include": [
            "[**/*.js]",
            "**/*.{css,html}"
          ],
          "exclude": [
            "**/test/**/*"
          ]
        }
      },
    
  • Add a new bundle (test-util-bundle), which includes files from the test\util folder and excludes files within the src and test/unit folders

    {
      "name": "test-util-bundle.js",
      "source": {
        "include": [
          "[**/*.js]"
        ],
        "exclude": [
          "**/src/**/*",
          "**/test/unit/**/*"
        ]
      }
    },
    

After bundling the app with 'au build', I have three bundles (app/vendor/test-util), with the test-util-bundle.js bundle defining the helper class like this:

define('../test/util/helper',["require", "exports"], function (require, exports) {
    "use strict";
    var Helper = (function () {
        function Helper() {
        }
        return Helper;
    }());
    exports.Helper = Helper;
});

I suspect this is the root of the problem, but not that familiar with RequireJS.

When I do run 'au test' the test fails with the following error:

11 10 2016 12:05:24.606:DEBUG [middleware:source-files]: Fetching C:/git/aurelia-cli-testing/test/test/util/helper
11 10 2016 12:05:24.608:WARN [web-server]: 404: /base/test/test/util/helper
Chrome 53.0.2785 (Windows 7 0.0.0) ERROR
Uncaught Error: Script error for "C:/git/aurelia-cli-testing/test/test/util/helper", needed by: C:/git/aurelia-cli-testing/test/util/helper
http://requirejs.org/docs/errors.html#scripterror
at C:/git/aurelia-cli-testing/scripts/vendor-bundle.js:3763

Note: This works fine if I move the helper.ts file under the src tree (as done here). This is all available here if you would like to see the behavior.

Approach #2 - Without Bundling of utility class

  • Modify karma.conf.js
    let testSrc = [
      { pattern: project.unitTestRunner.source, included: false },
      { pattern: "test/util/**/*.ts", included: false },
      'test/aurelia-karma.js'
    ];

    ...

    preprocessors: {
      [project.unitTestRunner.source]: [project.transpiler.id],
      ["test/util/**/*.ts"]: [project.transpiler.id]
    },

With this modification (no bundling of the utility class) karma produces the following error:

18 10 2016 16:56:59.151:DEBUG [middleware:source-files]: Fetching C:/git/aurelia-cli-testing/test/util/helper
18 10 2016 16:56:59.152:WARN [web-server]: 404: /base/test/util/helper
Chrome 53.0.2785 (Windows 7 0.0.0) ERROR
  Uncaught Error: Script error for "C:/git/aurelia-cli-testing/test/util/helper", needed by: C:/git/aurelia-cli-testing/test/unit/app.spec.js
  http://requirejs.org/docs/errors.html#scripterror
  at C:/git/aurelia-cli-testing/scripts/vendor-bundle.js:3763

Thanks for reading, any help would be greatly appreciated!

like image 268
Chris Mancini Avatar asked Oct 11 '16 21:10

Chris Mancini


2 Answers

With the help of an Aurelia team member, a small modification to the aurelia-karma.js file that is distributed with the aurelia cli fixes the issue:

The normalizePath function should be modified to append '.js' where applicable:

function normalizePath(path) {
  var normalized = []
  var parts = path
    .split('?')[0] // cut off GET params, used by noext requirejs plugin
    .split('/')

  for (var i = 0; i < parts.length; i++) {
    if (parts[i] === '.') {
      continue
    }

    if (parts[i] === '..' && normalized.length && normalized[normalized.length - 1] !== '..') {
      normalized.pop()
      continue
    }

    normalized.push(parts[i])
  }

  //Use case of testing source code. RequireJS doesn't add .js extension to files asked via sibling selector
  //If normalized path doesn't include some type of extension, add the .js to it
  if(normalized.length > 0 && normalized[normalized.length-1].indexOf('.') < 0){
    normalized[normalized.length-1] = normalized[normalized.length-1] + '.js';
  }

  return normalized.join('/')
}
like image 184
Chris Mancini Avatar answered Sep 27 '22 23:09

Chris Mancini


I had to do the following: 1. update the aurelia-project/aurelia.json file. add this

  "unitTestRunnerUtils": {
"id": "karmaUtils",
"displayName": "Karma",
"source": "test\\utils\\**\\*.js"   },

Then in the karma.conf.js file updated these two places.

let testSrc = [ { pattern: project.unitTestRunner.source, included: false }, { pattern: project.unitTestRunnerUtils.source, included: false}, 'test/aurelia-karma.js' ];

and

preprocessors: { [project.unitTestRunner.source]: [project.transpiler.id], [project.unitTestRunnerUtils.source]: [project.transpiler.id] },

And then it worked...

Here is the example project on github.

https://github.com/duranmg/demo-aurelia-testing

like image 32
Mike Avatar answered Sep 27 '22 23:09

Mike