QUnit tests failing intermittently - javascript

Below is my javascript file that shows the sum of two numbers.
var getSum = function (arg1, arg2) {
var intArg1 = parseInt(arg1);
var intArg2 = parseInt(arg2);
return intArg1 + intArg2;
};
var getSumText = function (arg1, arg2) {
var sum = getSum(arg1, arg2);
return 'The sum of ' + arg1 + ' and ' + arg2 + ' is ' + sum + '.';
};
$(document).ready(function () {
$("#button1").click(function (e) {
console.log('button clicked');
var sumText = getSumText($("#arg1").val(), $("#arg2").val());
$("#output1").text(sumText);
e.stopPropagation();
});
});
Here's my QUnit.html file.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Test Suite</title>
<link href="Content/qunit-1.12.0.css" rel="stylesheet" />
<script src="Scripts/jquery-2.0.0.min.js"></script>
<script src="Scripts/qunit-1.12.0.js"></script>
<script src="Scripts/main.js" data-cover></script>
<script src="Scripts/mainTests.js"></script>
<script src="Scripts/blanket.min.js"></script>
</head>
<body>
<h1 id="qunit-header">Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">
<input type="text" id="arg1" />
<input type="text" id="arg2" /> <br />
<div id="output1"> </div>
<input type="button" id="button1" value="Show sum" />
</div>
<script type="text/javascript">function blanket_toggleSource(e) {
var t = document.getElementById(e);
t.style.display === "block" ? t.style.display = "none" : t.style.display = "block";
}</script>
</body>
</html>
And here's my js tests file.
module('DOM');
test('should add correctly', 1, function() {
$('#arg1').val('2');
$('#arg2').val('5');
console.log($('#arg1').val());
console.log($('#arg2').val());
$('#button1').trigger('click');
var output = $('#output1').text();
equal(output, 'The sum of 2 and 5 is 7.', 'sum text is correct');
});
module('Sum');
test('should add correctly', 1, function() {
var sum = getSum('2', '1');
deepEqual(sum, 3, 'sum is correct');
});
If I move the 'Sum' module above the 'DOM' one, the test in the DOM module fail intermittently. What am I missing?
Thanks,
Arun

You need to separate the library code, that you can test, from the initialization code, that you don't really need to test in this case. Move the code inside the click handler into another named function and called that from a separate script tag or file. That way you can test all three functions from your tests. Currently you end up with document-ready executing code at a some point in time, while your tests run at another. That causes the seemingly random behaviour you're seeing.

Related

Open Source Spell Check for javascript Typo.js

As I try to use the typo.js spell checker in my file. But it's throw some error's I can't find the solutions. I just followed the Typo.js Documentation Here is the document link.
https://github.com/cfinke/Typo.js/
Kindly check the below issue and help me to reach out this issue
Here is the console issue image
Here is the used code
JS
<!doctype html>
<html>
<head>
<title>Typo.js Example</title>
<meta charset="UTF-8" />
<script type="text/javascript" src="typo/typo.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script type="text/javascript">
var dictionary = new Typo("en_US", false, false, { dictionaryPath: "typo/dictionaries" });
// function load() {
// $('#loading-progress').append('Loading affix data...').append($('<br />'));
// $.get('typo/dictionaries/en_US/en_US.aff', function (affData) {
// $('#loading-progress').append('Loading English dictionary (this takes a few seconds)...').append($('<br />'));
// $.get('typo/dictionaries/en_US/en_US.dic', function (wordsData) {
// $('#loading-progress').append('Initializing Typo...');
// dictionary = new Typo("en_US", affData, wordsData);
// checkWord('mispelled');
// });
// });
// }
checkWord('mispelled');
function checkWord(word) {
var wordForm = $('#word-form');
wordForm.hide();
var resultsContainer = $('#results');
resultsContainer.html('');
resultsContainer.append($('<p>').text("Is '" + word + "' spelled correctly?"));
var is_spelled_correctly = dictionary.check(word);
resultsContainer.append($('<p>').append($('<code>').text(is_spelled_correctly ? 'yes' : 'no')));
if (!is_spelled_correctly) {
resultsContainer.append($('<p>').text("Finding spelling suggestions for '" + word + "'..."));
var array_of_suggestions = dictionary.suggest(word);
resultsContainer.append($('<p>').append($('<code>').text(array_of_suggestions.join(', '))));
}
wordForm.show();
}
</script>
</head>
<body>
<h1>Typo.js Demo</h1>
<p>This page is an example of how you could use Typo.js in a webpage
if you need spellchecking beyond what the OS provides.</p>
<p id="loading-progress"></p>
<div id="results"></div>
<form method="GET" action="" onsubmit="checkWord( document.getElementById( 'word' ).value ); return false;"
id="word-form" style="display: none;">
<p>Try another word:</p>
<input type="text" id="word" value="mispelled" />
<input type="submit" value="Spellcheck" />
</form>
</body>
</html>

Why is my save function not executing in its entirety?

I am trying to create a to-do list in HTML, CSS and pure JS.
const dSubmit = document.getElementById('submit');
const storeData = [];
let typer = document.getElementById('type');
let input = document.getElementById('text');
const list = document.getElementById('listHolder');
dSubmit.addEventListener("click", (e) => {
e.preventDefault();
if (input.value == "") {
typer.innerHTML = "Please enter a task";
} else {
typer.innerHTML = "";
store();
}
});
function store() {
const tData = document.getElementById('text').value;
storeData.push(tData);
updater();
input.value = "";
}
function deleter (index) {
storeData.splice(index, 1);
updater();
}
function updater() {
let htmlCode = "";
storeData.forEach(function(item, index){
htmlCode += "<div class='test'><div id = "+ index +">" + item + "</div><div class='sideBtn'><button type='button' class='edit' onClick= 'editF("+ index +")'>Edit</button><button class='delBtn' onClick= 'deleter("+ index +")'>Delete</button> </div> </div>"
})
list.innerHTML = htmlCode;
}
function editF (index) {
let tempOne = document.getElementById(index);
let tempTwo = "<input id='inputText"+String(index)+"' type='text' name='task' value ='" + String(storeData[index]) + "'><button id='saveText"+String(index)+"' onClick= 'save("+index+")' >Save</button>"
tempOne.innerHTML = tempTwo;
}
function save (index) {
console.log('test1')
let tempOne= document.getElementById('saveText'+String(index));
let tempTwo = document.getElementById('inputText'+String(index));
console.log('test2')
tempOne.addEventListener("click", function foo (){
console.log('test3')
storeData.splice(index,1,tempTwo.value)
updater()
}
)
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8">
<title>To Do List</title>
</head>
<body>
<h1>To-do-list</h1>
<form>
<label for="task">Please enter item:</label>
<input type="text" name="task" id="text">
<button id="submit">Submit</button>
</form>
<div id='type'></div>
<div>List:</div>
<div id="listHolder" class="test"></div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
I am facing problems with the save function. If I edit an item in the to-do list and click the save button, the function executes up to the point of console.log('test2'). If I click save again the function executes in its entirety.
I would like to ask why the first click results in execution of the save function up to 'test2'?
Additionally would anyone be kind enough to critique my JS? are there things in dire need of improvement? or is there a more practical/efficient method of writing my JS code?
Thank you for your help in advance.
After the 'test2' log, you are adding an event listener, and the rest of the code is inside of the listener block. The code in the listener block is only executed once that listener receives a 'click' event, which is why it works the second time.

button click event fires on page load [duplicate]

This question already has answers here:
What is the difference between a function call and function reference?
(6 answers)
Closed 3 years ago.
I have a js and htlm code in jfiddle.
I have created the button onclick event on the object method and on the page load it firing the event.
Is this some problem with my code.
var user = {
data: [
{name: 'T. Woods', age: 37},
{name: 'P. Mickelson', age: 43}
],
clickHandler: function (event) {
console.log(this);
var randomNum = ((Math.random() * 2 | 0) + 1) - 1; // Random number between 0 and 1
$('input').val(this.data[randomNum].name + ' ' + this.data[randomNum].age);
}
};
console.log(user);
$('button').click(user.clickHandler(this));
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h1>Homepage Headline</h1>
<div id="div1">
<p>
<button>Get Random Person</button><br>
<input type="text">
</p>
</div>
<script type="text/javascript" src="oops.js"></script>
</body>
</html>
Your click event listener needs to be a function otherwise it will trigger .click() on the button instead of creating a listener
See the documentation for .click()
$("button").click(function () {
user.clickHandler(this)
});
Test it with your code here -
var user = {
data :[
{name: "T. Woods", age:37},
{name: "P. Mickelson", age:43}
],
clickHandler:function (event) {
console.log(this);
var randomNum = ((Math.random () * 2 | 0) + 1) - 1; // random number between 0 and 1
//console.log(this.data[randomNum].name + " " + this.data[randomNum].age);
// This line is adding a random person from the data array to the text field
$ ("input").val (this.data[randomNum].name + " " + this.data[randomNum].age);
}
};
console.log(user);
$("button").click(function() {
user.clickHandler(this)
});
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h1>Homepage Headline</h1>
<div id="div1">
<p>
<button>Get Random Person</button><br>
<input type="text">
</p>
</div>
<script type="text/javascript" src="oops.js"></script>
</body>
</html>
The issue is because you invoke the user.clickhandler() function when the page loads and set its response as the click handler for the element.
You instead want to provide the reference to the function to the event handler. You will also need to bind() the scope of user to the reference, as that's what clickhandler() expects to run under. Try this:
$("button").click(user.clickHandler.bind(user));
Working example:
var user = {
data: [{
name: "T. Woods",
age: 37
}, {
name: "P. Mickelson",
age: 43
}],
clickHandler: function(event) {
console.log(this);
var randomNum = ((Math.random() * 2 | 0) + 1) - 1;
$("input").val(this.data[randomNum].name + " " + this.data[randomNum].age);
}
};
$("button").click(user.clickHandler.bind(user));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<h1>Homepage Headline</h1>
<div id="div1">
<p>
<button>Get Random Person</button><br>
<input type="text">
</p>
</div>
You need to attach the handler, not call it, and then bind the this object accordingly:
user.clickHandler.bind(user)
This is not a problem, you call
$("button").click(user.clickHandler(this));
at the loading, then it call the click event
Replace it by
$("button").bind("click", user.clickHandler(this));

Input that searches google

I am making a extension theme for my Chromebook that searches coding sites (like this site, w3schools, ect.) How sould I make it? This is my code so far:
<html>
<head>
</head>
<body>
<input id="input1">
<button onclick="searchGoogle()">Search Google</button>
<script>
function searchGoogle() {
var one = document.getElementById("input1").value;
var two = 'http://www.google.com/search?q=' + one;
window.location = two;
}
</script>
</body>
</html>
My code doesn't work
When it runs, this pops up:
(Image of my code running)
Is my code wrong?
Any help will be aapreciated.
EDIT
<html>
<head>
<script src="searchgoogle.js">
</script>
</head>
<body>
<input id="input1">
<button id="link">Search Google</button>
</body>
</html>
and
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementById('link');
// onClick's logic below:
link.addEventListener('click', function() {
function searchGoogle() {
var one = document.getElementById("input1").value;
var two = 'https://www.google.com/search?q=' + one;
window.location = two;
}
});
});
Didn't work either
You declare the function searchGoogle inside the listener function but it is never called. Try with:
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementById('link');
// onClick's logic below:
link.addEventListener('click', function() {
//there is no need to declare a new function here.
var one = document.getElementById("input1").value;
var two = 'https://www.google.com/search?q=' + encodeURIComponent(one);
window.location = two;
});
});

Javascript opener window

I have function that opens up a window, and the values from the newly opened window are listed in the opener window.
The 2nd window - has this function:
function AddOtherRefDoc(name, number) {
var remove = "<a href='javascript:void(0);' onclick='removeRefDoctor(this)'>Remove</a>";
var html = "<li><b> Referral Doctor: </b>"+name+"<b>, Referral No: </b>"+number+ " " +remove+" <input type='text' name='ref_docs' value='"+name+"'></input><input type='text' name='ref_nos' value='"+number+"'></input></li>";
opener.jQuery("#r_docs").append(jQuery(html));
}
The function that calls the one above is:
function addRefDoc(){
var count = 0;
var ref_docarray ;
var ref_noarray ;
<%for(int i1=0; i1<vec.size(); i1++) {
prop = (Properties) vec.get(i1);
String ref_no = prop.getProperty("referral_no","");
String ref_name = (prop.getProperty("last_name", "")+ ","+ prop.getProperty("first_name", ""));
%>
if(document.getElementById("refcheckbox_<%=ref_no%>").checked) {
count++;
if ((ref_doctor!=null)&&(ref_doctor!="")&&(ref_docno!=null)&&(ref_docno!="")) {
ref_docarray = ref_doctor.split(";");
ref_noarray = ref_docno.split(";");
if ((containsElem(ref_docarray,"<%=ref_name%>"))||(containsElem(ref_noarray,<%=ref_no%>))) {
alert("Referral doctor " + "<%=ref_name%>" + " already exists");
} else {
AddOtherRefDoc("<%=ref_name%>", <%=ref_no%>);
}
} else {
AddOtherRefDoc("<%=ref_name%>", <%=ref_no%>);
}
}
<%} %>
self.close();
}
function containsElem(array1,elem) {
for (var i=0;i<array1.length;i++) {
if(array1[i]==elem){
return true;
} else{
return false;
}
}
}
When this function is called, it is supposed to carry the 2 input elements "ref_docs" and "ref_nos" into the page that opened this window. But it is not doing so. It lists the elements alright but when I try to use "ref_docs" and "ref_nos" in another Javascript function in the 1st window, I see that "ref_nos" and "ref_docs" are empty.
What am I doing wrong?
function updateRd(){
var ref_docs = jQuery("#updatedelete").find('input[name="ref_docs"]');
var ref_nos = jQuery("#updatedelete").find('input[name="ref_nos"]'); alert(ref_docs.val() + ref_nos.val());
var rdocs = new Array();
var rnos = new Array();
ref_docs.each(function() { rdocs.push($(this).val()); } );
ref_nos.each(function() { rnos.push($(this).val()); } );
$('#r_doctor').val(rdocs.join(";"));
$('#r_doctor_ohip').val(rnos.join(";")); }
–
This function returns an error saying "ref_docs" and "ref_nos" are undefined.
I think it is trying to use the jQuery on the other page to find "#r_docs" on the current page.
Try:
jQuery(opener.document).find("#r_docs").append(html);
UPDATE:
I created index.html:
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> - jsFiddle demo</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.2.js"></script>
<script type="text/javascript">
window.jQuery = jQuery;
function openChild ()
{
var mychildwin = window.open("child.html");
}
</script>
</head>
<body>
<input type="button" value="click" onclick="openChild();" />
<div id="r_docs">
Redocs here.
</div>
</body>
</html>
and child.html:
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> - jsFiddle demo</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.2.js"></script>
<script type="text/javascript">
function AddOtherRefDoc(name, number) {
var remove = "<a href='javascript:void(0);' onclick='removeRefDoctor(this)'>Remove</a>";
var html = "<li><b> Referral Doctor: </b>"+name+"<b>, Referral No: </b>"+number+ " " +remove+" <input type='text' name='ref_docs' value='"+name+"'></input><input type='text' name='ref_nos' value='"+number+"'></input></li>";
jQuery(opener.document).find("#r_docs").append(html);
}
</script>
</head>
<body>
<input type="button" value="click" onclick="AddOtherRefDoc('name', 42);"/>
</body>
</html>
UPDATE2:
in your update function document.updatedelete has no attributes ref_docs and ref_nos.
try:
jQuery("#updatedelete")
.find('input[name="ref_docs"], input[name="ref_nos"]')
Where your form is
<form id="updatedelete" ... >
Your function that accesses the DOM elements is incorrect. updatedelete is not a property of document, nor will accessing a ref_docs or ref_nos property automatically build a collection of input elements. Since you're using jQuery already, try this:
var ref_docs = $('input[name="ref_docs"]');
var ref_nos = $('input[name="ref_nos"]');
That will give you Array (or at least array-like) objects that will let you access your inputs:
var rdocs = new Array();
var rnos = new Array();
ref_docs.each(function() { rdocs.push($(this).val()); } );
ref_nos.each(function() { rnos.push($(this).val()); } );
$('#r_doctor').val(rdocs.join(";"));
$('#r_doctor_ohip').val(rnos.join(";"));

Categories

Resources