d.zurico
d.zurico

Reputation: 99

angular - requireJs - karma

I've created a simple test application that write hello.

The application is: boot.js

   require.config({
  appDir: '',
  baseUrl: '',
  paths: {
    angular: 'app/bower_components/angular/angular',
    Controller: 'app/js/Controller'
  },
  shim: {
    'angular': {'exports': 'angular'}
  },
  config: {
  },
  priority: [
    "angular"
  ]
});

require(['app/js/Module'], function()
{
  console.log("Loaded!");
});

Module.js:

(function(define) {
  "use strict";

  define(['angular', 'Controller'],
          function(angular, NccController) {
            var app, appName = 'myApp';
            app = angular
                    .module(appName, [])
                    .controller('Controller', NccController);
            angular.bootstrap(document.getElementsByTagName("body")[0], [appName]);
            return app;
          });
}(define));

Controller.js

(function(define) {
  "use strict";
  define([], function()
  {
    var NccController = function($scope)
    {
      $scope.message = "ciao";           //data to graph


    };
    return NccController;
  });
}(define));

The content of karma.conf.js is:

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine', 'requirejs'],


    // list of files / patterns to load in the browser
    files: [
      {pattern: 'public_html/app/bower_components/angular/angular.js', included: false}

      'test-main.js',

      {pattern: 'public_html/app/js/*.js', included: false},
      {pattern: 'public_html/app/test/**/*Spec.js', included: false},
    ],


    // list of files to exclude
    exclude: [
      'public_html/app/js/boot.js'
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],


    // web server port
    port: 9876,


    // 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: true,


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


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

the test-main.js is

var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;

var pathToModule = function(path) {
  return path.replace(/^\/base\//, '').replace(/\.js$/, '');
};

Object.keys(window.__karma__.files).forEach(function(file) {
  if (TEST_REGEXP.test(file)) {
    // Normalize paths to RequireJS module names.
    allTestFiles.push(pathToModule(file));
  }
});

require.config({
  // Karma serves files under /base, which is the basePath from your config file
  baseUrl: '/base',
  paths: {
        'angular': 'public_html/app/bower_components/angular/angular',
        'Module': 'public_html/app/js/Module',
        'Controller': 'public_html/app/js/Controller',
    },

  // dynamically load all test files
  deps: allTestFiles,

  // we have to kickoff jasmine, as it is asynchronous
  callback: window.__karma__.start
});

the MainSpec.js is:

define(['Module','Controller'], function(angular,Module,Controller) {

  describe('Controller', function(){

  beforeEach(module('myApp'));

  it('should print hello', inject(function($controller) {
    var scope = {},
        ctrl = $controller('Controller', {$scope:scope});

    expect(scope.message).toBe('ciao');
  }));

});

});

But when i run the test i obtain:

/usr/local/lib/node_modules/karma/bin/karma start
INFO [karma]: Karma v0.12.17 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 36.0.1985 (Mac OS X 10.8.5)]: Connected on socket 14waTQA-kAa0VgYpvBBk with id 39770086
Chrome 36.0.1985 (Mac OS X 10.8.5) ERROR
  Uncaught TypeError: Cannot read property 'module' of undefined
  at /Users/daniele/Desktop/JARK/public_html/app/js/Module.js:8

What's wrong???? Thank you a lot.

Upvotes: 0

Views: 954

Answers (3)

Subash
Subash

Reputation: 7266

Look at this project that uses requirejs and karma for angular js. Try and follow the set up. https://github.com/adikari/angular-seed

Upvotes: 0

d.zurico
d.zurico

Reputation: 99

Great tbranyen, you've solved my great problem after 2 days of configuration. I post here all codes because I think that there're a lot of people that want to use angular/karma/RequireJs but have a lot of difficulty to setup all. So boot.js, Module.js and controller.js are the same otherwise the file:

karma.conf.js is:

// Karma configuration
// Generated on Sat Jul 26 2014 18:36:34 GMT+0200 (CEST)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine', 'requirejs'],



    // list of files / patterns to load in the browser
    files: [
      {pattern: 'public_html/app/bower_components/angular/angular.js', included: false},
      {pattern: 'public_html/app/bower_components/angular-mocks/angular-mocks.js', included: false},
      {pattern: 'public_html/app/js/*.js', included: false},
      {pattern: 'public_html/app/test/**/*Spec.js', included: false},
      'test-main.js',
    ],


    // list of files to exclude
    exclude: [
      'public_html/app/js/boot.js'
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],


    // web server port
    port: 9876,


    // 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: true,


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


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

test.main.js is:

var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;

var pathToModule = function(path) {
  return path.replace(/^\/base\//, '').replace(/\.js$/, '');
};

Object.keys(window.__karma__.files).forEach(function(file) {
  if (TEST_REGEXP.test(file)) {
    // Normalize paths to RequireJS module names.
    allTestFiles.push(pathToModule(file));
  }
});

require.config({
  // Karma serves files under /base, which is the basePath from your config file
  baseUrl: window.__karma__ ? "/base/" : "/",
  paths: {
        'angular': 'public_html/app/bower_components/angular/angular',
        'angular-mocks': 'public_html/app/bower_components/angular-mocks/angular-mocks',
        'Module': 'public_html/app/js/Module',
        'Controller': 'public_html/app/js/Controller',
    },
    shim: {
    'angular': {'exports': 'angular'},
    'angular-mocks': ['angular']
  },
});

require(['angular-mocks'], function() {
  require(allTestFiles, window.__karma__.start);
});

and MainSpec.js is:

define(['angular','angular-mocks','Module','Controller'], function(angular,mocks,Module,Controller) {

  describe('Controller', function(){

  beforeEach(module('myApp'));

  it('should print hello', inject(function($controller) {
    var scope = {},
        ctrl = $controller('Controller', {$scope:scope});

    expect(scope.message).toBe('ciao');
  }));

});

});

I hope that can help same people that want use it

Upvotes: 1

tbranyen
tbranyen

Reputation: 8577

Karma serves files under the /base/ root path, not /. You need to change your baseUrl property within the RequireJS configuration to be baseUrl: "/base/".

A simple way of handling this conditionally is:

baseUrl: window.__karma__ ? "/base/" : "/"

Edit:

I'm incorrect with the above, you have it configured correctly. The only other guess I have is that deps is loading your tests before the configuration has finished being set. Although you have mentioned that Angular loads 200 OK. My recommendation here would be to try extracting the test loading away from deps and instead break the configuration and loading into two different operations.

require.config({
  "paths": { "angular": "<path/to/angular>" }
});

require(allTestFiles, function() {
  window.__karma__.start();
});

I would also remove the callback from the karma Require configuration.

Edit 2:

Another recommendation would be to share your main application configuration so that you don't have to declare paths over again. An example of how this would look is:

https://gist.github.com/tbranyen/e37a7d888f7f90c25e63#file-config-js-L27-L28

Edit 3 (Hopefully last):

After debugging the project the error ended up being a missing Angular shim configuration in the test-main.js file.

Upvotes: 0

Related Questions