diff --git a/test/built-ins/Promise/all/resolve-non-thenable.js b/test/built-ins/Promise/all/resolve-non-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..659e10a219985f1cbefeb2274be651d697057955
--- /dev/null
+++ b/test/built-ins/Promise/all/resolve-non-thenable.js
@@ -0,0 +1,74 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-thenable object value
+es6id: 25.4.4.1
+info: >
+    [...]
+    6. Let promiseCapability be NewPromiseCapability(C).
+    [...]
+    11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+    [...]
+
+    25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+    [...]
+    6. Repeat
+       [...]
+       d. If next is false,
+          [...]
+          iii. If remainingElementsCount.[[value]] is 0,
+             1. Let valuesArray be CreateArrayFromList(values).
+             2. Let resolveResult be Call(resultCapability.[[Resolve]],
+                undefined, «valuesArray»).
+             3. ReturnIfAbrupt(resolveResult)
+          iv. Return resultCapability.[[Promise]].
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        a. Return FulfillPromise(promise, resolution).
+---*/
+
+var v1 = {};
+var v2 = {};
+var v3 = {};
+
+Promise.all([v1, v2, v3])
+  .then(function(values) {
+    if (!values) {
+      $DONE('The promise should be resolved with a value.');
+      return;
+    }
+    if (values.constructor !== Array) {
+      $DONE('The promise should be resolved with an Array instance.');
+      return;
+    }
+
+    if (values.length !== 3) {
+      $DONE('The promise should be resolved with an array of proper length.');
+      return;
+    }
+
+    if (values[0] !== v1) {
+      $DONE('The promise should be resolved with the correct element values (#1)');
+      return;
+    }
+
+    if (values[1] !== v2) {
+      $DONE('The promise should be resolved with the correct element values (#2)');
+      return;
+    }
+
+    if (values[2] !== v3) {
+      $DONE('The promise should be resolved with the correct element values (#3)');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/all/resolve-poisoned-then.js b/test/built-ins/Promise/all/resolve-poisoned-then.js
new file mode 100644
index 0000000000000000000000000000000000000000..b8a17cf4f606de5412579757b897d63354d607ad
--- /dev/null
+++ b/test/built-ins/Promise/all/resolve-poisoned-then.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with an object with a "poisoned" `then` property
+es6id: 25.4.4.1
+info: >
+    [...]
+    6. Let promiseCapability be NewPromiseCapability(C).
+    [...]
+    11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+    [...]
+
+    25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+    [...]
+    6. Repeat
+       [...]
+       d. If next is false,
+          [...]
+          iii. If remainingElementsCount.[[value]] is 0,
+             1. Let valuesArray be CreateArrayFromList(values).
+             2. Let resolveResult be Call(resultCapability.[[Resolve]],
+                undefined, «valuesArray»).
+             3. ReturnIfAbrupt(resolveResult)
+          iv. Return resultCapability.[[Promise]].
+
+    7.3.16 CreateArrayFromList (elements)
+    [...]
+    2. Let array be ArrayCreate(0) (see 9.4.2.2).
+
+    9.4.2.2 ArrayCreate(length, proto)
+    [...]
+    4. If the proto argument was not passed, let proto be the intrinsic object
+       %ArrayPrototype%.
+    5. Let A be a newly created Array exotic object.
+    [...]
+    8. Set the [[Prototype]] internal slot of A to proto.
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       a. Return RejectPromise(promise, then.[[value]]).
+---*/
+
+var value = {};
+var promise;
+
+try {
+  Object.defineProperty(Array.prototype, 'then', {
+    get: function() {
+      throw value;
+    },
+    configurable: true
+  });
+
+  promise = Promise.all([]);
+} finally {
+  delete Array.prototype.then;
+}
+
+promise.then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(val) {
+    if (val !== value) {
+      $DONE('The promise should be rejected with the expected value.');
+      return;
+    }
+
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/all/resolve-thenable.js b/test/built-ins/Promise/all/resolve-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..99b32585d8faf12defab380e1c6e31d9e7175bc4
--- /dev/null
+++ b/test/built-ins/Promise/all/resolve-thenable.js
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a thenable object value
+es6id: 25.4.4.1
+info: >
+    [...]
+    6. Let promiseCapability be NewPromiseCapability(C).
+    [...]
+    11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+    [...]
+
+    25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+    [...]
+    6. Repeat
+       [...]
+       d. If next is false,
+          [...]
+          iii. If remainingElementsCount.[[value]] is 0,
+             1. Let valuesArray be CreateArrayFromList(values).
+             2. Let resolveResult be Call(resultCapability.[[Resolve]],
+                undefined, «valuesArray»).
+             3. ReturnIfAbrupt(resolveResult)
+          iv. Return resultCapability.[[Promise]].
+
+    7.3.16 CreateArrayFromList (elements)
+    [...]
+    2. Let array be ArrayCreate(0) (see 9.4.2.2).
+
+    9.4.2.2 ArrayCreate(length, proto)
+    [...]
+    4. If the proto argument was not passed, let proto be the intrinsic object
+       %ArrayPrototype%.
+    5. Let A be a newly created Array exotic object.
+    [...]
+    8. Set the [[Prototype]] internal slot of A to proto.
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        [...]
+    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+        «promise, resolution, thenAction»)
+---*/
+
+var value = {};
+var promise;
+
+try {
+  Array.prototype.then = function(resolve) {
+    resolve(value);
+  };
+
+  promise = Promise.all([]);
+} finally {
+  delete Array.prototype.then;
+}
+
+promise.then(function(val) {
+    if (val !== value) {
+      $DONE('The promise should be resolved with the expected value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-fulfilled.js b/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-fulfilled.js
deleted file mode 100644
index 4e63f8502de6d88c96cdd9031891641a35ae2e8f..0000000000000000000000000000000000000000
--- a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-fulfilled.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2015 the V8 project authors. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-/*---
-es6id: 25.4.5.3
-description: The return value of the `onFulfilled` method is a fulfilled promise
-info: >
-    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
-       resultCapability).
-
-    25.4.5.3.1 PerformPromiseThen
-
-    [...]
-    8. Else if the value of promise's [[PromiseState]] internal slot is
-       "fulfilled",
-       a. Let value be the value of promise's [[PromiseResult]] internal slot.
-       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
-          «fulfillReaction, value»).
-
-    25.4.1.3.2 Promise Resolve Functions
-
-    [...]
-    8. Let then be Get(resolution, "then").
-    9. If then is an abrupt completion, then
-       a. Return RejectPromise(promise, then.[[value]]).
-    10. Let thenAction be then.[[value]].
-    11. If IsCallable(thenAction) is false, then
-        a. Return FulfillPromise(promise, resolution).
-    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
-        resolution, thenAction»)
-    13. Return undefined.
----*/
-
-var executor1Counter = 0;
-var thenCounter = 0;
-var executor2Counter = 0;
-var promise = new Promise(function(resolve) {
-    resolve();
-
-    assert.sameValue(executor1Counter, 0);
-    assert.sameValue(thenCounter, 0);
-    assert.sameValue(executor2Counter, 0);
-
-    executor1Counter += 1;
-  });
-
-promise.then(function() {
-    assert.sameValue(executor1Counter, 1);
-    assert.sameValue(thenCounter, 0);
-    assert.sameValue(executor2Counter, 0);
-
-    thenCounter += 1;
-
-    return new Promise(function(resolve) {
-      resolve();
-
-      assert.sameValue(executor1Counter, 1);
-      assert.sameValue(thenCounter, 1);
-      assert.sameValue(executor2Counter, 0);
-
-      executor2Counter += 1;
-    });
-  }).then(function() {
-    assert.sameValue(executor1Counter, 1);
-    assert.sameValue(thenCounter, 1);
-    assert.sameValue(executor2Counter, 1);
-
-    $DONE();
-  }, function() {
-    $DONE('The promise should not be rejected');
-  });
diff --git a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-pending-to-fulfilled.js b/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-pending-to-fulfilled.js
deleted file mode 100644
index ff0791c5e3df54f746dd53ceb48dd07cf4ecd6b5..0000000000000000000000000000000000000000
--- a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-pending-to-fulfilled.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (C) 2015 the V8 project authors. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-/*---
-es6id: 25.4.5.3
-description: The return value of the `onFulfilled` method is a pending promise
-info: >
-    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
-       resultCapability).
-
-    25.4.5.3.1 PerformPromiseThen
-
-    [...]
-    8. Else if the value of promise's [[PromiseState]] internal slot is
-       "fulfilled",
-       a. Let value be the value of promise's [[PromiseResult]] internal slot.
-       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
-          «fulfillReaction, value»).
-
-    25.4.1.3.2 Promise Resolve Functions
-
-    [...]
-    8. Let then be Get(resolution, "then").
-    9. If then is an abrupt completion, then
-       a. Return RejectPromise(promise, then.[[value]]).
-    10. Let thenAction be then.[[value]].
-    11. If IsCallable(thenAction) is false, then
-        a. Return FulfillPromise(promise, resolution).
-    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
-        resolution, thenAction»)
-    13. Return undefined.
----*/
-
-var executor1Counter = 0;
-var then1Counter = 0;
-var executor2Counter = 0;
-var then2Counter = 0;
-var promise = new Promise(function(resolve) {
-    resolve();
-
-    assert.sameValue(executor1Counter, 0);
-    assert.sameValue(then1Counter, 0);
-    assert.sameValue(executor2Counter, 0);
-    assert.sameValue(then2Counter, 0);
-
-    executor1Counter += 1;
-  });
-
-promise.then(function() {
-    assert.sameValue(executor1Counter, 1);
-    assert.sameValue(then1Counter, 0);
-    assert.sameValue(executor2Counter, 0);
-    assert.sameValue(then2Counter, 0);
-
-    then1Counter += 1;
-
-    return new Promise(function(resolve) {
-      promise.then(function() {
-        resolve();
-
-        assert.sameValue(executor1Counter, 1);
-        assert.sameValue(then1Counter, 1);
-        assert.sameValue(executor2Counter, 1);
-        assert.sameValue(then2Counter, 0);
-
-        then2Counter += 1;
-      });
-
-      assert.sameValue(executor1Counter, 1);
-      assert.sameValue(then1Counter, 1);
-      assert.sameValue(executor2Counter, 0);
-      assert.sameValue(then2Counter, 0);
-
-      executor2Counter += 1;
-    });
-  }).then(function() {
-    assert.sameValue(executor1Counter, 1);
-    assert.sameValue(then1Counter, 1);
-    assert.sameValue(executor2Counter, 1);
-    assert.sameValue(then2Counter, 1);
-
-    $DONE();
-  }, function() {
-    $DONE('The promise should not be rejected');
-  });
diff --git a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-pending-to-rejected.js b/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-pending-to-rejected.js
deleted file mode 100644
index 2b3613c7befdfe63e9e41a3a95a44b67f7e54922..0000000000000000000000000000000000000000
--- a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-pending-to-rejected.js
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (C) 2015 the V8 project authors. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-/*---
-es6id: 25.4.5.3
-description: The return value of the `onFulfilled` method is a pending promise
-info: >
-    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
-       resultCapability).
-
-    25.4.5.3.1 PerformPromiseThen
-
-    [...]
-    8. Else if the value of promise's [[PromiseState]] internal slot is
-       "fulfilled",
-       a. Let value be the value of promise's [[PromiseResult]] internal slot.
-       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
-          «fulfillReaction, value»).
-
-    25.4.1.3.2 Promise Resolve Functions
-
-    [...]
-    8. Let then be Get(resolution, "then").
-    9. If then is an abrupt completion, then
-       a. Return RejectPromise(promise, then.[[value]]).
-    10. Let thenAction be then.[[value]].
-    11. If IsCallable(thenAction) is false, then
-        a. Return FulfillPromise(promise, resolution).
-    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
-        resolution, thenAction»)
-    13. Return undefined.
----*/
-
-var executor1Counter = 0;
-var then1Counter = 0;
-var executor2Counter = 0;
-var then2Counter = 0;
-var promise = new Promise(function(resolve) {
-    resolve();
-
-    assert.sameValue(executor1Counter, 0);
-    assert.sameValue(then1Counter, 0);
-    assert.sameValue(executor2Counter, 0);
-    assert.sameValue(then2Counter, 0);
-
-    executor1Counter += 1;
-  });
-
-promise.then(function() {
-    assert.sameValue(executor1Counter, 1);
-    assert.sameValue(then1Counter, 0);
-    assert.sameValue(executor2Counter, 0);
-    assert.sameValue(then2Counter, 0);
-
-    then1Counter += 1;
-
-    return new Promise(function(_, reject) {
-      promise.then(function() {
-        reject();
-
-        assert.sameValue(executor1Counter, 1);
-        assert.sameValue(then1Counter, 1);
-        assert.sameValue(executor2Counter, 1);
-        assert.sameValue(then2Counter, 0);
-
-        then2Counter += 1;
-      });
-
-      assert.sameValue(executor1Counter, 1);
-      assert.sameValue(then1Counter, 1);
-      assert.sameValue(executor2Counter, 0);
-      assert.sameValue(then2Counter, 0);
-
-      executor2Counter += 1;
-    });
-  }).then(function() {
-    $DONE('The promise should not be fulfilled');
-  }, function() {
-    assert.sameValue(executor1Counter, 1);
-    assert.sameValue(then1Counter, 1);
-    assert.sameValue(executor2Counter, 1);
-    assert.sameValue(then2Counter, 1);
-
-    $DONE();
-  });
diff --git a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-rejected.js b/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-rejected.js
deleted file mode 100644
index 47948dc48013e68defbe008b6b1cca87f2ad2139..0000000000000000000000000000000000000000
--- a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-prms-rejected.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2015 the V8 project authors. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-/*---
-es6id: 25.4.5.3
-description: The return value of the `onFulfilled` method is a rejected promise
-info: >
-    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
-       resultCapability).
-
-    25.4.5.3.1 PerformPromiseThen
-
-    [...]
-    8. Else if the value of promise's [[PromiseState]] internal slot is
-       "fulfilled",
-       a. Let value be the value of promise's [[PromiseResult]] internal slot.
-       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
-          «fulfillReaction, value»).
-
-    25.4.1.3.2 Promise Resolve Functions
-
-    [...]
-    8. Let then be Get(resolution, "then").
-    9. If then is an abrupt completion, then
-       a. Return RejectPromise(promise, then.[[value]]).
-    10. Let thenAction be then.[[value]].
-    11. If IsCallable(thenAction) is false, then
-        a. Return FulfillPromise(promise, resolution).
-    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
-        resolution, thenAction»)
-    13. Return undefined.
----*/
-
-var executor1Counter = 0;
-var thenCounter = 0;
-var executor2Counter = 0;
-var promise = new Promise(function(resolve) {
-    resolve();
-
-    assert.sameValue(executor1Counter, 0);
-    assert.sameValue(thenCounter, 0);
-    assert.sameValue(executor2Counter, 0);
-
-    executor1Counter += 1;
-  });
-
-promise.then(function() {
-    assert.sameValue(executor1Counter, 1);
-    assert.sameValue(thenCounter, 0);
-    assert.sameValue(executor2Counter, 0);
-
-    thenCounter += 1;
-
-    return new Promise(function(_, reject) {
-      reject();
-
-      assert.sameValue(executor1Counter, 1);
-      assert.sameValue(thenCounter, 1);
-      assert.sameValue(executor2Counter, 0);
-
-      executor2Counter += 1;
-    });
-  }).then(function() {
-    $DONE('The promise should not be fulfilled');
-  }, function() {
-    assert.sameValue(executor1Counter, 1);
-    assert.sameValue(thenCounter, 1);
-    assert.sameValue(executor2Counter, 1);
-
-    $DONE();
-  });
diff --git a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-thenable.js b/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-thenable.js
deleted file mode 100644
index 1a7974b718bab736514b5329627869b493956f2a..0000000000000000000000000000000000000000
--- a/test/built-ins/Promise/prototype/then/prfm-when-fulfilled-return-thenable.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2015 the V8 project authors. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-/*---
-es6id: 25.4.5.3
-description: The return value of the `onFulfilled` method is a "thenable" object
-info: >
-    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
-       resultCapability).
-
-    25.4.5.3.1 PerformPromiseThen
-
-    [...]
-    8. Else if the value of promise's [[PromiseState]] internal slot is
-       "fulfilled",
-       a. Let value be the value of promise's [[PromiseResult]] internal slot.
-       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
-          «fulfillReaction, value»).
-
-    25.4.1.3.2 Promise Resolve Functions
-
-    [...]
-    8. Let then be Get(resolution, "then").
-    9. If then is an abrupt completion, then
-       a. Return RejectPromise(promise, then.[[value]]).
-    10. Let thenAction be then.[[value]].
-    11. If IsCallable(thenAction) is false, then
-        a. Return FulfillPromise(promise, resolution).
-    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «promise,
-        resolution, thenAction»)
-    13. Return undefined.
----*/
-
-var callCount = 0;
-var promise = new Promise(function(resolve) {
-  resolve();
-});
-
-var thenable = {
-  then: function(resolve, reject) {
-    assert.sameValue(
-      this, thenable, 'method invoked with correct `this` value'
-    );
-    assert.sameValue(typeof resolve, 'function', 'type of first argument');
-    assert.sameValue(
-      resolve.length,
-      1,
-      'ES6 25.4.1.3.2: The length property of a promise resolve function is 1.'
-    );
-    assert.sameValue(typeof reject, 'function', 'type of second argument');
-    assert.sameValue(
-      reject.length,
-      1,
-      'ES6 25.4.1.3.1: The length property of a promise reject function is 1.'
-    );
-    assert.sameValue(arguments.length, 2, 'total number of arguments');
-    resolve();
-
-    callCount += 1;
-  }
-};
-
-promise.then(function() {
-  return thenable;
-}).then(function() {
-  assert.sameValue(callCount, 1);
-
-  $DONE();
-}, function() {
-  $DONE('This promise should not be rejected');
-});
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-obj.js b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-obj.js
new file mode 100644
index 0000000000000000000000000000000000000000..65f95ba0b69cd7b3fb5dca56da242d56461287cc
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-obj.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-object value from a pending promise that is later fulfilled
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       a. Append fulfillReaction as the last element of the List that is the
+          value of promise's [[PromiseFulfillReactions]] internal slot.
+       [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+var resolve;
+var p1 = new Promise(function(_resolve) { resolve = _resolve; });
+var p2;
+
+p2 = p1.then(function() {
+    return 23;
+  });
+
+p2.then(function(value) {
+    if (value !== 23) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
+
+resolve();
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-thenable.js b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..8012d94a7df18664abfbd2cec7b257a62a56a942
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-thenable.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-thenable object value from a pending promise that is later fulfilled
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       a. Append fulfillReaction as the last element of the List that is the
+          value of promise's [[PromiseFulfillReactions]] internal slot.
+       [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        a. Return FulfillPromise(promise, resolution).
+---*/
+
+var nonThenable = { then: null };
+var resolve;
+var p1 = new Promise(function(_resolve) { resolve = _resolve; });
+var p2;
+
+p2 = p1.then(function() {
+    return nonThenable;
+  });
+
+p2.then(function(value) {
+    if (value !== nonThenable) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
+
+resolve();
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-poisoned-then.js b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-poisoned-then.js
new file mode 100644
index 0000000000000000000000000000000000000000..9abf9511e31e5423d1be88a89525a71471423ec5
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-poisoned-then.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with an object with a "poisoned" `then` property from a pending promise that is later fulfilled
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       a. Append fulfillReaction as the last element of the List that is the
+          value of promise's [[PromiseFulfillReactions]] internal slot.
+       [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       a. Return RejectPromise(promise, then.[[value]]).
+---*/
+
+var value = {};
+var resolve;
+var poisonedThen = Object.defineProperty({}, 'then', {
+  get: function() {
+    throw value;
+  }
+});
+var p1 = new Promise(function(_resolve) { resolve = _resolve; });
+var p2;
+
+p2 = p1.then(function() {
+    return poisonedThen;
+  });
+
+p2.then(function(x) {
+    $DONE('The promise should not be fulfilled.');
+  }, function(x) {
+    if (x !== value) {
+      $DONE('The promise should be rejected with the thrown exception.');
+      return;
+    }
+
+    $DONE();
+  });
+
+resolve();
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-self.js b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-self.js
new file mode 100644
index 0000000000000000000000000000000000000000..9a2f1da696203b3715fb8f6b7f01beaa0df90cd7
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-self.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a reference to the promise itself from a pending promise that is later fulfilled
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       a. Append fulfillReaction as the last element of the List that is the
+          value of promise's [[PromiseFulfillReactions]] internal slot.
+       [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    6. If SameValue(resolution, promise) is true, then
+       a. Let selfResolutionError be a newly created TypeError object.
+       b. Return RejectPromise(promise, selfResolutionError).
+---*/
+
+var resolve;
+var p1 = new Promise(function(_resolve) { resolve = _resolve; });
+var p2;
+
+p2 = p1.then(function() {
+    return p2;
+  });
+
+p2.then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(reason) {
+    if (!reason) {
+      $DONE('The promise should be rejected with a value.');
+      return;
+    }
+
+    if (reason.constructor !== TypeError) {
+      $DONE('The promise should be rejected with a TypeError instance.');
+      return;
+    }
+
+    $DONE();
+  });
+
+resolve();
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-thenable.js b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6153bc8f1652dc8b932e838eb76e5acdd90172b
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-fulfilled-thenable.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a thenable object value from a pending promise that is later fulfilled
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       a. Append fulfillReaction as the last element of the List that is the
+          value of promise's [[PromiseFulfillReactions]] internal slot.
+       [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        [...]
+    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+        «promise, resolution, thenAction»)
+---*/
+
+var value = {};
+var resolve;
+var thenable = new Promise(function(resolve) { resolve(value); });
+var p1 = new Promise(function(_resolve) { resolve = _resolve; });
+var p2;
+
+p2 = p1.then(function() {
+    return thenable;
+  });
+
+p2.then(function(x) {
+    if (x !== value) {
+      $DONE('The promise should be fulfilled with the resolution value of the provided promise.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
+
+resolve();
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-rejected-non-obj.js b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-non-obj.js
new file mode 100644
index 0000000000000000000000000000000000000000..576cdf0067646aa486d5301d5e614d3d75bb1af7
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-non-obj.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-object value from a pending promise that is later rejected
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       [...]
+       b. Append rejectReaction as the last element of the List that is the
+          value of promise's [[PromiseRejectReactions]] internal slot.
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+var reject;
+var p1 = new Promise(function(_, _reject) { reject = _reject; });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return 23;
+  });
+
+p2.then(function(value) {
+    if (value !== 23) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
+
+reject();
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-rejected-non-thenable.js b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-non-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..95191b0b8817f0377ebb7e01dc9b29c57521db06
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-non-thenable.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-thenable object value from a pending promise that is later rejected
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       [...]
+       b. Append rejectReaction as the last element of the List that is the
+          value of promise's [[PromiseRejectReactions]] internal slot.
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        a. Return FulfillPromise(promise, resolution).
+---*/
+
+var nonThenable = { then: null };
+var reject;
+var p1 = new Promise(function(_, _reject) { reject = _reject; });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return nonThenable;
+  });
+
+p2.then(function(value) {
+    if (value !== nonThenable) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
+
+reject();
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-rejected-poisoned-then.js b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-poisoned-then.js
new file mode 100644
index 0000000000000000000000000000000000000000..f7808d038d28a8c87f4c554c86b97d7c2765f1f8
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-poisoned-then.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with an object with a "poisoned" `then` property from a pending promise that is later rejected
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       [...]
+       b. Append rejectReaction as the last element of the List that is the
+          value of promise's [[PromiseRejectReactions]] internal slot.
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       a. Return RejectPromise(promise, then.[[value]]).
+---*/
+
+var value = {};
+var reject;
+var poisonedThen = Object.defineProperty({}, 'then', {
+  get: function() {
+    throw value;
+  }
+});
+var p1 = new Promise(function(_, _reject) { reject = _reject; });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return poisonedThen;
+  });
+
+p2.then(function(x) {
+    $DONE('The promise should not be fulfilled.');
+  }, function(x) {
+    if (x !== value) {
+      $DONE('The promise should be rejected with the thrown exception.');
+      return;
+    }
+
+    $DONE();
+  });
+
+reject();
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-rejected-self.js b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-self.js
new file mode 100644
index 0000000000000000000000000000000000000000..87937e398cf957edeaa526ea650756a277d4c221
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-self.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a reference to the promise itself from a pending promise that is later rejected
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       [...]
+       b. Append rejectReaction as the last element of the List that is the
+          value of promise's [[PromiseRejectReactions]] internal slot.
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    6. If SameValue(resolution, promise) is true, then
+       a. Let selfResolutionError be a newly created TypeError object.
+       b. Return RejectPromise(promise, selfResolutionError).
+---*/
+
+var reject;
+var p1 = new Promise(function(_, _reject) { reject = _reject; });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return p2;
+  });
+
+p2.then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(reason) {
+    if (!reason) {
+      $DONE('The promise should be rejected with a value.');
+      return;
+    }
+
+    if (reason.constructor !== TypeError) {
+      $DONE('The promise should be rejected with a TypeError instance.');
+      return;
+    }
+
+    $DONE();
+  });
+
+reject();
diff --git a/test/built-ins/Promise/prototype/then/resolve-pending-rejected-thenable.js b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..bb33553bd9b14045c8f5d39089dbc7b9d9f2ff5d
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-pending-rejected-thenable.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a thenable object value from a pending promise that is later rejected
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    7. If the value of promise's [[PromiseState]] internal slot is "pending",
+       [...]
+       b. Append rejectReaction as the last element of the List that is the
+          value of promise's [[PromiseRejectReactions]] internal slot.
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        [...]
+    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+        «promise, resolution, thenAction»)
+---*/
+
+var value = {};
+var reject;
+var thenable = new Promise(function(resolve) { resolve(value); });
+var p1 = new Promise(function(_, _reject) { reject = _reject; });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return thenable;
+  });
+
+p2.then(function(x) {
+    if (x !== value) {
+      $DONE('The promise should be fulfilled with the resolution value of the provided promise.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
+
+reject();
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-obj.js b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-obj.js
new file mode 100644
index 0000000000000000000000000000000000000000..35e9e3f7fadb61ccf3f5253dd687d4866af5c3aa
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-obj.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-object value from a fulfilled promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    8. Else if the value of promise's [[PromiseState]] internal slot is
+       "fulfilled",
+       a. Let value be the value of promise's [[PromiseResult]] internal slot.
+       b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
+          value»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+var p1 = new Promise(function(resolve) { resolve(); });
+var p2;
+
+p2 = p1.then(function() {
+    return 23;
+  });
+
+p2.then(function(value) {
+    if (value !== 23) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-thenable.js b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..07c40145a546a240fce26394688b6424c36d2c8f
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-thenable.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-thenable object value from a fulfilled promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    8. Else if the value of promise's [[PromiseState]] internal slot is
+       "fulfilled",
+       a. Let value be the value of promise's [[PromiseResult]] internal slot.
+       b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
+          value»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        a. Return FulfillPromise(promise, resolution).
+---*/
+
+var nonThenable = { then: null };
+var p1 = new Promise(function(resolve) { resolve(); });
+var p2;
+
+p2 = p1.then(function() {
+    return nonThenable;
+  });
+
+p2.then(function(value) {
+    if (value !== nonThenable) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-poisoned-then.js b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-poisoned-then.js
new file mode 100644
index 0000000000000000000000000000000000000000..ef5a9e0834afdce42c976f49ca11b790649a1987
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-poisoned-then.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with an object with a "poisoned" `then` property from a fulfilled promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    8. Else if the value of promise's [[PromiseState]] internal slot is
+       "fulfilled",
+       a. Let value be the value of promise's [[PromiseResult]] internal slot.
+       b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
+          value»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       a. Return RejectPromise(promise, then.[[value]]).
+---*/
+
+var value = {};
+var poisonedThen = Object.defineProperty({}, 'then', {
+  get: function() {
+    throw value;
+  }
+});
+var p1 = new Promise(function(resolve) { resolve(); });
+var p2;
+
+p2 = p1.then(function() {
+    return poisonedThen;
+  });
+
+p2.then(function(x) {
+    $DONE('The promise should not be fulfilled.');
+  }, function(x) {
+    if (x !== value) {
+      $DONE('The promise should be rejected with the thrown exception.');
+      return;
+    }
+
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-self.js b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-self.js
new file mode 100644
index 0000000000000000000000000000000000000000..d97a348c2bd9c94f2b295980acfa52b9d5780e98
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-self.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a reference to the promise itself from a fulfilled promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    8. Else if the value of promise's [[PromiseState]] internal slot is
+       "fulfilled",
+       a. Let value be the value of promise's [[PromiseResult]] internal slot.
+       b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
+          value»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    6. If SameValue(resolution, promise) is true, then
+       a. Let selfResolutionError be a newly created TypeError object.
+       b. Return RejectPromise(promise, selfResolutionError).
+---*/
+
+var p1 = new Promise(function(resolve) { resolve(); });
+var p2;
+
+p2 = p1.then(function() {
+    return p2;
+  });
+
+p2.then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(reason) {
+    if (!reason) {
+      $DONE('The promise should be rejected with a value.');
+      return;
+    }
+
+    if (reason.constructor !== TypeError) {
+      $DONE('The promise should be rejected with a TypeError instance.');
+      return;
+    }
+
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-thenable.js b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..86691de55cf89e37e992fe18b7331e848fa66906
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-fulfilled-thenable.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a thenable object value from a fulfilled promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    8. Else if the value of promise's [[PromiseState]] internal slot is
+       "fulfilled",
+       a. Let value be the value of promise's [[PromiseResult]] internal slot.
+       b. EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction,
+          value»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        [...]
+    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+        «promise, resolution, thenAction»)
+---*/
+
+var value = {};
+var thenable = new Promise(function(resolve) { resolve(value); });
+var p1 = new Promise(function(resolve) { resolve(); });
+var p2;
+
+p2 = p1.then(function() {
+    return thenable;
+  });
+
+p2.then(function(x) {
+    if (x !== value) {
+      $DONE('The promise should be fulfilled with the resolution value of the provided promise.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-rejected-non-obj.js b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-non-obj.js
new file mode 100644
index 0000000000000000000000000000000000000000..f9151850dc5c40a448cd63c119781ee852bce0c8
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-non-obj.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-object value from a rejected promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    9. Else if the value of promise's [[PromiseState]] internal slot is
+       "rejected",
+       a. Let reason be the value of promise's [[PromiseResult]] internal slot.
+       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
+          «rejectReaction, reason»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+var p1 = new Promise(function(_, reject) { reject(); });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return 23;
+  });
+
+p2.then(function(value) {
+    if (value !== 23) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-rejected-non-thenable.js b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-non-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..421376088fd65e980206294aa16b2f4fa6602b63
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-non-thenable.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-thenable object value from a rejected promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    9. Else if the value of promise's [[PromiseState]] internal slot is
+       "rejected",
+       a. Let reason be the value of promise's [[PromiseResult]] internal slot.
+       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
+          «rejectReaction, reason»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        a. Return FulfillPromise(promise, resolution).
+---*/
+
+var nonThenable = { then: null };
+var p1 = new Promise(function(_, reject) { reject(); });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return nonThenable;
+  });
+
+p2.then(function(value) {
+    if (value !== nonThenable) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-rejected-poisoned-then.js b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-poisoned-then.js
new file mode 100644
index 0000000000000000000000000000000000000000..785f557b7b7f2e759867fcca5f4c6bcf79854973
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-poisoned-then.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with an object with a "poisoned" `then` property from a rejected promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    9. Else if the value of promise's [[PromiseState]] internal slot is
+       "rejected",
+       a. Let reason be the value of promise's [[PromiseResult]] internal slot.
+       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
+          «rejectReaction, reason»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       a. Return RejectPromise(promise, then.[[value]]).
+---*/
+
+var value = {};
+var poisonedThen = Object.defineProperty({}, 'then', {
+  get: function() {
+    throw value;
+  }
+});
+var p1 = new Promise(function(_, reject) { reject(); });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return poisonedThen;
+  });
+
+p2.then(function(x) {
+    $DONE('The promise should not be fulfilled.');
+  }, function(x) {
+    if (x !== value) {
+      $DONE('The promise should be rejected with the thrown exception.');
+      return;
+    }
+
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-rejected-self.js b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-self.js
new file mode 100644
index 0000000000000000000000000000000000000000..cfdf3e4b0a466248ba0eb4cb1748f264bac1bc6e
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-self.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a reference to the promise itself from a rejected promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    9. Else if the value of promise's [[PromiseState]] internal slot is
+       "rejected",
+       a. Let reason be the value of promise's [[PromiseResult]] internal slot.
+       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
+          «rejectReaction, reason»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    6. If SameValue(resolution, promise) is true, then
+       a. Let selfResolutionError be a newly created TypeError object.
+       b. Return RejectPromise(promise, selfResolutionError).
+---*/
+
+var p1 = new Promise(function(_, reject) { reject(); });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return p2;
+  });
+
+p2.then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(reason) {
+    if (!reason) {
+      $DONE('The promise should be rejected with a value.');
+      return;
+    }
+
+    if (reason.constructor !== TypeError) {
+      $DONE('The promise should be rejected with a TypeError instance.');
+      return;
+    }
+
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/prototype/then/resolve-settled-rejected-thenable.js b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..9d1ee3f629c20c695fbacce26b4e10bdfcef1671
--- /dev/null
+++ b/test/built-ins/Promise/prototype/then/resolve-settled-rejected-thenable.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a thenable object value from a rejected promise
+es6id: 25.4.5.3
+info: >
+    [...]
+    7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+       resultCapability).
+
+    25.4.5.3.1 PerformPromiseThen
+    [...]
+    9. Else if the value of promise's [[PromiseState]] internal slot is
+       "rejected",
+       a. Let reason be the value of promise's [[PromiseResult]] internal slot.
+       b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob,
+          «rejectReaction, reason»).
+
+    25.4.2.1 PromiseReactionJob
+    [...]
+    8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+       «handlerResult.[[value]]»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        [...]
+    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+        «promise, resolution, thenAction»)
+---*/
+
+var value = {};
+var thenable = new Promise(function(resolve) { resolve(value); });
+var p1 = new Promise(function(_, reject) { reject(); });
+var p2;
+
+p2 = p1.then(function() {}, function() {
+    return thenable;
+  });
+
+p2.then(function(x) {
+    if (x !== value) {
+      $DONE('The promise should be fulfilled with the resolution value of the provided promise.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/race/resolve-non-obj.js b/test/built-ins/Promise/race/resolve-non-obj.js
new file mode 100644
index 0000000000000000000000000000000000000000..6dfd31a9cbfc25808bd39d79e595c50aae8e7568
--- /dev/null
+++ b/test/built-ins/Promise/race/resolve-non-obj.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-object value
+es6id: 25.4.4.3
+info: >
+    [...]
+    6. Let promiseCapability be NewPromiseCapability(C).
+    [...]
+    11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+    [...]
+
+    25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+    1. Repeat
+       [...]
+       j. Let result be Invoke(nextPromise, "then",
+          «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+var thenable = {
+  then: function(resolve) {
+    resolve(23);
+  }
+};
+
+Promise.race([thenable])
+  .then(function(value) {
+    if (value !== 23) {
+      $DONE('The promise should be resolved with the correct value.');
+      return;
+    }
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/race/resolve-non-thenable.js b/test/built-ins/Promise/race/resolve-non-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..179ab43445ca66ac1b9e2e617e05a511fc8c2ef7
--- /dev/null
+++ b/test/built-ins/Promise/race/resolve-non-thenable.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-thenable object value
+es6id: 25.4.4.3
+info: >
+    [...]
+    6. Let promiseCapability be NewPromiseCapability(C).
+    [...]
+    11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+    [...]
+
+    25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+    1. Repeat
+       [...]
+       j. Let result be Invoke(nextPromise, "then",
+          «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        a. Return FulfillPromise(promise, resolution).
+---*/
+
+var value = {};
+var thenable = {
+  then: function(resolve) {
+    resolve(value);
+  }
+};
+
+Promise.race([thenable])
+  .then(function(val) {
+    if (val !== value) {
+      $DONE('The promise should be resolved with the correct value.');
+      return;
+    }
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/race/resolve-poisoned-then.js b/test/built-ins/Promise/race/resolve-poisoned-then.js
new file mode 100644
index 0000000000000000000000000000000000000000..c25563dad430948e42a9180ae707c4aad777a74b
--- /dev/null
+++ b/test/built-ins/Promise/race/resolve-poisoned-then.js
@@ -0,0 +1,46 @@
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with an object with a "poisoned" `then` property
+es6id: 25.4.4.3
+info: >
+    [...]
+    6. Let promiseCapability be NewPromiseCapability(C).
+    [...]
+    11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+    [...]
+
+    25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+    1. Repeat
+       [...]
+       j. Let result be Invoke(nextPromise, "then",
+          «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       a. Return RejectPromise(promise, then.[[value]]).
+---*/
+
+var value = {};
+var poisonedThen = Object.defineProperty({}, 'then', {
+  get: function() {
+    throw value;
+  }
+});
+var thenable = {
+  then: function(resolve) {
+    resolve(poisonedThen);
+  }
+};
+
+Promise.race([thenable])
+  .then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(val) {
+    if (val !== value) {
+      $DONE('The promise should be rejected with the correct value.');
+      return;
+    }
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/race/resolve-self.js b/test/built-ins/Promise/race/resolve-self.js
new file mode 100644
index 0000000000000000000000000000000000000000..511a03200a0dc741b81fb718bf74ba229b7819b5
--- /dev/null
+++ b/test/built-ins/Promise/race/resolve-self.js
@@ -0,0 +1,54 @@
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a reference to the promise itself
+es6id: 25.4.4.3
+info: >
+    [...]
+    6. Let promiseCapability be NewPromiseCapability(C).
+    [...]
+    11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+    [...]
+
+    25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+    1. Repeat
+       [...]
+       j. Let result be Invoke(nextPromise, "then",
+          «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    6. If SameValue(resolution, promise) is true, then
+       a. Let selfResolutionError be a newly created TypeError object.
+       b. Return RejectPromise(promise, selfResolutionError).
+---*/
+
+var self, resolve;
+var builtinResolve = Promise.resolve;
+var thenable = {
+  then: function(r) {
+    resolve = r;
+  }
+};
+
+try {
+  Promise.resolve = function(v) { return v; };
+  self = Promise.race([thenable]);
+} finally {
+  Promise.resolve = builtinResolve;
+}
+
+resolve(self);
+
+self.then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(value) {
+    if (!value) {
+      $DONE('The promise should be rejected with a value.');
+      return;
+    }
+    if (value.constructor !== TypeError) {
+      $DONE('The promise should be rejected with a TypeError instance.');
+      return;
+    }
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/race/resolve-thenable.js b/test/built-ins/Promise/race/resolve-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..8eb3f059c6bc0a9b8ad5b627c0280907d247da6d
--- /dev/null
+++ b/test/built-ins/Promise/race/resolve-thenable.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a thenable object value
+es6id: 25.4.4.3
+info: >
+    [...]
+    6. Let promiseCapability be NewPromiseCapability(C).
+    [...]
+    11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+    [...]
+
+    25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+    1. Repeat
+       [...]
+       j. Let result be Invoke(nextPromise, "then",
+          «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        [...]
+    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+        «promise, resolution, thenAction»)
+---*/
+
+var value = {};
+var thenableValue = {
+  then: function(resolve) {
+    resolve(value);
+  }
+};
+var thenable = {
+  then: function(resolve) {
+    resolve(thenableValue);
+  }
+};
+
+Promise.race([thenable])
+  .then(function(val) {
+    if (val !== value) {
+      $DONE('The promise should be resolved with the correct value.');
+      return;
+    }
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/resolve-non-obj-deferred.js b/test/built-ins/Promise/resolve-non-obj-deferred.js
new file mode 100644
index 0000000000000000000000000000000000000000..2516dbd418932461ab50b0255266fc6a92014271
--- /dev/null
+++ b/test/built-ins/Promise/resolve-non-obj-deferred.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    Resolving with a non-object value after invocation of the executor function
+es6id: 25.4.3.1
+info: >
+    [...]
+    8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+    9. Let completion be Call(executor, undefined,
+       «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+var resolve;
+var promise = new Promise(function(_resolve) {
+  resolve = _resolve;
+});
+
+promise.then(function(value) {
+    if (value !== 45) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
+
+resolve(45);
diff --git a/test/built-ins/Promise/resolve-non-obj-immed.js b/test/built-ins/Promise/resolve-non-obj-immed.js
new file mode 100644
index 0000000000000000000000000000000000000000..163a1938f9c2fdb87d2704933ea5fb061bc4473b
--- /dev/null
+++ b/test/built-ins/Promise/resolve-non-obj-immed.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-object value from within the executor function
+es6id: 25.4.3.1
+info: >
+    [...]
+    8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+    9. Let completion be Call(executor, undefined,
+       «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+var promise = new Promise(function(resolve) {
+  resolve(45);
+});
+
+promise.then(function(value) {
+    if (value !== 45) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/resolve-non-thenable-deferred.js b/test/built-ins/Promise/resolve-non-thenable-deferred.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6ed8524208a0d49f18e0cc178c111f98a87ffee
--- /dev/null
+++ b/test/built-ins/Promise/resolve-non-thenable-deferred.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    Resolving with a non-thenable object value after invocation of the executor function
+es6id: 25.4.3.1
+info: >
+    [...]
+    8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+    9. Let completion be Call(executor, undefined,
+       «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        a. Return FulfillPromise(promise, resolution).
+---*/
+
+var nonThenable = { then: null };
+var resolve;
+var promise = new Promise(function(_resolve) {
+  resolve = _resolve;
+});
+
+promise.then(function(value) {
+    if (value !== nonThenable) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
+
+resolve(nonThenable);
diff --git a/test/built-ins/Promise/resolve-non-thenable-immed.js b/test/built-ins/Promise/resolve-non-thenable-immed.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae02361404f1d552594bc7a5277b9ad0932995ce
--- /dev/null
+++ b/test/built-ins/Promise/resolve-non-thenable-immed.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    Resolving with a non-thenable object value from within the executor function
+es6id: 25.4.3.1
+info: >
+    [...]
+    8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+    9. Let completion be Call(executor, undefined,
+       «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        a. Return FulfillPromise(promise, resolution).
+---*/
+
+var nonThenable = { then: null };
+var promise = new Promise(function(resolve) {
+  resolve(nonThenable);
+});
+
+promise.then(function(value) {
+    if (value !== nonThenable) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/resolve-poisoned-then-deferred.js b/test/built-ins/Promise/resolve-poisoned-then-deferred.js
new file mode 100644
index 0000000000000000000000000000000000000000..33c2b7846962adcffb2772eba4fc669884b1e51c
--- /dev/null
+++ b/test/built-ins/Promise/resolve-poisoned-then-deferred.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    Resolving with an object with a "poisoned" `then` property after invocation
+    of the executor function
+es6id: 25.4.3.1
+info: >
+    [...]
+    8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+    9. Let completion be Call(executor, undefined,
+       «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+var value = {};
+var resolve;
+var poisonedThen = Object.defineProperty({}, 'then', {
+  get: function() {
+    throw value;
+  }
+});
+var promise = new Promise(function(_resolve) {
+  resolve = _resolve;
+});
+
+promise.then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(val) {
+    if (val !== value) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  });
+
+resolve(poisonedThen);
diff --git a/test/built-ins/Promise/resolve-poisoned-then-immed.js b/test/built-ins/Promise/resolve-poisoned-then-immed.js
new file mode 100644
index 0000000000000000000000000000000000000000..ec806a2359e37515fdc1356782e02a9ccd843d07
--- /dev/null
+++ b/test/built-ins/Promise/resolve-poisoned-then-immed.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    Resolving with an object with a "poisoned" `then` property from within the
+    executor function
+es6id: 25.4.3.1
+info: >
+    [...]
+    8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+    9. Let completion be Call(executor, undefined,
+       «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+var value = {};
+var poisonedThen = Object.defineProperty({}, 'then', {
+  get: function() {
+    throw value;
+  }
+});
+var promise = new Promise(function(resolve) {
+  resolve(poisonedThen);
+});
+
+promise.then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(val) {
+    if (val !== value) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/resolve-self.js b/test/built-ins/Promise/resolve-self.js
new file mode 100644
index 0000000000000000000000000000000000000000..9425d42b5bc3cbefdf653d45405e041e630eee02
--- /dev/null
+++ b/test/built-ins/Promise/resolve-self.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a reference to the promise itself
+es6id: 25.4.3.1
+info: >
+    [...]
+    8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+    9. Let completion be Call(executor, undefined,
+       «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    6. If SameValue(resolution, promise) is true, then
+       a. Let selfResolutionError be a newly created TypeError object.
+       b. Return RejectPromise(promise, selfResolutionError).
+---*/
+
+var resolve;
+var promise = new Promise(function(_resolve) {
+  resolve = _resolve;
+});
+
+promise.then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(reason) {
+    if (!reason) {
+      $DONE('The promise should be rejected with a value.');
+      return;
+    }
+
+    if (reason.constructor !== TypeError) {
+      $DONE('The promise should be rejected with a TypeError instance.');
+      return;
+    }
+
+    $DONE();
+  });
+
+resolve(promise);
diff --git a/test/built-ins/Promise/resolve-thenable-deferred.js b/test/built-ins/Promise/resolve-thenable-deferred.js
new file mode 100644
index 0000000000000000000000000000000000000000..93dfab0e5368ef50dfea049a2025e1105bc9c9f9
--- /dev/null
+++ b/test/built-ins/Promise/resolve-thenable-deferred.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    Resolving with a thenable object value after execution of the executor
+    function
+es6id: 25.4.3.1
+info: >
+    [...]
+    8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+    9. Let completion be Call(executor, undefined,
+       «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        [...]
+    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+        «promise, resolution, thenAction»)
+---*/
+
+var value = {};
+var resolve;
+var thenable = new Promise(function(resolve) { resolve(value); });
+var promise = new Promise(function(_resolve) {
+  resolve = _resolve;
+});
+
+promise.then(function(val) {
+    if (val !== value) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
+
+resolve(thenable);
diff --git a/test/built-ins/Promise/resolve-thenable-immed.js b/test/built-ins/Promise/resolve-thenable-immed.js
new file mode 100644
index 0000000000000000000000000000000000000000..c39f9aff684e3b6b90403b106ed72ca8dfcbb9b8
--- /dev/null
+++ b/test/built-ins/Promise/resolve-thenable-immed.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+    Resolving with a thenable object value from within the executor function
+es6id: 25.4.3.1
+info: >
+    [...]
+    8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+    9. Let completion be Call(executor, undefined,
+       «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        [...]
+    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+        «promise, resolution, thenAction»)
+---*/
+
+var value = {};
+var thenable = new Promise(function(resolve) { resolve(value); });
+var promise = new Promise(function(resolve) {
+  resolve(thenable);
+});
+
+promise.then(function(val) {
+    if (val !== value) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/resolve/resolve-non-obj.js b/test/built-ins/Promise/resolve/resolve-non-obj.js
new file mode 100644
index 0000000000000000000000000000000000000000..9a99e4d1f5ac4b25e1fb12a8c7e6d34f9cb9dd9a
--- /dev/null
+++ b/test/built-ins/Promise/resolve/resolve-non-obj.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-object value
+es6id: 25.4.4.5
+info: >
+    [...]
+    6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
+       «x»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    7. If Type(resolution) is not Object, then
+       a. Return FulfillPromise(promise, resolution).
+---*/
+
+Promise.resolve(23).then(function(value) {
+    if (value !== 23) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/resolve/resolve-non-thenable.js b/test/built-ins/Promise/resolve/resolve-non-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..446f0f9920006ed2c6cbd8e09e9be105f2553f16
--- /dev/null
+++ b/test/built-ins/Promise/resolve/resolve-non-thenable.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-thenable object value
+es6id: 25.4.4.5
+info: >
+    [...]
+    6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
+       «x»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        a. Return FulfillPromise(promise, resolution).
+---*/
+
+var value = {};
+
+Promise.resolve(value).then(function(value) {
+    if (value !== value) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });
diff --git a/test/built-ins/Promise/resolve/resolve-poisoned-then.js b/test/built-ins/Promise/resolve/resolve-poisoned-then.js
new file mode 100644
index 0000000000000000000000000000000000000000..8ada16e3328e03b3508cc5256b206856aa1709fc
--- /dev/null
+++ b/test/built-ins/Promise/resolve/resolve-poisoned-then.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with an object with a "poisoned" then property
+es6id: 25.4.4.5
+info: >
+    [...]
+    6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
+       «x»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       a. Return RejectPromise(promise, then.[[value]]).
+---*/
+
+var value = {};
+var resolve;
+var poisonedThen = Object.defineProperty({}, 'then', {
+  get: function() {
+    throw value;
+  }
+});
+
+Promise.resolve(poisonedThen).then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(val) {
+    if (val !== value) {
+      $DONE('The promise should be rejected with the provided value.');
+      return;
+    }
+
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/resolve/resolve-self.js b/test/built-ins/Promise/resolve/resolve-self.js
new file mode 100644
index 0000000000000000000000000000000000000000..a9b9b73c48e56499344f8f72905b8c1f0bed1891
--- /dev/null
+++ b/test/built-ins/Promise/resolve/resolve-self.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a reference to the promise itself
+es6id: 25.4.4.5
+info: >
+    1. Let C be the this value.
+    [...]
+    4. Let promiseCapability be NewPromiseCapability(C).
+    [...]
+    6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
+       «x»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    6. If SameValue(resolution, promise) is true, then
+       a. Let selfResolutionError be a newly created TypeError object.
+       b. Return RejectPromise(promise, selfResolutionError).
+---*/
+
+var resolve, reject;
+var promise = new Promise(function(_resolve, _reject) {
+  resolve = _resolve;
+  reject = _reject;
+});
+var P = function(executor) {
+  executor(resolve, reject);
+  return promise;
+};
+
+Promise.resolve.call(P, promise)
+  .then(function() {
+    $DONE('The promise should not be fulfilled.');
+  }, function(value) {
+    if (!value) {
+      $DONE('The promise should be rejected with a value.');
+      return;
+    }
+    if (value.constructor !== TypeError) {
+      $DONE('The promise should be rejected with a TypeError instance.');
+      return;
+    }
+
+    $DONE();
+  });
diff --git a/test/built-ins/Promise/resolve/resolve-thenable.js b/test/built-ins/Promise/resolve/resolve-thenable.js
new file mode 100644
index 0000000000000000000000000000000000000000..62b061b2ee78800cfd10cfc6a4dc73fbeca3092a
--- /dev/null
+++ b/test/built-ins/Promise/resolve/resolve-thenable.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a thenable object value
+es6id: 25.4.4.5
+info: >
+    [...]
+    6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
+       «x»).
+    [...]
+
+    25.4.1.3.2 Promise Resolve Functions
+    [...]
+    8. Let then be Get(resolution, "then").
+    9. If then is an abrupt completion, then
+       [...]
+    10. Let thenAction be then.[[value]].
+    11. If IsCallable(thenAction) is false, then
+        [...]
+    12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+        «promise, resolution, thenAction»)
+---*/
+
+var value = {};
+var thenable = {
+  then: function(resolve) {
+    resolve(value);
+  }
+};
+
+Promise.resolve(thenable).then(function(val) {
+    if (val !== value) {
+      $DONE('The promise should be fulfilled with the provided value.');
+      return;
+    }
+
+    $DONE();
+  }, function() {
+    $DONE('The promise should not be rejected.');
+  });