Getting chai to play nice with requirejs - requirejs

I am attempting to set up Karma/Mocha/Chai into my Backbone project, which uses requirejs and not having much luck.
First, here's my setup:
- app/
- js/
- bower_components/
- node_modules/
- test/
- test-main.js
- karma.conf.js
// relevant bits of karma.conf.js
frameworks: ['mocha', 'requirejs', 'chai'],
files: [
'test/test-main.js',
{pattern: 'bower_components/requirejs-text/text.js', included: false},
{pattern: 'bower_components/jquery/dist/jquery.js', included: false},
{pattern: 'bower_components/underscore/underscore.js', included: false},
{pattern: 'bower_components/backbone/backbone.js', included: false},
{pattern: 'app/js/**/*.js', included: false},
{pattern: 'test/**/*Spec.js', included: falase}
],
exclude: [ 'app/js/requireConfig.js', 'app/js/main.js' ],
preprocessors: { '**/*.html': [] },
// test-main.js
var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$\i;
var pathToModules = function(path) {
return path.replace(/^\/base\//, '').replace(/\.js$/, '');
}
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.text(file)) {
allTestFiles.push(pathToModule(file));
}
});
require.config({
baseUrl: '/base/app/js',
paths: {
text: '../../bower_components/requirejs-text/text',
jquery: '../../bower_components/jquery/dist/jquery',
underscore: '../../bower_components/underscore/underscore',
backbone: '../../bower_components/backbone/backbone',
test: '../../test',
},
deps: allTestFiles,
callback: window.__karma__.start;
});
When I run karma, I get:
Error: Mismatched anonymous define() module: function(module) {
--the entire contents of text.js --
I tried changing the order of "frameworks" to frameworks: ['mocha', 'chai', requirejs'], which made the mismatch error go away, but then got:
TypeError: 'undefined' is not an object (evaluating 'window.chai.should')
This is a known issue and the recommendation is to keep requirejs before chai.
Does anyone have experience getting requirejs-text to work? Thanks.

Welp, sorry to waste a question on SO. I started from scratch and my above configuration (aside from needing "{pattern: 'app/js/**/*.html', included: false}") worked fine.
For completeness, here is the updated configuration:
- app/
- js/
- bower_components/
- node_modules/
- test/
- test-main.js
- karma.conf.js
// ---- relevant bits of karma.conf.js ----
// "requirejs" must come before "chai" or Chai will not load properly.
// Sidenote: Karma loads the listed frameworks backwards.
frameworks: ['mocha', 'requirejs', 'chai'],
// Contrary to what a few stackoverflow and github issue responses
// suggested, the order of files do not appear to matter at all.
files: [
'test/test-main.js',
// app files
{pattern: 'app/js/**/*.html', included: false},
{pattern: 'app/js/**/*.js', included: false},
// tests
{pattern: 'test/**/*Spec.js', included: false},
// libraries
{pattern: 'bower_components/jquery/dist/jquery.js', included:false, watching: false},
{pattern: 'bower_components/underscore/underscore.js', included:false, watching: false},
{pattern: 'bower_components/backbone/backbone.js', included:false, watching: false},
{pattern: 'bower_components/requirejs-text/text.js', included:false, watching: false},
],
exclude: [ 'app/js/requireConfig.js', 'app/js/main.js' ],
preprocessors: {},
// ---- test-main.js ----
var allTestFiles = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
if (/Spec\.js$/.test(file)) {
allTestFiles.push(file);
}
}
}
require.config({
baseUrl: '/base/app/js',
paths: {
jquery: '../../bower_components/jquery/dist/jquery',
underscore: '../../bower_components/underscore/underscore',
backbone: '../../bower_components/backbone/backbone',
text: '../../bower_components/requirejs-text/text',
},
deps: allTestFiles,
callback: window.__karma__.start;
});

Related

Adding Karma, Jasmine specs to working anuglar app

We have an angular app under development. Business code is working and is almost stable. In the app, we have placed JSPs and ts (and generated *.js, *.js.map) files into different folders. Please find project folder structure below:
/angular
--node_modules
--package.json
--
--bills
--a.component.ts
--a.component.spec.ts
--a.component.js
--a.component.spec.js
--a.component.js.map
--a.component.spec.js.map
--pages
--com
--bills
--a.jsp
Karma start prints below error log:
c:\...\angular>.\node_modules\.bin\karma start
24 07 2018 15:33:27.883:ERROR [karma]: { Error: ENOENT: no such file or directory, open 'c:\..\angular\<jsp_path_mentioned_in_component_template_url>'
We cannot have JSPs and ts files in the same folder. We have lot of files and its not feasible to change the project structure now.
Could you help us know where to update karma config to pic JSP from a custom location.
Hope to find some helpful pointers/inputs. Thanks in advance.
Update: Added karma.config.js
karma.config.js:
module.exports = function(config) {
config.set({
basePath: '.',
frameworks: ['jasmine'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('karma-generic-preprocessor'),
require('karma-mocha-reporter'),
require('karma-sourcemap-loader')
],
client: {
clearContext: true // leave Jasmine Spec Runner output visible in browser
},
files: [
// System.js for module loading
'node_modules/systemjs/dist/system.src.js',
// Polyfills
'node_modules/core-js/client/shim.min.js',
'node_modules/systemjs/dist/system-polyfills.js',
// zone.js
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/long-stack-trace-zone.js',
'node_modules/zone.js/dist/proxy.js',
'node_modules/zone.js/dist/sync-test.js',
'node_modules/zone.js/dist/jasmine-patch.js',
'node_modules/zone.js/dist/async-test.js',
'node_modules/zone.js/dist/fake-async-test.js',
// RxJs
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
// Paths loaded via module imports: Angular itself
{ pattern: 'node_modules/#angular/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/#angular/**/*.js.map', included: false, watched: false },
{ pattern: 'systemjs.config.js', included: false, watched: false },
'karma-test-shim.js',
{ pattern: 'payment-pending/payment-pending-select.component.js', included: false, watched: true },
{ pattern: '**/test.component.js', included: false, watched: true },
{ pattern: '**/test.component.spec.js', included: false, watched: true },
],
proxies: {
// required for modules fetched by SystemJS
'/base/resources/js/plugins/angular/': '/base/node_modules/'
},
exclude: [],
preprocessors: { 'test.component.js': ['coverage'], "**/*.component.js": ["generic"], "**/*.js" : ['sourcemap']},
coverageReporter: {
includeAllSources: true,
dir: 'mycoverage/',
reporters: [
{ type: "html", subdir: "html" },
{ type: 'text-summary' }
]
},
reporters: ['mocha','coverage'],
mochaReporter: {
colors: {
success: 'green',
info: 'grey',
warning: 'yellow',
error: 'red'
},
symbols: {
success: '-',
info: '#',
warning: '!',
error: 'x'
}
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
genericPreprocessor: {
rules: [{
process: function (content, file, done, log) {
//Prepare content for parser
file.contents = new Buffer(content);
// Every file has a parser
var parse = require('gulp-inline-ng2-template/parser')(file, { base: "", useRelativePaths: true, templateExtension:'.jsp' });
// Call real parse function
parse(function (err, contents) {
// Callback with content with template and style inline
done(contents);
});
}
}]
},
})
}

karma-browserify coverage reports contain file include paths instead of source code

Using karma-browserify to do unit tests with Jasmine. The tests correctly run but the coverage reports show file include paths instead of source code. You can reproduce this by installing the following project and run 'gulp unit':
https://github.com/bshack/shackstack
Here is an example of the coverage report contents:
typeof require === "function" && require("/xxx/xxx/xxx/shackstack/app/media/script/service/utilities.js");
Here is my karma.config:
module.exports = function(karma) {
'use strict';
karma.set({
basePath: '',
frameworks: [
'jasmine',
'browserify'
],
files: [{
pattern: 'app/media/script/service/*.js',
included: true
},
{
pattern: 'app/media/test/spec/*Spec.js',
included: true
}],
reporters: [
'progress',
'coverage'
],
preprocessors: {
'app/media/script/service/*.js': [
'browserify',
'coverage'
],
'app/media/test/spec/*Spec.js': [
'browserify'
]
},
browsers: [
//'Chrome',
//'Firefox',
//'Safari',
'PhantomJS'
],
singleRun: false,
autoWatch: false,
// browserify configuration
browserify: {
debug: true,
transform: [
'brfs',
'browserify-shim'
]
},
coverageReporter: {
type: 'html',
dir: 'app/report/istanbul/',
subdir: '.'
},
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000
});
};
any thoughts?
Fixed, basically you don't use karma coverage as you would normally, instead you have to use istanbul as a browserify transform.
var istanbul = require('browserify-istanbul');
module.exports = function(karma) {
'use strict';
karma.set({
basePath: '',
frameworks: [
'jasmine',
'browserify'
],
files: [{
pattern: 'app/media/script/service/*.js'
},
{
pattern: 'app/media/test/spec/*Spec.js'
}],
reporters: [
'progress',
'coverage'
],
preprocessors: {
'app/media/script/service/*.js': [
'browserify'
],
'app/media/test/spec/*Spec.js': [
'browserify'
]
},
browsers: [
//'Chrome',
//'Firefox',
//'Safari',
'PhantomJS'
],
singleRun: false,
autoWatch: false,
browserify: {
debug: true,
transform: [
'brfs',
'browserify-shim',
istanbul({
ignore: ['**/node_modules/**']
})
]
},
coverageReporter: {
type: 'html',
dir: 'app/report/istanbul/',
subdir: '.'
},
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000
});
};

Simple Karma-RequireJS-Jasmine configuration fails

I have the following simple configuration.
My source code is simple JavaScript. No libraries or modules or anything else.
It appears that there is a specific order for loading things which seems to be tricky even for a simple System-Under-Test.
None of my specs are executing even though Karma starts properly. What could be the problem ?
My test-main.js is this.
var tests = ['bootstrap'];
for (var file in window.__karma__.files) {
if (/spec\.js$/.test(file)) {
tests.push(file);
console.log('[' + file + ']');
}
};
require.config({
// Karma serves files from '/base'
baseUrl: '/base/src',
paths: {
'individual': 'individual',
'demographic': 'demographic',
'tradingpartner': 'tradingpartner',
'enrollmentstate': 'enrollmentstate',
'affiliation': 'affiliation',
'address': 'address',
'provider': 'provider',
'transactionmessage': 'transactionmessage',
'transactionformat': 'transactionformat',
'jquery': '../lib/jquery',
'bootstrap': '../lib/bootstrap',
},
shim: {
'bootstrap':{
deps: ['jquery']
},
'individual':{
deps: ['demographic']
},
'business':{
deps:['demographic']
},
'tradingpartner':{
deps:['enrollmentstate']
},
'tradingpartner':{
deps:['affiliation']
}
},
// ask Require.js to load all the test spec files
//deps: filesToLoad
deps: tests,
// kickoff jasmine tests from karma, once require loading is complete
callback: window.__karma__.start
});
My karma.conf.js is this
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: 'D:/Angular-Demo',
// 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: 'lib/**/*.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'spec/**/*Spec.js', included: false},
'test/test-main.js',
],
// list of files to exclude
exclude: [
],
// 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_DEBUG,
// 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,
// required plugins to run unit testing using Karma & jasmin
plugins: [
'karma-jasmine',
'karma-requirejs',
'karma-junit-reporter',
'karma-commonjs',
'karma-coverage',
'karma-ng-html2js-preprocessor',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-safari-launcher',
'karma-ie-launcher',
'karma-opera-launcher',
'karma-phantomjs-launcher',
'karma-htmlfile-reporter'
]
});
};

How to optimize large js app with r.js optimizer + load libs like jquery, bootstrap from a CDN?

We have built a huge backbone-marionette application with a lot of different libraries (bootstrap, gmaps, momentjs etc.). Everything works like charm when I combine everything into a single even in production mode. To improve the performance most of the libraries should be loaded from a CDN now.
But this seems not be as easy as expected. I started with this great tutorial (http://tech.pro/blog/1639/using-rjs-to-optimize-your-requirejs-project) and added a infrastructure module which is responsible to load the external libs.
infrastructure.js
define([
'jquery'
], function($) {
'use strict';
});
main.js (it has grown in the last few months a bit :D)
require.config({
urlArgs: 'bust=1386581060770',
paths: {
// jquery: '../../bower_components/jquery/dist/jquery',
jquery: '//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min',
underscore: '../../bower_components/underscore/underscore',
marionette: '../../bower_components/marionette/lib/backbone.marionette',
backbone: '../../bower_components/backbone/backbone',
moment: '../../bower_components/moment/moment',
'moment.de': '../../bower_components/moment/lang/de',
text: '../../bower_components/text/text',
'backbone.modelbinder': '../../bower_components/backbone.modelbinder/Backbone.ModelBinder',
'backbone.analytics': '../../bower_components/backbone.analytics/backbone.analytics',
'requirejs-i18n': '../../bower_components/requirejs-i18n/i18n',
'jquery.cookie': '../../bower_components/jquery.cookie/jquery.cookie',
'jquery.simplePagination': '../../bower_components/jquery.simplePagination/jquery.simplePagination',
'underscore.string': '../../bower_components/underscore.string/dist/underscore.string.min',
parsleyjs: '../../bower_components/parsleyjs/dist/parsley',
'parsleyjs-de': '../../bower_components/parsleyjs/src/i18n/de',
'parsleyjs-comparison': '../../bower_components/parsleyjs/src/extra/validator/comparison',
requirejs: '../../bower_components/requirejs/require',
'underscore.deepExtend': '../../vendor/others/tools/underscore.mixin.deepExtend',
'underscore.templatehelper': '../../vendor/others/tools/underscore.mixin.templateHelper',
templates: '../templates',
infrastructure: 'infrastructure',
confighandler: 'config/confighandler',
layout: 'views/layout',
general: 'general',
helper: 'helper',
vent: 'vent',
view: 'views',
model: 'models',
module: 'modules',
behaviors: 'behaviors',
collection: 'collections',
controller: 'controllers',
nls: 'nls',
'bootstrap-select': '../../bower_components/bootstrap-select/bootstrap-select',
'eonasdan-bootstrap-datetimepicker': '../../bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
'eonasdan-bootstrap-datetimepicker.de': '../../bower_components/eonasdan-bootstrap-datetimepicker/src/js/locales/bootstrap-datetimepicker.de',
'bootstrap': '../../bower_components/bootstrap/dist/js/bootstrap',
'jquery-cropbox': '../../bower_components/jquery-cropbox/jquery.cropbox',
'jquery-geocomplete': '../../bower_components/jquery-geocomplete/jquery.geocomplete',
'seiyria-bootstrap-slider': '../../bower_components/seiyria-bootstrap-slider/js/bootstrap-slider',
'leaflet': '../../vendor/leaflet/leaflet-custom',
modernizr: '../../bower_components/modernizr/modernizr',
intro: '../../bower_components/intro.js/intro',
lightbox2: '../../bower_components/lightbox2/js/lightbox'
},
shim: {
'underscore.deepExtend': 'underscore',
'underscore.string': 'underscore',
'parsleyjs': 'jquery',
'eonasdan-bootstrap-datetimepicker': 'moment',
'parsleyjs-comparison': 'parsleyjs',
'parsleyjs-de': 'parsleyjs',
'select2-de': 'select2',
'lightbox2': 'jquery',
'jquery.simplePagination': 'jquery',
'bootstrap-select': 'bootstrap',
'bootstrap-slider': 'bootstrap',
'backbone.modelbinder': 'backbone',
underscore: {
deps: ['jquery'],
exports: '_'
},
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
'backbone.analytics': {
deps: [
'underscore',
'backbone'
],
exports: 'Backbone.Analytics'
},
'backbone.deepmodel': {
deps: [
'underscore',
'backbone'
]
},
marionette: {
deps: [
'backbone'
],
exports: 'Backbone.Marionette'
},
leaflet: {
exports: 'L'
},
'jquery-geocomplete': {
deps: [
'jquery',
'general/googlemaps'
]
}
}
});
require(['infrastructure'], function() {
'use strict';
console.log('infrastructure');
require(['app', 'model/session'], function(App, Session) {
console.log('app, model/session');
App.session = Session;
App.session.login(function() {
App.start();
});
});
});
the build.js part included in my grunt configuration
requirejs: {
compile: {
options: {
mainConfigFile: 'app/scripts/main.js',
paths: {
jquery: 'empty:'
},
modules: [{
name: 'main',
exclude: [
'infrastructure'
]
}, {
name: 'infrastructure'
}],
findNestedDependencies: true,
preserveLicenseComments: false,
stubModules: ['text'],
inlineText: true,
optimize: 'none',
dir: '<%= build.dest %>/app/scripts/',
wrapShim: true
}
}
}
On the first step I only wanted to include jquery from a CDN. After the build process I've got two files a main.js and the infrastrucute.js. But if I try to run the application that error message is thrown in the console:
Uncaught Error: Bootstrap's JavaScript requires jQuery
I thought this problem wont occur, because the app requires the manufacture-module before all other parts of the application and the dependent libraries were loaded in the main.js. But it seems that all dependencies within main.js are still being loaded before the manufacture-module.
At the moment I'm a bit confused and don't know how to go on or even where to start.
Does anybody has already optimized apps from that size using r.js with libs from CDN. In addition what do you think about the concatenating/minification process + loading libs from a CDN at all? Does it boost the loading performance really?
thx in advance
Add a dependancy on JQuery for Bootstrap. When JQuery was loaded from your server, it is loaded fast enough to be available when Bootstrap starts. Now that JQuery comes from a CDN, it takes more time to be loaded, and is not available when Bootstrap starts.

Karma with RequireJS loading specs but not src and lib files

I'm using karma 0.10.9 with requirejs, coffeescript, jasmine and jasmine-sprockets (because I'm working on a RoR project, and we have a few files that only contain sprockets directives).
When I start karma, I get that "Executed 0 of 0 ERROR" message.
Looks like on the runner page (localhost:9876) the lib and src files don't get loaded but the specs do. No errors in the console. When I copy the url of a lib or src file directly into the address bar, the file gets loaded.
On the debug page all files (libs, sources and tests) get loaded.
I'm clueless...
Here's my karma.conf.js:
module.exports = function(config) {
config.set({
basePath: '../../..',
frameworks: ['jasmine', 'requirejs'],
files: [
{pattern: 'vendor/assets/javascripts/**/*.js', included: false},
{pattern: 'app/assets/javascripts/v5/**/*.coffee', included: false},
'spec/javascripts/helpers/jasmine-jquery.js',
'spec/javascripts/helpers/maps-helper.js',
{pattern: 'spec/javascripts/fixtures/*.html', watched: true, included: false, served: true},
{pattern: 'spec/javascripts/v5/**/*_spec.coffee', included: false},
'spec/javascripts/v5/test-main.coffee'
],
hostname: [
'localhost'
],
exclude: [
],
preprocessors: {
'**/*.coffee': ['coffee']
},
coffeePreprocessor: {
// transforming the filenames
transformPath: function(path) {
return path.replace(/(.js.coffee|.coffee)/, '.js');
}
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: [],
captureTimeout: 20000,
singleRun: false,
reportSlowerThan: 500,
sprocketsPath: 'vendor/assets/javascripts',
sprocketsBundles: [
'bootstrap.js',
'plugins_jquery.js'
],
plugins: [
'karma-jasmine',
'karma-requirejs',
'karma-coffee-preprocessor',
'karma-sprockets'
]
});
};
And the test-main.coffee:
tests = []
for file of window.__karma__.files
tests.push file if /_spec\.js$/.test(file) if window.__karma__.files.hasOwnProperty(file)
# https://github.com/karma-runner/karma-requirejs/issues/6#issuecomment-23037725
for file of window.__karma__.files
window.__karma__.files[file.replace(/^\//, "")] = window.__karma__.files[file]
requirejs.config
baseUrl: 'base/app/assets/javascripts/'
paths:
jquery: '../../../vendor/assets/javascripts/jquery'
underscore: '../../../vendor/assets/javascripts/lodash'
backbone: '../../../vendor/assets/javascripts/backbone'
// etc.pp.
shim:
backbone:
deps: ['jquery', 'underscore', 'json2']
exports: 'Backbone'
json2:
exports: 'JSON'
deps: tests
callback: window.__karma__.start
Any help appreciated.
Thanks!
Your spec should require the file it tests.
In your karma.conf.js the files section should have your src files. once the files are served by karma. then you can require them in your spec.

Resources