Groovy Comparing two Strings - groovy

Why these two strings are not matching on neither one: .equals() OR .compareTo() OR == OR Objects.equals()? I believe it should match atleast at one comparions.
Process proc1 = 'cat /home/output.txt'.execute()
Process proc2 = 'grep -o -m 1 webServiceReturn'.execute()
Process all = proc1 | proc2
def log = all.text.toString()
String svc = "webServiceReturn";
println (log)
println (svc)
//if (svc.equals(log)) {
//if (svc.compareTo(log)) {
//if(svc == log) {
if (Objects.equals((svc),(log))) {
println "MATCHED" }
else {
println "NOT MATCHED" }
The result on all four comparison are:
webServiceReturn
webServiceReturn
NOT MATCHED

I was able to reproduce your issue and making one minor modification to trim the white space on the results allowed it to match.
Do a trim on your all.text to remove any extraneous white space.
def log = all.text.trim()
You don't need the .toString() call either.

I just learned from another StackOverflow answer that using equals(), .contains and in fail to see same contents of strings of different type.
Groovy different results on using equals() and == on a GStringImpl
According to an answer by #dunes in the above question, the Groovy comparison using == uses compareTo() opportunistically before equals(). (The == comparison in Groovy has a remarkable difference from Java where it compares references).
def expandedString = "${'test'}"
def simpleString = 'test'
println "Expansion: ${expandedString}"
println "equals 'test' ? ${expandedString.equals(simpleString)}"
println " == 'test' ? ${expandedString == simpleString}"
The above outputs the following,
Expansion: test
equals 'test' ? false
== 'test' ? true
The following excerpt from the Groovy documentation omits the compareTo() piece that makes == different from equals().
In Groovy, using == to test equality is different from using the same operator in Java. In Groovy, it is calling equals. If you want to compare reference equality, you should use is like in the following example:
def list1 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3']
def list2 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3']
assert list1 == list2
assert !list1.is(list2)
http://docs.groovy-lang.org/next/html/documentation/core-operators.html#_identity_operator

Related

How to assert in Spock that list contains only some particular element?

In pure Spock/Groovy I need two separate assertions to verify that list contains some element and nothing else:
def "list has single element"() {
given:
def list = ['x']
expect:
list.size() == 1
list.first() == 'x'
}
I can make this assertion single-line by using Guava dependency:
expect:
Iterables.getOnlyElement(list) == 'x'
Is there a way to do the same in single line in pure Groovy/Spock? I don't want to use Guava too much in my tests.
EDIT
Actually for such a simple example just list == ['x'] is enough. I'm looking for a non Guava solution for something more complex, when multiple assertions must be performed on this single element:
def "list has single element"() {
given:
def list = [5.0]
expect:
def bigDecimal = Iterables.getOnlyElement(list)
bigDecimal.scale() == 1
bigDecimal.precision() == 2
}
If creating a helper method is acceptable, one can use with():
def "list has single element"() {
given:
def list = [5.0]
expect:
with onlyElementOf(list), {
it.scale() == 1
it.precision() == 2
}
}
where onlyElementOf() is
static <T> T onlyElementOf(Iterable<T> iterable) {
Iterator iterator = iterable.iterator()
def first = iterator.next()
assert !iterator.hasNext(), "Iterable has more than 1 element"
return first
}
This makes the test pretty readable.

Python3: make a chain call of functions

This question could be senseless, it's just interesting for me is it possible ot not.
In my code I had a lot of similar checks and calls like:
if self.command == self.CMD_HELP:
help(self.id)
if self.command == self.CMD_FIND:
find(self.id)
...
I found that in theory it could be done as:
self.COMMANDS = {
'help': help,
'find': find,
...
}
And execution:
self.COMMANDS[command](self.id)
It's fine if I will call one function.
But what if I need to call something like first(second(arg)) is it possible?
Update:
Sorry, my initial description appeared not very clear.
All this stuff is about the refactoring of the current implementation:
if command == MessageSettings.MSG_GLOBAL_HELP:
notify_help(guid)
if command == MessageSettings.MSG_GLOBAL_DISCORD:
sv_async.submit_fast(sv_discord.notify_discord_help(guid))
if command == MessageSettings.MSG_GLOBAL_FIND:
sv_async.submit_fast(sv_discord.notify_found_discord_users(guid, param))
... a lot of other 'ifs'
In the same time I have to support the list of the values to make the comparison:
class MessageSettings:
MSG_GLOBAL_HELP = 'help'
MSG_GLOBAL_DISCORD = 'discord'
MSG_GLOBAL_FIND = 'find'
...
MSG_VALUES = [
MSG_GLOBAL_HELP,
MSG_GLOBAL_DISCORD,
MSG_GLOBAL_FIND,
...
]
In this case if I add new option I will have to modify 3 places: new field in the class, add it into the array, add comparison and execution of if == value -> function.
Since functions can receive different amount of parameters I can rewrite all functions to take an array [] as a singe param.
I thought of using a dictionary with a "key -> function".
My question was that I did not understand if that was possible to apply this approach in cases if multiple function calls.
Also I don't know and I am not sure if such approach worth it.
ps: in my 3rd case there are:
def submit_fast(task):
future = asyncio.run_coroutine_threadsafe(task, loop_fast)
def notify_found_discord_users(will_replace_with_array):
anything
You could use lamda as in :
def help (n):
return "help " + n + " "
def find (n):
return "find " + n + " "
COMMANDS = {
'help': help,
'find': find,
'other' : (lambda x: help(x) + find(x))
}
print (COMMANDS['other']("Joe"))
If you mean something like this,
def lower(x):
return x.lower()
def upper(x):
return x.upper()
a = "a string"
b = upper(lower(upper(a)))
Of course.
the output of an inner function will be chained as the input of its outer function (as long as their parameters match).
It's the fundamental of any programming language.

What is the purpose of question mark(?) after a variable in Groovy

I am new to grails I found in many examples that a variable may end with question mark (?)
like this
boolean equals(other) {
if(other?.is(this))
return true
}
above code contains If condition in that other is ending with a ? so I want to know the meaning of that representation
?. is a null safe operator which is used to avoid unexpected NPE.
if ( a?.b ) { .. }
is same as
if ( a != null && a.b ) { .. }
But in this case is() is already null safe, so you would not need it
other.is( this )
should be good.
There is a subtlety of ?., the Safe navigation operator, not mentioned in #dmahapatro's answer.
Let me give an example:
def T = [test: true]
def F = [test: false]
def N = null
assert T?.test == true
assert F?.test == false
assert N?.test == null // not false!
In other words, a?.b is the same as a != null && a.b only when testing for a boolean value. The difference is that the first one can either evaluate to a.b or null, while the second one can only be a.b or false. This matters if the value of the expression is passed on to another expression.

Find if any value in a list exists in another list

im a newbie in groovy so i have a question, i have two lists, and i want to know if a value that exists in the first list also exists in the second list, and it must return true or false.
I tried to make a short test but it doesn't works... here is what i tried:
// List 1
def modes = ["custom","not_specified","me2"]
// List 2
def modesConf = ["me1", "me2"]
// Bool
def test = false
test = modesConf.any { it =~ modes }
print test
but if i change the value of "me2" in the first array to "mex2" it returns true when it must return false
Any idea?
Simplest I can think of is using intersect and let Groovy truth kick in.
def modes = ["custom","not_specified","me2"]
def modesConf = ["me1", "me2"]
def otherList = ["mex1"]
assert modesConf.intersect(modes) //["me2"]
assert !otherList.intersect(modes) //[]
assert modesConf.intersect(modes) == ["me2"]
In case the assertion passed, you can get the common elements out of the intersection without doing a second operation. :)
I believe you want:
// List 1
def modes = ["custom","not_specified","me2"]
// List 2
def modesConf = ["me1", "me2"]
def test = modesConf.any { modes.contains( it ) }
print test
This disjoint() method returns true if there's no item that is common to both lists. It sounds like you want the negation of that:
def modes = ["custom","not_specified","me2"]
def modesConf = ["me1", "me2"]
assert modes.disjoint(modesConf) == false
modesConf = ["me1", "mex2"]
assert modes.disjoint(modesConf) == true
You can use any of the disjoint()/intersect()/any({}) which will return true/false. Below given are the examples:
def list1=[1,2,3]
def list2=[3,4,5]
list1.disjoint(list2) // true means there is no common elements false means there is/are
list1.any{list2.contains(it)} //true means there are common elements
list1.intersect(list2) //[] empty list means there is no common element.
def missingItem = modesConf.find { !modes.contains(it) }
assert missingFile == "me1"
In such case, missingItem will contain a missing element which exists in modesConf but doesn't exist in modes. Or will be null if everything is fine.

Groovy split csv and empty fields

Groovy split seems to be ignoring empty fields.
Here is the code:
line = abc,abc,,,
line.split(/,/)
println
prints only..
abc abc
It seems to ignore empty fields. How do I retrieve empty fields using split?
First of all, method split(regex) is not provided by Groovy, it is provided by Java.
Second, you can achieve what you need by using the generic split(regex, int limit) as below:
def line = "abc,abc,,,"
println line.split(/,/, -1) //prints [abc, abc, , , ]
println line.split(/,/, -1).size() //prints 5
Note:-
The string array you would end up in the print would throw a compilation error when asserted. But you can use the result as a normal list.
line.split(/,/, -1).each{println "Hello $it"}
I would rather use limit 0 or the overloaded split to discard unwanted empty strings.
Explanation on using -1 as limit:
Stress on the below statements from the javadoc.
The limit parameter controls the number of times the pattern is
applied and therefore affects the length of the resulting array. If
the limit n is greater than zero then the pattern will be applied at
most n - 1 times, the array's length will be no greater than n, and
the array's last entry will contain all input beyond the last matched
delimiter. If n is non-positive then the pattern will be applied as
many times as possible and the array can have any length. If n is zero
then the pattern will be applied as many times as possible, the array
can have any length, and trailing empty strings will be discarded.
Interesting. The split method works as expected provided there's a non-empty element at the end.
def list = 'abc,abc,,,abc'.split(/,/)
println list // prints [abc, abc, , ]
assert list.size() == 5
assert list[0] == 'abc'
assert list[1] == 'abc'
assert list[2] == ''
assert list[3] == ''
assert list[4] == 'abc'
Maybe you could just append a bogus character to the end of the string and sublist the result:
def list = 'abc,abc,,,X'.split(/,/) - 'X'
println list // prints [abc, abc, , ]

Resources