How to repeat/loop through mocha tests - tdd

I've been working on a few mocha/chai tests, and I still haven't found a good way of running my tests over many different possibilities aside from placing a loop within each of the 'it' tests and iterating one and a time. The problem is, if I have tens or hundreds of tests, I don't want to write the same for-loop over and over again.
Is there a more elegant way of doing this? Particularly one that loops through all the tests at once with different test parameters?
describe('As a dealer, I determine how many cards have been dealt from the deck based on', function(){
console.log(this);
beforeEach(function(){
var deck = new Deck();
var myDeck = deck.getCards();
});
it('the number of cards are left in the deck', function(){
for(var i = 1; i<=52; i++){
myDeck.dealCard();
expect(myDeck.countDeck()).to.equal(52-i);
}
});
it('the number of cards dealt from the deck', function(){
expect(myDeck.countDealt()).to.equal(i);
});
it('the sum of the cards dealt and the cards left in the deck', function(){
expect(myDeck.countDeck() + myDeck.countDealt()).to.equal(52)
});
});

I implemented neezer's solution at Loop Mocha tests?, which involves putting the entire test into a closure and executing it with a loop.
Please be aware that the loop messes with beforeEach() within the function, as it executes it 52 times per test. Placing elements within the beforeEach() function is not a good idea if those elements are dynamic, and are not to be executed more than once per loop.
The code looks like this, and it seems to work.
var myDeck = new Deck(Card);
function _Fn(val){
describe('As a dealer, I determine how many cards have been dealt from the deck based on', function(){
myDeck.dealCard();
var cardCount = 0;
var dealtCount = 0;
cardCount = myDeck.countDeck();
dealtCount = myDeck.countDealt();
it('the number of cards are left in the deck', function(){
expect(cardCount).to.equal(52-val);
});
it('the number of cards dealt from the deck', function(){
expect(dealtCount).to.equal(val);
});
it('the sum of the cards dealt and the cards left in the deck', function(){
expect(cardCount + dealtCount).to.equal(52);
});
});
}
for(var i = 1; i<=52; i++){
_Fn(i);
}

Related

Cypress test is timing out

I need to validate that one of the elements I am searching for appears on the page.
if one of them appears the expect statement should evaluate to true.
I have pressed f12 and validated that the 'downloadReferencesRow' along with one of the other elements is appearing. but cypress it timing out.
Does my code look ok?
var numberOfElements = 0;
cy.get('downloadReferencesRow').then((body) =>{
if (body.find('createApplicationReferencesPresent').length > 0) {
numberOfElements +=1;
}
if (body.find('createApplicationNoReferencesPresent').length > 0) {
numberOfElements +=1;
}
});
expect(numberOfElements).eq(1);
The code has mixed synchronous and asynchronous commands, which is problematic.
You can more easily do it with jQuery multiple selectors
cy.get('createApplicationReferencesPresent,createApplicationNoReferencesPresent')
.then($els => {
const numberOfElements = $els.length // 1 or 2 - fails if neither present
})
Like all conditional testing, it only works if the page is stable.

Applying change event on j-Query Data-Table Search Box?

I have j-Query data-table with many records and I have builtin search-box. What I am trying is to sum all values in all the tds which have class="amount". It's happening succesfully. Now, the problem is search box. I want to sum the values of tds with class name amount which are only visible. I tried many ways but nothing worked Following is my code:
var salaryTable = $('#tblSalary').DataTable();
salaryTable.on('search', function () {
var sum = 0;
$(".amount").each(function() {
var value = $(this).text();
if(!isNaN(value) && value.length != 0) {
sum += parseFloat(value);
}
});
alert(sum);
});
This logic is not working as expected. How can I solve this or What am I doing wrong? Is there any better approach?
Update: The problem is when I search something it gives me total of visible and invisible records. When I clear the search box with backspace, it gives me total of all records where were visible before.
If you only want visible elements with class amount you could use the jQuery :visible selector
$(".amount:visible").each(...)
jQuery docs https://api.jquery.com/visible-selector/

Faster Iterative Calculation

I've made a script that performs an iterative calculation to find values based on a gross percentage of project cost.
This is what I have so far:
//<!-- FEE, BOND, & INSURANCE CALCULATOR --!>
function feeBondInsCalculator (){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Pretty Sum Form");
sheet.activate();
// Get all variables from named ranges
var bondValue = ss.getRangeByName("bondValue");
var bondCalc = ss.getRangeByName("bondCalc");
var insValue = ss.getRangeByName("insValue");
var insCalc = ss.getRangeByName("insCalc");
var feeValue = ss.getRangeByName("feeValue");
var feeCalc = ss.getRangeByName("feeCalc");
var interCount = ss.getRangeByName("interCount")
// Interative calculation to paste calculated values into the body of the spreadsheet
for (var i = 0; i<11; i++){
feeCalc.copyTo(ss.getRangeByName("feeValue"), {contentsOnly: true});
bondCalc.copyTo(ss.getRangeByName("bondValue"), {contentsOnly: true});
insCalc.copyTo(ss.getRangeByName("insValue"), {contentsOnly: true});
interCount.setValue(i)
}
}
I used range names so that users can add/delete rows and columns and not have to reset the code. When executed, the code works fine, but takes about two seconds per iteration. Is there a more efficient way to make this work?
Instead of using copy, you might try referencing your ranges directly in a formula like:
=arrayformula(if(bondValue <>"",bondValue,""))

Polymer core-animation-group imperative example?

I'm fairly new to Polymer and struggling to get some animations to work imperatively. My page displays a grid of cards. When one is clicked, I want the rest to move off screen.
I can get the cards to move one at a time in code, but since they all need to move in parallel, I think I need a core-animation-group to run them. But...
I can't figure out the syntax for creating a core-animation-group in code, and there doesn't seem to be a "play()" method...?
I'd be very, very grateful for a quick example.
TIA
The documentation on core-animation-group is a bit lackluster, but it is possible to create and play a core-animation-group using only JavaScript. Create your core-animation-group with new CoreAnimationGroup(). Then add child animations with animGroup.appendChild(coreAnim). Finally, play the group with animGroup.play().
You say you want to animate an indeterminate number of cards in parallel. Try something like this:
var cards = document.querySelector("#cards-wrapper").children;
var anim = new CoreAnimationGroup();
anim.type = "par"; // Display child animations in parallel.
anim.duration = 200; // Milliseconds
var cardAnimKeyframes = [
// CSS properties {propName: "value"}
{opacity: 1},
{opacity: 0},
];
for (var i = 0; i < cards.length; i++) {
var childAnim = new CoreAnimation();
childAnim.target = cards[i];
childAnim.keyframes = cardAnimKeyframes;
anim.appendChild(childAnim); // This is critical.
}
// Then, when you are ready...
anim.play();
Hope this helps :D

For loop with events

I'm working with along with an online tutorial and trying to understand the code below. What I don't get is why this works more than two times. When the loop has been executed two times i == len and the condition i < len isn't true anymore. So how come it's possible to toggle the different clases more than two times?
My guess is that when the condition is false i gets set to 0 again, did I understand that correctly? Hope someone can help me, I didn't find an explanation of this particular problem anywhere online.
HTML
<button>Normal</button>
<button>Changed</button>
CSS
.normal {background-color: white;color:black;}
.changed {background-color: black;color:white;}
JavaScript
(function() {
var buttons = document.getElementsByTagName("button");
for (var i = 0, len = buttons.length; i < len; i +=1)
buttons[i].onclick = function() {
var className = this.innerHTML.toLowerCase();
document.body.className = className;
}}
}());
The for loop gets excecuted only once and iterates through all buttons.
In the for loops body, you define an onclick function for each button.
So, before you can click anywhere the loop already has finished, and added an onclick function to each single button, which will be called everytime, you click on that button.
With button[i].onclick = function() {...} you add an event handler function to the buttons click event.
You should read more about event handlers in general.

Resources