Global JavaScript namespace and Mocha - javascript

I have been tasked with implementing Mocha tests for some JavaScript that already exists on a large website. This website has a global namespace object to hold all of it's functions and common vars, as well as a per page set within the same object, and I have attempted to use Mocha to recognise this but I cant seem to.
For example:
//global namespace declaration in the common.js file
var ns = {};
ns.commonValue = 1;
ns.commonFunc = function () {};
//extension of the namespace on an individual page
ns.thisPage = {};
ns.thisPage.pageVal = 1;
When testing the individual page JavaScript, ns is undefined.
Any help would be good.
Thanks in advance

Given your files are named
common.js
page.js
Then you should have
<script src="common.js"></script>
<script src="page.js"></script>
<script src="test.page.js"></script>
load page without mocha, and look at what inspector says, then correct, then add mocha

Related

How to put Global Variables in a Globals.js module and access them in other modules?

I feel silly but I can't find a good example of how to do this. I've seen some that come close and maybe they are right on target but I can't figure it out.
How do I create a module that contains all my global variables?
How do I export or import or whatever I need to do to use those global variables in another js module?
I'm creating a small application that contains about 6 variables that must have a global scope to my application. Can someone please show me an example?
Global variables:
var scene = viewer.scene;
var ellipsoid = scene.globe.ellipsoid;
var entity;
var newPolygon;
var newOutline;
var canvas = document.getElementById("canvas");
var gl = canvas.getContext("webgl");
var extensions = gl.getSupportedExtensions();
I have the above in a file called globals.js
<script src="Source/globals.js"></script>
<script src="Source/index.js"></script>
<script src="Source/positionHandler.js"></script>
<script src="Source/polyCreate.js"></script>
<script src="Source/polyUpdate.js"></script>
It is listed in the html file. All appears to work just fine but there is a browser level variable that thinks it's false. So now I want to be sure global variables are accessible as expected.
Globals = {
scene: require('scene'),
ellipsoid: require('ellipsoid'),
canvas: require('canvas')
};
module.exports = Common;
or
Globals = {
scene: require('viewer.scene'),
ellipsoid: require('scene.globe.ellipsoid'),
canvas: require('document.getElementById("canvas")')
};
module.exports = Common;
or
Globals = {
scene : viewer.scene,
ellipsoid : scene.globe.ellipsoid,
canvas : document.getElementById("canvas"),
gl : canvas.getContext("webgl"),
extensions : gl.getSupportedExtensions()
};
module.exports = Common;
I don't get the require and how to set it up.
In the browser any variable declared outside of a function scope will be a global var (set on the window object). Make sure that your '< script >' tags are in the correct order (declare your globals before you try to access them).
This is kinda complex in JavaScript land, and depends on what context you are speaking about. I assume you are talking about code that runs in the browser (vs node), If this is the case, the simplest way would be to use a name spacing object. and imply import it before other code that replies on it.
for example, you could make the file globals.js which contains :
MyAppGlobals = { property1: "some-value", anotherProperty2: "other-value" };
In the html just make sure that <script src="path/to/globals.js"></script> is added before any code that depends on the globals.
if you want a more structured approach, check out projects like webpack. They are great, but a little complex to set up.
Basically webpack or browserify let you write proper import and export statements (the way you can in node.js) and then preforms a dependency analysis and "compiles" all the needed code into a bundle file which you would then include in your html. (sort of a rough description but I hope it helps)

Best way to share an instance of a module that is inside a closure [duplicate]

If I want to span my JavaScript project across multiple source files, but have each file have access to the same private variable, how would one do that?
For example, if I have the following code:
APP = (function () {
var _secret = {},
app = {};
// Application part 01:
app.part01 = (function () { /* function that uses _secret */ }());
// Application part 02:
app.part02 = (function () { /* function that uses _secret */ }());
//
return app;
}());
How do I put app.part01 and app.part02 in seperate files, but still have access to _secret?
I don't want to pass it as an argument. That's just giving the secret away, as app.part01() could be replaced by any other function.
Maybe I am asking the impossible, but your suggestions might lead me in the right way.
I want to work with multiple files, but I don't know how. Copying and pasting everything inside a single function each time before testing is not something I want to do.
How do I put app.part01 and app.part02 in seperate files, but still have access to _secret?
That's impossible indeed. Script files are executed in the global scope, and don't have any special privileges. All variables that they will be able to access are just as accessible to all other scripts.
Copying and pasting everything inside a single function each time before testing is not something I want to do
What you are looking for is an automated build script. You will be able to configure it so that it bundles your files together, and wraps them in an IEFE in whose scope they will be able to share their private state. The most simple example:
#!/bin/sh
echo "APP = (function () {
var _secret = {},
app = {};" > app.js
cat app.part01.js >> app.js
cat app.part02.js >> app.js
echo " return app;
}());" >> app.js
The only way that you can share _secret is attaching it to the application object and then application object to the window object. Here is an example.
// FIRST JS FILE...
var application; // will be attached to window
(function(app) {
app.secret = "blah!"; // will be attached to application
})(application || (application = {}));
// ANOTHER JS FILE
var application;
(function(app) {
app.method1 = function(){ console.log(app.secret); }; // will be attached to application;
})(application || (application = {}));
console.log(application.method1()); // will display 'blah!' on the console
Working example on jsbin
One way I was able to accomplish this was to create a JS file that contained the global object.
// Define a global object to contain all environment and security variables
var envGlobalObj = {
appDatabase: process.env.YCAPPDATABASEURL,
sessionDatabase: process.env.YCSESSIONDATABASEURL,
secretPhrase: process.env.YCSECRETPHRASE,
appEmailAddress: process.env.YCAPPEMAILADDRESS,
appEmailPassword: process.env.YCAPPEMAILPASSWORD
}
module.exports = envGlobalObj
Then in the files I wish to reference this object, I added a require statement.
var envGlobalObj = require("./envGlobalObj.js");
This allowed me to centralize the environment and secrect variables.

Multiple Javascript files, I want to take out URL constants into a seperate file

As the title says, I have a few javascript files. There are sections that call a few websites. I want to be able to store the websites in a different file, this way if the website changes we just need to make one change and not many.
Any suggestions?
I tried doing something like
/**
* Returns URLs
*/
var URLCONTEXT = "/root-url/context/";
var URLROOT = "/root-url/";
function getContextUrl(){
return URLCONTEXT;
}
function getRootUrl(){
return URLROOT;
}
but this doesn't have a way to communicate with the other JS files =/
Include your url constants in a js file like
url-constants.js
var URLCONTEXT = "/root-url/context/";
var URLROOT = "/root-url/";
and reference this js file first before other js files.
and you will be able to use url-constants variable in any other js file.
other.js
function getContextUrl(){
return URLCONTEXT;
}
function getRootUrl(){
return URLROOT;
}
include these in your page like
<script language="text/javascript" src="url-constants.js"></script>
<script language="text/javascript" src="other.js"></script>
var's defined outside of a function, and functions defined with a name are in the global namespace. You can access them from your other JS files as long as this JS file is loaded first.
You should be able to do that. Just make sure the file with the urls is included before the files where it's accessed from.
Also, I would not recommend polluting the global scope with these, even if you named them in capital letters. How about defining
var URLS = {
urlContext: '/root-url/context',
urlRoot: '/root-url'
};
and using them in other files with URLS.urlContext and URLS.urlRoot?

Invoking JavaScript "new" from CoffeeScript

I am trying to reuse a JavaScript library (sim.js) in CoffeeScript code. In an example that comes with sim.js, there are 3 files, "sim-0.26.js", "buffet_restaurant.js", and "buffet_restaurant.html" wired together like this (I've eliminated some parameters to simplify):
Inside of "buffet_restaurant.html", there is
<script type="text/javascript" src="./buffet_restaurant_files/sim-0.26.js"></script>
<script type="text/javascript" src="./buffet_restaurant_files/buffet_restaurant.js"></script>
<script type="text/javascript">
$(function () {
$("#run_simulation").click(function () {
var results = buffetRestaurantSimulation();
...
where buffetRestaurantSimulation is a function inside of buffet_restaurant.js. The code in buffet_restaurant.js starts off like this:
function buffetRestaurantSimulation()
{
var sim = new Sim();
...
where Sim is defined in sim-0.26.js, like this:
function Sim(){...};
This example runs fine. I want to reuse "Sim" in a CoffeeScript file in node.js. So I try this (invoked from jasmine-node):
sjs = require "./sim-0.26.js"
mysim = new sjs.Sim()
where sim-0.26.js is in the same directory as testsim.spec.coffee, the file containing this code. When I invoke this using:
jasmine-node --coffee ./testsim.spec.coffee
I get this:
mysim = new sjs.Sim();
^
TypeError: undefined is not a function
I suspect I am doing a ton of things wrong. I'm pretty new to all this.
Any ideas?
Unless Sim is added to exports it will not be available when required - see the docs on modules for more information on the way Node.js modules need to be written.
If this needs to work in both the browser and in node, then simply add this to the code for sim.js:
var root = typeof exports === "object" ? exports : window;
root.Sim = Sim;

javascript linking

I'm going to build a rather complicated application in html5 with some heavy javascripting.
In this I need to make some objects which can be pass around. But since there is no like #import foobar.js.
Then I assume that if my html page loads the scripts, then all the scripts can access eachother?
I read (here) that ajax somehow is able to load a .js file from within another .js file. But i dont think this is what I need?
Can go more into details if needed, thanks in advance.
In our projects, we do the following: Suppose you're going to call your project Foo, and have a module called Bar in it,
Then what we do is declare a file called Foo.js that just defines an equivalent to a Foo namespace:
Foo = (function(){
return {
};
})();
Then we create a file called Foo.Bar.js that contains the code for the Bar module:
Foo.Bar = (function(){
// var declarations here that should be invisible outside Foo.Bar
var p, q;
return {
fun1 : function(a, b){
// Code for fun1 here
},
fun2 : function(c) {
// Code for fun2 here
}
} // return
})();
Note that how it is a function that executes immediately, and returns an object that gets assigned to Foo.Bar. Any local variables, like p and q are available to fun1 and fun2 because they're in a closure, but they are invisible outside of Foo.Bar
The functions in Foo.Bar can be constructors for objects and so on.
Now in your HTML you simple include both files like so:
<script type="text/javascript" src="Foo.js"></script>
<script type="text/javascript" src="Foo.Bar.js"></script>
The result will be that you can call Foo.Bar's functions in the JavaScript of your main HTML file without any problems.
You should check out the module pattern:
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth/
This describes alternatives for creating modular code in javascript, how you can protect your code and share APIs and data among them.
You should also consider using and AMD. Require.js is quite popular, but I tend to prefer head.js for this. Keep in mind that these put some requirements on how you structur your code in files, and personally, I don't think it's worth it, compared to a concatenated and minified file included in the bottom of the page.
Then I assume that if my html page loads the scripts, then all the scripts can access eachother?
Yes.

Categories

Resources