Hi there,
I'm currently trying to write a few test cases for the browser functions [1].
So far, I only introduced generic signature checks for all functions
(because from the Java perspective, all browser functions look the same, but
they still expect correctly typed input from the JavaScript world).
It looks like this:
----
@Signature({ @Argument(String.class), @Argument(String.class) })
public class AddContact extends JavascriptFunction {
// ...
@Override
public Object function(final Object[] arguments) {
// some logic that expects 'arguments' to consist of two
// Strings
}
}
----
Both @Signature and @Argument are newly introduced annotations that can be
evaluated by the test cases (and also by Matthias' ValidationUtils).
A signature checking test case looks like this:
----
public class AddContactTest extends AbstractBrowserFunctionTest {
// ...
@Test
public void testSignature() {
validateSignature(AddContact.class, new AddContact(mockedStateFacade));
}
}
----
That's it.
The method AbstractBrowserFunctionTest.validateSignature() looks for the
@Signature annotation of the class under test, extracts the @Arguments,
constructs an Object array of matching dummy objects (in the above case it
would be {"foo", "foo"} because of two String arguments), and calls the
'function(Object[])' method with this array.
Since not all browser functions use plain Strings, there are other
@Signatures as well, e.g.
* ConnectAccount:
@Signature({ @Argument(Account.class) })
* SendInvitation:
@Signature({ @Argument(ProjectTree[].class), @Argument(Contact[].class) })
I already implemented dummy objects for the signature tests for Account.class
and Contact[].class.
I struggling, however, with the ProjectTree[].class -- and this finally leads
to the actual question of this e-mail.
I encountered two problems while implementing a dummy ProjectTree[] to test
the browser function "SendInvitation".
(1) I used the ProjectListManager to retrieve the project model from a simple,
mocked workspace: With EasyMock, I created an IWorkspaceRoot with only
one IProject underneath, which in turn is empty (i.e. empty array on
'members()').
I was able to retrieve the project model by calling
"createAndMapProjectModels"
and "getProjectModels" on the ProjectListManager.
But as soon as I handed the result over to GSON, I got an
StackOverflowError,
usually indicating a circular reference.
I was not able to find such a circular reference in the ProjectTree and
ProjectTreeNode classes (which make up the "project models").
Therefore I changed the GSON configuration so it does only consider fields
with the "@Expose" annotation, and started with an empty serialization, as
no field currently has this annotation.
I annotated the fields of ProjectTree and ProjectTreeNode one by one to find
the field that leads to the StackOverflow on serialization.
Guess what: After I annotated *all* fields with @Expose, the serialization
still worked fine, and I still don't know why it doesn't work when I don't
exclude unexposed fields.
But I chose to ignore that issue, as the @Expose annotations are not too
expensive, so this problem can be considered "somewhat solved".
(2) The second problem still bugs me: Upon deserialization (from JSON back to
Java objects), GSON naturally needs to create instances for the
non-primitive
fields of the classes. In the case of ProjectTree these non-primitive fields
are 'root' (of type ProjectTreeNode) and 'displayName' (of type String).
GSON can handle that easily.
But for ProjectTreeNode, there is a field 'path' of type IPath, which, of
course, has no ctor as it's an interface.
Consequently, GSON prompts the following error:
"java.lang.RuntimeException: Unable to invoke no-args constructor for
interface
de.fu_berlin.inf.dpp.filesystem.IPath. Register an InstanceCreator with
Gson
for this type may fix this problem."
Using an InstanceCreator sounds like a solution for this problem (I didn't
try
it yet), but I cannot help but ask:
Has actually *no one* *ever* tried to call the SendInvitation browser
function
yet?
Because if s/he had, s/he must have stumbled upon the same problem: IPath
cannot be instantiated!
Any comments (including the @Signature approach mentioned in the beginning) are
appreciated.
Cheers,
Franz
[1]
https://github.com/saros-project/saros/tree/master/de.fu_berlin.inf.dpp.ui/src/de/fu_berlin/inf/dpp/ui/browser_functions
------------------------------------------------------------------------------
Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
http://pubads.g.doubleclick.net/gampad/clk?id=278785351&iu=/4140
_______________________________________________
DPP-Devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dpp-devel