Trying to test function with mocha + nyc - javascript

I'm trying to test my function with mocha + nyc for cheching coverage.
This is function to test:
function TypeCompare(Obj){
Obj.forEach(function (el){
el.Age = StringToNumber(el.Age);
el.Name = isValidString(el.Name);
el.Surname = isValidString(el.Surname);
el.Mail = isEmail(el.Mail);
el.DateofReg = StringToDate(el.DateofReg);
el.Phone = isPhone(el.Phone);
el.Time = StringToTime(el.Time);
if(el.Age == "Age error" || el.Name == "Name/Sname error" || el.Surname == "Name/Sname error" || el.DateofReg == "Date error" || el.Time == "Time error" ||el.Mail == "Email error" || el.Phone == "Phone error"){
invalid_types.push(el);
} else {
valid_types.push(el);
}
});
RecordToDB(valid_types);
RecordToCSV(invalid_types);
}
The function getting array of objects check objects with other function for valid and push valid objects to valid_types and invalid to invalid_types.
This is my testing function:
describe('Testing function TypeCompare which getting arr[objects] on input
check arr for valid and invalid objects', function () {
it('should return [valid_obj] and [] if all objects is valid', function ()
{
var arr = [{Age: '20', Name: 'Kiryl', Surname: 'Kazushchyk', Mail: 'kastys1#yandex.ru', DateofReg: '10-20-2015',
Phone: '+375257794915', Time: '10:44'},
{Age: 'fgh', Name: 'Kiryl', Surname: 'Kazushchyk', Mail: 'kastys1#yandex.ru', DateofReg: '10-20-2015',
Phone: '+375257794915', Time: '10:44'}];
app.TypeCompare(arr);
// console.log(TypeCompare.valid_types);
// console.log(TypeCompare.invalid_types);
var expected_valid = [{Age: '20', Name: 'Kiryl', Surname: 'Kazushchyk', Mail: 'kastys1#yandex.ru', DateofReg: '2015-10-20',
Phone: '+375257794915', Time: '10:44:00'}];
var expected_invalid = [{Age: 'Age error', Name: 'Kiryl', Surname: 'Kazushchyk', Mail: 'kastys1#yandex.ru', DateofReg: '2015-10-20',
Phone: '+375257794915', Time: '10:44:00'}];
assert(app.invalid_types[0].Age === expected_invalid[0].Age);
assert(app.valid_types[0].Age === expected_valid[0].Age);
});
});
I'm export this:
module.exports.TypeCompare =TypeCompare;
module.exports.valid_types = valid_types;
module.exports.invalid_types = invalid_types;
The test is passed ok, but i don't recive any information about summary:
test result without coverage
If i test my other functions everything is okay:test result other functions
Can someone tell me what is the problem?

Solved. The problem was in functions which called with TypeCompare

Related

Storing the name of the current user and matched user in state using useEffect returning incorrect output

I have a function in my context that takes in two data points, the current username and the username of a randomly selected user who is online
const pairProgrammingMatching = (username, matchedUser) => {
setPairUsers({username: matchedUser })
}
I call this function in another component using useEffect()
useEffect((() => {
console.log('curr username is', username)
pairProgrammingMatching(username, checkOnlineUsers(pickRandom()).username)
console.log('inside pairUsers state', pairUsers)
}), [])
checkOnlineUsers simply returns a list of all users who are currently online and active
let checkOnlineUsers = () => {
const results = onlineUsers.filter(obj => {
return obj.profile.is_online === true && obj.profile.currently_active === false && obj.username !== user.username
})
return results
}
Here's a sample of what this function returns
[{ email: "***#gmail.com"
first_name: ""
last_name: ""
profile: {city: 'Washington DC', country: 'USA', is_online: true, currently_active: false}
username: "testingUser" }]
pickRandom simply picks a number between 0 and n, with n being the number of users returned in checkOnlineUsers:
const pickRandom = () => {
return Math.round(Math.random()*onlineUsers.length)
}
The problem here is that if I print out pairUsers inside my useEffect I expect to see this:
{ 'userA': 'testingUser' }
with userA being the name of the current user. However this is what I get:
{username: undefined}

Problem validating array filter time in JavaScript

I wrote a program that searches the array and displays the content on the console
I want to first do the validation in the input that I wrote to show the results if it is valid and if it is not valid or has no result, the search will show the aleart message
But unfortunately the program of the if part is not done properly, please help me
Please test the app and see the problem
this.array = [{
name: "nadiya",
phone: 123456
}, {
name: "amir",
phone: 123456
},
{
name: "niloufar",
phone: 123456
}, {
name: "arman",
phone: 123456
},
{
name: "sara",
phone: 123456
}, {
name: "pariya",
phone: 123456
}
];
const self = this;
const selectID = (idName) => document.getElementById(idName);
this.search = function() {
function filterArray() {
const selectInput = document.getElementById("inputSearch").value;
const validStr = /^[A-Za-z]+$/;
const validInpout = selectInput.length >= 2
const result = self.array.filter((obj) => {
return obj.name.toUpperCase().includes(selectInput.toUpperCase())
});
if (selectInput.value === validInpout && validInpout) {
if (result.length <= 0) {
alert("Contact not found")
} else {
return result;
}
} else {
alert("To search, it must be more than 2 characters and use letters")
}
}
return filterArray();
};
this.showResultSearch = function() {
const searchResult = self.search();
searchResult.forEach((ele) => {
console.log(`name: ${ele.name} phone: ${ele.phone}`);
});
};
this.startSearch = function() {
console.clear();
this.showResultSearch();
};
<form>
<input type="text" placeholder="Search" id="inputSearch">
<button type="button" id="BtnSearch" onclick="startSearch()">Search</button>
</form>
Lots of issues - see comments to your question
Additionally:
I return immediately there is no input
I only search if valid input
this.array = [{
name: "nadiya",
phone: 123456
}, {
name: "amir",
phone: 123456
},
{
name: "niloufar",
phone: 123456
}, {
name: "arman",
phone: 123456
},
{
name: "sara",
phone: 123456
}, {
name: "pariya",
phone: 123456
}
];
const self = this;
const selectID = (idName) => document.getElementById(idName);
this.search = function() {
const selectInput = document.getElementById("inputSearch").value.trim();
const validStr = /[A-Za-z]{2,}/;
const validInput = validStr.test(selectInput);
if (!validInput) alert("To search, it must be more than 2 characters and use letters")
else {
const result = self.array.filter((obj) => {
return obj.name.toUpperCase().includes(selectInput.toUpperCase())
});
if (result.length === 0) {
alert("Contact not found")
} else {
return result;
}
}
};
this.showResultSearch = function() {
const searchResult = self.search();
if (searchResult && searchResult.length > 0) searchResult.forEach((ele) => {
console.log(`name: ${ele.name} phone: ${ele.phone}`);
});
};
this.startSearch = function() {
console.clear();
this.showResultSearch();
};
<form>
<input type="text" placeholder="Search" id="inputSearch">
<button type="button" id="BtnSearch" onclick="startSearch()">Search</button>
</form>

How do I deal with an array of input strings and make them match to an objects array keys even if there is nesting?

https://codesandbox.io/s/lucid-bhaskara-fohmt
For example I have an array of strings:
let inputNames = ['name', 'address[city]', 'address[state]'];
with this sample error object:
let errors = {
name: {message:"error in name"},
address: {
city: {message:"error in address city"},
state: {message:"error in address state"}
}
}
When looping through names I would like to check the error based on the input name:
inputNames.forEach(n=> {
if(typeof errors[n] !== 'undefined') {
console.log(errors[n]);
} else {
console.log('SHOULD have returned value of', errors.address.city);
}
})
Keep it simple and use lodash's get function.
const {get} = require("lodash");
let inputNames = ['name', 'address.city', 'address.state'];
let errors = {
name: {message:"error in name"},
address: {
city: {message:"error in address city"},
state: {message:"error in address state"}
}
}
inputNames.forEach(n=> {
if(get(errors, n)) {
console.log(get(errors, n));
} else {
console.log('SHOULD have returned value of', errors.address.city);
}
})
OR you can use plain javascript to achieve this using this function
function get(obj, path) {
return path.split('.').reduce((parent, child)=> parent && parent[child]||null, obj)
}
You can use lodash. _.get(obj, key, defaultVal)
let inputNames = ['name', 'address[city]', 'address[state]'];
let errors = {
name: {message:"error in name"},
address: {
city: {message:"error in address city"},
state: {message:"error in address state"}
}
};
console.log(_.get(errors, inputNames[1]))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

How can I pass parameter correctly?

const root = {
user: (id) => {
console.log("returning object " + JSON.stringify(id.id) + " " + JSON.stringify(storage.select("users", id.id)))
return storage.select("users", id.id)
}
}
I want to call the arrow function in root.user but I think I can't pass the parameter correctly, so I tried this --> let user = root.user('101')
and on the console I got this -->
returning object undefined
[{"firstName":"Gokhan","lastName":"Coskun","login":"gcoskun","id":101}]
{"firstName":"George","lastName":"Clooney","login":"gclooney"}
[{"firstName":"Gokhan","lastName":"Coskun","login":"gcoskun","id":101}]
I wanted the user with the id 101 get returned and got instead all of the users returned.
Why are you doing id.id but passing a string? You either pass an object with an id prop (root.user({ id: '101' })) or replace id.id with simply id.
Also, it looks like the id fields in your user objects are of type number, while you are passing a string, so depending on the logic inside storage.select you might have to change that.
Passing a number id:
// Just mocking it for the example:
const storage = {
select(key, id) {
return [
{ firstName: 'Gokhan', lastName: 'Coskun', login: 'gcoskun', id: 101 },
{ firstName: 'George', lastName: 'Clooney', login: 'gclooney' },
{ firstName: 'Gokhan', lastName: 'Coskun', login: 'gcoskun', id: 101 },
// Depending on the logic here, these types need to match.
// Using == instead of === so that it's not required here.
].filter(user => user.id == id)
},
};
const root = {
user: (id) => {
console.log(`ID = ${ id }`);
// We make sure we only return a single user or null if there isn't one:
return storage.select('users', id)[0] || null;
},
};
const user = root.user('101');
console.log(user);
Passing an object with an id prop of type number:
// Just mocking it for the example:
const storage = {
select(key, id) {
return [
{ firstName: 'Gokhan', lastName: 'Coskun', login: 'gcoskun', id: 101 },
{ firstName: 'George', lastName: 'Clooney', login: 'gclooney' },
{ firstName: 'Gokhan', lastName: 'Coskun', login: 'gcoskun', id: 101 },
// Depending on the logic here, these types need to match.
// Using == instead of === so that it's not required here.
].filter(user => user.id == id);
},
};
const root = {
user: (query) => {
console.log(`ID = ${ query.id }`);
// We make sure we only return a single user or null if there isn't one:
return storage.select('users', query.id)[0] || null;
},
};
const user = root.user({ id: '101' });
console.log(user);

Handling multiple return values in javascript

Finally i'm writing a question on my own because i read other question here but still don't understand why my code doesn't work. Perhaps someone can explain me what i got wrong?
The Code runs till the search for the name "Joe", Then it say par2 is not defined...Why? In the check after the search function i can clearly see that both parameters par1 and par2 are returned...
var friends = {};
friends.bill = {
firstName: "Bill",
lastName: "Gates",
number: "(206) 555-5555",
address: ['One Microsoft Way', 'Redmond', 'WA', '98052']
};
friends.steve = {
firstName: "Steve",
lastName: "Jobs",
number: "(408) 555-5555",
address: ['1 Infinite Loop', 'Cupertino', 'CA', '95014']
};
function list(obj) {
for (var prop in obj) {
console.log(prop);
}
};
function bettersearch(name2) {
var sna = name2
for (var prop in friends) {
if (friends[prop].firstName === name2) {
// console.log("Value found :",friends[prop]);
return {
par1: friends[prop],
par2: sna
}
}
}
};
// Test if the variables are returned
var test = bettersearch("Bill")
console.log("\n\n",test);
console.log("\n\n",test.par1);
console.log("\n\n",test.par2);
//Formatting function for a nice Output
function format(obj) {
if (obj) {
var result = "";
result += "\nName: " + obj.par1.firstName + " " + obj.lastName;
result += "\nNumber: " + obj.par1.number;
result += "\nAddress: " + obj.par1.address.join(', ');
console.log(result);
} else {
console.log("\nDer Name", obj.par2, "wurde nicht gefunden");
}
}
//Call the functions
format(bettersearch("Bill"));
format(bettersearch("Steve"));
format(bettersearch("Joe"));
Then it say par2 is not defined...
No, it doesn't. It says something like Cannot convert 'obj' to object or Cannot access 'par2' on undefined.
Why?
Because your bettersearch function does not return anything when it doesn't find the name. In your format function you explicitly check for the existence of obj, but despite it being undefined you try to access obj.par2.
I think you are looking for
function bettersearch(name) {
for (var prop in friends)
if (friends[prop].firstName === name)
return {
friend: friends[prop],
name: name
};
return {
name: name
}; // always return a result object
}
function format(obj) {
if (obj.friend) {
var result = "";
result += "\nName: " + obj.friend.firstName + " " + obj.friend.lastName;
result += "\nNumber: " + obj.friend.number;
result += "\nAddress: " + obj.friend.address.join(', ');
console.log(result);
} else {
console.log("\nDer Name", obj.name, "wurde nicht gefunden");
}
}
This might be a much better way to structure your data and write your search function
var friends = [
{
firstName: "Bill",
lastName: "Gates",
number: "(206) 555-5555",
address: ['One Microsoft Way', 'Redmond', 'WA', '98052']
},
{
firstName: "Steve",
lastName: "Jobs",
number: "(408) 555-5555",
address: ['1 Infinite Loop', 'Cupertino', 'CA', '95014']
}
];
function searchFriends(firstName) {
return friends.filter(function(f) {
return f.firstName === firstName;
});
}
console.log(searchFriends("Bill"));
//=> [{"firstName":"Bill","lastName":"Gates","number":"(206) 555-5555","address":["One Microsoft Way","Redmond","WA","98052"]}]
console.log(searchFriends("Steve"));
//=> [{"firstName":"Steve","lastName":"Jobs","number":"(408) 555-5555","address":["1 Infinite Loop","Cupertino","CA","95014"]}]
console.log(searchFriends("Joe"));
//=> []
I make this suggestion because in your code, it'd be very easily to have duplicates.
E.g., what about John Smith and John Smyth? Both would use friends.john...
If you want the search result to return the query and the matches
function searchFriends(firstName) {
return {
search: firstName,
result: friends.filter(function(f) {
return f.firstName === firstName;
})
};
}
Use it the same way
console.log(searchFriends("Steve"));
// {
// search: "Steve",
// result: [{"firstName":"Steve","lastName":"Jobs","number":"(408) 555-5555","address":["1 Infinite Loop","Cupertino","CA","95014"]}]
// }
console.log(searchFriends("Joe"));
// {
// search: "Joe",
// result: []
// }
The actual error is
"TypeError: Cannot read property 'par2' of undefined
Your error is in your console.log() line where if(obj) returns false (meaning there is no object - it's actually undefined):
console.log("\nDer Name", obj.par2, "wurde nicht gefunden");
Remove that line altogether.

Categories

Resources