big merge from master, fix rpm creation, drop fetching swfdec
[gnash.git] / plugin / npapi / test.cpp
blobeaa4b9cedfbef211c11a518d69c023b49d21f0b2
1 //
2 // Copyright (C) 2010, 2011 Free Software Foundation, Inc
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 #ifdef HAVE_CONFIG_H
19 #include "gnashconfig.h"
20 #endif
22 #include <iostream>
23 #include <string>
24 #include <cstdlib>
25 #include <vector>
26 #include <map>
27 #include <cassert>
28 #include <memory>
30 #if NPAPI_VERSION == 190
31 #include "npupp.h"
32 #else
33 #include "npapi.h"
34 #include "npruntime.h"
35 #include "npfunctions.h"
36 #endif
37 #include "pluginbase.h"
38 #include "dejagnu.h"
39 #include "../../testsuite/check.h"
40 #include <regex.h>
42 #include "external.h"
43 #include "GnashNPVariant.h"
45 TestState& runtest = _runtest;
47 std::map<NPIdentifier, NPVariant *> _properties;
48 std::map<NPIdentifier, NPInvokeFunctionPtr> _methods;
50 int
51 main(int , char **)
53 using namespace gnash;
55 NPVariant *value = (NPVariant *)NPN_MemAlloc(sizeof(NPVariant));
57 BOOLEAN_TO_NPVARIANT(true, *value);
58 std::string str = plugin::ExternalInterface::convertNPVariant(value);
59 if (str == "<true/>") {
60 runtest.pass("convertNPVariant(true)");
61 } else {
62 runtest.fail("convertNPVariant(true)");
65 BOOLEAN_TO_NPVARIANT(false, *value);
66 str = plugin::ExternalInterface::convertNPVariant(value);
67 if (str == "<false/>") {
68 runtest.pass("convertNPVariant(false)");
69 } else {
70 runtest.fail("convertNPVariant(false)");
73 NULL_TO_NPVARIANT(*value);
74 str = plugin::ExternalInterface::convertNPVariant(value);
75 if (str == "<null/>") {
76 runtest.pass("convertNPVariant(null)");
77 } else {
78 runtest.fail("convertNPVariant(null)");
81 VOID_TO_NPVARIANT(*value);
82 str = plugin::ExternalInterface::convertNPVariant(value);
83 if (str == "<void/>") {
84 runtest.pass("convertNPVariant(void)");
85 } else {
86 runtest.fail("convertNPVariant(void)");
89 DOUBLE_TO_NPVARIANT(123.456, *value);
90 str = plugin::ExternalInterface::convertNPVariant(value);
91 if (str == "<number>123.456</number>") {
92 runtest.pass("convertNPVariant(double)");
93 } else {
94 runtest.fail("convertNPVariant(double)");
97 INT32_TO_NPVARIANT(78, *value);
98 str = plugin::ExternalInterface::convertNPVariant(value);
99 if (str == "<number>78</number>") {
100 runtest.pass("convertNPVariant(int32)");
101 } else {
102 runtest.fail("convertNPVariant(int32)");
105 STRINGZ_TO_NPVARIANT("Hello World!", *value);
106 str = plugin::ExternalInterface::convertNPVariant(value);
107 if (str == "<string>Hello World!</string>") {
108 runtest.pass("convertNPVariant(string)");
109 } else {
110 runtest.fail("convertNPVariant(string)");
113 str = plugin::ExternalInterface::makeProperty("hi", "Hello World!");
114 if (str == "<property id=\"hi\">Hello World!</property>") {
115 runtest.pass("plugin::ExternalInterface::makeProperty()");
116 } else {
117 runtest.fail("plugin::ExternalInterface::makeProperty()");
120 #if 0
121 ARRAY_TO_NPVARIANT(*value);
122 str = plugin::ExternalInterface::convertNPVariant(value);
123 if (str == "<array></array>") {
124 runtest.pass("convertNPVariant(array)");
125 } else {
126 runtest.fail("convertNPVariant(array)");
128 #endif
130 std::string prop1 = plugin::ExternalInterface::makeString("foobar");
131 std::string prop2 = plugin::ExternalInterface::makeNumber(12.34);
132 std::string prop3 = plugin::ExternalInterface::makeNumber(56);
133 std::vector<std::string> aargs;
134 aargs.push_back(prop1);
135 aargs.push_back(prop2);
136 aargs.push_back(prop3);
138 regex_t regex_pat;
139 regcomp (&regex_pat, "<array><property id=\"0\"><string>foobar</string></property><property id=\"1\"><number>12.34</number></property><property id=\"2\"><number>56</number></property></array>", REG_NOSUB|REG_NEWLINE);
140 str = plugin::ExternalInterface::makeArray(aargs);
141 if (regexec (&regex_pat, reinterpret_cast<const char*>(str.c_str()), 0, (regmatch_t *)0, 0)) {
142 runtest.fail("plugin::ExternalInterface::makeArray()");
143 } else {
144 runtest.pass("plugin::ExternalInterface::makeArray()");
147 std::map<std::string, std::string> margs;
148 margs["test1"] = prop1;
149 margs["test2"] = prop2;
150 margs["test3"] = prop3;
152 str = plugin::ExternalInterface::makeObject(margs);
153 std::string xml = "<object><property id=\"test1\"><string>foobar</string></property><property id=\"test2\"><number>12.34</number></property><property id=\"test3\"><number>56</number></property></object>";
155 regfree (&regex_pat);
156 regcomp (&regex_pat, xml.c_str(), REG_NOSUB|REG_NEWLINE);
158 // std::cout << str << std::endl;
159 if (regexec (&regex_pat, reinterpret_cast<const char*>(str.c_str()), 0, (regmatch_t *)0, 0)) {
160 runtest.fail("plugin::ExternalInterface::makeObject()");
161 } else {
162 runtest.pass("plugin::ExternalInterface::makeObject()");
166 // Parsing tests
168 xml = "<string>Hello World!</string>";
169 GnashNPVariant np = plugin::ExternalInterface::parseXML(xml);
170 std::string data = NPStringToString(NPVARIANT_TO_STRING(np.get()));
171 if (NPVARIANT_IS_STRING(np.get()) &&
172 (data == "Hello World!")) {
173 runtest.pass("plugin::ExternalInterface::parseXML(string)");
174 } else {
175 runtest.fail("plugin::ExternalInterface::parseXML(string)");
178 xml = "<number>123.456</number>";
179 np = plugin::ExternalInterface::parseXML(xml);
180 double num = NPVARIANT_TO_DOUBLE(np.get());
181 if (NPVARIANT_IS_DOUBLE(np.get()) &&
182 (num == 123.456)) {
183 runtest.pass("plugin::ExternalInterface::parseXML(double)");
184 } else {
185 runtest.fail("plugin::ExternalInterface::parseXML(double)");
188 xml = "<number>78</number>";
189 np = plugin::ExternalInterface::parseXML(xml);
190 int inum = NPVARIANT_TO_INT32(np.get());
191 if (NPVARIANT_IS_INT32(np.get()) &&
192 (inum == 78)) {
193 runtest.pass("plugin::ExternalInterface::parseXML(int32)");
194 } else {
195 runtest.fail("plugin::ExternalInterface::parseXML(int32)");
198 xml = "<true/>";
199 np = plugin::ExternalInterface::parseXML(xml);
200 bool flag = NPVARIANT_TO_BOOLEAN(np.get());
201 if (NPVARIANT_IS_BOOLEAN(np.get()) &&
202 (flag == true)) {
203 runtest.pass("plugin::ExternalInterface::parseXML(true)");
204 } else {
205 runtest.fail("plugin::ExternalInterface::parseXML(true)");
208 xml = "<false/>";
209 np = plugin::ExternalInterface::parseXML(xml);
210 flag = NPVARIANT_TO_BOOLEAN(np.get());
211 if (NPVARIANT_IS_BOOLEAN(np.get()) &&
212 (flag == false)) {
213 runtest.pass("plugin::ExternalInterface::parseXML(false)");
214 } else {
215 runtest.fail("plugin::ExternalInterface::parseXML(false)");
218 xml = "<null/>";
219 np = plugin::ExternalInterface::parseXML(xml);
220 if (NPVARIANT_IS_NULL(np.get())) {
221 runtest.pass("plugin::ExternalInterface::parseXML(null)");
222 } else {
223 runtest.fail("plugin::ExternalInterface::parseXML(null)");
226 xml = "<void/>";
227 np = plugin::ExternalInterface::parseXML(xml);
228 if (NPVARIANT_IS_VOID(np.get())) {
229 runtest.pass("plugin::ExternalInterface::parseXML(void)");
230 } else {
231 runtest.fail("plugin::ExternalInterface::parseXML(void)");
234 xml = "<property id=\"0\"><string>foobar</string></property><property id=\"1\"><number>12.34</number></property><property id=\"2\"><number>56</number></property>";
235 std::map<std::string, GnashNPVariant> props = plugin::ExternalInterface::parseProperties(xml);
236 np = props["0"];
237 data = NPStringToString(NPVARIANT_TO_STRING(np.get()));
238 if ((props.size() == 3) && (data == "foobar")) {
239 runtest.pass("plugin::ExternalInterface::parseProperties()");
240 } else {
241 runtest.fail("plugin::ExternalInterface::parseProperties()");
244 xml = "<object><property id=\"test1\"><string>foobar</string></property><property id=\"test2\"><number>12.34</number></property><property id=\"test3\"><number>56</number></property></object>";
245 np = plugin::ExternalInterface::parseXML(xml);
246 if (NPVARIANT_IS_OBJECT(np.get())) {
247 runtest.pass("plugin::ExternalInterface::parseXML(object)");
248 } else {
249 runtest.fail("plugin::ExternalInterface::parseXML(object)");
252 std::vector<std::string> iargs;
253 str = plugin::ExternalInterface::makeString("barfoo");
254 iargs.push_back(str);
255 str = plugin::ExternalInterface::makeNumber(135.78);
256 iargs.push_back(str);
258 str = plugin::ExternalInterface::makeInvoke("barbyfoo", iargs);
259 xml = "<invoke name=\"barbyfoo\" returntype=\"xml\"><arguments><string>barfoo</string><number>135.78</number></arguments></invoke>";
260 // std::cout << str << std::endl;
261 regfree (&regex_pat);
262 regcomp (&regex_pat, xml.c_str(), REG_NOSUB|REG_NEWLINE);
263 if (regexec (&regex_pat, reinterpret_cast<const char*>(str.c_str()), 0, (regmatch_t *)0, 0) == 0) {
264 runtest.pass("plugin::ExternalInterface::makeInvoke()");
265 } else {
266 runtest.fail("plugin::ExternalInterface::makeInvoke()");
269 xml = "<arguments><string>barfoo</string><number>135.78</number><number>89</number></arguments>";
270 std::vector<GnashNPVariant> arguments = plugin::ExternalInterface::parseArguments(xml);
271 np = arguments[0];
272 str = NPStringToString(NPVARIANT_TO_STRING(np.get()));
273 double dub = NPVARIANT_TO_DOUBLE(arguments[1].get());
274 int val = NPVARIANT_TO_INT32(arguments[2].get());
275 if ((arguments.size() == 3) && (str == "barfoo")
276 && (dub == 135.78) && (val == 89)) {
277 runtest.pass("plugin::ExternalInterface::parseArguments()");
278 } else {
279 runtest.fail("plugin::ExternalInterface::parseArguments()");
282 // Parse an invoke message
283 xml = "<invoke name=\"barbyfoo\" returntype=\"xml\"><arguments><string>barfoo</string><number>135.78</number></arguments></invoke>";
284 boost::shared_ptr<plugin::ExternalInterface::invoke_t> invoke ( plugin::ExternalInterface::parseInvoke(xml) );
285 str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[0].get()));
286 if ((invoke->name == "barbyfoo") && (invoke->type == "xml")
287 && (NPVARIANT_IS_STRING(invoke->args[0].get()))
288 && (str == "barfoo")
289 && (NPVARIANT_IS_DOUBLE(invoke->args[1].get()))
290 && (NPVARIANT_TO_DOUBLE(invoke->args[1].get()) == 135.78)
292 runtest.pass("plugin::ExternalInterface::parseInvoke()");
293 } else {
294 runtest.fail("plugin::ExternalInterface::parseInvoke()");
297 // Test for bug #31766
298 xml = "<invoke name=\"reportFlashTiming\" returntype=\"xml\"><arguments><string>reportFlashTiming</string><object><property id=\"5\"><number>1297286708921</number></property><property id=\"4\"><string>vr</string></p";
299 invoke = plugin::ExternalInterface::parseInvoke(xml);
300 if ((invoke->name == "reportFlashTiming") && (invoke->type == "xml")
301 && invoke->args.empty())
303 runtest.pass("plugin::ExternalInterface::parseInvoke() with missing closing invoke tag");
304 } else {
305 runtest.fail("plugin::ExternalInterface::parseInvoke() with missing closing invoke tag");
309 xml = "<invoke name=\"reportFlashTiming\" returntype=\"xml\"><arguments><string>reportFlashTiming</string><object><property id=\"5\"><number>1297326407594</number></property><property id=\"4\"><string>vr</string></property><property id=\"3\"><number>1297326407147</number></property><property id=\"2\"><string>gv</string></property><property id=\"1\"><number>1297326406281</number></property><property id=\"0\"><string>fs</string></property></object><string>34</string><number>2</number><string>AASb6VeOkQtvnu_8</string><string>0</string><string>LNX%2010%2C1%2C999%2C0</string><string>Gnash%20GNU%2FLinux</string></arguments></invoke>";
310 invoke = plugin::ExternalInterface::parseInvoke(xml);
311 check_equals (invoke->name, "reportFlashTiming");
312 check_equals (invoke->type, "xml");
313 xcheck_equals (invoke->args.size(), 8);
315 check(NPVARIANT_IS_STRING(invoke->args[0].get()));
316 str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[0].get()));
317 check_equals(str, "reportFlashTiming");
319 xcheck(NPVARIANT_IS_OBJECT(invoke->args[1].get()));
320 // TODO: check object contents
322 xcheck(NPVARIANT_IS_STRING(invoke->args[2].get()));
323 // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[2].get()));
324 // check_equals(str, "34");
326 xcheck(NPVARIANT_IS_DOUBLE(invoke->args[3].get()));
327 // check_equals(NPVARIANT_TO_DOUBLE(invoke->args[3].get()), 2);
329 check(NPVARIANT_IS_STRING(invoke->args[4].get()));
330 str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[4].get()));
331 xcheck_equals(str, "AASb6VeOkQtvnu_8");
333 xcheck(NPVARIANT_IS_STRING(invoke->args[5].get()));
334 // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[5].get()));
335 // check_equals(str, "0");
337 xcheck(NPVARIANT_IS_STRING(invoke->args[6].get()));
338 // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[6].get()));
339 // check_equals(str, "LNX%2010%2C1%2C999%2C0");
341 xcheck(NPVARIANT_IS_STRING(invoke->args[7].get()));
342 // str = NPStringToString(NPVARIANT_TO_STRING(invoke->args[7].get()));
343 // check_equals(str, "Gnash%20GNU%2FLinux");
347 xml = "<object><property id=\"5\">";
348 GnashNPVariant v = plugin::ExternalInterface::parseXML(xml);
349 check(NPVARIANT_IS_NULL(v.get()));
353 NPVariant val;
354 NULL_TO_NPVARIANT(val);
355 check(NPVARIANT_IS_NULL(val));
356 GnashNPVariant v = val;
357 check(NPVARIANT_IS_NULL(v.get()));
360 regfree (&regex_pat);
361 NPN_MemFree(value);
364 // We have to implement these two memory allocation functions as
365 // they're used in the code we're testing.
366 void *
367 NPN_MemAlloc(uint32_t size)
369 void * rv = NULL;
370 rv = malloc(size);
371 return rv;
374 void
375 NPN_MemFree(void* ptr)
377 assert(ptr);
378 free(ptr);
381 // These are just stubs to get the test case to link standalone.
382 NPIdentifier
383 NPN_GetStringIdentifier(const NPUTF8 *)
385 return 0;
388 nsPluginInstanceBase *
389 NS_NewPluginInstance(nsPluginCreateData *)
391 return NULL;
394 NPError
395 NS_PluginGetValue(NPPVariable, void *)
397 return NPERR_INVALID_INSTANCE_ERROR;
400 NPError
401 NS_PluginInitialize()
403 return NPERR_INVALID_INSTANCE_ERROR;
406 void
407 NS_PluginShutdown()
411 char*
412 NPP_GetMIMEDescription(void)
414 char *x = 0;
415 return x;
418 void
419 NS_DestroyPluginInstance(nsPluginInstanceBase *)
423 // Implement minimal properties handling
424 bool
425 NPN_SetProperty(NPP, NPObject*, NPIdentifier name,
426 const NPVariant *value)
428 _properties[name] = const_cast<NPVariant *>(value);
429 return true;
432 bool
433 NPN_GetProperty(NPP, NPObject* , NPIdentifier name,
434 const NPVariant *value)
436 std::map<NPIdentifier, NPVariant *>::iterator it;
437 it = _properties.find(name);
438 if (it == _properties.end()) return false;
439 value = it->second;
440 return true;
443 bool
444 NPN_HasProperty(NPP , NPObject* , NPIdentifier name)
446 std::map<NPIdentifier, NPVariant *>::iterator it;
447 it = _properties.find(name);
448 if (it != _properties.end()) {
449 return true;
451 return false;
454 void
455 NPN_ReleaseVariantValue(NPVariant *variant)
457 switch(variant->type) {
458 case NPVariantType_String:
460 NPN_MemFree(const_cast<NPUTF8*>(gnash::GetNPStringChars(NPVARIANT_TO_STRING(*variant))));
461 break;
463 case NPVariantType_Object:
465 NPObject* obj = NPVARIANT_TO_OBJECT(*variant);
466 if (obj) {
467 NPN_ReleaseObject(obj);
469 break;
471 default:
475 NULL_TO_NPVARIANT(*variant);
478 NPObject*
479 NPN_RetainObject(NPObject *obj)
480 { assert(obj); ++obj->referenceCount; return obj; }
483 void
484 NPN_ReleaseObject(NPObject *npobj)
486 assert(npobj);
487 --npobj->referenceCount;
488 if (npobj->referenceCount == 0) {
489 NPN_MemFree(npobj);
492 // Local Variables:
493 // mode: C++
494 // indent-tabs-mode: nil
495 // End: