What do Groovy assertions look like with parentheses? - groovy

The example on this page only shows Groovy assertions without parentheses.
assert a != null, 'First parameter must not be null'
What would this look like if I wanted to include the parentheses? I presume that this is the closest equivalent to Perl's die() function (print error message and exit in one statement)?

The answer is:
assert(a != null), "First parameter must not be null"

Related

Expected string literal in condition express in Jenkins pipeline

I am using ?: to determine the build agent of Jenkins shared library groovy script like this:
def call(String type, Map map) {
if (type == "gradle") {
pipeline {
agent "${map.agent == null}" ? "any" : "${map.agent}"
}
}
}
but it gives me the following error:
org.jenkinsci.plugins.workflow.cps.CpsCompilationErrorsException: startup failed:
/Users/dabaidabai/.jenkins/jobs/soa-robot/builds/154/libs/pipeline-shared-library/vars/ci.groovy: 6: Expected string literal # line 6, column 42.
agent "${map.agent == null}" ? "any" :
^
/Users/dabaidabai/.jenkins/jobs/soa-robot/builds/154/libs/pipeline-shared-library/vars/ci.groovy: 6: Only "agent none", "agent any" or "agent {...}" are allowed. # line 6, column 13.
agent "${map.agent == null}" ? "any" : "${map.agent}"
^
/Users/dabaidabai/.jenkins/jobs/soa-robot/builds/154/libs/pipeline-shared-library/vars/ci.groovy: 6: No agent type specified. Must be one of [any, docker, dockerfile, label, none] # line 6, column 13.
agent "${map.agent == null}" ? "any" : "${map.agent}"
What am I doing wrong?
This error is thrown by the pipeline syntax validator that runs before your pipeline code gets executed. The reason you see this error is the following:
Only "agent none", "agent any" or "agent {...}" are allowed. # line 6, column 13.
This is the constraint for the label section. It means that the following values are valid:
agent any
agent none
agent "constant string value here"
agent { ... }
When you pass something like:
agent "${map.agent ?: 'any'}
agent(map.agent ?: 'any')
you are getting Expected string literal because any form of an expression is not allowed in this place, including interpolated GStrings of any form.
Solution
There is a way to define pipeline agent dynamically however. All you have to do is to use a closure block with the label set to either expression or empty string (an equivalent of agent any in this case.)
pipeline {
agent {
label map.agent ?: ''
}
stages {
...
}
}
The label section allows you to use any expression, so map.agent is a valid construction here. Just remember to use an empty string instead of "any" - otherwise Jenkins will search for a node labeled as "any".
Don't use string replacments everyhwhere:
agent(map.agent==null ? "any" : map.agent)
Or get groovy:
agent(map.agent?:"any")
The actual problem is most likely the "ternary operator" battling against the "parens are maybe optional"-rule.
It seems to me that agent is a method taking a string argument and the way your code is written is ambiguous. Try surrounding the argument expression with parens:
agent(map.agent == null ? "any" : "${map.agent}")
I removed the quotes around map.agent == null as they seemed extraneous.
Also this could probably be rewritten using the groovy "elvis operator" (:?) as:
agent(map.agent ?: "any")
Which essentially means "use map.agent if it has a value, otherwise use 'any'". "If it has a value" is in this context being defined using groovy truth where both empty string and null represent "no value".

How can I reference an unnamed argument of a when expression?

I have a when expression that looks something like this:
when(foo.toString()){
"" ->'A'
"HELLO" ->'B'
"GOODBYE"->'C'
else ->foo.toString()[0]//problematic method call duplication
}
Now, I don't want to call foo.toString() twice, but I also want this to remain a single expression. Is there a convenient way for me to access the value I passed into the when expression in its else block, such as the it or this# syntax found elsewhere in the language?
I'm currently using the following work-around:
with(foo.toString()){
when(this){
"" ->'A'
"HELLO" ->'B'
"GOODBYE"->'C'
else ->this[0]
}
}
But this introduces another block, and is less readable than I'd like. Is there a better solution?
For the when block there's no variable specified, but you can use the let() function for a similar behavior which might be a little better than your workaround, but behaving the same.
foo.toString().let{
when(it){
"" ->'A'
"HELLO" ->'B'
"GOODBYE"->'C'
else ->it[0]
}
}

String comparison in groovy script not working

I am trying to compare 2 Strings in groovy script. both have same value but they are in different case while m trying compare it using equalsIgnoreCase still it is showing not equals.
Here is my code:
def st1=Austin
def ct=AUSTIN
if(st1.equalsIgnoreCase(ct)){
log.info "city equals"
}
else{
log.info "not eq"
}
it's printing "not eq".I tried toString() and toUpperCase methods.Plz help me out
Sorry for the erroneous post. I got my problem I was working with db. it gives me value with some extra spaces. So my comparison was not working. later I used
trim()
to remove it.

Does assert.equal offer any advantages over assert (assert.ok)?

In this question I refer to the assert module that is included within the node.js core.
As far as I can tell the following two assertions are pretty much identical:
assert.equal(typeof path, "string", "argument 'path' must be a string");
assert(typeof path === "string", "argument 'path' must be a string");
Upon failure both variations report the same message:
AssertionError: argument 'path' must be a string
Are there any notable advantages of the former over the latter in this situation?
Well, depending on the test runner framework, assert.equal will probably give you a more descriptive error message. For instance, in this case:
assert.equal(typeof path, "string");
assert(typeof path === "string");
the first statement would give you a message along the lines of:
actual: number
expected: string
which already tells you that the test case fails because typeof path is a number.
The latter will only print something like this:
AssertionError: false == true
Also, note that if you want to check for strict equality (===), you should use assert.strictEqual instead of assert.equal.
assert.equal doesn't check for identity, only equality. It's equivalent to:
assert(typeof path == 'string', "argument 'path' must be a string");
The real equivalent would be assert.strictEqual, which uses the identity operator ===:
assert.strictEqual(typeof path, "string", "argument 'path' must be a string");
For typeof, no, there's no difference. You'll run into problems with other data types though:
> assert.equal('test', ['test']);
undefined
> 'test' == ['test']
true
> 'test' === ['test']
false
Both will work.
First, assert uses the coercive == operator, not strict ===
Also, when you read a lot of your unit tests or other people's unit tests, you'll strain your eyes on repetitive syntax. You'll love it when people will write this
assert.equal(aValue, anotherValue) // sexy
/** But you will hate people writing this. **/
assert.ok(aValue == anotherValue) // ugly
In the first case, you can see the condition being checked within the first 9 letters. You don't even need to look further. In the other case, you have to read 20 letters to know what the test is checking. It's more cryptic.
Also, assert.equal is more declarative of your intention than assert.ok.
Imagine you are writing a test for testing a set intersection. You would read better
assert.setIntersect(set1, set2) // wow
assert.ok(setIntersect(set1, set2)); // hm.
To sum it up, the advantage is in readability (thus maintainability) of you unit tests. It's not much, but it helps writing better understandable code.
As alexander said, too, you will have more precise error messages when test fail if you don't specify a message.

Groovy - How can I compare part of a list to a string

I have a list which contains two types of text. One type is used for authorization while other type is used for all other purposes.
The type used for authorization always uses the same text + some code after it.
I would like to compare content of these two types of text and separate them based on content.
My idea is to look for pattern in authorization type and if it matches the pattern then this would be marked as authorization, otherwise it would be marked as "other".
I researched about comparison of patterns in Groovy, but all variations I tried did not work for me. Here is the part which should do the comparison, I am obviously doing something wrong but I don't know what.
jdbcOperations.queryForList(sql).collect { row ->
if(assert (row['MSG'] ==~ /token/)){
mark as authorization
}
else{
mark as other
}
}
Sorry for the vague code, I can not share more than this.
I think you just missing the match for the rest of the text, since you are looking only for the first part to match.
assert ("abc" ==~ /abc/) == true
assert ("abcdefg" ==~ /abc/) == false
assert ("abcdefg" ==~ /abc(.*)/) == true // <--- This can also be made more complicated

Resources