Jasmine toThrow() syntax - javascript

I have an activity I am doing for an apprenticeship opportunity and the main engineer that I could discuss this with is not responding so I figure I ask on here.
Basically this is a 'triangle' exercise with the main purpose of writing in TDD with jasmine.
Now, I have written the simple ones and when I moved to writing the edge cases, I am having trouble with throwing invalid input. Looking at the Docs it seems simple but my test fails with invalid thrown as error
describe('Triangle', function(){
var Triangle = function(x, y, z){
if (x <= 0 || y <= 0 || z <= 0) {
throw 'invalid';}
if(x === y && y === z){
return 'equilateral';}
if(x === y || x === z || y === z){
return 'isosceles';}
else{return 'scalene';}
};
it('test triangles with no size are illegal', function() {
var triangle = Triangle(0,0,0);
expect(triangle).toThrow();
});
});

The problem is that you are actually calling the function here:
var triangle = Triangle(0,0,0);
Instead, you should let expect() call it by providing a callable:
expect(function() { Triangle(0, 0, 0); }).toThrow();

Related

Function call and definition have different names in stack trace

I was trying to understand the JavaScript on a website when I found a weird phenomenon. I enabled breakpoints for XHRs in devtools and was reading through the stack trace when it hit the breakpoint. The issue is this.
There would be a function definition that is something like:
function foo(someObject) {
//Some code
}
and when I went one more step up the stack trace to see the call to this function, I'd see something like:
bar(someobject);
The name of the call doesn't match the definition! Someone please explain how this works. Some references to articles would be appreciated too.
This may be a rookie question so thank you for the patience.
Edit 1 - Here are some screenshots:
This is at the last item in the stack. The code paused at line 1829. This is inside the function named _() starting at line 1805. If I jump one step back in the stack trace,
it jumps to line 268 of the same js file, where the function call is. But the call is to t.scheduleFn(), not to _(). I have checked and verified that the object passed in is identical to the object received at the definition. Please drop a comment if you need any more info.
If you need to see this live, please go to this website, turn on breakpoints for XHRs, enter any number into the input field, click on 'Get OTP' and look at the stack trace.
Edit 3 - Here's some of the code:
Please read the comments that I've added.
This is the function inside which the code paused:
function _(e) { //Note that this is the function name
const o = e.data,
c = o.target;
c[i] = !1,
c[h] = !1;
const l = c[r];
d || (d = c[s], g = c[a]),
l && g.call(c, 'readystatechange', l);
const u = c[r] = () =>{
if (c.readyState === c.DONE) if (!o.aborted && c[i] && 'scheduled' === e.state) {
const n = c[t.__symbol__('loadfalse')];
if (n && n.length > 0) {
const r = e.invoke;
e.invoke = function () {
const n = c[t.__symbol__('loadfalse')];
for (let t = 0; t < n.length; t++) n[t] === e && n.splice(t, 1);
o.aborted || 'scheduled' !== e.state || r.call(e)
},
n.push(e)
} else e.invoke()
} else o.aborted || !1 !== c[i] || (c[h] = !0)
};
return d.call(c, 'readystatechange', u),
c[n] || (c[n] = e),
T.apply(c, o.args), //The code paused here.
c[i] = !0,
e
}
If I went one step back to see the call to the function _() I see this:
scheduleTask(e, t) {
let n = t;
if (this._scheduleTaskZS) this._hasTaskZS && n._zoneDelegates.push(this._hasTaskDlgtOwner),
n = this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt, this._scheduleTaskCurrZone, e, t),
n || (n = t);
else if (t.scheduleFn) t.scheduleFn(t); //The debugger shows that this is where the call to _() happened.
else {
if (t.type != S) throw new Error('Task is missing scheduleFn.');
k(t)
}
return n
}
My question is simply, how can a call to t.scheduleFn() go to _(). Hope this is clear.

Parameters will not be hoisted and will hit temporal dead zone?

function bar(x=y, y=2) {
return [x, y];
}
bar();//uncaught reference: y is not defined
I can't understand why the above code will hit exception. If from other languages it make sense because flow of programs are important and we can't reference to y because y is not created yet and it would be resulted in compilation error. However this is JS, both x and y should equally be hoisted first and such reference shouldn't throw exception. I would expect the pseudo-code to be similar like below?
x=y
var x;
var y;
console.log(x,y); //undefined undefined (which is fine as no value but instead of throwing exception)
UPDATES:
function bar() {
var x = arguments.length >= 1 ? arguments[0] : y;
{
var y = arguments.length >= 2 ? arguments[1] : 2;
return [x, y];
}
}
console.log(bar());//[undefined, 2]
Your assumption is wrong, they're not hoisted like that. It's more like:
function bar() {
let x = arguments.length >= 1 ? arguments[0] : y;
{
let y = arguments.length >= 2 ? arguments[1] : 2;
return [x, y];
}
}
The scope of each variable default value only includes the variables to the left of it, not the variables to the right.

If then logic with && ||

Can someone explain to me or point me to documentation as to why the following function doesn't work?
var x = 1;
var y = 2;
var z = 1;
function logicTest() {
if ((x && y && z) === 1) {
return true;
} else {
return false;
}
}
console.log(logicTest())
I know that I can type it out the long way as follows:
var x = 1;
var y = 2;
var z = 1;
function logicTest() {
if (x === 1 && y === 1 && z === 1) {
return true;
} else {
return false;
}
}
console.log(logicTest())
But I'm really trying to understand why the first doesn't work and also if there is a better way of typing the second if/then statement or if that is just the way it will always have to be.
Thanks!
The expression
((x && y && z) === 1)
first involves the evaluation of (x && y && z). To evaluate that, JavaScript tests, in sequence, the values of x, y, and z. If, left to right, one of those values when coerced to boolean is false, evaluation stops with that (uncoerced) value as the value of the whole thing. Otherwise, the value of that subexpression will be the value of z, because it's the last subexpression in the && sequence.
In this case, x, y, and z are all non-zero numbers, so the overall result will be 1, because z is 1.
What you seem to want to be able to do is test whether all of a set of subexpressions are equal to the same value. That, as you've found, can only be determined by explicit comparison. It's also something that could be done by creating a list and then using array functions to perform the tests, which would be useful when there are more than just three subexpressions to test.
Also, on a stylistic note:
function logicTest() {
if (x === 1 && y === 1 && z === 1) {
return true;
} else {
return false;
}
}
Performing tests with relational operators like === generates boolean values. It's more concise to take advantage of that:
function logicTest() {
return x === 1 && y === 1 && z === 1;
}

trying to get offsetTop on window.scroll and then traverse the DOM according to the touched slide

I am creating one page site and then trying to get offsetTop on window.scroll, by which i want to traverse the DOM according to the slide.
a lot of tries.. feeling dumb now..
if anyone can help, would be highly appreciable.
thanks
here is the code and fiddle URL:
$(window).scroll(function () {
var y = $(window).scrollTop(),
a = $('#first').offset().top - 200,
b = $('#second').offset().top - 200,
c = $('#third').offset().top - 200,
d = $('#fourth').offset().top - 200;
if (y > a) {
$('h1').html('This is First Slide');
}
if (y > b) {
$('h1').html('This is Second Slide');
}
if (y > c) {
$('h1').html('This is Third Slide');
}
if (y > d) {
$('h1').html('This is Third Slide');
}
else{
$('h1').html('No heading');
}
});
http://jsfiddle.net/A8Hmr/9/
Your logic is correct it's just a miss with the ifs.
I will show the code and explain:
var a = $('#first').offset().top - 200,
b = $('#second').offset().top - 200,
c = $('#third').offset().top - 200,
d = $('#fourth').offset().top - 200;
$(window).scroll(function () {
var y = $(window).scrollTop();
if (y > a && y < b) {
$('h1').text('This is First Slide');
}
else if (y > b && y < c) {
$('h1').text('This is Second Slide');
}
else if (y > c && y < d) {
$('h1').text('This is Third Slide');
}
else if (y > d) {
$('h1').text('This is Third Slide');
}
else{
$('h1').text('No heading');
}
});
Demo
1) You don't need to take the offset of the slides on every scroll, since they don't change, you can put them outside of the scroll event, that way it will improve the performance.
2) The problem in the code was the if. Since they were all ifs (and not if/else if) statements, all of theme were checked if they were true. Meaning that if the first one was true the next one will not be true and it will enter in the else statement automaticaly overwriting the if that was true.
So you have to make them if/else if and since once y > a become true it will always be true (untill it goes to y < a) you must have an additional condition if y < b meaning if y is less then the next slide. Ofcourse once again you can use only if/else but what is the point in checking 5 things if only one is correct ? Performance should be a main thing in every js code. ;)
Version 2:
(function(){
var a = $('#first').offset().top - 200,
b = $('#second').offset().top - 200,
c = $('#third').offset().top - 200,
d = $('#fourth').offset().top - 200,
h1 = $('h1'),
textChange = ['No heading','This is First Slide','This is Second Slide','This is Third Slide', 'This is Third Slide']
$(window).scroll(function () {
var y = $(window).scrollTop();
if (y > a && y < b && h1.text() != textChange[1]) {
h1.text(textChange[1]);
}
else if (y > b && y < c && h1.text() != textChange[2]) {
h1.text(textChange[2]);
}
else if (y > c && y < d && h1.text() != textChange[3]) {
h1.text(textChange[3]);
}
else if (y > d && h1.text() != textChange[4]) {
h1.text(textChange[4]);
}
else if(y <= a && h1.text() != textChange[0]){
h1.text(textChange[0]);
}
});
})();
Demo
What change here?
1) I wrapped the whole thing in self invoking anonymous function (since it's not a good practice to have global variables).
2) We made a variable outside the scroll event that will hold the h1 so we don't have to go in the dom on every scroll event.
3) We made an array that will hold the text that will change. (and updated the values in the text scroll)
4) We changed the if condition in the if statement to check if the text is already the same so we don't have to change it again. So now it will fire only once instead of firing every time we scroll.
5) We changed the else to else if since it would enter once the text is the same an jump to the else.
Pretty much that should increase the performance a lot.

Order of execution - can I control it? [duplicate]

This question already has answers here:
How can I control Javascript execution order?
(2 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
Its an ASP.Net application, and this is part of a javascript function:
//x & y are global variables
x = document.getElementById(MapXVal).value;
y = document.getElementById(MapYVal).value;
if ((x === undefined || x === null || x === "") &&
(XVal !== undefined && XVal !== null && XVal !== "")) {
x = document.getElementById(XVal).value;
y = document.getElementById(YVal).value;
point = new esri.geometry.Point(x, y, new esri.SpatialReference({ "wkt": ...}));
var OutSR = new esri.SpatialReference({ "wkid": 102113 });
gsvc.project([point], OutSR, function (projectedPoints) {
var output = projectedPoints[0];
alert('deep inside');
x = output.x;
y = output.y;
});
}
alert('outer scope');
if (x !== null && y !== null && x !== "" && y !== "") {
//do something with x & y
}
What I am trying to do: call the function gsvc.project...etc to calcuate the values for my global variables x & y which will be used later on in the code.
Problem: the code within gsvc.project will be executed after its containing function is done executing (e.g. the message outer scope will be shown before deep inside) so I will not have the values for x & y until its too late.
I am not an expert in Javascript, so I've been looking for why this is happening and found nothing much up to this point. I already solved the problem by duplicating my code inside the gsvc.project..function(projectedPoints){ declaration, but I dont want to have duplicates and would like to know if there is a solution to my problem: control the execution, cause a delay, or maybe a better way to do this?

Categories