How do you use concordion:run with parameters? - bdd

I would like to run a Concordion spec using a parameter. What I'd like to do is execute the spec using concordion:run. A little research pointed me to the existence of a concordion:params attribute, but I cannot find any documentation or examples.
I'm not sure how these two commands fit together; should the params element be nested inside the run element or outside? What is the value to fill in concordion:params="?" Where do I specify the param values themselves--in a concordion:set call?

concordion:params is an attribute to be used on the same element as the concordion:run attribute.
For example, in MyIndex.html:
<a concordion:run="concordion" concordion:params="foo=5" href="MySpec.html">My Spec</a>
with the fixture class:
#RunWith(ConcordionRunner.class)
#FullOGNL
public class MyIndex {
public void setFoo(Integer foo) {
System.out.println("foo = " + foo);
}
}
Note that the #FullOGNL attribute is required to allow the syntax foo=5 in the expression that wouldn't otherwise be allowed.
NOTE:
Tim Wright has pointed out an issue with this approach:
The issue I see is that the same specification might be run from two
different specifications (or run twice from a single specification)
with different parameters as well as from jUnit with no parameters. As
we only create one HTML file, the behaviour might not be what the user
expects. It also means that using concordion:run will create a
different specification from running the spec directly as a jUnit test
- which is something we've tried hard to avoid.
The current behaviour (with the concordion run cache) is that the
first one to be called will create the HTML file - and the second one
will return a run results from the cache thus ignoring the parameter.
This may mean that we deprecate concordion:params and remove it in 2.0.

Related

Specify arguments in grails command

I'm using grails 3.2.6. I'm writing a custom grails command. It's a command and not a script because I need access to object in the spring application context in the command. I would like for my command to accept command line arguments with values such as "name" and "group" and "id". For example, I'd like to be able to run the command like this:
grails run-command process-group --name=foo --group=bar --id=2
However, when I do this, my command implementation class doesn't seem to have access to any of these arguments (name, group, or id). I've tried accessing them through the args attribute that comes from the GrailsApplicationCommand trait, but that is empty. I've also tried accessing it through various methods of the CommandLine object that is accessible through executionContext.commandLine object which also comes from the GrailsApplicationCommand trait. However, everything there seems to be empty as well (undeclaredOptions is empty, remainingArgs is empty, rawArguments just has my command name which is "process-group", etc.). If I remove the leading "--" from my argument names like this:
grails run-command process-group name=foo group=bar id=2
then the args attribute contains 3 entries: ["name=foo", "group=bar", and "id=2"]. I suppose that I could implement my command this way (no leading "--" on the command arguments), but it's kind of ugly, and it also means that I have to parse the arguments myself. The grails docs (http://docs.grails.org/latest/guide/single.html#creatingCustomCommands) say that, "Since Grails 3.2.0, commands have similar abilities as scripts in regards to retrieving arguments, template generation, file access, and model building." I'm interested in the retrieving arguments part of that statement. The examples shown in the documentation for scripts (not commands) show (http://docs.grails.org/latest/guide/single.html#creatingCustomScripts) how to declare parameters that a script will take from the command line. For example, this command line is supposed to work with a custom script that declares the "force" parameter for the generate-all custom script:
grails generate-all MyClass --force
This all seems to be tied to the use of the description() method in the script:
description( "Generates a controller that performs CRUD operations and the associated views" ) {
usage "grails generate-all <<DOMAIN CLASS>>"
flag name:'force', description:"Whether to overwrite existing files"
argument name:'Domain Class', description:'The name of the domain class'
}
However, there doesn't seem to be a description() method available for use for custom commands as there is for custom scripts. I just confused about how the grails docs state that retrieving arguments is supposed to now work the same for both custom scripts and custom commands, yet I can't seem to retrieve arguments from a custom command like I can from a custom script. Is there a way that I can retrieve the arguments for a custom command just like it can be done for a custom script?
Set the properties using the -D option:
-Dsample.message=foo
Grab the system properties using the follow code:
System.properties['sample.message']
Link to the where I found this example:
Passing Properties

Unit testing grails ConfigSlurper behavior

I'd like to write tests that would test behavior of externalized configs and assert that what gets set is what I expect. This is for the specific case where something like this is done:
Config.groovy:
a.reused.value = 'orig'
my.variable = '${a.reused.value}'
Externalized groovy file:
a.reused.value = 'new_value'
I expect that both a.reused.value and my.variable would be 'new_value'.
Now, I think I could have my unit test read in strings representing these config files (I do similar things for other unit tests to populate Holders.grailsApplication.config, for example), utilizing perhaps merge?
But what I cannot figure out is how to get the value that Grails actually gets during application run time. Instead, I get "${a.reused.value}" in my unit tests.
Is there a way to mimic this behavior of what Grails does of actually resolving this value? I did some digging around in Grails 2.4.4 source (which is what we are using) and didn't have any luck in figuring this part out. I also did try Eval.me(), but that doesn't seem to be quite right either.
While setting my.variable, you are not using a GString object, causing the expression to be treated as a value itself. Use double quotes to resolve expression automatically.
a.reused.value = 'orig' my.variable = "${a.reused.value}"
Update 1:
What you want to do is directly not possible. You are assigning the value to a variable from an expression. During evaluation of the config object for the first time, my.variable has been assigned a value, and now it doesn't contain an expression any more. So you have two options: 1) either reassign the second variable in external config also or 2) use a closure to assign the value to second variable.
my.variable = { -> "$a.reused.value" }
and while accessing do: grailsApplication.config.my.variable.call()
But again, in your code, you would have to be sure that this variable contains a closure not a value itself.

Use variable to access config in Grails Holders

Using Grails 2.3.7, I set a property in my config file:
foo.bar = ['whatever']
I can access using Holders...
Holders.config.foo.bar
For convenience I put Holders in util method:
static getCfgProp(key){
Holders.config.get(key)
}
But getCfgProp('foo.bar') doesn't work (guessing because foo.bar is nested map key).
It works if I flatten the config:
static getCfgProp(key){
Holders.getFlatConfig().get(key)
}
..but don't want to do that each time method is invoked.
Tried these, none worked, I must be missing something simple
Holders.config."${key}"
Holders.config."$key"
Holders.config.getProperty(key)
Holders.config.(key)
This is what I've used for displaying a config var value (via a form input):
grailsApplication.config.flatten()."${it}"
where ${it} is the input string. This works for both non-nested and nested keys due to the flatten() method.
EDIT: just realised this is the equivilent of your Holders.getFlatConfig() so probably not useful. Not sure why you
don't want to do that each time method is invoked
Performance? Have you benchmarked it?
This has worked for me with grails-2.5.6:
Holders.config[key].subkey.subsubkey...
Holders.config[key][subkey].subsubkey...
// for Holders.config.foo.bar.zet
Holders.config['foo'].bar.zet
Holders.config['foo']['bar'].zet
Holders.config['foo']['bar']['zet']

Canoo and Groovy - how to use storeRegEx

We would like to test the following flow using Canoo. The tests are written in Groovy, and not as Ant tasks.
Send a request to a specific URL (we use "invoke")
Extract specific information from the response (we use "storeRegEx" with property:"ans")
Print the extracted value (for debug purposes). println "${ans}" - does not work
Use the extracted value in the next action (e.g. invoke "new/url/id=#{ans}")
We saw some references to using an AntBuilder, it fails as well.
Is there some example for that flow?
Thanks
remember that it depends on the ant property type (dynamic or ant) whether you have to use #{ans} or ${ans}
println will not work in webtests. Use the description property of webtest steps instead:
group(description:"#{ans}") {
...
}
this will show you the value of your property in the test result.

How do you use a String array as a member field in a Grails domain?

I'm trying to create a basic grails domain object and for one of the fields I want to use an array of Strings. However even after running grails generate-views I still don't see the ability to edit said array. Am I going about this wrong?
If you run 'grails install-templates' you can edit src/templates/scaffolding/renderEditor.template which is where the HTML generation for editors is defined. Add in a new "else if" for String[]:
else if (property.type == String[].class)
out << renderStringArrayEditor(domainClass, property)
and implement renderStringArrayEditor however you think best:
private renderStringArrayEditor(domainClass, property) {
...
}
I have no idea what HTML to use, but I might go with a textarea and split on \n. Whatever you decide on, you'll need to convert the input parameter to a String array in your controller methods.
If you're already run 'grails generate-all' or 'grails generate-views' you'll need to run 'grails generate-views' to regenerate your GSPs with the new editor.

Resources