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 DPP-Devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dpp-devel