From: Nutchanon Wetchasit <Nutchanon.Wetchasit@gmail.com>
Subject: Add an container-emulated automated ExternalInterface test case.
Bug: https://savannah.gnu.org/bugs/?37223

diff --git a/testsuite/misc-mtasc.all/Makefile.am b/testsuite/misc-mtasc.all/Makefile.am
index d2bd7f2..39b0db0 100644
--- a/testsuite/misc-mtasc.all/Makefile.am
+++ b/testsuite/misc-mtasc.all/Makefile.am
@@ -34,8 +34,12 @@ SANE_ASTESTS = \
 # These ones are the ones for which consistency check fail 
 BOGUS_ASTESTS = \
 	$(NULL)
+# This one is host container communication (ExternalInterface) test
+EXTCOMM_ASTESTS = \
+	extcomm.as \
+	$(NULL)
 
-ASTESTS = $(SANE_ASTESTS) $(BOGUS_ASTESTS)
+ASTESTS = $(SANE_ASTESTS) $(BOGUS_ASTESTS) $(EXTCOMM_ASTESTS)
 
 
 # These will get compiled to SWFs just as above, but will not be executed as a test
@@ -49,11 +53,13 @@ AUXMOVIES = \
 EXTRA_DIST = $(ASTESTS) $(AUXMOVIES) TestClass.as Dejagnu.as check.as Derived1.as Base1.as  implementsOp/BExtendingImplementation.as  implementsOp/ImplementationA.as  implementsOp/ImplementationB.as implementsOp/SimpleInterface.as
 
 MTASC_FLAGS = -version 6 -cp $(MTASC_CLASSPATH) -cp $(srcdir) -v -header 800:600:20
+MTASCV8_FLAGS = -version 8 -cp $(MTASC_CLASSPATH) -cp $(srcdir) -v -header 800:600:20
 MTASC_CPP = $(CPP) -x c -P -I$(srcdir)
 
 SANE_ASTESTS_OUT = $(SANE_ASTESTS:.as=.swf)
 BOGUS_ASTESTS_OUT = $(BOGUS_ASTESTS:.as=.swf)
-ASTESTS_OUT = $(SANE_ASTESTS_OUT) $(BOGUS_ASTESTS_OUT)
+EXTCOMM_ASTESTS_OUT = $(EXTCOMM_ASTESTS:.as=.swf)
+ASTESTS_OUT = $(SANE_ASTESTS_OUT) $(BOGUS_ASTESTS_OUT) $(EXTCOMM_ASTESTS_OUT)
 
 AUXMOVIES_OUT = $(AUXMOVIES:.as=.swf)
 
@@ -64,6 +70,7 @@ TEST_DRIVERS = ../simple.exp
 TEST_CASES = \
 	sanetests-runner \
 	bogustests-runner \
+	extcommtests-runner \
 	$(NULL)
 
 sanetests-runner: $(srcdir)/../generic-testrunner.sh $(SANE_ASTESTS_OUT) $(AUXMOVIES_OUT) Makefile
@@ -74,6 +81,14 @@ bogustests-runner: $(srcdir)/../generic-testrunner.sh $(BOGUS_ASTESTS_OUT) $(AUX
 	sh $(srcdir)/../generic-testrunner.sh -C __END_OF_TEST__ -r 50 $(top_builddir) $(BOGUS_ASTESTS_OUT) > $@
 	chmod 755 $@
 
+extcommtests-runner: $(srcdir)/extcommtests-runner.sh $(EXTCOMM_ASTESTS_OUT) Makefile
+	sh $(srcdir)/extcommtests-runner.sh $(top_builddir) $(top_srcdir) $(EXTCOMM_ASTESTS_OUT) > $@
+	chmod 755 $@
+
+extcomm.swf: extcomm.as
+	$(MTASC_CPP) $< > $(@:%.swf=pp_%.as)
+	$(MTASC) $(MTASCV8_FLAGS) -swf $@ -main $(@:%.swf=pp_%.as)
+
 .as.swf: 
 	$(MTASC_CPP) $< > $(@:%.swf=pp_%.as) 
 	$(MTASC) $(MTASC_FLAGS) -swf $@ -main $(@:%.swf=pp_%.as)
diff --git a/testsuite/misc-mtasc.all/extcomm.as b/testsuite/misc-mtasc.all/extcomm.as
new file mode 100644
index 0000000..0a71b94
--- /dev/null
+++ b/testsuite/misc-mtasc.all/extcomm.as
@@ -0,0 +1,58 @@
+// extcomm.as - Host container communication (ExternalInterface) tests
+//
+//   Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+//
+//
+// Original author: Nutchanon Wetchasit <Nutchanon.Wetchasit@gmail.com>
+//
+
+import flash.external.*;
+
+#include "check.as"
+
+class ExternalCommTest
+{
+	// Entry point
+	public static function main(mc:MovieClip):Void
+	{
+		// ExternalInterface should be available
+		check(ExternalInterface.available);
+
+		mc.script_call = function(arg1, arg2):String
+		{
+			// This function should NOT be called
+			check(false);
+			check_equals(arg1, "Hello");
+			check_equals(arg2, "World");
+			return "Too";
+		};
+
+		// Registering callback shouldn't fail
+		check(
+			ExternalInterface.addCallback("script_call", mc,
+				function(arg1, arg2):String
+				{
+					// This function should be called
+					check(true);
+					check_equals(arg1, "Hello");
+					check_equals(arg2, "World");
+					return "Too";
+				}
+			)
+		);
+	}
+}
diff --git a/testsuite/misc-mtasc.all/extcommtests-runner.sh b/testsuite/misc-mtasc.all/extcommtests-runner.sh
new file mode 100644
index 0000000..10aa3ef
--- /dev/null
+++ b/testsuite/misc-mtasc.all/extcommtests-runner.sh
@@ -0,0 +1,194 @@
+#!/bin/sh
+
+# 
+# extcommtests-runner.sh: container-emulated, automated
+#     ExternalInterface test generator
+# 
+# Copyright (C) 2015 Free Software Foundation, Inc.
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
+# 
+# Usage:
+#     ./extcommtests-runner.sh <builddir> <srcdir> <swf>
+# 
+# Exit codes:
+#     0         if tester ran completely
+#     non-zero  if tester encountered an error
+# 
+# Note:
+#     The generated test file requires a filesystem that supports a named pipe.
+# 
+
+# Check for generation parameters
+while getopts "" name
+do
+	case $name in
+		?)
+			echo "Usage: $0 <builddir> <srcdir> <swf>" >&2
+			exit 1;;
+	esac
+done
+shift $(($OPTIND - 1))
+if [ "$#" -ne 3 ]
+then
+	echo "Usage: $0 <builddir> <srcdir> <swf>" >&2
+	exit 1
+fi
+
+# Load generation parameters
+top_builddir=$1
+shift
+top_srcdir=$1
+shift
+swf=$1
+
+# Generate the test runner
+echo "#!/bin/sh"
+echo
+
+echo "# Environment variables"
+env | grep '^GNASH' | while read reply
+do
+	echo "export \"${reply}\""
+done
+
+timeout=10
+
+cat << EOF
+
+# Filenames and constants
+LOGFILE=${top_builddir}/testoutlog.\$$
+PIPE2CONTAINER=${top_builddir}/tocontainer.\$$
+PIPE2PLAYER=${top_builddir}/toplayer.\$$
+READTIMEOUT=5
+
+# Test counts
+TESTED=0
+FAILED=0
+PASSED=0
+
+# check_equals(\$op1, \$op2, \$msg)
+# Equality checker and counter
+check_equals() {
+	if [ "\$1" = "\$2" ]
+	then
+		echo "PASSED: \$3"
+		PASSED=\`expr "\$PASSED" + 1\`
+	else
+		echo "FAILED: \$3 (\"\$1\" != \"\$2\")"
+		FAILED=\`expr "\$FAILED" + 1\`
+	fi
+	TESTED=\`expr "\$TESTED" + 1\`
+}
+
+# check_totals(\$op, \$msg)
+# Test count checker
+check_totals() {
+	check_equals "\$TESTED" "\$1" "\$2"
+}
+
+# check_error(\$bool, \$msg)
+# Assert \$bool is 0; if not, flag error in the test, and exit
+check_error() {
+	if [ "\$1" -ne 0 ]
+	then
+		echo "ERROR: \$2" >&2
+		exit 1
+	fi
+}
+
+# read_timeout(\$varname, \$timeout)
+# Read one line from standard input, with a specified timeout (in seconds)
+read_timeout() {
+	trap 'trap - USR1; return 142' USR1
+	(sleep "\$2" && kill -USR1 "\$\$" > /dev/null 2>&1) &
+	TIMEOUTPID=\$!
+	read "\$1"
+	READERROR=\$?
+	kill "\$TIMEOUTPID" > /dev/null 2>&1
+	trap - USR1
+	return \$READERROR
+}
+
+# Create required named pipes
+if [ \! -p "\$PIPE2CONTAINER" ]
+then
+	mkfifo "\$PIPE2CONTAINER"
+	check_error "\$?" "Failed to create a named pipe: \$PIPE2CONTAINER"
+fi
+if [ \! -p "\$PIPE2PLAYER" ]
+then
+	mkfifo "\$PIPE2PLAYER"
+	check_error "\$?" "Failed to create a named pipe: \$PIPE2PLAYER"
+fi
+
+# Open player-to-host pipe
+exec 3<> "\$PIPE2CONTAINER"
+check_error \$? "Failed to open a named pipe: \$PIPE2CONTAINER"
+
+# Open host-to-player pipe
+exec 4<> "\$PIPE2PLAYER"
+check_error \$? "Failed to open a named pipe: \$PIPE2CONTAINER"
+
+# Start player
+"${top_builddir}/gui/gnash" -r 0 -t ${timeout} -vv -F 3:4 "${swf}" > "\$LOGFILE" 2>&1 &
+GNASHPID=\$!
+
+# Read for callback registration statement
+read_timeout LINE \$READTIMEOUT <&3
+check_equals \
+	"\$LINE" \
+	'<invoke name="addMethod" returntype="xml"><arguments><string>script_call</string></arguments></invoke>' \
+	"Gnash should properly register an ExternalInterface callback"
+
+# Call the callback
+echo '<invoke name="script_call" returntype="xml"><arguments><string>Hello</string><string>World</string></arguments></invoke>' >&4
+
+# Read for callback return value statement
+read_timeout LINE \$READTIMEOUT <&3
+check_equals "\$LINE" '<string>Too</string>' "Gnash should return a correct value from ExternalInterface callback"
+
+# Close pipes
+exec 3<&-
+exec 4<&-
+
+# Wait for Gnash to exit
+wait \$GNASHPID
+check_equals "\$?" "0" "Gnash should terminate successfully"
+
+# Show player-side output
+exec 5< "\$LOGFILE"
+cat <&5
+exec 5<&-
+
+# Include total number of tests from player side
+exec 5< "\$LOGFILE"
+PLAYERPASSED=\`grep "TRACE: PASSED:" <&5 | wc -l\`
+exec 5<&-
+exec 5< "\$LOGFILE"
+PLAYERFAILED=\`grep "TRACE: FAILED:" <&5 | wc -l\`
+exec 5<&-
+PASSED=\`expr "\$PASSED" + "\$PLAYERPASSED"\`
+FAILED=\`expr "\$FAILED" + "\$PLAYERFAILED"\`
+TESTED=\`expr "\$TESTED" + "\$PLAYERPASSED" + "\$PLAYERFAILED"\`
+
+# Check for total number of test run
+check_totals "8" "There should be 8 tests run"
+
+# Remove temporary files
+rm "\$LOGFILE"
+rm "\$PIPE2CONTAINER"
+rm "\$PIPE2PLAYER"
+EOF
