Scala - testing function that return json as string - scala

im trying to learn how to write good tests in general. I happen to write a function in Scala and I want to make sure the model that is returned from the function matches with the model that I define in the test case. here is an example json that is returned from the function
[
{
"id":1,
"uuid":"11111-1111111-11111111-11111111-11111",
"name":"test",
"type":"doc",
"contact":"abc#example.com",
"expires":213293842,
"user":1,
"ad":[
"test.com"
],
"details":{
"creation_time":1123212324,
"agent":2,
"apps":{
"type1":{
"mode":"standard"
},
"type2":{
"mode":"non-standard"
}
}
}
}
]
can I please get some help on how to test my model to make sure I account for model changes during testing
btw, I found this git https://github.com/stephennancekivell/scalatest-json but I cant figure out how to implement it

Related

Writing nested path parameters in FeathersJS

How to generate multi level path parameters in feathers js like below :
api.com/category/catergoryId/subCatergory/subCatergoryId
The following is taken from this Feathers FAQ entry:
Normally we find that they actually aren't needed and that it is much better to keep your routes as flat as possible. For example something like users/:userId/posts is - although nice to read for humans - actually not as easy to parse and process as the equivalent /posts?userId=<userid> that is already supported by Feathers out of the box. Additionaly, this will also work much better when using Feathers through websocket connections which do not have a concept of routes at all.
However, nested routes for services can still be created by registering an existing service on the nested route and mapping the route parameter to a query parameter like this:
app.use('/posts', postService);
app.use('/users', userService);
// re-export the posts service on the /users/:userId/posts route
app.use('/users/:userId/posts', app.service('posts'));
// A hook that updates `data` with the route parameter
function mapUserIdToData(hook) {
if(hook.data && hook.params.userId) {
hook.data.userId = hook.params.userId;
}
}
// For the new route, map the `:userId` route parameter to the query in a hook
app.service('users/:userId/posts').hooks({
before: {
find(hook) {
hook.params.query.userId = hook.params.userId;
},
create: mapUserIdToData,
update: mapUserIdToData,
patch: mapUserIdToData
}
})
Now going to /users/123/posts will call postService.find({ query: { userId: 123 } }) and return all posts for that user.

Provide check in RHS for existence of a field inside pojo in drools

I am new to drools.
I want to check in RHS that if a field is present in POJO or not.
{
"category": [
{
"nlp": [
{
"mainCategory": "Politics"
}
],
"crawler": [
{
"isNLP": true,
"mainCategory": "Politics"
}
]
}
]
}
This is list of the pojo that are generated
EsRootDoc.java
Crawler.java
Nlp.java
EsRootDoc is the main class which have methods and fields.`when
$RHSmap1:EsRootDoc()
and
$map1:EsRootDoc($categorylist1:category)
$category2:Category($nlplist2:nlp) from $categorylist1
$nlp2:Nlp(mainCategory=="politics") from $nlplist2
then
$RHSmap1.setEvent("fight");
end`
This is giving me following error
[Error: unable to resolve method using strict-mode: com.orkash.EnrichmentService.EnrichmentController.tempJsonToClass.EsRootDoc.setEvent(java.lang.String)]
[Near : {... $RHSmap1.setEvent("fight"); ....}]
I need to provide a check in RHS :- that if EsRootDoc has a field event or not
There is nothing in Drools (as far as I know) that allows you to do what you are looking for. The RHS of a rule is - almost- pure Java. The basic rule then is: if it can't be done in Java, it can't be done in the RHS of a rule in Drools.
The good news is that what you are trying to do can be achieved in Java using reflection. My recommendation would be for you to create a helper class that uses reflection to set the value of an attribute in an object if that attribute exists. Your rules then would look like this:
rule 'Some Rule'
when
$RHSmap1:EsRootDoc()
$map1:EsRootDoc($categorylist1:category)
$category2:Category($nlplist2:nlp) from $categorylist1
$nlp2:Nlp(mainCategory=="politics") from $nlplist2
then
Helper.setAttribute($RHSmap1, "event", "fight");
end
Hope it helps,

Good way to repeat a test, inserting an extra action?

I like the way Catch has nested hierarchies of tests, and it works through the combinations. It feels more natural than the setup/teardown of xUnit frameworks.
I now have a set of tests. What I want to do, about halfway down is insert a load/save serialization test, and then repeat all the tests below that point, first without the load/save, then again using the data it loaded from the serialization process. I.e. to prove that the load/save was correct.
I cannot get my head around if Catch has anything that can help with this? If it was phpUnit, I would be thinking about a string of #depends tests, and use a #dataProvider with a boolean input. A bit ugly.
(If that does not make sense, let me know, and I'll try to work out a minimal example)
The issue here is that Catch is designed to descend a tree-like organisation of tests and it automatically discovers all of the leaf-nodes of the structure and calls back into the test cases with untested code paths until they're all tested. The leaf nodes (tests, sections) are meant to be independent.
It sounds like you want to test a repository - something that can persist some data and then load it back in.
To repeat the exact same tests in two different scenarios (before serialisation, after serialisation) you'd need to put the same tests into some common place and call into that place. You can still use the same Catch macros in a non-test-case function, as long as you call it from a test case.
One possible way to do this is:
struct TestFixture {
Data data;
Repository repository;
TestFixture() : data(), instance() { }
};
void fillUpData(Data& data) {
// ...
}
void isDataAsExpected(Data& data) {
// Verify that 'data' is what we expect it to be, whether we
// loaded it or filled it up manually
SECTION("Data has ...) {
REQUIRE(data...);
}
}
TEST_CASE_METHOD(TestFixture, "Test with raw data") {
fillUpData(data);
isDataAsExpected(data);
REQUIRE(repository.save(data));
}
TEST_CASE_METHOD(TestFixture, "Operate on serialised data") {
REQUIRE(repository.load(data));
isDataAsExpected(_data);
}
One possible alternative is to supply your own main and then use command-line arguments to control whether/not the data is first serialised.
There's a third way I can think of that uses a non-quite-ready-yet feature of Catch - Generators:
TEST_CASE("...") {
using Catch::Generators;
int iteration(GENERATE(values(0, 1)));
const bool doSave(iteration == 0);
const bool doLoad(iteration == 1);
Repository repository;
Data data;
if (doLoad) {
REQUIRE(repository.load(data));
} else {
// fill up data
}
REQUIRE(..data..test..);
if (doSave) {
REQUIRE(repository.save(data));
}
}
The advantage of this method is you can see the flow and the test runs twice (for the two values) but the major disadvantage is that Generators are incompatible with SECTIONs and BDD-style features.

How do I use findOrCreateEach in waterline/sailsjs?

I been looking around on the sails site and was lead to the waterline page. I am curious to how I can use the findOrCreateEach method. Specifically, number of arguments, what it will return, and how it will benefit me using it? I been searching, around and going to have to dive into the source code. I figure I ask here while I look.
Method without bluebird promises
Model.findOrCreateEach(/* What Goes Here */).exec(/* What Returns Here */);
With bluebird promises
Model.findOrCreateEach(/* What Goes Here */).then(/* What Returns Here */);
findOrCreateEach is deprecated; that's why it's not in the documentation. The best way to replicate the functionality is by using .findOrCreate() in an asynchronous loop, for example with async.map:
// Example: find or create users with certain names
var names = ["scott", "mike", "cody"];
async.map(names, function(name, cb) {
// If there is a user with the specified name, return it,
// otherwise create one
User.findOrCreate({name: name}, {name: name}).exec(cb);
},
function done(err, users) {
if (err) { <handle error and return> }
<users now contains User instances with the specified names>
});

SailsJS best practice to seed database with data before other Models are initialized

There is a model that all other models assume its existence.
It should be initialized before any API function is called.
The way I do this (it doesn't work):
1) Define model in api/models, let's call it Location.js
2) Add the following to bootstrap.js
var Locations = require('../api/models/Locations.js');
module.exports.bootstrap = function (cb) {
// seed the database with Locations
var locationsObj = {
country: 'Australia',
states: ['Brisbane', 'Perth', 'Sydney']
};
Location.create(locationsObj, function locationsObj(err, locations) {
if (err) {
cb(err);
}
console.log('locations created: ', locations);
});
}
Question 1
Is it the right way to do initial database seeding?
I get this error:
Locations.create(locationsObj, function locationsObj(err, locations) {
^
TypeError: Object #<bject> has no method 'create'
Question 2
How does the cb function of bootstrap work?
what if there as an error, what to do?
The sails models are globally available; so you don't need to require at bootstrap.js.
This is what I use to seed my database. (See the links I enclose to go to the gists)
Include seed function at config/models.js. The methods you declare in this file will be extended to all your models.
Link: Seed method gist
Define de data the seed will consume in your model Link: Model's seed data
Call the seed method in config/bootstrap.js using async. Link: Calling method
UPDATE
Have a look at this threat also: Best way to migrate table changes to production sailsjs tables
From Cannot unit test my model in sailsjs:
"Once Sails app is lifted, you will have your models available automatically...
And in your case, your first line overrides the User model which would be otherwise constructed by Sails.js, that's why even though you have an object it's not a Waterline model."
I know this is old but, for completeness:
You set
var Locations = ...
But but you call
Location.create()
(no 's') so you just have a typo.
in config/bootstrap.js you can write your seeds directly. Take a look at the example below.
await sails.models.role.createEach([
{
name: 'Admin',
},
{
name: 'Normal-user',
},
]);
here 'role' is name of the table created and not the model name.