1// 2// Copyright (C) 2008, 2009, 2010 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 2 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. 13// 14// You should have received a copy of the GNU General Public License 15// 16// along with this program; if not, write to the Free Software 17// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18// 19// Test case for ExternalInterface ActionScript class 20// compile this test case with Ming makeswf, and then 21// execute it like this gnash -1 -r 0 -v out.swf 22 23#include "check.as" 24 25flash.system.Security.allowDomain("localhost"); 26 27ASSetPropFlags (_global, "flash", 0, 5248); 28EI = flash.external.ExternalInterface; 29 30#if OUTPUT_VERSION < 6 // { 31 32check_equals(typeof(EI), 'undefined'); 33 34#else // OUTPUT_VERSION >= 6 }{ 35 36check_equals(typeof(EI), 'function'); 37check(EI.hasOwnProperty('addCallback')); 38check(EI.hasOwnProperty("_argumentsToAS")); 39check(EI.hasOwnProperty("_argumentsToXML")); 40check(EI.hasOwnProperty("_arrayToAS")); 41check(EI.hasOwnProperty("_arrayToJS")); 42check(EI.hasOwnProperty("_arrayToXML")); 43check(EI.hasOwnProperty('available')); 44check(EI.hasOwnProperty('call')); 45check(EI.hasOwnProperty("_callIn")); 46check(EI.hasOwnProperty("_callOut")); 47check(EI.hasOwnProperty("_escapeXML")); 48check(EI.hasOwnProperty("_evalJS")); 49check(EI.hasOwnProperty("_initJS")); 50check(EI.hasOwnProperty("_jsQuoteString")); 51check(EI.hasOwnProperty("_objectID")); 52check(EI.hasOwnProperty("_objectToAS")); 53check(EI.hasOwnProperty("_objectToJS")); 54check(EI.hasOwnProperty("_objectToXML")); 55check(EI.hasOwnProperty("_toAS")); 56check(EI.hasOwnProperty("_toJS")); 57check(EI.hasOwnProperty("_toXML")); 58check(EI.hasOwnProperty("_unescapeXML")); 59check(EI.hasOwnProperty("prototype")); 60check(!EI.hasOwnProperty("marshallExceptions")); 61check(!EI.hasOwnProperty("objectID")); 62// Empty prototype... 63var s = ''; for (var i in EI.prototype) s += i; check_equals(s, ''); 64 65#if OUTPUT_VERSION < 8 // { 66 67xcheck_equals(typeof(EI.addCallback), 'undefined'); 68xcheck_equals(typeof(EI._argumentsToAS), 'undefined'); 69xcheck_equals(typeof(EI._argumentsToXML), 'undefined'); 70xcheck_equals(typeof(EI._arrayToAS), 'undefined'); 71xcheck_equals(typeof(EI._arrayToJS), 'undefined'); 72xcheck_equals(typeof(EI._arrayToXML), 'undefined'); 73check_equals(typeof(EI.available), 'undefined'); 74check_equals(typeof(EI.call), 'function'); 75xcheck_equals(typeof(EI._callIn), 'undefined'); 76check_equals(typeof(EI._callOut), 'undefined'); 77check_equals(typeof(EI._escapeXML), 'undefined'); 78check_equals(typeof(EI._evalJS), 'undefined'); 79check_equals(typeof(EI._initJS), 'undefined'); 80check_equals(typeof(EI._jsQuoteString), 'undefined'); 81check_equals(typeof(EI._objectID), 'undefined'); 82xcheck_equals(typeof(EI._objectToAS), 'undefined'); 83xcheck_equals(typeof(EI._objectToJS), 'undefined'); 84xcheck_equals(typeof(EI._objectToXML), 'undefined'); 85xcheck_equals(typeof(EI._toAS), 'undefined'); 86xcheck_equals(typeof(EI._toJS), 'undefined'); 87xcheck_equals(typeof(EI._toXML), 'undefined'); 88check_equals(typeof(EI._unescapeXML), 'undefined'); 89 90#else // OUTPUT_VERSION >= 8 }{ 91 92check_equals(typeof(EI.addCallback), 'function'); 93check_equals(typeof(EI._argumentsToAS), 'function'); 94check_equals(typeof(EI._argumentsToXML), 'function'); 95check_equals(typeof(EI._arrayToAS), 'function'); 96check_equals(typeof(EI._arrayToJS), 'function'); 97check_equals(typeof(EI._arrayToXML), 'function'); 98check_equals(typeof(EI.available), 'boolean'); 99check_equals(typeof(EI.call), 'function'); 100check_equals(typeof(EI._callIn), 'function'); 101check_equals(typeof(EI._callOut), 'function'); 102check_equals(typeof(EI._escapeXML), 'function'); 103check_equals(typeof(EI._evalJS), 'function'); 104check_equals(typeof(EI._initJS), 'function'); 105check_equals(typeof(EI._jsQuoteString), 'function'); 106check_equals(typeof(EI._objectID), 'function'); 107check_equals(typeof(EI._objectToAS), 'function'); 108check_equals(typeof(EI._objectToJS), 'function'); 109check_equals(typeof(EI._objectToXML), 'function'); 110check_equals(typeof(EI._toAS), 'function'); 111check_equals(typeof(EI._toJS), 'function'); 112check_equals(typeof(EI._toXML), 'function'); 113check_equals(typeof(EI._unescapeXML), 'function'); 114 115// Create a test function for the callback 116function TestASMethod (msg) { 117 note("TestASMethod called! " + msg); 118 return "I am here!"; 119} 120 121// ExternalInterface::available is always false when run standalone, 122// and true if running under a browser and has allowable access to the 123// resource. So we can't have a test case for this property that works 124// both standalone and online Instead we do depend on it being correct 125// as the ExternalInterface::call() tests require this test case to 126// be run under a browser. 127 128// ::call() calls JavaScript functions in the browser, not in flash, 129// so we can't test it when running standalone. So this will always 130// return null unless run from a browser 131 132// This adds a callback that the brower can call from Javascript. This is 133// a bit of a bogus test case, as addCallback() doesn't return anything, but 134// we need to add a method anyway to test being called by Javascript. 135ret = EI.addCallback("TestASMethod", null, TestASMethod); 136check_equals(typeof(ret), 'boolean'); 137check_equals(ret, EI.available); // returns true if available... 138ret = EI.call("TestJSMethod", "test"); 139if ( EI.available ) { 140 check_equals(typeof(ret), 'undefined'); 141} else { 142 check_equals(typeof(ret), 'null'); 143} 144 145// A native class 146nc = Mouse; 147 148// Try instantiating. 149r = new EI; 150// You get an object 151check_equals(typeof(r), 'object'); 152check(r instanceOf EI); 153 154// All methods are class statics, not inherited 155check_equals(typeof(r.addCallback), 'undefined'); 156check_equals(typeof(r._argumentsToAS), 'undefined'); 157check_equals(typeof(r._argumentsToXML), 'undefined'); 158check_equals(typeof(r._arrayToAS), 'undefined'); 159check_equals(typeof(r._arrayToJS), 'undefined'); 160check_equals(typeof(r._arrayToXML), 'undefined'); 161check_equals(typeof(r.available), 'undefined'); 162check_equals(typeof(r.call), 'undefined'); 163check_equals(typeof(r._callIn), 'undefined'); 164check_equals(typeof(r._callOut), 'undefined'); 165check_equals(typeof(r._escapeXML), 'undefined'); 166check_equals(typeof(r._evalJS), 'undefined'); 167check_equals(typeof(r._initJS), 'undefined'); 168check_equals(typeof(r._jsQuoteString), 'undefined'); 169check_equals(typeof(r._objectID), 'undefined'); 170check_equals(typeof(r._objectToAS), 'undefined'); 171check_equals(typeof(r._objectToJS), 'undefined'); 172check_equals(typeof(r._objectToXML), 'undefined'); 173check_equals(typeof(r._toAS), 'undefined'); 174check_equals(typeof(r._toJS), 'undefined'); 175check_equals(typeof(r._toXML), 'undefined'); 176check_equals(typeof(r._unescapeXML), 'undefined'); 177 178xml = EI._objectToXML(nc); 179check_equals (xml, '<object></object>'); 180 181// An object 182o = { a: 1, b: "string" }; 183 184xml = EI._objectToXML(o); 185check_equals (xml, '<object><property id="a"><number>1</number></property><property id="b"><string>string</string></property></object>'); 186 187xml = EI._objectToXML(o, 1, 2, 3); 188check_equals (xml, '<object><property id="a"><number>1</number></property><property id="b"><string>string</string></property></object>'); 189 190// An object with an object reference 191 192o = { o: o }; 193xml = EI._objectToXML(o); 194check_equals (xml, '<object><property id="o"><object><property id="a"><number>1</number></property><property id="b"><string>string</string></property></object></property></object>'); 195 196// An object with circular references 197// (the proprietary player hangs here, we jus don't want to segfault) 198// oc = {}; 199// oc.cr = oc; 200// xml = EI._objectToXML(oc); 201// check_equals (xml, ''); 202 203// An undefined 204 205xml = EI._objectToXML(undefined); 206check_equals (xml, '<object></object>'); 207 208xml = EI._objectToXML(null); 209check_equals (xml, '<object></object>'); 210 211xml = EI._objectToXML(6); 212check_equals (xml, '<object></object>'); 213 214xml = EI._objectToXML(); 215check_equals (xml, '<object></object>'); 216 217// An Array 218anArray = [ 12, "tr", 1 ]; 219anArray.length = 4; 220 221xml = EI._arrayToXML(anArray); 222check_equals (xml, 223'<array><property id="0"><number>12</number></property><property id="1"><string>tr</string></property><property id="2"><number>1</number></property><property id="3"><undefined/></property></array>' 224); 225 226xml = EI._argumentsToXML(anArray); 227check_equals (xml, 228'<arguments><string>tr</string><number>1</number><undefined/></arguments>' 229); 230xml = EI._argumentsToXML(); 231check_equals (xml, '<arguments></arguments>'); 232xml = EI._argumentsToXML(['single']); 233check_equals (xml, '<arguments></arguments>'); 234xml = EI._argumentsToXML('one'); 235check_equals (xml, '<arguments><undefined/><undefined/></arguments>'); 236xml = EI._argumentsToXML(1,2,3); 237check_equals (xml, '<arguments></arguments>'); 238 239// It uses the length property... 240str = "hi"; 241ret = flash.external.ExternalInterface._arrayToXML(str); 242check_equals(ret, '<array><property id="0"><undefined/></property><property id="1"><undefined/></property></array>'); 243 244// xml = EI._toXML(o); 245// if (xml == '<object><property id="a"><number>1</number></property><property id="b"><string>string</string></property></object>') { 246// pass("ExternalInterface::_toXML(object)"); 247// } else { 248// fail("ExternalInterface::_toXML(object)"); 249// } 250 251// xml = EI._toXML("Hello World!"); 252// if (xml == "<string>Hello World!</string>") { 253// pass("ExternalInterface::_toXML(string)"); 254// } else { 255// fail("ExternalInterface::_toXML(string)"); 256// } 257 258xml = EI._toXML(123.456); 259check_equals (xml , "<number>123.456</number>"); 260 261// A native object 262no = new XML; 263 264xml = EI._objectToXML(no); 265xcheck_equals (xml, '<object><property id="namespaceURI"><null/></property><property id="localName"><null/></property><property id="prefix"><null/></property><property id="previousSibling"><null/></property><property id="parentNode"><null/></property><property id="nodeValue"><null/></property><property id="nodeType"><number>1</number></property><property id="nodeName"><null/></property><property id="nextSibling"><null/></property><property id="lastChild"><null/></property><property id="firstChild"><null/></property><property id="childNodes"><array></array></property><property id="attributes"><null/></property><property id="getPrefixForNamespace"><null/></property><property id="getNamespaceForPrefix"><null/></property><property id="toString"><null/></property><property id="hasChildNodes"><null/></property><property id="appendChild"><null/></property><property id="insertBefore"><null/></property><property id="removeNode"><null/></property><property id="cloneNode"><null/></property><property id="xmlDecl"><undefined/></property><property id="status"><number>0</number></property><property id="loaded"><undefined/></property><property id="ignoreWhite"><false/></property><property id="docTypeDecl"><undefined/></property><property id="contentType"><string>application/x-www-form-urlencoded</string></property><property id="addRequestHeader"><null/></property><property id="getBytesTotal"><null/></property><property id="getBytesLoaded"><null/></property><property id="onData"><null/></property><property id="onLoad"><null/></property><property id="sendAndLoad"><null/></property><property id="send"><null/></property><property id="load"><null/></property><property id="parseXML"><null/></property><property id="createTextNode"><null/></property><property id="createElement"><null/></property></object>'); 266 267// xcheck_equals(EI._objectToJS(o), '({a:1,b:"string"})'); 268 269// xcheck_equals(EI._objectToAS(no).toString(), '[object Object]'); 270 271// check_equals(EI._objectID(o), null); 272 273// escape / unescape 274rin = "& ß+ü < << <>''\""; 275rout = "& ß+ü < << <>''""; 276ret = EI._escapeXML(rin); 277check_equals(ret, rout); 278 279// It doesn't escape html entities. 280rin = "& ß+ü < << <>''""; 281rout = "& ß+ü .. < << <>''\""; 282ret = EI._unescapeXML(rin); 283// This test will until fail until we can figure out the best way to 284// match the converted strings. Testing in GDB show the result is correct, 285// so this is mainly a test case problem. 286xcheck_equals (ret, "& ß+ü < << <>''\""); 287 288// This isn't how _toAS works: 289val = EI._toAS("<number>34.56</number>"); 290check_equals (typeof(val), 'undefined'); 291 292val = EI._toAS("<string>Hello World!</string>"); 293check_equals (typeof(val), 'undefined'); 294 295val = EI._toAS("<null/>"); 296check_equals (typeof(val), 'undefined'); 297 298val = EI._toAS("<true/>"); 299check_equals (typeof(val), 'undefined'); 300 301val = EI._toAS("<false/>"); 302check_equals (typeof(val), 'undefined'); 303 304// This is how it works: 305// Note that it's really designed for XMLNodes, but it's quite happy with 306// the faked nodes we're giving it here. 307 308o = {}; 309o.nodeName = "false"; 310check_equals(EI._toAS(o), false); 311 312o = {}; 313o.nodeName = "true"; 314check_equals(EI._toAS(o), true); 315 316o = {}; 317o.nodeName = "number"; 318check_equals(EI._toAS(o).toString(), "NaN"); 319o.firstChild = new String("45"); 320check_equals(EI._toAS(o), 45); 321 322e = {}; 323e.toString = function() { return "23"; }; 324o.firstChild = e; 325check_equals(EI._toAS(o), 23); 326 327// This way doesn't work. 328o = {}; 329o.nodeName = "boolean"; 330check_equals(EI._toAS(o), undefined); 331o.firstChild = new String("false"); 332check_equals(EI._toAS(o), undefined); 333 334o = {}; 335o.nodeName = "null"; 336check_equals(EI._toAS(o), null); 337 338o = {}; 339o.nodeName = "class"; 340o.firstChild = new String("foo"); 341check_equals(EI._toAS(o), undefined); 342 343o.firstChild = new String("Date"); 344check_equals(typeof(EI._toAS(o)), "function"); 345 346val = EI._objectToAS('<object><property id="b"><string>string</string></property><property id="a"><number>1</number></property></object>'); 347xcheck_equals (typeOf(val), 'object'); 348 349// Check what happens with addCallback 350 351// It doesn't add the callback as a member of ExternalInterface. 352o = {}; 353EI.addCallback("func1", o); 354check_equals(EI.func1, undefined); 355 356#endif // version > 7 } 357 358#endif // OUTPUT_VERSION >= 6 } 359 360 361#if OUTPUT_VERSION < 6 // { 362 check_totals(1); 363#elif OUTPUT_VERSION < 8 // }{ 364 check_totals(49); 365#else // SWF8+ }{ 366 check_totals(112); 367# endif // } 368 369