what is shouldFail in groovy? - groovy

How does the code within the 'shouldFail?' block work? I understand that it is a closure, but the code gets called regardless of whether or not I call is using its signature. Besides, what's the deal with the "ReadOnlyPropertyException" showing up in the parenthesis? If it is a parameter, then it is not setup as listed in the official documentation!!
Questions: What is 'shouldFail'? How should it be invoked? How to handle the exception purportedly thrown by this method/function/closure?
void test02_ReadOnlyFieldInGroovyBean() {
// You've probably noticed how Groovy automatically generates getters/setters for you. But what if you don't
// want to generate a setter because it's a read-only field? Just mark it with 'final'. Groovy will understand.
// Try to modify Ken's ssn. You should get a ReadOnlyPropertyException.
def person = new GroovyPerson('Ken', 'Kousen', '7878')
def failed = false
shouldFail (ReadOnlyPropertyException) {
// ------------ START EDITING HERE ----------------------
System.out.println(" i am in should fail")
person.ssn='8332';
// ------------ STOP EDITING HERE ----------------------
failed = false
System.out.println(" exiting should fail")
}
//def foobar=shouldFail("hjh");
//def foobar=true;
failed=shouldFail('abc');
//System.out.println("Failed: "+failed);
assert failed
// The code wrapping your additions verifies that the ReadOnlyProperty exception has been thrown.
// The curly brackets ({}) represent a closure. We'll get into what that means very soon.
}

shouldFail() (in this variant) takes a class and a closure. It runs the closure and reports a test failure if the closure does NOT exit by throwing an exception of that type. As to catching the exception, you don't - shouldFail() does that for you.
See: http://docs.groovy-lang.org/latest/html/gapi/groovy/test/GroovyAssert.html#shouldFail%28java.lang.Class,%20groovy.lang.Closure%29
(Reading the comments and the code around them, it looks like this unit test should pass because setting the .ssn property of GroovyPerson will fail as it is a read-only property, causing a ReadOnlyPropertyException.)

Related

Variable visibility in a Groovy Script

I have created a temp.groovy script:
def loggedMessages = [];
def log(message) {
loggedMessages << message;
}
log "Blah"
print loggedMessages.join('\n')
When I run it I get an exception relating to the log method:
groovy.lang.MissingPropertyException: No such property: loggedMessages
Why can't the log method see the loggedMessages variable? I obviously have a fundamental misunderstanding of what's going on. I've tried to read the docs but I can't seem to find the relevant section.
From the comments, as an answer:
The Script class documentation states (in the last section 3.4 Variables) that:
if the variable is declared as in the first example [with a type definition], it is a local variable. It will be declared in the run method that the compiler will generate and will not be visible outside of the script main body. In particular, such a variable will not be visible in other methods of the script
And further: if the variable is undeclared, it goes into the script binding. The binding is visible from the methods [...]
Therefore removing the def from loggedMessages fixes the error:
loggedMessages = [];
def log(message) {
loggedMessages << message;
}
log "Blah"
print loggedMessages.join('\n')
(Alternatively it can be annotated using #groovy.transform.Field as #aetheria pointed out in the comments)

TypeInitializationException/ArgumentException when referencing initialized variable

I just received an exception when I try to reference a static variable in another class, which is also statically initialized. This worked before, and for some reason it fails now. The only changes I made were resetting Visual Studio (2010) to its default setting, which I can't imagine to be the reason for this. Any other code I added didn't touch any of the affected parts either.
This is my code
WinForms class 'MainForm':
partial class MainForm : Form
{
// ...
private RefClass convMan;
private Dictionary<EnumType, string> LogNames = RefClass.LogNames;
// ...
public MainForm() { .... }
}
Referenced class 'RefClass':
class RefClass
{
// ...
public enum EnumType { TypeOne = 0, TypeTwo = 1, TypeThree = 2 };
public static Dictionary<EnumType, string> LogNames = new Dictionary<EnumType, string>()
{
{ EnumType.TypeOne, "Text0" },
{ EnumType.TypeTwo, "Text1" },
{ EnumTypy.TypeThree, "Text2" }
};
}
The error I get now is (translated from German):
An unhandled exception of type "System.TypeInitializationException" occurred.
Additional information: The type initializer for "RefClass" threw an exception.
which has the InnerException
System.ArgumentException
So, as far as I'm concerned, my static dictionary should be initialized once it gets accessed, thus when my Form class references it. I tried debugging to see if the static dictionary is initialized before it gets referenced in the Form class, which is not the case. Also, when I stop at a breakpoint for the reference line, the variable LogNames is null.
I'm really confused as to why this happens, it all worked before.
I found my error, the exceptions I got were quite misleading though. It was a problem with a different dictionary than the one I referenced. It probably didn't get initialized in the first place because something before that failed (If someone can clear this up, please feel free to do so!). Basically what I did wrong was using a two-directional dictionary and adding a value twice. This should normally produce a normal exception, but since it was done statically it got wrapped into a TypeInitializationException. I had a deeper look into the exact stacktrace of the inner exception and found where the exception originated from. Maybe this helps someone in the future...
I had a simular issue getting the same exception. Found that my static constructor for my utility class was generating the exception. Took some time locating since the description of the exception was misleading.
As #Yeehaw mentioned, it appears that the exception gets wrapped, so the common denominator here I would say is that the class/object is static.

Capturing a javafx Change event with mockito throws an IllegalStateException

I want to test using mockito, that some events are triggered when a javafx ObservableList is modified.
I have tried to to it this way :
#Test
public void handleListChanged() throws Exception {
// [given]
ObservableList<String> list = FXCollections.observableArrayList();
ListChangeListener<String> listener = mock(ListChangeListener.class);
list.addListener(listener);
// [when]
list.add("test");
// [then]
ArgumentCaptor<Change> argument = ArgumentCaptor.forClass(Change.class);
verify(listener).onChanged(argument.capture());
assertTrue(argument.getValue().wasAdded());
}
bu an IllegalStateException raises on the last line :
java.lang.IllegalStateException
at com.sun.javafx.collections.NonIterableChange.checkState(NonIterableChange.java:101)
at com.sun.javafx.collections.NonIterableChange.getPermutation(NonIterableChange.java:81)
at javafx.collections.ListChangeListener$Change.wasPermutated(ListChangeListener.java:156)
at javafx.collections.ListChangeListener$Change.wasAdded(ListChangeListener.java:165)
at FXCollectionsTest.handleListChanged(FXCollectionsTest.java:28
The documentation of the wasAdded() method warns that an IllegalArgumentException could be thrown "if this Change is in initial state" but i don't understand it.
Why my code is not working ?
Is there a solution for testing this code using mockito ?
You must call the next method first on the Change object before you can call any other method like wasAdded.
Unit test
assertTrue(argument.getValue().next());
assertTrue(argument.getValue().wasAdded());
Documentation
public abstract boolean next()
Go to the next change. In initial state is invalid a require a call to next() before calling other methods. The first next() call will make this object represent the first change.
Source

System.Linq.Dynamic .Select("new ...") does not appear to be thread safe

I grabbed System.Linq.Dynamic.DynamicQueryable from here:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
The issue that I am running into is in code that looks like this:
var results = dataContext.GetTable<MyClass>.Select("new (MyClassID, Name, Description)").Take(5);
It appears that if that line of code is executed by multiple threads near simultaneously, Microsoft's dynamic Linq code crashes in their ClassFactory.GetDynamicClass() method, which looks like this:
public Type GetDynamicClass(IEnumerable<DynamicProperty> properties)
{
rwLock.AcquireReaderLock(Timeout.Infinite);
try
{
Signature signature = new Signature(properties);
Type type;
if (!classes.TryGetValue(signature, out type))
{
type = CreateDynamicClass(signature.properties);
classes.Add(signature, type); // <-- crashes over here!
}
return type;
}
finally
{
rwLock.ReleaseReaderLock();
}
}
The crash is a simple dictionary error: "An item with the same key has already been added."
In Ms code, The rwLock variable is a ReadWriterLock class, but it does nothing to block multiple threads from getting inside classes.TryGetValue() if statement, so clearly, the Add will fail.
I can replicate this error pretty easily in any code that creates a two or more threads that try to execute the Select("new") statement.
Anyways, I'm wondering if anyone else has run into this issue, and if there are fixes or workarounds I can implement.
Thanks.
I did the following (requires .NET 4 or later to use System.Collections.Concurrent):
changed the classes field to a ConcurrentDictionary<Signature, Type> ,
removed all the ReaderWriterLock rwLock field and all the code referring to it,
updated GetDynamicClass to:
public Type GetDynamicClass(IEnumerable<DynamicProperty> properties) {
var signature = new Signature(properties);
return classes.GetOrAdd(signature, sig => CreateDynamicClass(sig.properties));
}
removed the classCount field and updated CreateDynamicClass to use classes.Count instead:
Type CreateDynamicClass(DynamicProperty[] properties) {
string typeName = "DynamicClass" + Guid.NewGuid().ToString("N");
...

How do I print a Groovy stack trace?

How do I print a Groovy stack trace? The Java method, Thread.currentThread().getStackTrace() produces a huge stack trace, including a lot of the Groovy internals. I'm seeing a function called twice from a StreamingMarkupBuilder that looks like it should only be called once and I would like to see why Groovy thinks it should be calling it twice.
Solution:
org.codehaus.groovy.runtime.StackTraceUtils.sanitize(new Exception()).printStackTrace()
Original answer:
A Google search returns the following information:
Apparently, there is a method in org.codehaus.groovy.runtime.StackTraceUtils called printSanitizedStackTrace. There isn't much documentation for the method, though there is a method called sanitize which is described as
remove all apparently groovy-internal
trace entries from the exception
instance This modifies the original
instance and returns it, it does not
clone
So I would try org.codehaus.groovy.runtime.StackTraceUtils.printSanitizedStackTrace(Throwable t) (it is static)
and see if that works for you.
I found this questions when searching for "spock print full stack trace".
My unit tests are written in Groovy, using the Spock testing framework and they're run in the context of a Gradle build.
The fix for me was as simple as adding exceptionFormat = 'full' to my Gradle test task specification:
test {
testLogging {
exceptionFormat = 'full'
}
}
I have designed this simple code for stack trace printing, based on artificial simulation of a NullPointerException.
This code produces the same output in both modes: from a Jenkinsfile (Pipeline) and from a normal .groovy script in a command line.
def getStackTrace() {
try {
null.class.toString() // simulate NPE
} catch (NullPointerException e) {
return e.getStackTrace()
}
return null
}
def printStackTrace() {
def stackTraceStr = ""
def callingFuncFound = false
for (StackTraceElement ste : getStackTrace()) {
if (callingFuncFound) {
stackTraceStr += ste.toString() + '\n'
}
if (!callingFuncFound && ste.toString().startsWith(this.class.name + '.printStackTrace(')) {
callingFuncFound = true
}
}
println(stackTraceStr)
}
Some explanations:
The output is concatenated into a single string to avoid being mixed with "[Pipeline] echo" message prefix of Jenkins Pipeline's println()).
The number of "unnecessary" upper stack trace elements related to the NPE is different in Jenkinsfile and in a normal command line. This is why I calculate callingFuncFound and don't use just something like e.getStackTrace()[2..-1] to skip them.

Resources