Grails / Spock testing .. unexpected error thrown - grails

Using spock to unit test a comand object .. I have a line in the command object ..
some code ..
} else {
if ((val && obj.part) && obj.transactionType.transactionIsATransfer()) {
println "obj.part .. class is ${obj.part.getClass()} .. serial is ${val.getClass()}"
if(! isAValidPartSerialCombo(obj.part,val)) <-- line 79
return 'com.myStuff.TransactionDetailCommand.serialReference.not.for.part'
}
..
def isAValidPartSerialCombo {part, serialReference ->
return InventoryMaster.hasPartandSerial(part,serialReference)
}
I have a unit test where I mock out the dependency
def obj = new TransactionDetailCommand(transactionType: new TransactionType(type: 'Transfer', requireSerial: true),
serialReference: 'AAA', part: new Part(partNumber: 'AAA'))
obj.metaClass.isAValidPartSerialCombo = {a,b -> false}
and: "we try to validate the transaction "
obj.validate()
then: "we get an error on the transaction for the 'serialReference' property"
obj.errors['serialReference']
which is giving me an error ..
java.lang.IllegalArgumentException: object is not an instance of declaring class
at com.vantec.TransactionDetailCommand._clinit__closure1_closure7(TransactionDetailCommand.groovy:90)
at grails.test.MockUtils.addValidateMethod_closure87_closure114(MockUtils.groovy:1035)
at grails.test.MockUtils.addValidateMethod_closure87(MockUtils.groovy:1031)
at grails.test.MockUtils.addValidateMethod_closure88(MockUtils.groovy:1065)
at com.myStuff.transaction.TransactionDetailCommandSpec.Ensure that for issues / transfer transactions then serial/part numbers are required to match .. (TransactionDetailCommandSpec.groovy:79)
However if I create a separate dummy test it works without a problem ..
def "A simple test .. "(){
when:
def obj = new TransactionDetailCommand()
obj.metaClass.isAValidPartSerialCombo = {a,b -> false}
then: 'we get a false ..'
!obj.isAValidPartSerialCombo(new Part(),"AAA")
}
Can anyone shed any light ??
Thanks
Complete test ...
def "Ensure that for issues / transfer transactions then serial/part numbers are required to match .. "(){
when: "The transaction type indicates a transfer and we supply a serial number and a part .."
def obj = new TransactionDetailCommand(transactionType: new TransactionType(type: 'Transfer', requireSerial: true),
serialReference: '12345', part: new Part(partNumber: 'PartA'))
obj.metaClass.isAValidPartSerialCombo = {a,b -> false}
and: "we try to validate the transaction "
obj.validate()
then: "we get an error on the transaction for the 'serialReference' property"
obj.errors['serialReference']
and: "the error is the correct one .."
'com.myStuff.TransactionDetailCommand.serialReference.not.for.part' == obj.errors['serialReference']
}
and the constraint i'm testing ..
serialReference nullable: true, validator: { val, obj ->
println "One .. "
if ((val == null || val.toString().isEmpty()) && obj.transactionType.requireSerial) {
println "Two .. "
return 'com.myStuff.TransactionDetailCommand.serialReference.required'
} else {
println "Three .. "
if ((val && obj.part) && obj.transactionType.transactionIsATransfer()) {
println "Four ..."
if(! isAValidPartSerialCombo(obj.part, val)){
println("Five .. ")
return 'com.myStuff.TransactionDetailCommand.serialReference.not.for.part'
}
}
}
return 'oops'
}
def isAValidPartSerialCombo = {part, serialReference ->
println "Six .."
// return InventoryMaster.hasPartandSerial(part,serialReference)
return true
}
The println's are just so I can see where the code goes ..

Not sure about it, but it would be worthy to give a try to mock the instance of obj after the creation of the instance
mockDomain(TransactionDetailCommand, [obj])

Try to organise in that way your test:
def "Ensure that for issues / transfer transactions then serial/part numbers are required to match .. "(){
given: "The transaction type indicates a transfer and we supply a serial number and a part .."
def obj = new TransactionDetailCommand(transactionType: new TransactionType(type: 'Transfer', requireSerial: true),
serialReference: '12345', part: new Part(partNumber: 'PartA'))
obj.metaClass.isAValidPartSerialCombo = {a,b -> false}
when: "we try to validate the transaction "
obj.validate()
then: "we get an error on the transaction for the 'serialReference' property"
obj.errors['serialReference']
and: "the error is the correct one .."
'com.myStuff.TransactionDetailCommand.serialReference.not.for.part' == obj.errors['serialReference']
}
as the creation of the object and the metaprogramming are all set up actions.

Related

Compare two lists in jenkins pipeline

In my pipeline, I have two lists and want to compare it and print output accordingly
1- println abc
[aaa, bbb, ccc]
2- println xyz
[bbb, ccc]
I need to print the output to a file like:
aaa not present in xyz
bbb present
ccc preset
Code I tried:
def test []
test = abc - xyz
println test
def abc = ['aaa', 'bbb', 'ccc']
def xyz = ['bbb', 'ccc']
//simple
println 'present in xyz: ' + abc.intersect(xyz).join(', ')
println 'not present in xyz: ' + abc.minus(xyz).join(', ')
//with for-each
for(i in abc){
if(i in xyz) println "present in xyz: $i"
else println "not present in xyz: $i"
}
You can try something along those lines:
abc.each{valueOne ->
doesValueExist = false
xyz.each{ valueTwo->
if(valueOne.equals(valueTwo}{
doesValueExist = true
}
}
if(doesValueExist){
echo "${valueOne} is present"
} else {
echo "${valueOne} is not present"
}
}

Groovy: Read contents of a file in an array and grep for something

I am trying to implement following in GROOVY script but getting errors:
Read contents of an HTML file in an array and then grep for something in that array.
def file1 = new File("/path/to/the/file/xyz.html");
def lines = file1.readLines()
if ((-e "/path/to/the/file/xyz.html") and (!(grep /jira.bugtracker.com/, lines))
{
println (" the changes are present\n");
exit 0;
}
else
{
println (" the changes are not present\n");
exit 1;
}
Please review the code and suggest the correct method.
def file1 = new File("/path/to/the/file/xyz.html" )
def lines = file1.readLines()
def found = lines.find{ line-> line =~ /jira.bugtracker.com/ }
println ("the changes are ${ found ? '' : 'not ' }present")
return found ? 0 : 1
you can try like this.
if ( new File("/path/to/the/file/xyz.html").text?.contains("jira.bugtracker.com")){
println (" the changes are present\n");
} else {
println (" the changes are not present\n");
}

Lua displaying table

I'v made a quiz with multiple choices. Before starting the game, a user has to use an identifier and then the user is added to the table and ready to play:
function addUser(msg)
local id = msg.from.username
if (userScore == nil) then
userScore = {}
end
if (userScore[id]) then
return "user already in Game"
else
userScore[id] = 100
return id
end
This adds the points in the table:
function addScore(msg)
local id = msg.from.username
if (userScore[id] == nil) then
return "user unknown. start het spel!"
end
if (game == "on") then
if (userScore[id]) then
userScore[id] = userScore[id] - 1
return id .. ", punje eraf!"
else
return id .. " is not yet a user! where to start huh?"
end
else
return "Game mode is off"
end
end
Then with !score the users can see the score:
elseif (matches[1] == "!score") then
for k, v in pairs(userScore) do
return k .. " : " .. v
end
The issue I have is that I only see one line in the table, knowing that other users are added to the table. What am I doing wrong?
From the comments it seems you want to return a single string that contains the userScore table's key-value pairs on each line.
You can do this by constructing a string that has the lines.
For example like this:
local res = {}
for k, v in pairs(userScore) do
table.insert(res, k .. " : " .. v)
end
return table.concat(res, "\n")

contains() method is not working

I receive JSON data as below,
def data = JSON.parse(params.company) //it's [name:foo, users:[1,2,3]]
And I want to check if it contained. I did like this,
if(data.users.contains(2)){
println 'true'
}
else {
println 'false'
}
It's always print 'false'
But when I try by new data like
def test = [1,2,3]
if(test.contains(2)){
println 'true'
}
else {
println 'false'
}
It's 'true'.
Although you said in a comment that you solved it, I think you did it the wrong way.
You should try
def test = [1,2,3]
if(test.contains('2')){
println 'true'
}
else {
println 'false'
}
You have to understand that 2 == '2' is false. Types matters.

Create dynamically closures in Groovy from a String object

i would like to create a query with the Criteria API in Grails (GORM).
The query will have to be something like this:
MyEntity.createCriteria().list{
assoc{
parent{
eq("code", val)
}
}
}
What i need is to build the nested closure dynamically from a String object. The String for the example above will be "assoc.parent.code" . I splitted the String by dot (by doing String.split("\\.") ) but i don't know how to construct the nested closures:
assoc{
parent{
eq("code", val)
}
}
dynamically based on the array of the splitted Strings above.
What about createAlias?. You could try something like this:
def path = "assoc.parent.code"
def split = path.split(/\./)
MyEntity.createCriteria().list {
// this will get you 'createAlias( assoc.parent, alias1 )'
createAlias split.take( split.size() - 1 ), "alias1"
// this will get you 'eq(alias1.code, userInput)'
eq "alias1.${split[-1]}", userInput
}
This snippet is not generic, but you get the idea.
Update
Not conventional, but you can build a string containing the code with the closures and evaluate it using GroovyShell:
assoc = 'assoc.parent.child.name'
split = assoc.split( /\./ )
path = split[-2..0] // will get us 'child.parent.assoc';
// we will build it from inside-out
def firstClosure = "{ eq '${split[-1]}', 'john doe' }"
def lastClosure = firstClosure
for (entity in path) {
def criteriaClosure = "{ ${entity} ${lastClosure} }"
lastClosure = criteriaClosure
}
assert lastClosure == "{ assoc { parent { child { eq 'name', 'john doe' } } } }"
def builtClosure = new GroovyShell().evaluate("return " + lastClosure)
assert builtClosure instanceof Closure
A more generic approach would be to metaClass String as below, and use it for any kind of separator
. | , - ~ and more.
String.metaClass.convertToClosureWithValue = {op, val ->
split = delegate.split(op) as List
if(split.size() == 1) {return "Cannot split string '$delegate' on '$op'"}
items = []
split.each{
if(it == split.last()){
items << "{ eq '$it', $val }"
split.indexOf(it).times{items.push("}")}
} else {
items << "{$it"
}
}
println items.join()
new GroovyShell().evaluate("return " + items.join())
}
assert "assoc.parent.child.name".convertToClosureWithValue(/\./, "John Doe") instanceof Closure
assert "assoc-parent-child-name".convertToClosureWithValue(/\-/, "Billy Bob") instanceof Closure
assert "assoc|parent|child|grandChild|name".convertToClosureWithValue(/\|/, "Max Payne") instanceof Closure
assert "assoc~parent~child~grandChild~name".convertToClosureWithValue('\\~', "Private Ryan") instanceof Closure
assert "assocparentchildname".convertToClosureWithValue(/\|/, "Captain Miller") == "Cannot split string 'assocparentchildname' on '\\|'"
//Print lines from items.join()
{assoc{parent{child{ eq 'name', John Doe }}}}
{assoc{parent{child{ eq 'name', Billy Bob }}}}
{assoc{parent{child{grandChild{ eq 'name', Max Payne }}}}}
{assoc{parent{child{grandChild{ eq 'name', Private Ryan }}}}}

Resources