From 7e07cc138d043ffdd0e6730d51d83914dfe6958f Mon Sep 17 00:00:00 2001
From: Sam Mikes <smikes@cubane.com>
Date: Thu, 17 Jul 2014 11:49:35 -0600
Subject: [PATCH] async,promises: initial tests of Promises

doneprintHandle.js: make $DONE accept any falsy argument as meaning 'pass'
PromiseHelper.js: checkSequence: new helper fn for async tests
.gitignore: port .hgignore to .gitignore syntax
test262.py: support $INCLUDE directive in python test runner

S25.4.4.1*: tests to cover Section 25.4.4.1, Promise.all( iterable )
A1.1: Promise.all is callable
A1.2: Promise.all expects 1 argument
A2.1: Promise.all([]) is a Promise
A2.2: Promise.all([]) is resolved immediately
A2.3: Promise.all([]) is resolved with a new empty array
A3.1: Promise.all expects an iterable argument
---
 .gitignore                                    |  5 ++++
 console/harness/PromiseHelper.js              |  9 +++++++
 console/harness/doneprintHandle.js            |  4 +--
 test/harness/PromiseHelper.js                 |  9 +++++++
 test/harness/doneprintHandle.js               |  4 +--
 .../25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.1_T1.js | 17 +++++++++++++
 .../25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.2_T1.js | 17 +++++++++++++
 .../25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.1_T1.js | 17 +++++++++++++
 .../25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.2_T1.js | 25 +++++++++++++++++++
 .../25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T1.js | 20 +++++++++++++++
 .../25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T2.js | 20 +++++++++++++++
 .../25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T3.js | 20 +++++++++++++++
 .../25.4/25.4.4/25.4.4.1/S25.4.4.1_A3.1_T1.js | 23 +++++++++++++++++
 tools/packaging/test262.py                    |  7 ++++++
 14 files changed, 193 insertions(+), 4 deletions(-)
 create mode 100644 .gitignore
 create mode 100644 console/harness/PromiseHelper.js
 create mode 100644 test/harness/PromiseHelper.js
 create mode 100644 test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.1_T1.js
 create mode 100644 test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.2_T1.js
 create mode 100644 test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.1_T1.js
 create mode 100644 test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.2_T1.js
 create mode 100644 test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T1.js
 create mode 100644 test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T2.js
 create mode 100644 test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T3.js
 create mode 100644 test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A3.1_T1.js

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..1203b32d2e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+.d8_history
+*~
+*.pyc
+console/TestCases
diff --git a/console/harness/PromiseHelper.js b/console/harness/PromiseHelper.js
new file mode 100644
index 0000000000..59ba0c74c9
--- /dev/null
+++ b/console/harness/PromiseHelper.js
@@ -0,0 +1,9 @@
+//-----------------------------------------------------------------------------
+function checkSequence(arr, message) {
+    arr.forEach(function(e, i) {
+        if (e !== (i+1)) {
+            $ERROR((message ? message : "Steps in unexpected sequence:") +
+                   " '" + arr.join(',') + "'");
+        }
+    });
+}
diff --git a/console/harness/doneprintHandle.js b/console/harness/doneprintHandle.js
index 317aa9c4ef..101a36bd49 100644
--- a/console/harness/doneprintHandle.js
+++ b/console/harness/doneprintHandle.js
@@ -3,8 +3,8 @@ function __consolePrintHandle__(msg){
 }
 
 function $DONE(){
-	if(arguments.length === 0)
+	if(!arguments[0])
 		__consolePrintHandle__('Test262:AsyncTestComplete');
 	else
 		__consolePrintHandle__('Error: ' + arguments[0]);
-}
\ No newline at end of file
+}
diff --git a/test/harness/PromiseHelper.js b/test/harness/PromiseHelper.js
new file mode 100644
index 0000000000..59ba0c74c9
--- /dev/null
+++ b/test/harness/PromiseHelper.js
@@ -0,0 +1,9 @@
+//-----------------------------------------------------------------------------
+function checkSequence(arr, message) {
+    arr.forEach(function(e, i) {
+        if (e !== (i+1)) {
+            $ERROR((message ? message : "Steps in unexpected sequence:") +
+                   " '" + arr.join(',') + "'");
+        }
+    });
+}
diff --git a/test/harness/doneprintHandle.js b/test/harness/doneprintHandle.js
index 317aa9c4ef..101a36bd49 100644
--- a/test/harness/doneprintHandle.js
+++ b/test/harness/doneprintHandle.js
@@ -3,8 +3,8 @@ function __consolePrintHandle__(msg){
 }
 
 function $DONE(){
-	if(arguments.length === 0)
+	if(!arguments[0])
 		__consolePrintHandle__('Test262:AsyncTestComplete');
 	else
 		__consolePrintHandle__('Error: ' + arguments[0]);
-}
\ No newline at end of file
+}
diff --git a/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.1_T1.js b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.1_T1.js
new file mode 100644
index 0000000000..0f7c216a53
--- /dev/null
+++ b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.1_T1.js
@@ -0,0 +1,17 @@
+// Copyright 2014 Ecma International.  All rights reserved.
+/// Ecma International makes this code available under the terms and conditions set
+/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
+/// "Use Terms").   Any redistribution of this code must retain the above
+/// copyright and this notice and otherwise comply with the Use Terms.
+
+/**
+ * Promise.all is callable
+ *
+ * @author Sam Mikes
+ */
+
+// CHECK#1
+var x = typeof Promise.all;
+if (x !== "function") {
+    $ERROR('#1: x = typeof Promise.all; x === "function". Actual: ' + (x));
+}
diff --git a/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.2_T1.js b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.2_T1.js
new file mode 100644
index 0000000000..49b563e1c9
--- /dev/null
+++ b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A1.2_T1.js
@@ -0,0 +1,17 @@
+/// Copyright 2012 Ecma International.  All rights reserved.
+/// Ecma International makes this code available under the terms and conditions set
+/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
+/// "Use Terms").   Any redistribution of this code must retain the above
+/// copyright and this notice and otherwise comply with the Use Terms.
+
+/**
+ * Promise.all expects 1 argument
+ *
+ * @author Sam Mikes
+ */
+
+// CHECK#1
+var x = Promise.all.length;
+if (x !== 1) {
+    $ERROR('#1: x = Promise.all.length; x === 1. Actual: ' + (x));
+}
diff --git a/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.1_T1.js b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.1_T1.js
new file mode 100644
index 0000000000..f73d5b21a7
--- /dev/null
+++ b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.1_T1.js
@@ -0,0 +1,17 @@
+// Copyright 2014 Ecma International.  All rights reserved.
+/// Ecma International makes this code available under the terms and conditions set
+/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
+/// "Use Terms").   Any redistribution of this code must retain the above
+/// copyright and this notice and otherwise comply with the Use Terms.
+
+/**
+ * Promise.all([]) is a Promise
+ *
+ * @author Sam Mikes
+ */
+
+// CHECK#1
+var x = (Promise.all([]) instanceof Promise);
+if (x !== true) {
+    $ERROR('#1: x (Promise.all([]) instanceof Promise); x === true. Actual: ' + (x));
+}
diff --git a/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.2_T1.js b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.2_T1.js
new file mode 100644
index 0000000000..2f07cd1928
--- /dev/null
+++ b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.2_T1.js
@@ -0,0 +1,25 @@
+// Copyright 2014 Ecma International.  All rights reserved.
+/// Ecma International makes this code available under the terms and conditions set
+/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
+/// "Use Terms").   Any redistribution of this code must retain the above
+/// copyright and this notice and otherwise comply with the Use Terms.
+
+/**
+ * Promise.all([]) is resolved immediately
+ *
+ * @author Sam Mikes
+ */
+
+$INCLUDE("PromiseHelper.js");
+var sequence = [];
+
+Promise.all([]).then(function () {
+    sequence.push(1);
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+    sequence.push(2);
+}).then(function () {
+    sequence.push(3);
+    checkSequence(sequence, "Promises resolved in unexpected sequence");
+}).then($DONE,$DONE);
diff --git a/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T1.js b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T1.js
new file mode 100644
index 0000000000..3ef2899127
--- /dev/null
+++ b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T1.js
@@ -0,0 +1,20 @@
+
+// Copyright 2014 Ecma International.  All rights reserved.
+/// Ecma International makes this code available under the terms and conditions set
+/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
+/// "Use Terms").   Any redistribution of this code must retain the above
+/// copyright and this notice and otherwise comply with the Use Terms.
+
+/**
+ * Promise.all is resolved with a new empty array
+ *
+ * @author Sam Mikes
+ */
+
+var arg = [];
+
+Promise.all(arg).then(function (result) {
+    if((result instanceof Array) !== true) {
+        $ERROR("expected an array from Promise.all, got " + result);
+    }
+}).then($DONE,$DONE);
diff --git a/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T2.js b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T2.js
new file mode 100644
index 0000000000..4615e1dae9
--- /dev/null
+++ b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T2.js
@@ -0,0 +1,20 @@
+
+// Copyright 2014 Ecma International.  All rights reserved.
+/// Ecma International makes this code available under the terms and conditions set
+/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
+/// "Use Terms").   Any redistribution of this code must retain the above
+/// copyright and this notice and otherwise comply with the Use Terms.
+
+/**
+ * Promise.all is resolved with a new empty array
+ *
+ * @author Sam Mikes
+ */
+
+var arg = [];
+
+Promise.all(arg).then(function (result) {
+    if(result.length !== 0) {
+        $ERROR("expected an empty array from Promise.all([]), got " + result);
+    }
+}).then($DONE,$DONE);
diff --git a/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T3.js b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T3.js
new file mode 100644
index 0000000000..264208e34e
--- /dev/null
+++ b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A2.3_T3.js
@@ -0,0 +1,20 @@
+
+// Copyright 2014 Ecma International.  All rights reserved.
+/// Ecma International makes this code available under the terms and conditions set
+/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
+/// "Use Terms").   Any redistribution of this code must retain the above
+/// copyright and this notice and otherwise comply with the Use Terms.
+
+/**
+ * Promise.all is resolved with a new empty array
+ *
+ * @author Sam Mikes
+ */
+
+var arg = [];
+
+Promise.all(arg).then(function (result) {
+    if(result === arg) {
+        $ERROR("expected a new array from Promise.all but argument was re-used");
+    }
+}).then($DONE,$DONE);
diff --git a/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A3.1_T1.js b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A3.1_T1.js
new file mode 100644
index 0000000000..1f755760bf
--- /dev/null
+++ b/test/suite/es6/ch25/25.4/25.4.4/25.4.4.1/S25.4.4.1_A3.1_T1.js
@@ -0,0 +1,23 @@
+// Copyright 2014 Ecma International.  All rights reserved.
+/// Ecma International makes this code available under the terms and conditions set
+/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
+/// "Use Terms").   Any redistribution of this code must retain the above
+/// copyright and this notice and otherwise comply with the Use Terms.
+
+/**
+ * Promise.all expects an iterable argument; 
+ * ref 7.4.1 non-Object fails CheckIterable
+ * ref 7.4.2 GetIterator throws TypeError if CheckIterable fails
+ *
+ * @author Sam Mikes
+ */
+
+var nonIterable = 3;
+
+Promise.all(nonIterable).then(function () {
+    $ERROR('Promise unexpectedly resolved: Promise.all(nonIterable) should throw TypeError');
+},function (err) {
+    if (!(err instanceof TypeError)) {
+        $ERROR('Expected TypeError, got ' + err);
+    }
+}).then($DONE,$DONE);
diff --git a/tools/packaging/test262.py b/tools/packaging/test262.py
index b2d4397387..98239c59a3 100755
--- a/tools/packaging/test262.py
+++ b/tools/packaging/test262.py
@@ -250,6 +250,12 @@ class TestCase(object):
   def IsAsyncTest(self):	
 	return '$DONE' in self.test
 
+  def GetIncludeList(self):
+    return re.findall('\$INCLUDE\([\'"]([^\)]+)[\'"]\)' ,self.test)
+
+  def GetAdditionalIncludes(self):
+    return '\n'.join([self.suite.GetInclude(include) for include in self.GetIncludeList()])
+
   def GetSource(self):
     # "var testDescrip = " + str(self.testRecord) + ';\n\n' + \
     source = self.suite.GetInclude("cth.js") + \
@@ -259,6 +265,7 @@ class TestCase(object):
         self.suite.GetInclude("testIntl.js") + \
 	self.suite.GetInclude("timer.js") + \
 	self.suite.GetInclude("doneprintHandle.js").replace('print', self.suite.print_handle) + \
+        self.GetAdditionalIncludes() + \
         self.test + '\n'
 
     if self.strict_mode: