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

Reply via email to