Simple TDD Jasmine / Karma test failing as undefined function - javascript

I'm completely new to jasmine / karma and having a few problems. Test run fine when i run a simple
describe('JavaScript addition operator', function () {
it('adds two numbers together', function () {
expect(1 + 2).toEqual(3);
});
});
test, it passes and is ok but I want to now start testing functions in my othe files, Naturally I started with the most difficult one and fell flat on my face. I then worked my way down the list / errors until I got to the most basic of functions, one that rounds a number to a decimal place by taking in the params. It gave me an undefined error, so I then thought I'd move the addition test that worked into that file just to see if I was being special and it doesn't work either so can someone please tell me what I'm doing wrong? :)
I've been hunting online for quite a while and haven't yet found an idiots guide. I'd like to be able to test my functions by passing in params that I'd expect. For ex:
describe("round results", function(){
var myFunc = roundresult(a,b);
var a = 99.923232;
var b = 1;
it("rounds the result to dec places", function(){
expect(myFunc(a,b).toEqual(99.9));
});
});
where this is the function:
function roundResult(value, places) {
var multiplier = Math.pow(10, places);
return (Math.round(value * multiplier) / multiplier);
}
the error:
ReferenceError: roundresult is not defined
at null.<anonymous> (http://localhost:9878/base/tests/objectTests.js:98:18)
at jasmine.Env.describe_ (http://localhost:9878/absolute/usr/local/lib/node_modules/karma-jasmine/lib/jasmine.js:884:21)
at jasmine.Env.describe (http://localhost:9878/absolute/usr/local/lib/node_modules/karma-jasmine/lib/jasmine.js:869:15)
at describe (http://localhost:9878/absolute/usr/local/lib/node_modules/karma-jasmine/lib/jasmine.js:629:27)
at http://localhost:9878/base/tests/objectTestTests.js:96:1
Any help is hugely appreciated, thanks.

In your describe block, roundresult should be roundResult.
SOLVED: the order in which you require your files determines whether a statement has been defined by the time you try to invoke it. Use plnkr.co to host a sample with multiple files.

expect(myFunc(a,b).toEqual(99.9)); // incorrect, should be as mentioned below
expect().toEqual();
And you have called the function and than initialize variables, which is also incorrect:
var myFunc = roundresult(a,b);
var a = 99.923232;
var b = 1;
Please have a look how I have done :
// I have created test.js
describe("round results", function(){ var a = 99.923232;
var b = 1;
var myfunc = roundResult(a,b);
it("rounds the result to dec places", function(){
expect(myfunc).toEqual(99.923232);
});
});
// main.js
function roundResult(value, places) {
var multiplier = value * places;
return multiplier;
}
I hope it will resolve your error.
Thanks.

Related

Refactoring javascript functions for reuse

I have this lovely, well written function (thanks to CSS Tricks (good article btw) - see Codepen):
document.documentElement.style.setProperty("--mainColor",
localStorage.getItem("userThemeColor"));
var colorInput = document.querySelector("#choose-theme-color");
colorInput.addEventListener("change", function() {
document.documentElement.style.setProperty("--mainColor", this.value);
localStorage.setItem("userThemeColor", this.value);
});
I use it more than once, so to avoid duplication I want to refactor it into a reusable function. I've been at it all day and am having real trouble getting the querySelector value (this.value and anything else I've named it) into the reworked function. Everything I've tried breaks the function (thought I'd broken Codepen a coupla times too...) or ends up with 'value not defined'
If I can see how it's done, I'm sure it'll make more sense to me and I'll be able to apply the same logic elsewhere in my code. I'm trying to learn 'good practice', so if anyone can help, I'd really appreciate it!
Thanks in advance.
document.documentElement.style.setProperty("--mainColor", localStorage.getItem("userThemeColor"));
document.documentElement.style.setProperty("--footerColor", localStorage.getItem("userFooterColor"));
var colorInput1 = document.querySelector("#choose-theme-color");
var colorInput2 = document.querySelector("#choose-theme-2");
var color1 = new Picker("--mainColor", "userThemeColor");
var color2 = new Picker("--footerColor", "userFooterColor");
// Object contructor
function Picker(arg1, arg2){
// this.arg1 = arg1; // property to set - not req'd
// this.arg2 = arg2; // local property item - not req'd
this.setStyles = function() { // this.value is original code
document.documentElement.style.setProperty(arg1, this.value);
localStorage.setItem(arg2, this.value);
}
}
colorInput1.addEventListener("change", color1.setStyles);
colorInput2.addEventListener("change", color2.setStyles);
// 14 LINES OF CODE / AGAINST 6 X 2 IF USING DUPLICATES OF THE ORIGINAL

Javascript function name in variable

Hi guys!
Could you please help me with the function beloW?
Code executes as planned, but as soon as i replace the 'SLL' string below with a variable, I get error.
This works fine: x = 'SLL'
This does not work: x = schemename (assuming i define var schemename = 'SLL' earlier in the code)
Please see code below
function sll() {
return 'got it';
}
var mySchemes = {
SLL: sll
};
x = 'SLL';
mySchemes[x]();
What are you using to run the code? You can run the code right here on StackOverflow and see that it's running fine. The one issue you could be having is if 'use strict' is being enforced, in which case you need to define x explicitly.
function sll() {
return 'got it';
}
var mySchemes = {
SLL: sll
};
var x = 'SLL';
console.log(mySchemes[x]());

Prototyping in JavaScript

I am learning a javascript and while I was go through it I was learning prototyping so i tried following code
function vehicle(type,year){
this.type="moped";
this.year="2012";
}
Activa=new vehicle;
console.log(Activa.type);
console.log(Activa.year);
function speed(km){
console.log(km);
}
vehicle.prototype.speed=speed;
console.log('160km/hr');
The above code gave me the proper and correct output
But
when i was trying varient of it of it it doesnt gave me the proper output
following is the code
function vehicle(type,year){
this.type="moped";
this.year="2012";
}
Activa=new vehicle;
console.log(Activa.type);
console.log(Activa.year);
function speed(km){
km="160";
console.log(km);
}
vehicle.prototype.speed=speed;
console.log(Activa.speed);
The above code gave me the following(snap shot of chrome console) output in chrome developer tool
whats wrong am i doing?and why it gave me the output like in the image the output I am expecting is 160
Issues with your code
Parenthesis missing with the speed() method in console.log(Activa.speed);
your speed() method is not returning anything that why you are getting undefined
Try something like below
function vehicle(type, year) {
this.type = "moped";
this.year = "2012";
}
Activa = new vehicle;
console.log(Activa.type);
console.log(Activa.year);
function speed(km) {
var km = km || "160";
console.log(km);
return km;
}
vehicle.prototype.speed = speed;
console.log(Activa.speed());
One more issue is the you are trying to replicate class type behavior in JS then you should stick to standard, base function should have first character capital, something like below -
function Vehicle(type, year) {
this.type = "moped";
this.year = "2012";
}
var activa = new Vehicle;
console.log(activa.type);
console.log(activa.year);
function speed(km) {
var km = km || "160";
console.log(km);
return km;
}
Vehicle.prototype.speed = speed;
console.log(activa.speed());
For more details follow here - http://www.phpied.com/3-ways-to-define-a-javascript-class/
Activa.speed is a function so if you use
console.log(Activa.speed());
it will output what you expect.
functions are also variables in javascript so console.log(Activa.speed); outputs the content of the variable, which in this case is a function.
That's normal,
You are referencing speed as a function
function speed(km){
km=km||"160";
return km;
}
So you should log speed like that
console.log(Activa.speed());
and not like that
console.log(Activa.speed);
And you will have your correct output (160)

Javascript testing, node + sinon, testing 'new' calls

I am trying to test a function that looks like so
ContentModel.prototype.fileHandlers = function() {
if (_.isUndefined(this.__cache__.fileHandler)) {
this.__cache__.fileHandlers = new FileHandlers(this.__data__.fileHandlers);
}
return this.__cache__.fileHandlers;
};
to simply check that it caches how I have it set up like so
it("should return cached the second time.", function() {
contentModel = new ContentModel({
fileHandlers: {}
});
var firstTime = contentModel.fileHandlers();
var secondTime = contentModel.fileHandlers();
expect(firstTime).to.equal(secondTime);
});
And getting the errors of :
AssertionError: expected { Object (__data__, __cache__) } to equal { Object (__data__, __cache__) }
+ expected - actual
I just want to basically check the second call is the same - so it's cached when I use the new ContentModel. Can't seem to figure out how to wrestle down this problem. It's sort of an odd problem, but I am going for as much coverage as possible. Thanks!
Just to clarify a little further - I can change .to.equal to to.deep.equal and the test will pass, however I want to check if the object is the same object being returned, not the content.

Recursion function not defined error

Hi i have a problem with recursion.
i followed this example from wc3 http://www.w3schools.com/jsref/met_win_settimeout.asp
But mine seems to not work at all.
function rotateImages(start)
{
var a = new Array("image1.jpg","image2.jpg","image3.jpg", "image4.jpg");
var c = new Array("url1", "url2", "url3", "url4");
var b = document.getElementById('rotating1');
var d = document.getElementById('imageurl');
if(start>=a.length)
start=0;
b.src = a[start];
d.href = c[start];
window.setTimeout("rotateImages(" + (start+1) + ")",3000);
}
rotateImages(0);
Firebug throws the error :
rotateImages is not defined
[Break On This Error] window.setTimeout('rotateImages('+(start+1)+')',3000);
However if i change the timeOut to :
window.setTimeout(rotateImages(start+1),3000);
It recursives but somehow the delay doesn't work and gives me too much recursion(7000 in a sec)
There are many reasons why eval should be avoided, that it breaks scope is one of them. Passing a string to setTimeout causes it to be evaled when the timer runs out.
You should pass a function instead.
window.setTimeout(rotateImages(start+1),3000);
This calls rotateImages immediately, then passes its return value to setTimeout. This doesn't help since rotateImages doesn't return a function.
You probably want:
window.setTimeout(rotateImages,3000,[start+1]);
Or create an anonymous function that wraps a closure around start and pass that instead:
window.setTimeout(function () { rotateImages(start + 1); },3000);
The latter option has better support among browsers.
Be wary of code from W3Schools.
The other answers give a solution. I'll just add that you're recreating the Arrays and repeating the DOM selection every time the rotateImages function is called. This is unnecessary.
You can change your code like this:
(function() {
var a = ["image1.jpg","image2.jpg","image3.jpg", "image4.jpg"];
var c = ["url1", "url2", "url3", "url4"];
var b = document.getElementById('rotating1');
var d = document.getElementById('imageurl');
function rotateImages(start) {
b.src = a[start];
d.href = c[start];
window.setTimeout(function() {
rotateImages( ++start % a.length );
}, 3000);
}
rotateImages(0);
})();
Try this syntax:
window.setTimeout(function() {
rotateImages(start+1);
},3000);
setTimeout() expects a function reference as the 1st parameter. Simply putting a function call there would give the return value of te function as the parameter, this is why the delay did not work. However your first try with evaluating a string was a good approach, but it is not recommended.

Categories

Resources