Sinon JQuery selectors mock - mocha.js

I am trying to test a function using mocha/sinonjs. The function I want to test is responsible for showing or hiding some element in my DOM.
This is my function
var updateUI = function() {
$('#login').show();
$('#logout').hide();
};
I tried to mock using sinon but I'm not sure if it is possible or the correct thing to do in this case.
This is what I have tried but I keep getting an error "TypeError: undefined is not a function" during the expect call
var mockLogin = sinon.mock($);
mockLogin.withArgs('#login').expects("show").once();
I simple want to test my 2 jquery calls have been called. I tried to use spies but continue to get exceptions

Looking further into the sinon doc I found that the following worked for me.
var jQueryShow = sinon.stub($.fn, 'show');
var jQueryHide = sinon.stub($.fn, 'hide');
jQueryShow.callCount.should.be.equal(1);
jQueryShow.thisValues[0].selector.should.be.equal("#login");
jQueryHide.callCount.should.be.equal(1);
jQueryHide.thisValues[0].selector.should.be.equal("#logout");
I'm not sure if there an easier way but it checks for the selectors I need

Related

How to use Jest to test React rendered async data?

I am using React for render and Jest/Jasmine for test. I have test written using old Jest/Jasmine waitsFor and runs but these are gone now in Jasmine 2 and I am not sure how to replace with new done asyncs.
In my code React renders a small page about a user. That page has an AJAX call to fetch user posts. I want to test that user posts have come back nice, and waitsFor was very, very good at this: wait until user has some post, then continue.
I looked online at lots of people talking about using AJAX calls inside Jest test which is not what I want. My Jest test has no idea about AJAX call being made, so I need a way to wait until results come back.
Here is my current code with waitsFor and runs:
it('loads user post', () => {
var page = TestUtils.renderIntoDocument(
<UserPage params={{user: 'fizzbuzz', 'pass': 'xxx'}} />
);
waitsFor(() => {
return page.state.posts.length > 0;
}, "post loaded", 10000);
runs(() => {
var posts = TestUtils.scryRenderedDOMComponentsWithClass(page, 'post');
expect(posts.length).toEqual(10);
});
});
How can I delete the waitsFor and runs and replace with Jasmine 2.0 code that works? All Jest test knows is that page.state.posts.length must be greater than 0 before expecting anything.
You should refactor this test into two unit tests that will provide a more rigorous testing of your code. It would make the tests more independent of one another and help identify errors in a more refined scope. These won't be exact as I do not know what your code is like, but here's something along the lines I would expect to see: -
it('generates the expected properties for a page', function () {
var page = TestUtils.renderIntoDocument(
<UserPage params={{user: 'fizzbuzz', 'pass': 'xxx'}} />
);
expect(page.someProperty).toBeDefined();
expect(page.user).toEqual('fizzbuzz');
});
it('generates the correct number of posts from a given page object', function () {
var fakePage = {
// put your fake mock data here that TestUtils expects
};
var posts = TestUtils.scryRenderedDOMComponentsWithClass(fakePage, 'post');
expect(posts.length).toEqual(10);
});
I am not too sure what is happening in your renderIntoDocument function so the top test may be a little broken... It looks like there is either too much going on inside the function, or you need to test the calls that function is making instead. If you elaborate on what it does I'll edit the answer.

how do I write jasmine test for innerHTML element

so my code does this...
diff = timevalue - (((Date.now() - startDate)/1000)|0);
document.getElementById("timer").innerHTML = diff.toLocaleString();
part of my current test looks like this...
it("count should define tictoc", function(){
jasmine.clock().install();
aTimer.count(25);
jasmine.clock().tick(1002);
expect(aTimer.tictoc).toEqual(1);
expect(document.getElementById("timer").innerHtml).toBe("success");
jasmine.clock().uninstall();
});
but I am getting this back from jasmine...
"TypeError: Cannot set property 'innerHTML' of null"
now I think this is because the html element is not present....which makes sense since I'm testing....but how do I mock that element so my test works?
I just got it:
it("count should define tictoc", function(){
jasmine.clock().install();
var dummyElement = document.createElement('span');
document.getElementById = jasmine.createSpy('HTML Element').and.returnValue(dummyElement);
aTimer.count(25);
jasmine.clock().tick(1002);
expect(aTimer.tictoc).toEqual(1);
expect(document.getElementById("timer").innerHTML).toEqual('25');
jasmine.clock().uninstall();
});

can.js validate method not working

Could anybody help me calling a validation function in can.js?
I'm adding can.jquery.js and can.map.validations.js
and then create such a small example:
var mymap = can.Map.extend({
init: function () {
this.validatePresenceOf('myfield'); // this line reports an error
}
});
when loading page with this script, I get an error in browser:
"Uncaught TypeError: undefined is not a function"
Actually any this.validate* function does not work
After some research I notice that when I put this code under
$(document).ready{}
it works, but if I put it into .js file and load via tag - browser reports an error.
And I'm not going to write all of my js code in the page itself
see here it tells pretty clearly(helped me last time) that you have to use $document.ready() or else it wont work, so try making a new file.js, have $document.ready() contain all your todo-code, and link it up, I hope I am helpful in this regard, if not then bug me up I wont mind at all :) ..
Commenting it late but anyway - it didn't work for me in either case so I just took the sample from http://jsbin.com/jofeq/5/edit?html,js,output - and copied it to my code. Surprisingly it worked after copying - not sure what was wrong on my side.
In that example it looks like this:
var Person = can.Map({
init: function () {
this.validatePresenceOf('firstName');
this.validatePresenceOf('lastName');
}
}, {});
and it works without document.ready tricks or anything else - just included into body tag

basic ajax function not working

i'm learning Ajax and i'm facing some problem with this very basic function:
function fetchData(url, objectID){
var pageReqtest=null;
if(window.XMLHttpRequest)pageRequest=new XMLHttpRequest();
if(window.ActiveXObject)pageRequest=new ActiveXObject("Microsoft.XMLHTTP");
else return false;
pageRequest.onreadystatechange= function(){
var object=document.getElementById(objectID);
object.innerHTML = pageRequest.responseText;
}
pageRequest.open("GET",url,true);
pageRequest.send(null);
}
And then i have:
<div id="control" onclick="fetchData('data.jsp','message');">Click here for Ajax!</div>
But unfortunatelly its not working, the function though is correctly called.
I have my project in Eclipse and i'm running this on Tomcat 6, the page data.jsp its a single line of html, the data.jsp is positioned at the same lavel as the page where the javascript function is written
Do you have some advice?
beside wrong spelling as mentioned by lonesomeday
you also have missing parameter here var object=document.getElementById();
Looks like others beat me to it, but in any case, here is working fiddle: http://jsfiddle.net/smendola/BcMMn/
As they said, typos...
My best bet is that it is a syntax error caused by your misspelling of function:
pageRequest.onreadystatechange= fucntion(){
This would cause the Javascript not to be parsed, so your function would never be defined.
On a different note, there are a couple of other little errors that, while they might not prevent your code working, might make your life difficult.
var pageReqtest=null;
Elsewhere you call the variable pageRequest. Be consistent: at the moment, you are creating a global variable called pageRequest and completely ignoring the local one pageReqtest.
if(window.XMLHttpRequest)pageRequest=new XMLHttpRequest();
if(window.ActiveXObject)pageRequest=new ActiveXObject("Microsoft.XMLHTTP");
else return false;
If the browser has both window.XMLHttpRequest and window.ActiveXObject, you will create both, first the XMLHttpRequest object, then you will overwrite it with the ActiveXObject. This isn't what you want – it's suboptimal and it's better to use the proper XMLHttpRequest if it's available.
The quick way to do this is to make the second line else if at the beginning.
And you miss out the id in the getElementById call:
var object=document.getElementById();
I think this should be:
var object = document.getElementById(objectID);

Jquery Event Listener for javascript objects

I apologize if this has been asked before but, is there a way to add an event listener/handler to a Javascript object? Preferably using JQuery.
Such as:
var foo;
$(foo).bind('change', function() {
alert("Foo has changed!");
});
I have tried this, but nothing seems to happen. Does this only work with DOM elements?
EDIT:
I need an event fired every time that the audio or video tags throw an error. Originally, I was using an interval to check whether or not the error, 'media.error', object was null, but this uses excess processing power and I would like to avoid it.
EDIT 2: Apparently I was going about it wrong, easiest way I found was to add the "onerror" property to the video/audio tag.
I agree with Cheeso that it's more important for you to state what you actually want to do, however one workaround for your specific question could be to store your variable within an object and only provide access through getter / setter, then you can do what you want in the setter. e.g.
function data() {
var foo = 0;
this.setFoo = function(newVal) {
foo = newVal;
alert(foo);
};
}
var theData = new data();
theData.setFoo(5);
Yes, that's correct. You cannot make a "variable watcher". There is no event fired for variables when they are changed.
What are you really trying to do?
You could try:
http://higginsforpresident.net/js/static/jq.pubsub.js
See
http://weblog.bocoup.com/publishsubscribe-with-jquery-custom-events
Or use a framework like backbone/underscore or knockout.js.
HTML/Elements/audio
var foo;
$(foo).bind('error', function() {
//your code here
});

Resources