jQuery not defined using mocha for testing wordpress javascript - javascript

I've set up mocha to run tests in the terminal. It works for basic test like expect(1).to.equal(1). The problem I run into is that my script is wrapped in the jQuery like so jQuery( function( $ ) { // my code here }); and I get an error when running the tests.
evalmachine.<anonymous>:15
jQuery( function ( $ ) {
^
ReferenceError: jQuery is not defined
at evalmachine.<anonymous>:15:1
at Object.exports.runInThisContext (vm.js:54:17)
at Suite.<anonymous> (/Users/grahamlutz/Documents/BBC/poolproof/test/test.js:21:8)
at context.describe.context.context (/usr/local/lib/node_modules/mocha/lib/interfaces/bdd.js:47:10)
at Object.<anonymous> (/Users/grahamlutz/Documents/BBC/poolproof/test/test.js:8:1)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at /usr/local/lib/node_modules/mocha/lib/mocha.js:220:27
at Array.forEach (native)
at Mocha.loadFiles (/usr/local/lib/node_modules/mocha/lib/mocha.js:217:14)
at Mocha.run (/usr/local/lib/node_modules/mocha/lib/mocha.js:469:10)
at Object.<anonymous> (/usr/local/lib/node_modules/mocha/bin/_mocha:404:18)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:141:18)
at node.js:933:3
my test.js looks like this:
var assert = require('assert');
var chai = require('chai');
var expect = chai.expect;
var fs = require('fs');
var vm = require('vm');
var jsdom = require('mocha-jsdom');
describe('mocha tests', function () {
jsdom();
before(function () {
$ = require('jquery');
});
var path = __dirname + '/../wp-content/themes/bb-theme-child/myscript.js';
var code = fs.readFileSync(path);
vm.runInThisContext(code);
describe('getSession', function() {
it('should return the empty string because it fails', function () {
applyCoupon();
});
});
});
My question is either why is jQuery undefined or what incorrect assumptions am I making? Do I need to change the way I think about testing javascript within a wordpress set up?

The following two lines worked for me. For convenience I just put these at the top of my mocha test file. I used 'jsdom-global' package instead of 'mocha-jsdom' per the recommendation on the mocha-jsdom github readme. https://github.com/rstacruz/jsdom-global
this.jsdom = require('jsdom-global')()
global.$ = global.jQuery = require('jquery');

You have to export $ and jQuery to the global space yourself:
before(function () {
global.$ = global.jQuery = require('jquery');
});
If you read mocha-jsdom's documentation you'll see that it puts in the global space symbols like window and document. When you load jquery, it finds window and adds itself as window.$. In a browser, this also makes $ visible in the global space because window is the global space. In Node, however, the global space is global, and so you have to put $ in it yourself.

Related

"TypeError: jsdom.jsdom is not a function" with paper-node.js in npm paper module

I have installed webppl-agents library (along with webppl and webppl-dp) and am trying to run the command line test, but I'm running into some trouble. It appears there is a dependency issue with jsdom from the npm paper module (1) (2) (3) (4), but I haven't been able to get a complete handle on the issue at this point.
Does anybody know what's going on here? Do I just need to use a newer version of paper?
PS C:\Users\user\.webppl\node_modules\webppl-agents> webppl --require webppl-dp --require . tests/tests.wppl
C:\Users\user\.webppl\node_modules\webppl-agents\node_modules\paper\dist\paper-node.js:10835
document = jsdom.jsdom('<html><body></body></html>'),
^
TypeError: jsdom.jsdom is not a function
at new <anonymous> (C:\Users\user\.webppl\node_modules\webppl-agents\node_modules\paper\dist\paper-node.js:10835:19)
at Object.<anonymous> (C:\Users\user\.webppl\node_modules\webppl-agents\node_modules\paper\dist\paper-node.js:33:13)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (C:\Users\user\.webppl\node_modules\webppl-agents\src\visualization\gridworld.js:1:75)
There has been some breaking changes recently. The following way of initializing jsodm, document and window fixed it for me:
import jsdom from 'jsdom';
const {JSDOM} = jsdom;
const {document} = (new JSDOM('<!doctype html><html><body></body></html>')).window;
global.document = document;
global.window = document.defaultView;

I cannot use import in Jasmine2 spec when using protractor 4.0.9 when using typescript 2.0

When I try to use typescript .ts spec and run them in protractor, I get:
[17:05:52] E/launcher - Error: SyntaxError: Unexpected token import
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:387:25)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at C:\Users\gwk736\Gitlab\inform-locate-E2E-tests\node_modules\jasmine\lib\jasmine.js:84:5
at Array.forEach (native)
at Jasmine.loadSpecs (C:\Users\gwk736\Gitlab\inform-locate-E2E-tests\node_modules\jasmine\lib\jasmine.js:83:18)
[17:05:52] E/launcher - Process exited with error code 100
When I have .ts file and no import is present it's behaving ok. Why ?
) Get the same error, using: Jasmine2, Protractor 4.0.11, typescript 2.0.3
And I don't know what seems to be the problem. But my workaround is:
in file: main-page.ts
module.exports = {
setUrl: function(){
browser.get("/");
}
};
and in file you want to use the function setURL for example:
var mainPage = require('./main-page.ts');
describe('Test Main Page', function() {
it('should have a title', function() {
mainPage.setUrl();
expect(browser.getTitle()).toEqual('Titel meiner Seite');
});
});
That's just my workaround - actually I didn't find out the real reason for the problem you described!

Requiring other files in node

I'm trying to require another file within a node project I'm working on; this will be a command line tool. What I'm trying to do is create a formatted color output using the following file format.js:
modules.exports = {
warning: function(input){
say("\033[31m" + input)
},
info: function(input){
say("\033[36m" + input)
}
}
From there I want to create the colored output and put it into a file named gen_email.js. That file has these two functions in it:
function say(input){
console.log(input)
}
function helpPage(){
say('');
format.info("test")
}
When I attempt to run this it outputs the following:
C:\Users\thomas_j_perkins\bin\javascript\node\email\lib\format.js:1
(function (exports, require, module, __filename, __dirname) { modules.exports = {
^
ReferenceError: modules is not defined
at Object.<anonymous> (C:\Users\thomas_j_perkins\bin\javascript\node\email\lib\for
mat.js:1:63)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (C:\Users\thomas_j_perkins\bin\javascript\node\email\gen_ema
il.js:3:16)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
I'm not understanding what I'm doing wrong, according to this I am requiring the file the correct way. What am I doing wrong here, do I need to move the say function into the other file?
It should be
module.exports = {
warning: function(input){
say("\033[31m" + input)
},
info: function(input){
say("\033[36m" + input)
}
}
in the other file
const format = require("whatEverPathIsOn/format.js")
if the file is under the same path just
const format = require("./format.js")
That should be module, not modules.

Unit testing web-browser independent JavaScript

I have client-side JavaScript that does not interact with the DOM or the web-browser in any way. I would like to unit-test the functionality of this code (which is just a fancy database/buffer) in Travis-CI without starting up a web-browser. Command-line JavaScript made me think I need node.js. I looked through various unit-testing libraries and decided on Mocha for its simplicity, however testing a browser-based module/class seems to be excessively difficult with a node.js based library.
Specifically, I want to test this (simplified) browser JavaScript valid code:
// I need this NameSpace to organise my code and isolate from other code
var Nengo = {};
Nengo.DataStore = function(dims) {
this.times = [];
this.data = [];
for (var i=0; i < dims; i++) {
this.data.push([]);
}
}
Nengo.DataStore.prototype.push = function(row) {
this.times.push(row[0]);
for(var i = 0; i < this.data.length; i++){
this.data[i].push(row[i+1]);
}
}
When I try to test in Node.js, I can't import the idea of the Nengo namespace properly. This test can't even run:
// get the datastore code from the folder below
require("../simple_data")
var assert = require("assert")
describe("DataStore", function() {
var data_store = new Nengo.DataStore(2);
it("accepts data", function() {
data_store.push([0.0, 1.1, 1.2])
assert.deepEqual(data_store.data, [[1.1], [1.2]])
});
});
It fails with the following error:
/home/saubin/javascript_test/test/simple_test.js:5
var data_store = new Nengo.DataStore(2);
^
ReferenceError: Nengo is not defined
at Suite.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:5:22)
at context.describe.context.context (/usr/local/lib/node_modules/mocha/lib/interfaces/bdd.js:49:10)
at Object.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:4:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at /usr/local/lib/node_modules/mocha/lib/mocha.js:192:27
at Array.forEach (native)
at Mocha.loadFiles (/usr/local/lib/node_modules/mocha/lib/mocha.js:189:14)
at Mocha.run (/usr/local/lib/node_modules/mocha/lib/mocha.js:422:31)
at Object.<anonymous> (/usr/local/lib/node_modules/mocha/bin/_mocha:398:16)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:935:3
One way I have thought of solving this is abandoning node and outputting the test results to the DOM of a headless browser and getting the results, but this seems like a lot of excessive overhead. Can I change the structure of my code to be compatible with Node.js? Is there some other solution that I'm not seeing due to lack of knowledge in the area?
You can make your code "node.js-aware" so it puts global definitions into the actual global context while still remaining completely compatible with the browser environment:
if (typeof window !== "undefined") {
// in browser, define global to be an alias for window
// so global can be used to refer to the global namespace in
// both the browser and node.js
var global = window;
}
global.Nengo = {};
(function() {
var Nengo = global.Nengo;
Nengo.DataStore = function(dims) {
this.times = [];
this.data = [];
for (var i=0; i < dims; i++) {
this.data.push([]);
}
}
Nengo.DataStore.prototype.push = function(row) {
this.times.push(row[0]);
this.data.push(row.slice(1));
}
})();
Then, just remember that ANY global definitions, must be explicitly assigned to the global namespace. In node.js, this will assign them to the actual global namespace in node.js. In the browser, this will assign them to the window object which is the global namespace in the browser.
Although, #jfrien00's answer is technically correct, I came up with another answer later.
First, I needed to refactor my JavaScript code to declare my namespace outside of the DataStore file. Then I declare the Nengo global variable as jfriend00 describes global.Nengo = {};, but only in my Mocha test file.
This way, when I run in my web browser and my unit tests, my code is tested as expected.

Javascript Require

include.js file contain
var test = function(){
console.log("log from included file");
};
main.js file contain
require('./include.js');
test();
when i tried to run main.js using node main.js command it shows
module.js:340
throw err;
^
Error: Cannot find module 'include.js'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (d:\Nishada\test\main.js:1:63)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
what is the reason for this error ?
The error refers to a file not being found, make sure your file is in the same directory as main.js and try:
include.js
module.exports = {
test: function(){
console.log("log from included file");
}
}
main.js
var myInclude = require('include.js');
myInclude.test();
You will need to export the test function in order to use it in main.js
var test = function(){
console.log("log from included file");
};
module.exports = test
And in main.js add require as follows
require('./include.js'); // assuming include.js is in same directory as main.js
If you do require('include.js') then node will search include in global packages
You will have to give relative path of include.js while require.
If both are in same directory write it like bellow
var include = require('./include.js');
include.test();
and from include.js you can define them as function for exports
exports.test = function(){
console.log("log from included file");
};
Even Better
export just one object having multiple functions from include.js instead of exporting each separate function.
Like bellow
include.js
exports.test = obj;
obj.func1 = function(){};
obj.func2 = function(){};
main.js
var test = require('./include.js').test;
test.func1();
test.func2();

Categories

Resources