Jest and Bower Module loading in jest tests - bower

Lets say I have a project that uses bower, grunt, bowerify(with shim) and since I love Jest so much I want to test with that. How in the world do I get jest to see my browserify shim modules when it runs tests. I use grunt, to kick off the npm test command.
Here is my package.json file.
"browser": {
"jquery": "./bower_components/jquery/dist/jquery.js",
"foundation": "./bower_components/foundation/js/foundation/foundation.js",
"fastclick": "./bower_components/fastclick/lib/fastclick.js",
"greensock-tm": "./bower_components/gsap/src/uncompressed/TweenMax.js",
"greensock-css": "./bower_components/gsap/src/uncompressed/plugins/CSSPlugin.js",
"greensock-time": "./bower_components/gsap/src/uncompressed/TimelineMax.js",
"scrollmagic": "./bower_components/ScrollMagic/js/jquery.scrollmagic.js",
"handlebars": "./bower_components/handlebars/handlebars.runtime.js"
},
"browserify-shim": {
"jquery": "$",
"greensock-css": "CSSPlugin",
"fastclick": "FastClick",
"greensock-tm": "TweenMax",
"greensock-time": "TimelineMax",
"scrollmagic": "ScrollMagic",
"foundation": "foundation",
"handlebars": "Handlebars"
},
"browserify": {
"transform": [
"browserify-shim"
]
},
Right now I almost have this worked out by doing this in my grunt file before I run the test.
grunt.registerTask("shimBowerForTests",function(){
var readJson = require('read-package-json');
var fs = require('fs');
var remapify = require('remapify');
readJson('./package.json', console.error, false, function (er, data) {
if (er) {
throw "There was an error reading the file";
}
var packages = data.browser;
var browserify = require('browserify');
for (var key in packages){
var b = browserify();
var wstream = fs.createWriteStream("devjs/test/modules/"+key+'.js');
b.add(packages[key]);
b.bundle().pipe(wstream);
}
});
});
and.
exec: {
jestTest: {
command: 'cp -r devjs/modules devjs/test/modules && npm test'
}
}
The problem is that using browserify so combine everything for the browser works great with my setup and I can require my shimmed modules like this.
require('jquery') //example but in the jest cli the test fail because they can find the module unless I somehow prefix it with ./, like so require('./jquery')

I'm guessing that the problem is that you've only installed your shimmed modules with bower. If you want them to work in node/jest, you'll have to install them with npm as well. Then just make sure Jest isn't mocking anything in the node_modules directory, and it should find all the required modules in there as long as the names match up.
Your Jest config in package.json should look like:
"jest": {
"unmockedModulePathPatterns": [
"./node_modules"
]
}
And then just download all the dependencies.
npm install jquery --save-dev

UPDATE
Instead of using my below solution you should opt for using Karma,karma browserify. I have converted the below solution into using karma and it is working much much better.
----------------------OLD ANSWER
What I actually did to solve this was, used the Jest source preprocessor to rewrite the require statement to look for a module in a certain directory in my /tests/ folder that I have created using grunt. The Folder contains the files listed in my browserify-shim, browser section of the package.json file.
EDIT: Here is how I shim bower, I made this script in the Gruntfile.js that puts all the bower modules and any commonjs modules that I need into an accessible directory.
grunt.registerTask("shimBowerForTests", function() {
var readJson = require('read-package-json');
var fs = require('fs');
readJson('./package.json', console.error, false, function(er, data) {
if (er) {
throw "There was an error reading the file";
}
var packages = data.browser;
var shim = data['browserify-shim'];
var browserify = require('browserify');
var exclude = ["jquery.maskedinput", "jquery"];
for (var key in packages) {
var b = browserify();
var wstream = fs.createWriteStream("devjs/test/modules/" + key + '.js');
if (shim[key] !== undefined && exclude.indexOf(key) === -1) {
b.add(packages[key]);
b.bundle().pipe(wstream);
} else {
var rstream = fs.createReadStream(packages[key]);
rstream.pipe(wstream);
}
}
});
});
Then in the Jest pre processor file I do this.
module.exports = {
process: function(src, path) {
var src2= src.replace(/require\([\"\']([^\.\'\"]+)[\"\']\)/g, "require(\'../modules/$1\')");
src2= src2.replace(/jest\.dontMock\([\"\']([^\.\'\"]+)[\"\']\)/g, "jest.dontMock(\'../modules/$1\')");
return src2;
}
};

Related

Cant bundle angular app in gulp build

Im trying to bundle my app so that I can push it to the test server using Gulp. This is my gulp file. It is not done yet, (Build is supposed to also run vendor-js) but I get an error when it runs bundle:app. This is my gulp file:
var gulp = require('gulp'),
tsc = require('gulp-typescript'),
Builder = require('systemjs-builder'),
tslint = require('gulp-tslint'),
sourcemaps = require('gulp-sourcemaps'),
tscConfig = require('./tsconfig.json');
gulp.task('lint', function () {
return gulp.src('app/**/*.ts')
.pipe(tslint({ formatter: 'prose' }))
.pipe(tslint.report());});
gulp.task('compile', ['lint'], function () {
return gulp.src('app/**/*.ts')
.pipe(sourcemaps.init())
.pipe(tsc(tscConfig.compilerOptions))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/js'));});
var vendorJS = [
'node_modules/core-js/client/shim.min.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/systemjs/dist/system.src.js',
'node_modules/systemjs.config.js'];
var concat = require('gulp-concat');
gulp.task('vendor-js', function () {
return gulp.src(vendorJS)
.pipe(concat('vendor.js'))
.pipe(gulp.dest('dist/js'));});
var systemjsBuilder = require('gulp-systemjs-builder');
gulp.task('bundle:app', function () {
var builder = systemjsBuilder();
builder.loadConfigSync('./systemjs.config.js');
builder.buildStatic('dist/js/main.js', 'app.min.js', {})
.pipe(gulp.dest('dist/js'));});
gulp.task('build', ['compile', 'bundle:app']);
The error I am getting is :
Unhandled rejection Error on fetch for dist/js/app.module at
file:///C:/path/dist/js/app.module Loading dist/js/main.js Error:
ENOENT: no such file or directory, open
'C:\Dev\path\dist\js\app.module' at Error (native)
Do you guys have any suggestions on how to make this work and compress the whole thing to something like "app.min.js" anyone?

including devdependencies in package.json

I'd like to generate my devDependencies based on need. For this I have an array in my generator and some operations like this:
var FiddleGenerator = generator.Base.extend({
init: function() {
this.devDependencies = [];
},
//...excluded for brevity
gruntConfigure: function() {
this.devDepedencies = [
'grunt',
'grunt-contrib-watch',
'grunt-contrib-connect'
];
},
installStuff: {
if(this.option('skip-install')) return;
this.npmInstall(this.devDependencies, { saveDev: true });
}
});
The issue here is when the user opts to skip the npm installation and later does it manually (i.e. npm install) nothing gets installed.
However, I cannot simply write a package.json file like that...what versions do I put against each package in order to have them look like the following:
"devDependencies": {
"grunt": "~0.4.2",
"grunt-contrib-watch": "~0.5.3",
"grunt-contrib-connect": "^0.7.0"
}
Just write the devDependencies to the package.json file manually inside the JS code (this.fs.writeJSON). No need to use npmInstall() for that.
You can see this being done here: https://github.com/yeoman/generator-node/blob/master/generators/gulp/index.js#L38-L69

gulp plugin gulp-ruby-sass not compiling

Gulp plugin gulp-ruby-sass(https://github.com/sindresorhus/gulp-ruby-sass) giving not compiling, the error message in terminal coming like this 👇
Error: must provide pattern
Here is the gulpfile.js details
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
sass = require('gulp-ruby-sass');
gulp.task('styles', function (argument) {
gulp.src('sass/app.scss')
.pipe(sass())
.pipe(gulp.dest('css/'));
});
The gulp-ruby-sass syntax has been changed:
instead of: it is now:
gulp.task('styles', function (){ gulp.task('styles', function (){
gulp.src('sass/app.scss') return
.pipe(sass()) sass('sass/app.scss')
.pipe(gulp.dest('css/') .pipe(gulp.dest('css/')
; ;
}); });
Please check it out and mark your problem as solved.
The official gulp-ruby-sass documentation says it should be done like this:
var gulp = require('gulp');
var sass = require('gulp-ruby-sass');
gulp.task('sass', function () {
return sass('source/file.scss')
.on('error', sass.logError)
.pipe(gulp.dest('result'));
});
Install libsass because it runs much faster than ruby sass ,
it works with node
npm install gulp-sass --save-dev`
Install gulp load plugins because it does so much and loads
plugins from your json and you dont need to declare in your gulpfile
(carefull how many you use because if you load too many it hinders
performance)
npm install --save-dev gulp-load-plugins
var gulp = require('gulp'),
$ = require('gulp-load-plugins')({
pattern: ['gulp-*', 'gulp.*'],
replaceString: /\bgulp[\-.]/,
lazy: true,
camelize: true
});
gulp.task('libsass', function () {
gulp.src('sass/app.scss')
.pipe($.sass({errLogToConsole: true}))
.pipe($.autoprefixer({
browsers: ['last 2 versions'],
cascade: false
}))
.pipe($.sourcemaps.write('app/css/map'))
.pipe(gulp.dest('app/css'))
});

Installing and injecting ng-flow using yeoman

I am working with the yo meanjs boilerplate from here :yo meanjs.
I know I can create my own module using $ yo meanjs:angular-module <module-name> .
Is it possible to install and inject into my controller ng-flow using yo from the command line?
Something like : $ yo meanjs:ng-flow <module-name>
In the documentation it states found here meanjs modules: So unless there are any better suggestions I might try this route.
To add third-party modules use the public/config.js file where we added an array property called applicationModuleVendorDependencies. When you add a new third-party module you should add it to this array so the main module can load it as a depenedency.
'use strict';
// Init the application configuration module for AngularJS application
var ApplicationConfiguration = (function() {
// Init module configuration options
var applicationModuleName = 'theconnect';
var applicationModuleVendorDependencies = ['ngResource', 'ngCookies', 'ngAnimate', 'ngTouch', 'ngSanitize', 'ui.router', 'ui.bootstrap', 'ui.utils'];
// Add a new vertical module
var registerModule = function(moduleName, dependencies) {
// Create angular module
angular.module(moduleName, dependencies || []);
// Add the module to the AngularJS configuration file
angular.module(applicationModuleName).requires.push(moduleName);
};
return {
applicationModuleName: applicationModuleName,
applicationModuleVendorDependencies: applicationModuleVendorDependencies,
registerModule: registerModule
};
})();
After adding module via cmd line using :
bower install "ng-flow#~2" --save
grunt bower-install
I added it as as dependency to public/config.js :
var applicationModuleVendorDependencies = ['ngResource', 'ngCookies', 'ngAnimate', 'ngTouch', 'ngSanitize', 'ui.router', 'ui.bootstrap', 'ui.utils','flow'];
then added the module path to the all the JS files under the /config/env directory.
module.exports = {
db: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://' + (process.env.DB_1_PORT_27017_TCP_ADDR || 'localhost') + '/theconnect',
assets: {
lib: {
css: [
'public/lib/bootstrap/dist/css/bootstrap.min.css',
'public/lib/bootstrap/dist/css/bootstrap-theme.min.css',
],
js: [
'public/lib/angular/angular.min.js',
'public/lib/angular-resource/angular-resource.js',
'public/lib/angular-cookies/angular-cookies.js',
'public/lib/angular-animate/angular-animate.js',
'public/lib/angular-touch/angular-touch.js',
'public/lib/angular-sanitize/angular-sanitize.js',
'public/lib/angular-ui-router/release/angular-ui-router.min.js',
'public/lib/angular-ui-utils/ui-utils.min.js',
'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js',
'public/lib/ng-flow/dist/ng-flow.js'
]
},
css: 'public/dist/application.min.css',
js: 'public/dist/application.min.js'
},
......
...
}
Fabii's answer is helpful. To add to it...
I had to make 2 entries in the "all.js" file Fabii mentioned (which is located at /config/env/all.js
'public/lib/flow.js/dist/flow.min.js',
'public/lib/ng-flow/dist/ng-flow.js'

How can I integrate Bower with Gulp.js?

I am trying to write a gulp task that does a few things
Install the Bower dependencies
Concat those dependencies into one file in the order of the dependencies
I was hoping to do this without having to specify the paths to those dependencies. I know there is the command bower list --paths but I am unsure of if it is possible to tie it together.
Any thoughts?
Edit
So I am trying to use the gulp-bower-files and I am getting an eaccess error and its not generating the concatenated file.
gulpfile.js
var gulp = require('gulp');
var bower = require('bower');
var concat = require('gulp-concat');
var bower_files = require('gulp-bower-files');
gulp.task("libs", function(){
bower_files()
.pipe(concat('./libs.js'))
.pipe(gulp.dest("/"));
});
bower.json
{
"name": "ember-boilerplate",
"version": "0.0.0",
"dependencies": {
"ember": "1.6.0-beta.1",
"ember-data": "1.0.0-beta.7"
}
}
and I keep coming across this error
events.js:72
throw er; // Unhandled 'error' event
^
Error: EACCES, open '/libs.js'
Use main-bower-files
It grabs all production (main) files of your Bower packages defined in your project's bower.json and use them as your gulp src for your task.
integrate it in your gulpfile:
var mainBowerFiles = require('main-bower-files');
I made this task that grabs all production files, filters css/js/fonts and outputs them in the public folder in their respective subfolders (css/js/fonts).
Here's an example:
var gulp = require('gulp');
// define plug-ins
var flatten = require('gulp-flatten');
var gulpFilter = require('gulp-filter'); // 4.0.0+
var uglify = require('gulp-uglify');
var minifycss = require('gulp-minify-css');
var rename = require('gulp-rename');
var mainBowerFiles = require('main-bower-files');
// Define paths variables
var dest_path = 'www';
// grab libraries files from bower_components, minify and push in /public
gulp.task('publish-components', function() {
var jsFilter = gulpFilter('**/*.js');
var cssFilter = gulpFilter('**/*.css');
var fontFilter = gulpFilter(['**/*.eot', '**/*.woff', '**/*.svg', '**/*.ttf']);
return gulp.src(mainBowerFiles())
// grab vendor js files from bower_components, minify and push in /public
.pipe(jsFilter)
.pipe(gulp.dest(dest_path + '/js/'))
.pipe(uglify())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(dest_path + '/js/'))
.pipe(jsFilter.restore())
// grab vendor css files from bower_components, minify and push in /public
.pipe(cssFilter)
.pipe(gulp.dest(dest_path + '/css'))
.pipe(minifycss())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(dest_path + '/css'))
.pipe(cssFilter.restore())
// grab vendor font files from bower_components and push in /public
.pipe(fontFilter)
.pipe(flatten())
.pipe(gulp.dest(dest_path + '/fonts'));
});
I was attempting to run the listed gulpfile and ran into a couple errors. First gulpFilter.restore is not a function, and secondly if you plan on restoring the filtered files you need to pass {restore: true} when you define your filters.
Like so:
// gulpfile.js
var mainBowerFiles = require('main-bower-files');
var gulp = require('gulp');
// define plug-ins
var flatten = require('gulp-flatten'),
gulpFilter = require('gulp-filter'),
uglify = require('gulp-uglify'),
minifycss = require('gulp-minify-css'),
rename = require('gulp-rename'),
mainBowerFiles = require('main-bower-files');
// Define paths variables
var dest_path = 'www';
// grab libraries files from bower_components, minify and push in /public
gulp.task('publish-components', function() {
var jsFilter = gulpFilter('*.js', {restore: true}),
cssFilter = gulpFilter('*.css', {restore: true}),
fontFilter = gulpFilter(['*.eot', '*.woff', '*.svg', '*.ttf'], {restore: true});
return gulp.src(mainBowerFiles())
// grab vendor js files from bower_components, minify and push in /public
.pipe(jsFilter)
.pipe(gulp.dest(dest_path + '/js/'))
.pipe(uglify())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(dest_path + '/js/'))
.pipe(jsFilter.restore)
// grab vendor css files from bower_components, minify and push in /public
.pipe(cssFilter)
.pipe(gulp.dest(dest_path + '/css'))
.pipe(minifycss())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(dest_path + '/css'))
.pipe(cssFilter.restore)
// grab vendor font files from bower_components and push in /public
.pipe(fontFilter)
.pipe(flatten())
.pipe(gulp.dest(dest_path + '/fonts'));
});
After the changes mentioned it ran perfectly. :)

Resources