1
<chapter id="internals">
2
<title>Software Internals</title>
5
<title>A Tour of Gnash</title>
8
The top level of Gnash has several libraries, <emphasis>libgnashbase</emphasis>,
9
<emphasis>libgnashserver</emphasis>,
10
<emphasis>libgnashmedia</emphasis>,
11
<emphasis>libgnashamf</emphasis> and
12
<emphasis>libgnashbackend</emphasis>. There are several utility programs
13
included for debug parsing and processing of SWF movie files,
14
and other useful utilities for examining local Shared Objects and
15
sniffing LocalConnections.
18
<sect2 id="The Libraries">
19
<title>The Libraries</title>
22
<title>libgnashbase</title>
25
Libgnashbase contains support classes used by the rest of the
26
code.This library has no dependencies on any of the other
31
&app; makes heavy use of smart pointers, so memory allocations
32
are freed up automatically by the interpreter. Both STL and
33
Boost smart pointers are used.
37
<sect3 id="libgnashserver">
38
<title>libgnashserver</title>
40
Libgnashserver is the guts of the interpreter itself. This is where
41
the main code for the interpreter lives. Includes in
42
libserver are the two support libraries for the parser and
43
the core of the virtual machine.
47
<sect3 id="libgnashmedia">
48
<title>libgnashmedia</title>
50
Libgnashmedia handles Gnash's audio and video capabilities,
51
dealing with streamed video and sound as well as decoding
52
embedded media frames. Besides the standard SWF formats
53
FLV, MPEG4, Nellymoser, ADPCM, MP3 and RAW, &app; can
54
decode other formats supports by gstreamer or ffmpeg,
55
including the free OGG container and free codecs.
59
<sect3 id="libgnashamf">
60
<title>libgnashamf</title>
62
AMF is the data format used internally by SWF files. This is
63
Gnash's support library to handle AMF data. This is used by
64
the ActionScript classes SharedObject and
65
LocalConnection. This is also used by the NetStream class
66
when using thre RTMP streaming network protocol.
70
<sect3 id="libgnashbackend">
71
<title>libgnashbackend</title>
74
Libgnashbackend is a library containing the rendering
75
code that glues this display to the Gnash. Supported
76
rendering backends are OpenGL, Cairo, and AGG.
80
<sect3 id="libgnashpluin">
81
<title>libgnashplugin</title>
84
Libgnashplugin is the Mozilla/Firefox plugin.
88
<sect3 id="libklashpart">
89
<title>libklashpart</title>
92
Libklashpart is the Konqueror plugin.
99
<title>The Applications</title>
102
There are currently a few standalone programs in Gnash,
103
which serve either to assist with Gnash development or to play SWF
108
<title>The Standalone Player</title>
111
This is the standalone OpenGL backend used to play
112
movies. There are several command line options and keyboard
113
control keys used by Gnash.
118
<sect3 id="processor">
119
<title>Gprocessor</title>
122
Gprocessor is used to print out the actions (using the -va
123
option) or the parsing (using the -vp option) of a SWF
124
movie. It is also used to produce the <emphasis>.gsc</emphasis>
125
files that Gnash uses to cache data, thereby speeding up the
130
<sect3 id="soldumper">
131
<title>SOLdumper</title>
134
SOLDumper is a utility program used to find and dump the
135
content of <emphasis>Local Shared Objects</emphasis>, also
136
called "Flash Cookies" by some.
141
<title>Dumpshm</title>
144
Dumpshm is a program used to find and dump the contents of
145
the <emphasis>LocalConnection</emphasis> shared memory segment.
152
<title>The Plugin</title>
155
The plugin is designed to work within Mozilla or Firefox,
156
although there is Konqueror support as well. The plugin uses
157
the Mozilla plugin API (NPAPI) to be cross platform, and is
158
portable, as well as being well integrated into Mozilla based
162
<sect3 id="pluginstatus">
163
<title>Current Implementation</title>
165
The plugin works in a
166
fashion similar to MozPlugger: the standalone player
167
is used instead of using a thread. This gets around the
168
issue of having to maintain a separate player to support the
169
plugin. It also gets around the other issues that Gnash
170
itself is not thread safe at this time.
173
As of Jan, 2007, streaming video, ala "YouTube"
174
works, along with other video sharing sites.
179
<title>GUI Support</title>
182
Any plugin that wants to display in a browser window needs
183
to be tied into the windowing system of the platform being
184
used. On GNU/Linux systems, Firefox is a GTK2+ application.
185
There is also KDE support through the use of the Klash
190
Gnash can use either several different GUI toolkits to create the window,
191
and to handle events for the standalone player.
195
The SDL version is more limited, but runs on all
196
platforms, including win32. It has no support for event
197
handling, which means mouse clicks, keyboard presses, and
198
window resizing doesn't work. I personally find the default
199
event handler slow and unresponsive. Gnash has support to
200
use fast events, (currently not enabled) which is an SDL
201
hack using a background thread to pump events into the SDL
202
event queue at a much higher rate.
206
There are a variety of development libraries that build a GUI
207
widget system on top of SDL and OpenGL. The use of these to
208
add menus and dialog boxes to the SDL version is being
213
The GTK support is currently the most functional, and the
214
best integrated into Firefox. The performance of this
215
version is better than the SDL version because of the more
216
efficient event handling within GTK. For the best end user
217
experience, use the GTK enabled version.
221
GTK also allows Gnash to have menus and dialog
222
boxes. Currently this is only being utilized in a limited
223
fashion for now. There is a right mouse button menu that
224
allows the user to control the movie being player the same
225
way the existing keyboard commands do.
230
<sect3 id="mozplugger">
231
<title>Mozplugger</title>
235
url="http://mozplugger.mozdev.org/">Mozplugger</ulink> is a
236
<emphasis>Mozilla/Firefox</emphasis> plugin that uses external
237
programs to play video, audio, and other multimedia content
238
in the browser. With some support added to the external
239
application, it's possible to force the external program to
240
use the internal window in the browser where this plugin is
241
supposed to display. This enables one to then run the
242
standalone player and display its output in the browser.
246
While this is not an optimal solution, it does enable one to
247
use Gnash as the SWF player when browsing. The main issue
248
appears to be that the SWF movie being played doesn't get
249
any mouse or keyboard input. That may be a mozplugger
250
configuration issue, however.
254
Use of MozPlugger is obsolete now that the Gnash plugin
255
works. Still, this may be useful still on some platforms.
259
Add this to your <emphasis>$(HOME)/.mozilla/mozpluggerrc</emphasis>
263
application/x-shockwave-flash:swf:Shockwave Gnash
264
nokill embed noisy ignore_errors hidden fill swallow(Gnash) loop: gnash -v "$file" -x $window
265
: gnash -v "$file" -x $window
270
Once this is added, you must delete the
271
<emphasis>$(HOME)/.mozilla/firefox/pluginreg.dat</emphasis> file to
272
force Firefox to register the plugins again. This is an
273
ASCII text file, so if the patch has been added correctly,
274
you'll see an entry for <emphasis>swf</emphasis> files after it is
275
recreated. You will need to restart Firefox to recreate this
280
This file is not recreated immediately when restarting
281
Firefox, but waits till the first time a plugin is used. You
282
can force creation of this file by typing
283
<emphasis>about:plugins</emphasis> into the URL entry of the browser
284
window. The output will also contain information about the
285
mozplugger. You should see an entry for Gnash now.
293
Klash is MozPlugger type support for KDE's Konqueror web
294
browser. Klash makes Gnash a <emphasis>kpart</emphasis>, so it's
295
integrated into KDE better than when using MozPlugger. Klash
296
uses the standalone player, utilizing Gnash's "-x" window
297
plugin command line option.
301
By default, Klash is not built. To enable building Klash,
302
use the <emphasis>--enable-klash</emphasis> option when
303
configuring. Other than installing, there is nothing else
304
that needs to be done to install Klash.
314
<sect1 id="soundhandlers">
315
<title>Sound handling in Gnash</title>
318
When a SWF-file contains audio Gnash uses its sound handlers to play it.
319
At the moment there are two sound handlers, but it is likely that more
324
There are two different settings related to sound support:
325
<emphasis>pluginsound</emphasis> and <emphasis>sound</emphasis>.
326
This was done in order to allow the plugin to be independently
327
configured, for instance to block sound from advertisements.
330
<sect2 id="soundtypes">
331
<title>Sound types</title>
333
Sounds can be divided into two groups: event-sounds and soundstreams.
334
Event-sounds are contained in a single SWF frame, but the playtime can
335
span multiple frames. Soundstreams can be (and normally are) divided
336
between the SWF frames the soundstreams spans. This means that if a
337
gotoframe-action jumps to a frame which contains data for a soundstream,
338
playback of the stream can be picked up from there.
342
<sect2 id="soundparsing">
343
<title>Sound parsing</title>
345
When Gnash parses a SWF-file, it creates a sound handler if possible
346
and hands over the sounds to it. Since the event-sounds are contained
347
in one frame, the entire event-sound is retrieved at once, while a
348
soundstream maybe not be completely retrieved before the entire
349
SWF-file has been parsed. But since the entire soundstream doesn't need
350
to be present when playback starts, it is not necessary to wait.
354
<sect2 id="soundplayback">
355
<title>Sound playback</title>
357
When a sound is about to be played Gnash calls the sound handler, which
358
then starts to play the sound and return. All the playing is done by
359
threads (in both SDL and Gstreamer), so once
360
started the audio and graphics are not sync'ed with each other, which
361
means that we have to trust both the graphic backend and the audio
362
backend to play at correct speed.
366
<sect2 id="sdlsound">
367
<title>The SDL sound backend</title>
369
The current SDL sound backend has replaced the original sound
370
handler, based on SDL_mixer, which by design had some limitations,
371
making it difficult to implement needed features such as support
373
The SDL sound backend supports both event-sounds and soundstreams,
374
using Gnash's internal ADPCM, and optionally MP3 support, using
376
When it receives sound data it is stored without being decoded, unless
377
it is ADPCM, which is decoded in the parser. When playing, backend
378
relies on a function callback for retrieving output sound, which is
379
decoded and re-sampled if needed, and all sound output is mixed together.
380
The current SDL sound backend was made since Gnash needed a working
381
sound backend as soon as possible, and since the gstreamer backend at
382
the time suffered from bugs and/or lack of features in gstreamer. The
383
result was the most complete and best sound handler so far.
384
The advantages of the SDL sound handler is speed, and ease of use,
385
while its only real disadvantage is that it has to be compiled with
386
MP3 support, which some Linux distributions will probably not like...
390
<sect2 id="gstreamer">
391
<title>The Gstreamer backend</title>
393
The Gstreamer backend, though not complete, supports both soundstreams
394
and event-sounds. When receiving sound data it stores it compressed,
395
unless if it's ADPCM event-sounds, which it decodes by the parser.
396
When the playback starts, the backend sets up a
397
Gstreamer bin containing a decoder (and other things needed) and places
398
it in a Gstreamer pipeline, which plays the audio. All the sound data is
399
not passed at once, but in small chunks, and via callbacks the
400
pipeline gets fed. The advantages of the Gstreamer backend is that it
401
supports both kinds of sound, it avoids all the legal MP3-stuff, and it
402
should be relatively easy to add VORBIS support. The drawbacks are that
403
it has longer "reply delay" when starting the playback of a sound, and
404
it suffers under some bugs in Gstreamer that are yet to be fixed.
408
<sect2 id="audio-future">
409
<title>Future audio backends</title>
411
It would probably be desirable to make more backends in the future,
412
either because other and better backend systems are brought to our
413
attention, or perhaps because an internal sound handling is better
414
suited for embedded platform with limited software installed.
418
<sect2 id="gstreamer-details">
419
<title>Detailed description of the Gstreamer backend</title>
421
Gstreamer uses pipelines, bins and elements. Pipelines are the
422
main bin, where all other bins or elements are places. Visually the
423
audio pipeline in Gnash looks like this:
430
___ \ _____ ____________
431
|Bin|___|Adder|_____|Audio output|
432
|___| |_____| |____________|
440
There is one bin for each sound which is being played. If a sound is
441
played more the once at the same time, multiple bins will be made. The
447
|source|---|capsfilter|---|decoder|---|aconverter|---|aresampler|---|volume|
452
In the source element we place parts of the undecoded sound data, and
453
when playing the pipeline will pull the data from the element. Via
454
callbacks it is refilled if needed. In the capsfilter the data is
455
labeled with the format of the data. The decoder (surprise!) decodes
456
the data. The audioconverter converts the now raw sound data into a
457
format accepted by the adder, all input to the adder must in the same
458
format. The audio re-sampler re-samples the raw sound data into a sample
459
accepted by the adder, all input to the adder must in the same
460
sample rate. The volume element makes it possible to control the volume
465
When a sound is done being played it emits a End-Of-Stream-signal
466
(EOS), which is caught by an event-handler-callback, which then makes
467
sure that the bin in question is removed from the pipeline. When a
468
sound is told by Gnash to stop playback before it has ended playback,
469
we do something (not yet finally implemented), which makes the bin emit
470
an EOS, and the event-handler-callback will remove the sound from the
471
pipeline. Unfortunately Gstreamer currently has a bug which causes the
472
entire pipeline to stop playing when unlinking an element from the
473
pipeline; so far no fix is known.
477
Gstreamer also contains a bug concerning linking multiple elements to
478
the adder in rapid succession, which causes to adder to "die" and stop
487
<title>Testing </title>
490
<link linkend="runtests">Instructions on running tests</link>
491
can be found in the section on building Gnash.
494
<sect2 id="testtools">
495
<title>Testing Tools</title>
498
Currently Gnash uses three other tools to help with
499
testing. Two of these are free compilers for the SWF
500
format. This lets us write simple test cases for Gnash to test
501
specific features, and to see how the features operate.
505
The primary compiler used at this time is <ulink type="http"
506
url="http://ming.sf.net">Ming</ulink>. Since release 0.3,
507
<emphasis>Ming</emphasis> includes a command-line compiler,
508
<emphasis>makeswf</emphasis>. This allows test case development
509
to be done entirely with free tools.
513
The other tools are optional.
515
url="http://www.gnu.org/software/dejagnu">DejaGnu</ulink>
516
is used to run multiple test cases in an automated
517
manner. <emphasis>DejaGnu</emphasis> is used by many other <ulink
518
type="http" url="http://www.gnu.org">GNU</ulink> projects like
519
<ulink type="http" url="http://gcc.gnu.org">GCC</ulink> and
520
<ulink type="http" url="http://www.samba.org">Samba</ulink>.
525
<sect2 id="testcases">
526
<title>Test Cases</title>
529
ActionScript test cases are located under testsuite/actionscript.all/;
530
these are organized in one file for the ActionScript class.
531
Other Ming-generated tests are under testsuite/ming-misc.all/;
532
these are typically used to test specific tag types.
533
Full movies are located in testsuite/movies.all/ and
534
sample movies are found in testsuite/samples/.
535
Other directories in testsuite/ are (or shall be) used for other
541
<sect2 id="writeastests">
542
<title>Writing ActionScript Tests</title>
545
Writing ActionScript tests is very simple. The
546
<emphasis>makeswf</emphasis> compiler makes use of the C preprocessor,
547
thus allowing the inclusion of definitions for macros and external
548
files. We use these feature to provide common utilities
553
Each test unit sets an <emphasis>rcsid</emphasis> variable, includes the
554
<emphasis>check.as</emphasis> file and performs some checks using
555
the provided macros. Here is an example:
559
// This variable will be used by check.as
560
// to show testcase info as part of the test runs.
561
rcsid="Name and version of this testcase, usually the RCS id";
565
// Test object creation
566
check(new Object() instanceOf Object);
569
check(isNaN(parseInt('none')));
575
// .. your tests here ...
580
The check(expr) macro will <emphasis>trace</emphasis> PASSED or FAILED
581
together with the expression being evaluated and the line number
582
of the check. This is the format expected by DejaGnu.
586
The <emphasis>check_equals(obtained, expected)</emphasis> macro uses equality operator
587
<emphasis>==</emphasis> to check for equality. When possible, use of the
588
<emphasis>check_equals()</emphasis> macro is preferred over <emphasis>check()</emphasis>
589
because it shows what the actual result was in case of a failure.
593
Additionally, the check.as file provides a transparent way to send
594
results to a TextField rather then using trace. This is very useful
595
when you use a SWF player without tracing support.
599
Test units are built by running <emphasis>make TestName-v#.swf</emphasis>.
600
This will use TestName.as as source and the value of # as target version.
601
Allowed target version are from 5 to 8 (inclusive).
605
Note that if you get a syntax error from the compiler, the line
606
number will refer to the pre-processed file. This file is called
607
<emphasis>TestName.as.pp</emphasis> or <emphasis>TestName-v#.swf.frame#.pp</emphasis>
608
(depending on Ming version) and it's not thrown away by
609
<emphasis>makeswf</emphasis> to make debugging easier.
613
Sometimes an expression is only supported by a specific SWF
614
version, or it's evaluated differently by different SWF versions.
615
For this purpose the framework provides an OUTPUT_VERSION macro
616
that you can use to switch code based on output version. For example:
620
#if OUTPUT_VERSION >= 7
621
check(_root.getSWFVersion == OUTPUT_VERSION);
628
<sect2 id="writemingtests">
629
<title>Writing Ming-based self-contained SWF tests</title>
632
Ming-based test cases are located in testsuite/misc-ming.all
633
and contain a test generator and a test runner.
634
The test generator (usually a C program) is used to produce the SWF
635
file, while the test runner (a C++ program) will run it using a
637
Note that only the test generator needs Ming, not the test
638
runner, so if Ming isn't installed on the user's host,
639
the test cases can still be run as long as SWF has been distributed.
643
Producing tests using Ming has the advantage that you can easily see
644
and modify the full source code for the SWF movie, and you can use
645
some <link linkend="ming_testgenerator_facilities">facilities</link>
646
provided by the Gnash testing framework to easily run tests.
650
For generic Ming API documentation, see <ulink type="http"
651
url="http://www.libming.org/">http://www.libming.org</ulink>.
654
<sect3 id="ming_testgenerator_facilities">
655
<title>Using Ming-based test generators facilities</title>
658
Ming-based test generator facilities, which might be moved into
659
a loadable SWF in the future, can be currently used by your test
660
generator by including the ming_utils.h file and calling the
661
appropriate functions.
665
The most useful facility provided for Ming-based SWF test generators
666
is a Dejagnu-like TestState ActionScript class.
667
In order to use this facility you must call 'add_dejagnu_functions()'
668
right after Movie creation.
669
The function takes an SWFMovie object and some parameters specifying
670
depth and location of the "visual" trace textfield; it instantiates
671
a global 'TestState' ActionScript object to keep track of test's state.
675
You will <emphasis>not</emphasis> need to directly invoke the
676
TestState object created by the 'add_dejagnu_functions()' routine,
677
rather you will be using C macros hiding its complexity:
681
check(SWFMovie mo, const char* expr)
683
Evaluate an ActionScript expression.
685
xcheck(SWFMovie mo, const char* expr)
687
Evaluate an ActionScript expression.
688
A failure is expected
689
(for cases where the call exposes a known bug).
691
check_equals(SWFMovie mo, const char* obtained, const char* expected)
693
Evaluate an ActionScript expression against an expected output.
695
xcheck_equals(SWFMovie mo, const char* obtained, const char* expected)
697
Evaluate an ActionScript expression against an expected output.
698
A failure is expected (for cases where the call exposes a known bug).
700
print_tests_summary(SWFMovie mo)
702
This will print a summary of tests run, and should be
703
called as the last step in your SWF generator.
709
Test cases generated using Ming and the provided
710
<link linkend="ming_testgenerator_facilities">facilities</link>
711
will be self-contained, which means they can be used as tests
712
by simply running them with whatever Player you might have.
713
Any 'check' or 'check_equals' result will be both traced and
714
printed in a textfield. You can use 'gprocessor -v' to have
715
Gnash use them as tests.
719
See section <link linkend="writing_test_runners">Writing Test Runners</link>
720
for information about writing SWF test runners.
725
<sect2 id="writing_dejagnu_so_tests">
726
<title>Writing self-contained SWF tests with other compilers</title>
729
If you want/need to use a different compiler for your test cases (there's
730
plenty of open source tools for generating SWF out there), you can still
731
make use of a loadable SWF utility provided as part of the Gnash testsuite
732
to let your test consistent with the rest of the suite.
736
The loadable module is called <emphasis>Dejagnu.swf</emphasis> and is built during
737
<emphasis>make check</emphasis> under testsuite/misc-ming.all. In order to use it
738
you will need to load it into your SWF. We currently load it with an IMPORT
739
tag for our ActionScript based test cases, but you can probably also use
740
loadMovie or whatever works in the target SWF you're generating. Just make
741
sure that the module is initialized before using it. You can check this by
742
inspecting the <emphasis>dejagnu_module_initialized</emphasis> variable, which will
743
be set to 'true' when all initialization actions contained in the
744
<emphasis>Dejagnu.swf</emphasis> file are executed.
748
Once the module is loaded you will be able to invoke the following functions,
749
all registered against the <emphasis>_root</emphasis> sprite (effects of <emphasis>_lockroot</emphasis>
753
check(expression, [message]);
755
Evaluate the expression.
756
Trace result (PASSED: expression / FAILED: expression).
757
If fails, *visually* trace the failure.
758
If second argument is given, it will be used instead of
759
'expression' for printing results.
761
check_equals(obtained, expected)
763
Evaluate an expression against an expected output.
764
Trace result (PASSED: obtained == expected / FAILED: expected X, obtained Y)
765
If fails, *visually* trace the failure.
767
xcheck(expression, [message]);
769
Evaluate the expression.
770
Trace result (XPASSED: expression / XFAILED: expression).
771
If fails, *visually* trace the failure.
772
If second argument is given, it will be used instead of
773
'expression' for printing results.
775
xcheck_equals(obtained, expected)
777
Evaluate an expression against an expected output.
778
Trace result (XPASSED: obtained == expected / XFAILED: expected X, obtained Y)
779
If fails, *visually* trace the failure.
783
Print string, both as debugging and *visual* trace.
787
Print a summary of tests run, both as debugging and *visual* traces.
793
Visual traces are lines of text pushed to a textarea defined
794
by the <emphasis>Dejagnu.swf</emphasis> module. The textarea is
795
initially placed at <emphasis>0, 50</emphasis> and is
796
<emphasis>600x800</emphasis> in size. You can resize/move the clip
797
after loading it. Also, you can completely make the clip
798
invisible if that bothers you. The important thing is the
799
<emphasis>debugging</emphasis> trace (call to the trace
800
function). The latter will be used by the testing framework.
804
See section <link linkend="writing_test_runners">Writing Test Runners</link>
805
for information about writing a test runners for your self-contained tests.
810
<sect2 id="writing_test_runners">
811
<title>Writing Test Runners</title>
814
Test runners are executables that run one or more tests,
815
writing results in Dejagnu form to standard output.
819
The Dejagnu form uses a standard set of labels when printing test
821
<informaltable frame="all">
822
<?dbhtml table-width="75%" ?>
836
<entry valign="top" align="left">
839
<entry valign="top" align="left">
840
<para>The test succeeded.</para>
844
<entry valign="top" align="left">
847
<entry valign="top" align="left">
848
<para>The test failed.</para>
852
<entry valign="top" align="left">
855
<entry valign="top" align="left">
856
<para>The test succeeded, but was expected to fail.</para>
860
<entry valign="top" align="left">
863
<entry valign="top" align="left">
864
<para>The test failed, and was expected to fail.</para>
868
<entry valign="top" align="left">
869
<para>UNRESOLVED</para>
871
<entry valign="top" align="left">
872
<para>The results of the test could not be automatically
877
<entry valign="top" align="left">
878
<para>UNTESTED</para>
880
<entry valign="top" align="left">
881
<para>This test case is not complete.</para>
885
<entry valign="top" align="left">
886
<para>UNSUPPORTED</para>
888
<entry valign="top" align="left">
889
<para>The test case relies on a conditional feature which
890
is not present in your environment.</para>
899
The following labels may also appear:
900
<informaltable frame="all">
901
<?dbhtml table-width="75%" ?>
915
<entry valign="top" align="left">
918
<entry valign="top" align="left">
919
<para>There was a serious error in running the test. </para>
923
<entry valign="top" align="left">
926
<entry valign="top" align="left">
927
<para>There may have been a problem with running the
932
<entry valign="top" align="left">
935
<entry valign="top" align="left">
936
<para>There was some additional information given about
945
<sect3 id="generic_test_runner">
946
<title>Using the generic test runner for self-contained SWF tests</title>
949
The simplest test runner is one that simply invokes Gnash
950
in verbose mode against a self-contained SWF test movie.
951
Self-contained SWF test movies are the ones that print
952
the PASSED/FAILED etc. lines using ActionScript (traces).
953
By invoking Gnash in verbose mode this movie will behave
954
as a compliant "Test Runner".
958
A generator for simple test runners can be found in
959
<emphasis>testsuite/generic-testrunner.sh</emphasis>.
960
The script can be invoked by passing it <emphasis>$(top_builddir)</emphasis>
961
as the first argument and the name of the SWF file (without the path)
962
as the second argument. This will create a specific runner for your
963
test in the current build directory.
964
A simple Makefile.am rule for doing this follows:
966
MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
967
sh $(srcdir)/../generic-testrunner.sh $(top_builddir) MyTest.swf > $@
973
By default, the generated test runner will play the movie up to the
974
last frame. If you want the movie to be played more then once (maybe
975
because you're exactly testing loop features) you can use the -r switch
976
to the generic-testrunner.sh call. The following will create a runner
977
playing the movie twice:
979
MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
980
sh $(srcdir)/../generic-testrunner.sh -r2 $(top_builddir) MyTest.swf > $@
986
In case your test movie stops before the last frame, or you want to control the
987
exact number of times to call the frame advancement routine, you can use the
988
-f switch to control that.
990
MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
991
sh $(srcdir)/../generic-testrunner.sh -f10 $(top_builddir) MyTest.swf > $@
994
When both -f and -r are given, the first exit condition reached will take effect.
999
<sect3 id="writing_movie_testers">
1000
<title>Writing Movie testers</title>
1003
There are some parts of Gnash that can NOT be tested
1004
by only using ActionScript tests. Examples include: frame
1005
advancements, actual actions execution, gui events and so on.
1009
In this case you might want to use the MovieTester class to
1010
implement a C++ test runner. Be aware that you can <emphasis>mix</emphasis> tests in
1011
the MovieTester-based class with <emphasis>self-contained</emphasis>
1012
tests in the SWF file as long as you activate verbosity for
1013
the debug logfile. This is done, for example, for the
1014
DefineEditTextVariableNameTest.swf file. The corresponding
1015
test runner (DefineEditTextVariableNameTest-Runner) is a C++
1016
runner based on MovieTester class. If you run the runner you
1017
see two kinds of test results: the ones coming from the ActionScript
1018
engine, and the ones coming from the test runner. You can
1019
distinguish between the two because the former contains an additional
1020
timestamp and the latter does not. Also, you'll see two final
1021
summaries for the two test sets. The 'make check' rule, which uses
1022
the testsuite/simple.exp output parser as its work-horse, will
1023
count test results from both test sets.
1028
Movie testers are executables which load an SWF, generate events
1029
(both user or system) on it, and check its state using
1030
a standard interface.
1034
To help this process a MovieTester class is defined in the
1035
testsuite/MovieTester.{h,cpp} files; see Doxygen documentation
1036
for more information.
1040
Note that you do NOT need access to the SWF source code in order
1041
to implement a Movie tester for it. Some knowledge about the
1042
expected behavior suffices.