i want to implement jasmine test with the next code:
This is my filter-service.js
function FilterService() {
}
FilterService.prototype.filter = function (companies, filter) {
return companies;
};
And my filter-service-spec.js is
describe("Filter service filter(...) tests", function() {
var filterService = new FilterService();
var allTestCompanies= [
{ id: 1, name: "company1 Test", admin: "Test Admin" },
{ id: 2, name: "company2", admin: "Test Admin", country: 'London' },
{ id: 3, name: "company3", admin: "Mery Phill" }
];
it('returns original collection if called with undefined filter', function() {
var input = [1, 2, 3];
var result = filterService.filter(input, undefined);
expect(result).toEqual(input);
});
it('returns original collection if called with empty filter', function () {
var input = [2, 6, 7];
var result = filterService.filter(input, '');
expect(result).toEqual(input);
});
it('only includes matching companies once', function() {
var result = filterService.filter(allTestCompanies, 'Test');
expect(result.length).toEqual(2);
});
it('matches exact text on company name', function() {
var result = filterService.filter(allTestCompanies, "company1 Test");
expect(result[0]).toEqual(allTestCompanies[0]);
});
it('matches exact text contained in company name', function () {
var result = filterService.filter(allTestCompanies, "Test");
expect(result[0]).toEqual(allTestCompanies[0]);
});
it('matches case invarient text contained in company name', function () {
var result = filterService.filter(allTestCompanies, "test");
expect(result[0]).toEqual(allTestCompanies[0]);
});
it('matches exact text of admin', function() {
var result = filterService.filter(allTestCompanies, 'Mery Phill');
expect(result[0]).toEqual(allTestCompanies[2]);
});
it('matches exact text in admin', function () {
var result = filterService.filter(allTestCompanies, 'Phil');
expect(result[0]).toEqual(allTestCompanies[2]);
});
it('matches case invarient text in admin', function () {
var result = filterService.filter(allTestCompanies, 'PHIl');
expect(result[0]).toEqual(allTestCompanies[2]);
});
});
How i can implement a function in filter-service.js for pass the javascript tests. For now only pass the 2 first.
Sure, this is actually very easy to do, but I will provide just with approach you should take. So lets begin ...
I hope you have an environment where you able to run your tests (Jasmine installed and you able to run your tests against "FilterService" object and "filter" method in particular). You said two first methods are succeeded.
Each Jasmine "it" function has description, for example "matches exact text on company name" (test #4). This is most important part you will be dealing with. We will talk about this test. Ask yourself what this description tells you? This means if you pass into "filter" method exact name of the company, the function should go through array of given companies objects and try to find match for exact company name.
Next you would need to look at implementation of Jasmine "expect" function. You will notice that returned result from the "filter" function call must be equal to the first element of the given array of companies because the name of the company in the filter parameter match to this object's "name".
After you implement this part and test succeeded, you would go to next test and add/change existing implementation to accomplish next "it" description.
This is called TDD (test driven development). Please read a bit on it before you start working.
Finally lets try to implement this test #4. Please note the code provided may not work, but as we agreed you will make it work, I just show the approach ...
function FilterService() {
}
FilterService.prototype.filter = function (companies, filter) {
// this is our result variable which we will return at the end
var result;
// for test #1 the "filter" parameter is undefined and the test description says "returns original collection if called with undefined filter" (#2 will look similar to test #1, add this by yourself)
if (typeof filter === "undefined") {
result = companies;
}
// jump to test #4 we are talking about. "it" says "matches exact text on company name"
companies.forEach( function (companyObj) {
if (companyObj.name === filter) {
result = [companyObj];
return false;
}
});
// continue to modify the function to meet all criteria of every "it" description
// we return our result
return result;
};
Related
I have an array I want to use as base array of my work, and each time a unction calls I want it to be cloned to prevent changing the base one, but it doesn't work I don't know why and I tried all other solutions else where
this is my code:
const baseArray = [
{
english: {
name: "test1 english",
description: "test1 english"
},
spanish: {
name: "test1 spanish",
description: "test1 spanish"
}
}
];
function removeSpanish() {
// showing base array before work
console.log(baseArray); // expected to log the baseArray, but logs the edited array
// cloning the array
var result = [...baseArray];
// checking if passed by value or passed by reference
console.log(result[0] === baseArray[0]); // expected to log false, but it logs true
// removing other language details from each collection
result.map(collection => {
delete collection['spanish'];
return collection;
});
// showing base array after work
console.log(baseArray); // expected to log the baseArray, but logs the edited array
return result;
}
export { find };
and what surprises me is that even the first
console.log(baseArray)
shows the edited one.
and the
console.log(result[0] === baseArray[0]);
logs true so they are passed by refference
i also tried these 2 other approaches but none of them worked
var result = baseArray.splice();
var result = Array.from(baseArray);
NOTE: i use this in react and it will be excuted each time a state changes, I don't know if it causes the problem
thanks to Charles Bamford that suggested using lodash's cloneDeep, and thanks to Robin Zigmond that suggested using forEach instead of map
so i updated my code to this and it worked:
const _ = require('lodash');
const baseArray = [
{
english: {
name: "test1 english",
description: "test1 english"
},
spanish: {
name: "test1 spanish",
description: "test1 spanish"
}
}
];
function removeSpanish() {
// showing base array before work
console.log(baseArray);
// cloning the array
var result = _.cloneDeep(Collections);
// checking if passed by value or passed by reference
console.log(result[0] === baseArray[0]);
// removing other language details from each collection
result.forEach(collection => {
delete collection['spanish'];
return collection;
});
// showing base array after work
console.log(baseArray);
return result;
}
export { find };
you can read more about lodash here
Good afternoon, I am trying to make a method that tells me the number of elements an Array has that starts with "RT:"
For this I have developed the following code:
public getRowsRTs(idProyecto){
this.twitterService.getTargets().subscribe((data) => {
this.Twitter = data;
});
let countRT = this.Twitter.filter( tweet => tweet.message.startsWith("RT:")).length;
return countRT;
}
}
Here, data returns all the Documents that Mongo extracts, and puts them in the Twitter Array that I have defined at the beginning of the component. Within this Array each element has different attributes, such as _id, message, date ... I want you to tell me how many of those documents, the message value, begins with RT: and to return it to me, this code , it does not give me any problem, but it does not give me absolutely nothing, I do not know if someone could help me.
If the array is filled with strings, this should work:
let regixForRTStart = /^RT:/;
startArray = ['RT:1', 'RT:2', 'Other', 'Stuff'],
count = startArray.filter(item => regixForRTStart.test(item))
// length
console.log(count.length);
use filter and startsWith methods.
const arr = [
{ message: "abc" },
{ message: "RT:" },
{ message: "RT: 2" },
{ message: "test" }
];
const count = arr.filter(({ message }) => message.startsWith("RT:")).length;
console.log(count);
I need to test that an array of object contains a certain value. The test is written with Cypress, and for that, I use cy.wrap and .some().
My code looks like this:
const myCustomArray = [{ name: 'Lisa' }, { name: 'Katie' }];
cy.wrap(myCustomArray.some((user) => {
if (user.name === 'Lisa') {
return true;
} else {
return false;
}
})).should('eq', true);
This works well, but the problem is that it then returns me a very non-specific message in the Cypress console.
What I would like to have, is to change my code in a way that the message would be understandable. In the idea, it would be something like that:
const myCustomArray = [{ name: 'Lisa' }, { name: 'Katie' }];
cy.wrap(myCustomArray.some((user) => {
if (user.name === 'Lisa') {
return 'user name is Lisa';
}
})).should('eq', 'user name is Lisa');
But this can't work as .some() can only return a boolean. I suppose there is an array function that could help me do that, but I can't find which one.
I am not sure whether:
There are Cypress commands I am unaware of that could solve this issue, eg. customizing the assertion message.
Or it can just be solved with using JavaScript
Both solutions would be fine for me.
How about using .find() instead of .some(), and deep-eq the result,
cy.wrap(myCustomArray.find(user => user.name === 'Lisa'))
.should('deep.eq', { name: 'Lisa' });
ASSERT expected { name: Lisa } to deeply equal { name: Lisa }
or if you have big objects and just want to see the name,
cy.wrap(myCustomArray.map(user => user.name).find(name => name === 'Lisa'))
.should('eq', 'Lisa');
ASSERT expected Lisa to equal Lisa
I'm trying to send data (as an object) to a child process in Node.js, however, all of my regular expressions get lost in transfer.
var arguments = {
something: {
name: 'test',
age: 28,
active; true
},
otherThing: 'some string',
regex: /test/i,
regex2: new RegExp('test')
};
var child = cp.fork(path.join(__dirname, 'child.js'));
child.on('message', function (data) {
console.log(data);
});
child.send(arguments);
In the child.js file I have this at the top:
process.on('message', function () {
console.log(arguments); // This is where the data has changed
});
When the log is output from the child process the arguments object instead looks like this:
{
something: {
name: 'test',
age: 28,
active: true
},
otherThing: 'some string',
regex: {},
regex2: {}
}
So far unable to find anything elsewhere about why this may be happening, any ideas?
Because they are completely separate JavaScript processes, you can't send objects. When you pass an object, it gets serialized to JSON and parsed by the child. (See the docs.)
JSON does not support serializing regex objects. (Try putting JSON.stringify(/abc/) through your console -- you get back "{}".)
To include regexes in a JSON object, you can use the json-fn module. It supports serializing functions, dates, and regexes. (It was actually thanks to an issue i raised that they added regex support. :))
You could then do something like:
var JSONfn = require('json-fn');
var arguments = {
something: {
name: 'test',
age: 28,
active; true
},
otherThing: 'some string',
regex: /test/i,
regex2: new RegExp('test')
};
var child = cp.fork(path.join(__dirname, 'child.js'));
});
child.send(JSONfn.stringify(arguments));
and:
var JSONfn = require('json-fn');
process.on('message', function (data) {
console.log(JSONfn.parse(data))); // This is where the data has changed
});
You can store the regex as a string like
myRegex.string = "/test/";
myRegex.modif = "i";
Send it to child and then use it like
new RegExp(myRegex.string, myRegex.modif);
I tried json-fn but Date objects stringified are not reverted back to Date. This module JSON4Process stringifies the objects' properties of type Date, RegExp, Function, Set and Map while maintaining the object as a javascript object. You don't need to stringify the whole object if you're using fork, you can directly send it.
const { fork } = require('child_process');
const JSON4Process = require('json4process');
let obj = {
date: new Date(),
regex: new RegExp(/regex/g),
func: () => console.log('func')
}
obj = JSON4Process.stringifyProps(obj);
const child = fork('child.js');
child.send(obj);
And then parse the properties back in the other file:
process.on('message', data => {
let obj = JSON4Process.parseProps(data);
});
In case you need to use spawn or exec you can just use the default JSON.stringify over the modified object with json4process:
let newObj = JSON.stringify(JSON4Process.stringifyProps(obj));
let originalObj = JSON4Process.parseProps(JSON.parse(newObj));
I read with interest the blog post here, which describes how to make a query equivalent to sql WHERE email = x
new Firebase("https://examples-sql-queries.firebaseio.com/user")
.startAt('kato#firebase.com')
.endAt('kato#firebase.com')
.once('value', function(snap) {
console.log('accounts matching email address', snap.val())
});
I've tried to replicate this as follows:
root
|-rewards
|--JAJoFho0MYBMGNGrCdc
|-name: "apple"
|--JAJoFj7KsLSXMdGZ77V
|-name: "orange"
|--JAJoFp7HP6Ajq-VuMMx
|-name: "banana"
There are many other fields in each rewards object... but I want to index the object by name and to be able to query all these objects to find the one matching a given name. The blog post instructs us to use setPriority() to achieve this.
I have tried the following:
var ref = new Firebase('https://<example>.firebaseio.com/rewards').push({
name: 'apple',
otherKey: 'somevalue',
...
});
ref.setPriority('apple');
If I then query firebase, it returns null:
new Firebase('https://<example>.firebaseio.com/rewards')
.startAt('apple')
.endAt('apple')
.once('value', function(snap) {
console.log('found:', snap.val()); // logs: "found null"
});
What am I doing wrong?
Looks like you're attempting to run these commands synchronously. At the time that you request rewards, there may not be any data yet (your push ops may not have finished).
Next, you should use setWithPriority, which will allow you to push the data and priority at the same time.
Last but not least, you haven't mentioned errors. I'll assume you checked those like any diligent dev would. In addition to the JS console, you can log the results of the callback functions (there's one for each of the methods you called, which could return an error if something went wrong).
So all together, it should look more like this:
var ref = new Firebase('https://<example>.firebaseio.com/rewards').push();
ref.setWithPriority({
name: 'apple',
otherKey: 'somevalue',
...
}, 'apple', function(err) {
if( error ) { console.error(err); }
else {
fetchValue();
}
});
function fetchValue() {
// wait for the set to complete before fetching data
new Firebase('https://<example>.firebaseio.com/rewards')
.startAt('apple')
.endAt('apple')
.once('value', function(snap) {
console.log('found:', snap.val()); // logs: "found null"
});
}