jasmine-node - including helper - node.js

I am trying to test my Meteor application with jasmine-node. I've stubbed out some methods of Meteor framework in the helper (spec_helper.js):
var Meteor = {
startup: function (newStartupFunction) {
Meteor.startup = newStartupFunction;
},
Collection: function (collectionName) {
Meteor.instantiationCounts[collectionName] = Meteor.instantiationCounts[collectionName] ?
Meteor.instantiationCounts[collectionName] + 1 : 1;
},
instantiationCounts: {}
};
At this point I need to run the code in spec_helper.js (something equivalent of including a module in other languages). I've tried the following, but no success:
require(['spec_helper'], function (helper) {
console.log(helper); // undefined
describe('Testing', function () {
it('should test Meteor', function () {
// that's what I want to call from my stubs...
// ...it's obviously undefined
Meteor.startup();
});
});
});
Any help would be greatly appreciated.

jasmine_node will autoload helpers (any file containing the word helpers) from within your spec directory.
NOTE: you can cheat and use helper instead since it's a substring of helpers...makes more sense if you split helpers out across multiple files...singular vs plural.
If you're executing your specs from specs/unit, then create a file named specs/unit/meteor-helper.js, and jasmine_node will automagically source it for you. It will load files with the extension .js if your specs are written in vanilla JavaScript. If you pass the --coffee switch on the command line or via your grunt task config (you may even be using gulp if you're ambitious), then it will load helpers with the extensions js|coffee|litcoffee.
You should export a hash from each helper file as follows:
specs/unit/meteor-helper.js
// file name must contain the word helper
// x-helper is the convention I roll with
module.exports = {
key: 'value',
Meteor: {}
}
Then, jasmine_node will write each key to the global namespace.
This will allow you to simply type key or Meteor from your specs, or any system under test (typically code inside your lib folder that the specs are executing assertions against).
Additionally, jasmine_node will also allow you to suppress the loading of helpers via the --nohelpers switch (see code or README for more details).
This is the proper way to handle helpers for jasmine via node. You may come across some answers/examples that reference a jasmine.yml file; or maybe even spec_helper.js. But keep in mind that this is for ruby land and not node.
UPDATE: It appears jasmine-node will only source your file if it contains the word helpers. Naming each helper file x-helper.js|coffee|litcofee should do the trick. i.e. meteor-helper.coffee.

Related

Using node module in angularjs?

What's the best practice for using external code, e.g. code found in node modules, in angular?
I'd like to use this https://www.npmjs.com/package/positionsizingcalculator node module in my angular app. I've created an angular service intended to wrap the node module, and now I want to make the service use the node module.
'use strict';
angular.module('angularcalculator')
.service('MyService', function () {
this.calculate = function () {
return {
//I want to call the node module here, whats the best practice?
};
}
});
To do this, I would crack open the package and grab the .js out of it. This package is MIT license, so we can do whatever we want. If you navigate to /node_modules/positionsizingcalculator/ you'll find an index.js. Open that up and you'll see the moudle export, which takes a function that returns an object.
You'll notice this is an extremely similar pattern to .factory, which also takes a function that returns an object (or constuctor, depending on your pattern). So I'd do the following
.factory('positionsizingcalculator', function(){
basicValidate = function (argument) {
... //Insert whole declaration in here
return position;
})
and the inject it where you need it:
.controller('AppController', function(positionsizingcalculator){
//use it here as you would in node after you inject it via require.
})
--
Edit: This is good for one off grabs of the JS, but if you want a more extensible solution, http://browserify.org/ is a better bet. It allows you to transform your requirements into a single package. Note that this could result in pulling down a lot more code that you might otherwise need, if you make one require bundle for your whole site, as this is not true AMD, and you need to to load everything you might want one the client, unless you make page specific bundles.
You'd still want to do the require in a factory and return it, to keep it in angular's dependency injection framework.

Better way to require.extensions with Node.js

I'm testing a bunch of React JSX components. They all need to be transpiled with React, or Babel or whatever, but we have special needs for stubbing requirements, so I'm trying to override requires with a special compiler that's run with Mocha. The solution below works well, but you'll notice that we're using require.extensions[] to capture all the .jsx files. What concerns me is that require.extensions is locked and deprecated. Is there any better way to do this?
// Install the compiler.
require.extensions['.jsx'] = function(module, filename) {
return module._compile(transform(filename), filename);
};
Here's the whole transpiler for reference:
// Based on https://github.com/Khan/react-components/blob/master/test/compiler.js
var fs = require('fs'),
ReactTools = require('react-tools');
// A module that exports a single, stubbed-out React Component.
var reactStub = 'module.exports = require("react").createClass({render:function(){return null;}});';
// Should this file be stubbed out for testing?
function shouldStub(filename) {
if (!global.reactModulesToStub) return false;
// Check if the file name ends with any stub path.
var stubs = global.reactModulesToStub;
for (var i = 0; i < stubs.length; i++) {
if (filename.substr(-stubs[i].length) == stubs[i]) {
console.log('should stub', filename);
return true;
}
}
return false;
}
// Transform a file via JSX/Harmony or stubbing.
function transform(filename) {
if (shouldStub(filename)) {
delete require.cache[filename];
return reactStub;
} else {
var content = fs.readFileSync(filename, 'utf8');
return ReactTools.transform(content, {harmony: true});
}
}
// Install the compiler.
require.extensions['.jsx'] = function(module, filename) {
return module._compile(transform(filename), filename);
};
And some links to simalar solutions...
https://github.com/danvk/mocha-react/issues/1
https://github.com/Automattic/jsx-require-extension
https://www.npmjs.com/package/node-jsx
https://github.com/olalonde/better-require
http://mochajs.org/#usage
http://nodejs.org/api/globals.html#globals_require_extensions
A solution can be forked from here:
https://github.com/danvk/mocha-react
There are two reasons that API has been deprecated. One, the node module resolution algorithm is VERY complicated, it has to look at the specified file, if it doesn't exist it looks for that file and all the possible extensions in the keys of require.extensions, and if it's a directory, look for a package.json or index.js. Oh, and don't forget, if there is no ./ at the beginning, it looks in the node_modules directory, looking at the parent directory if it can't be found in that node_modules. Ryan Dahl said he regrets making it so complicated in his talk at JsConf 2018, and uses a much simpler module resolution algorithm in his deno project. Two, it needs more filesystem calls if there are more extensions in require.extensions, because it has to match extensionless files.
A solution to the second problem is require-extension. I haven't used it myself, but it abstracts the require.extensions API and makes it much more performant.
There is no other way to do this, and this is how everybody does transpiling (babel, etc). #uni_nake's answer - to use node-hook - is OK in that it hides this from you, but it essentially uses the same mechanism: a look in it's code shows that it uses Module._extensions, but this is the same as require.extensions, as shown by a test I wrote: https://github.com/giltayar/playing/blob/1f04f6ddc1a0028974b403b4d1974afa872edba4/javascript/node/test/is-module-extensions-same-as-require-extensions.test.js
So final answer - I would assume that nobody at Node will break Babel, and if they do, they will probably give another solution for the same problem. I would not hesitate to use it!
I use node-hook to stub all .scss calls in my tests.
You'll see from the docs that when a matching file is required it will execute the containing string instead and is really quite powerful as it also passes you the original source.
Hope that is what you're looking for.
I think you should use pirates
I think the PR when require.extensions used in babel-register was replaced with pirates would be helpful.
https://github.com/babel/babel/pull/3670/files#diff-75a0292ed78043766c2d5564edd84ad2L85-L93
Hope that is what you're looking for.

RequireJS - loading multiple config files

I am trying to load several RequireJS configs. In my html I am loading my main config via
<script src="../lib/require.js" data-main="../app/requireConfig"></script>
and once the document is ready I want to load all my plugin configs. So I created a new define file which holds a function that calls require.config:
define(['sharedServices/logger'], function (logger) {
function configVideo() {
logger.info('Adding video modules');
require.config({
path: {
Capabilities: 'videoProvider/Capabilities',
VideoProviderEnums: 'videoProvider/VideoProviderEnums',
VideoProviderCommon: 'videoProvider/VideoProviderCommon',
VideoProviderInstance: 'videoProvider/VideoProviderInstance',
DummyVideoInstance: 'videoProvider/DummyProvider/DummyVideoInstance'
}
});
}
return {
configVideo: configVideo
};
})
However, I get the following error:
Uncaught Error: Mismatched anonymous define() module: function (logger) {
The error you're getting isn't directly related to the stated problem (loading multiple configurations), but is caused by the way your code loading is organized. As the manual says:
To avoid the error:
Be sure to load all scripts that call define() via the RequireJS API. Do not manually code script tags in HTML to load scripts that have define() calls in them.
If you manually code an HTML script tag, be sure it only includes named modules, and that an anonymous module that will have the same name as one of the modules in that file is not loaded.
So the problem now is that when loading the module manually (as you state "when the document is ready", could you clarify how the quoted source is actually loaded?) requirejs doesn't know where the module came from, so it can't assign it a name. If the module were loaded via requirejs api (e.g. if it appeared in a dependencies list of a define call) and it were requirejs itself that determined its script path, it would name the module after the file.
In general it is advisable to have just a single script tag loading all the requirejs-managed javascript. This makes the development setup more closely match the eventual optimized situation (where all the scripts are concatenated together). It is still possible to make require.config calls inside individual modules if necessary and make some code execute only after document is ready. As an example, many our apps do something like the following in their main.js (the module loaded by the requirejs script tag):
// sort of bootstrap config
require.config({
packages: [{
name: "our-framework",
location: "../../our-framework/src/"
}],
// here some app-specific requirejs options
waitSeconds: 5
});
// load the framework, the "our-framework/rjs-config" contains
// framework specific requirejs config (another require.config call)
require(["our-framework/rjs-config"], function() {
// in this context both require configs are loaded
require(["application"], function(application) {
application.init().run();
});
});

RequireJS Dynamic Paths Replacement

I have a requirejs module which is used as a wrapper to an API that comes from a different JS file:
apiWrapper.js
define([], function () {
return {
funcA: apiFuncA,
funcB: apiFuncB
};
});
It works fine but now I have some new use cases where I need to replace the implementation, e.g. instead of apiFuncA invoke my own function. But I don't want to touch other places in my code, where I call the functions, like apiWrapper.funcA(param).
I can do something like the following:
define([], function () {
return {
funcA: function(){
if(regularUseCase){
return apiFuncA(arguments);
} else {
return (function myFuncAImplementation(params){
//my code, instead of the external API
})(arguments);
}
},
funcB: apiFuncB
};
});
But I feel like it doesn't look nice. What's a more elegant alternative? Is there a way to replace the module (apiWrapper) dynamically? Currently it's defined in my require.config paths definition. Can this path definition be changed at runtime so that I'll use a different file as a wrapper?
Well, first of all, if you use Require.js, you probably want to build it before production. As so, it is important you don't update paths dynamically at runtime or depends on runtime variables to defines path as this will prevent you from running r.js successfully.
There's a lot of tools (requirejs plugins) out there that can help you dynamically change the path to a module or conditionnaly load a dependency.
First, you could use require.replace that allow you to change parts (or all) of a module URL depending on a check you made without breaking the build.
If you're looking for polyfilling, there's requirejs feature
And there's a lot more listed here: https://github.com/jrburke/requirejs/wiki/Plugins

Global function in express.js?

How can I define a global function in express.js, that without require I can call it
"How" is simple enough:
global.fnName = function(){ return "hi"; }; // Andreas Hultgren's answer
But you don't need the global prefix; the thing about the global object is ...
fnName = function(){ return "hi"; }; // i.e. don't do: var name = function(){ ... };
console.log(fnName()); // this prints "hi"
console.log(global.fnName()); // this also prints "hi" - it was assigned to global.
"Without require" is a separate consideration: if you don't use require there is no guarantee your "globals" will have been declared by the time you need them. It enforces loading order of dependencies, among other things.
"Why am I" and "Is it correct to" are now hidden questions you should consider. It is accepted in javascript that Global Variables ...
... should be reserved for objects that have system-wide relevance and they should be named to avoid ambiguity and minimize the risk of naming collisions - Angus Croll, Namespacing in Javascript
i.e. global truly is Global: it is used by every author of every plugin or library you pull in to your application, not just you. Naming collisions between global variables break your application. This applies equally in node.js.
Global variables are also thought of as a code smell. In the detail sections below here you will see you can quickly get into trouble by using global variables, and they should really be treated as something that pushes you towards dependency injection and/or namespaces and modules.
Node.js and express - global vars and functions
Here's a good rule: if you upload it to a web server, or share it with other people, don't use global variables.
global is permissible in tiny "Saturday afternoon" apps in node.js with express.js, but tend to cause problems later if they get adopted into production. Therefore:
Modules and exports is best practice.
Injection should also be used to reduce coupling between javascript files. But in all cases you will usually need require to ensure they exist by the time you need them:
You should really consider app.locals data, and/or middleware functions, for anything that is view data related.
// call this as a function with an input object to merge
// the new properties with any existing ones in app.locals
app.locals.({
sayHello: function() { return "hi"; }
});
// now you can also use this in a template, like a jade template
=sayHello()
If you are creating global vars/functions for configuration settings purposes the below comments about namespaces still apply, and there are conventions emerging such as config.json files (still using require) for settings that are globally accessed.
Global variables - simple case
It is simple enough to declare a global variable in javascript, and for a function the process is no different. Simply omit the var keyword which would normally force a local scope on the declaration:
// app.js
blah = "boo";
sayHello = function(string toWho) { return "hello " + toWho; }
getVersion = function() { return "0.0.0.1"; }
// routes/main.js
console.log(blah); // logs: "boo"
console.log(global.blah); // logs: "boo"
console.log(sayHello("World")); // logs: "hello World"
console.log(global.sayHello("World")); // logs: "hello World"
console.log(getVersion()); // logs: "0.0.0.1"
But what if two separate plugins in your project use a global getVersion function - how do you get the right version number? Also, how do you ensure that getVersion exists before you need it, or exists at all?
Why do we need require?
To quote the nodejitsu docs the built in require function ...
... is the easiest way to include modules that exist in separate files. The basic functionality of require is that it reads a javascript file, executes the file, and then proceeds to return the exports object
"So", you may ask, "require just makes sure that a module from another file is included? Why bother?" It's better than that: you can make a whole folder a module, making your code easier to organise and test test test, it will recognise various extensions for file modules, not just .js, and it will look in various folders as well. Of course, it caches as well.
So, now that require has found your module, it ensures the code inside it is executed, and puts the objects your created into a "namespace":
// module file ./myModule.js
exports.blah = "boo";
exports.sayHello = function(string toWho) { return "hello " + toWho; }
// routes/main.js
var demoModuleReference = require('./myModule.js');
console.log(demoModuleReference.blah); // logs: "boo"
console.log(demoModuleReference.sayHello("World")); // logs: "hello World"
In that sample, demoModuleReference is an object that looks like:
{
blah: "foo",
sayHello: [Function]
}
Why modules and not global variables (a.k.a namespacing and "Global is the new private")?
Seems complicated now? Surely global variables are easier? requires ensures the following:
It ensures ordered loading of dependencies
It prevents variable name conflicts within global through the exports object.
This application at mankz.com (chrome or firefox only) is fascinating. Depending on how you use your js code, you are very likely to have variable name conflicts within the global scope. Name conflicts come from everywhere. In a browser, for instance, they can come from extensions. node.js is slightly different, but it is becoming more and more extended by compatible plugins as time goes on (you can load jquery in right now, for example). As the versions go on frameworks will get added, and name collisions in global will become more likely. My last run of that app in chrome showed over 1200 global namespace variables.
Namespaces - why?
This global namespace pollution was publicised early on by Douglas Crockford through Eric Miraglia in the article "A JavaScript Module Pattern". In summary:
All objects that need to be used between js files are really global
So, create a namespace object that will be unique
Assign the return value an anonymous function
Add private methods and variables inside that function
Do something useful with the pattern
Example:
ANDYBROWNSONICSUITE.BoomBox.SoundModule = function () {
var privateField = "can't touch this";
return {
play: function() {
console.log(privateField);
}
}
}
Why is this good?
Now you have only increased the global namespace members in the world by one, but this member contains as many items as you like.
Your application is far less likely to clash with other namespaces
It's a pattern, other frameworks expect you to use it to interact with them properly. In that reference, jQuery is a browser plugin, but you can use it with node and therefore your app, so the library interactivity policy statement is a perfect example.
It's a pattern, if we all follow it we our programs are all more likely to get along
When you read the Crockford reference along with the Croll reference (Direct Assignment section) I mentioned at the start, you see why it looks this complicated rather than just doing: sound.play = function() { ... } - ease of maintenance, refactoring the namespace etc. being just one reason.
Summary
In summary:
Can I create globals? Yes, it's simple, omit the var keyword before the declaration.
Should I create globals? You should use the module pattern, which is implicitly supported by node, and by express
Why am I creating globals? If it's for configuration, use a config namespace (e.g. How to store Node.js deployment settings/configuration files?)
You can:
global.name = function(){};
But you really should avoid using globals, even if it's possible to use them.

Resources