Home | History | Annotate | Download | only in TestNetscapePlugIn
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef PluginTest_h
     27 #define PluginTest_h
     28 
     29 #include <WebKit/npfunctions.h>
     30 #include <assert.h>
     31 #include <map>
     32 #include <string>
     33 
     34 // Helper classes for implementing has_member
     35 typedef char (&no_tag)[1];
     36 typedef char (&yes_tag)[2];
     37 
     38 #define DEFINE_HAS_MEMBER_CHECK(member, returnType, argumentTypes) \
     39 template<typename T, returnType (T::*member) argumentTypes> struct pmf_##member##_helper {}; \
     40 template<typename T> no_tag has_member_##member##_helper(...); \
     41 template<typename T> yes_tag has_member_##member##_helper(pmf_##member##_helper<T, &T::member >*); \
     42 template<typename T> struct has_member_##member { \
     43 static const bool value = sizeof(has_member_##member##_helper<T>(0)) == sizeof(yes_tag); \
     44 };
     45 
     46 DEFINE_HAS_MEMBER_CHECK(hasMethod, bool, (NPIdentifier methodName));
     47 DEFINE_HAS_MEMBER_CHECK(invoke, bool, (NPIdentifier methodName, const NPVariant*, uint32_t, NPVariant* result));
     48 DEFINE_HAS_MEMBER_CHECK(invokeDefault, bool, (const NPVariant*, uint32_t, NPVariant* result));
     49 DEFINE_HAS_MEMBER_CHECK(hasProperty, bool, (NPIdentifier propertyName));
     50 DEFINE_HAS_MEMBER_CHECK(getProperty, bool, (NPIdentifier propertyName, NPVariant* result));
     51 
     52 class PluginTest {
     53 public:
     54     static PluginTest* create(NPP, const std::string& identifier);
     55     virtual ~PluginTest();
     56 
     57     static void NP_Shutdown();
     58 
     59     // NPP functions.
     60     virtual NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved);
     61     virtual NPError NPP_Destroy(NPSavedData**);
     62     virtual NPError NPP_DestroyStream(NPStream* stream, NPReason reason);
     63     virtual NPError NPP_GetValue(NPPVariable, void* value);
     64     virtual NPError NPP_SetWindow(NPP, NPWindow*);
     65     virtual int16_t NPP_HandleEvent(void* event);
     66 
     67     // NPN functions.
     68     NPError NPN_GetURL(const char* url, const char* target);
     69 
     70     void NPN_InvalidateRect(NPRect* invalidRect);
     71     NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name);
     72     NPIdentifier NPN_GetIntIdentifier(int32_t intid);
     73     NPError NPN_GetValue(NPNVariable, void* value);
     74     NPObject* NPN_CreateObject(NPClass*);
     75     bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName);
     76 #ifdef XP_MACOSX
     77     bool NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
     78 #endif
     79 
     80     void executeScript(const char*);
     81     void log(const char* format, ...);
     82 
     83     void registerNPShutdownFunction(void (*)());
     84 
     85     static void indicateTestFailure();
     86 
     87     template<typename TestClassTy> class Register {
     88     public:
     89         Register(const std::string& identifier)
     90         {
     91             registerCreateTestFunction(identifier, Register::create);
     92         }
     93 
     94     private:
     95         static PluginTest* create(NPP npp, const std::string& identifier)
     96         {
     97             return new TestClassTy(npp, identifier);
     98         }
     99     };
    100 
    101 protected:
    102     PluginTest(NPP npp, const std::string& identifier);
    103 
    104     // FIXME: A plug-in test shouldn't need to know about it's NPP. Make this private.
    105     NPP m_npp;
    106 
    107     const std::string& identifier() const { return m_identifier; }
    108 
    109     void waitUntilDone();
    110     void notifyDone();
    111 
    112     // NPObject helper template.
    113     template<typename T> struct Object : NPObject {
    114     public:
    115         static NPObject* create(PluginTest* pluginTest)
    116         {
    117             Object* object = static_cast<Object*>(pluginTest->NPN_CreateObject(npClass()));
    118 
    119             object->m_pluginTest = pluginTest;
    120             return object;
    121         }
    122 
    123         // These should never be called.
    124         bool hasMethod(NPIdentifier methodName)
    125         {
    126             assert(false);
    127             return false;
    128         }
    129 
    130         bool invoke(NPIdentifier methodName, const NPVariant*, uint32_t, NPVariant* result)
    131         {
    132             assert(false);
    133             return false;
    134         }
    135 
    136         bool invokeDefault(const NPVariant*, uint32_t, NPVariant* result)
    137         {
    138             assert(false);
    139             return false;
    140         }
    141 
    142         bool hasProperty(NPIdentifier propertyName)
    143         {
    144             assert(false);
    145             return false;
    146         }
    147 
    148         bool getProperty(NPIdentifier propertyName, NPVariant* result)
    149         {
    150             assert(false);
    151             return false;
    152         }
    153 
    154     protected:
    155         Object()
    156             : m_pluginTest(0)
    157         {
    158         }
    159 
    160         virtual ~Object()
    161         {
    162         }
    163 
    164         PluginTest* pluginTest() const { return m_pluginTest; }
    165 
    166     private:
    167         static NPObject* NP_Allocate(NPP npp, NPClass* aClass)
    168         {
    169             return new T;
    170         }
    171 
    172         static void NP_Deallocate(NPObject* npObject)
    173         {
    174             delete static_cast<T*>(npObject);
    175         }
    176 
    177         static bool NP_HasMethod(NPObject* npObject, NPIdentifier methodName)
    178         {
    179             return static_cast<T*>(npObject)->hasMethod(methodName);
    180         }
    181 
    182         static bool NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
    183         {
    184             return static_cast<T*>(npObject)->invoke(methodName, arguments, argumentCount, result);
    185         }
    186 
    187         static bool NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
    188         {
    189             return static_cast<T*>(npObject)->invokeDefault(arguments, argumentCount, result);
    190         }
    191 
    192         static bool NP_HasProperty(NPObject* npObject, NPIdentifier propertyName)
    193         {
    194             return static_cast<T*>(npObject)->hasProperty(propertyName);
    195         }
    196 
    197         static bool NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result)
    198         {
    199             return static_cast<T*>(npObject)->getProperty(propertyName, result);
    200         }
    201 
    202         static NPClass* npClass()
    203         {
    204             static NPClass npClass = {
    205                 NP_CLASS_STRUCT_VERSION,
    206                 NP_Allocate,
    207                 NP_Deallocate,
    208                 0, // NPClass::invalidate
    209                 has_member_hasMethod<T>::value ? NP_HasMethod : 0,
    210                 has_member_invoke<T>::value ? NP_Invoke : 0,
    211                 has_member_invokeDefault<T>::value ? NP_InvokeDefault : 0,
    212                 has_member_hasProperty<T>::value ? NP_HasProperty : 0,
    213                 has_member_getProperty<T>::value ? NP_GetProperty : 0,
    214                 0, // NPClass::setProperty
    215                 0, // NPClass::removeProperty
    216                 0, // NPClass::enumerate
    217                 0  // NPClass::construct
    218             };
    219 
    220             return &npClass;
    221         };
    222 
    223         PluginTest* m_pluginTest;
    224     };
    225 
    226 private:
    227     typedef PluginTest* (*CreateTestFunction)(NPP, const std::string&);
    228 
    229     static void registerCreateTestFunction(const std::string&, CreateTestFunction);
    230     static std::map<std::string, CreateTestFunction>& createTestFunctions();
    231 
    232     std::string m_identifier;
    233 };
    234 
    235 #endif // PluginTest_h
    236