summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/built-ins/Promise
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /js/src/tests/test262/built-ins/Promise
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/built-ins/Promise')
-rw-r--r--js/src/tests/test262/built-ins/Promise/Symbol.species/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/Symbol.species/length.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/Symbol.species/prop-desc.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/Symbol.species/return-value.js16
-rw-r--r--js/src/tests/test262/built-ins/Promise/Symbol.species/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/Symbol.species/symbol-species-name.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/Symbol.species/symbol-species.js20
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A1.1_T1.js12
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.1_T1.js14
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.2_T1.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T1.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T2.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T3.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T1.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T2.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T3.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A4.1_T1.js18
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A5.1_T1.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.1_T1.js24
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.2_T1.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.1_T1.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T1.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T2.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/call-resolve-element-after-return.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/call-resolve-element-items.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/call-resolve-element.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/capability-executor-called-twice.js104
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/capability-executor-not-callable.js109
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-no-close.js79
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-reject.js68
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/ctx-ctor-throws.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/ctx-ctor.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/ctx-non-ctor.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/ctx-non-object.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/does-not-invoke-array-setters.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-close.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-reject.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error-reject.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js44
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-promise.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve-return.js49
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-resolve.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-then-error-close.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-then-error-reject.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-close.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-reject.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/invoke-then.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-arg-is-false-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-arg-is-null-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-arg-is-number-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-arg-is-string-resolve.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-arg-is-symbol-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-arg-is-true-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-arg-is-undefined-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-assigned-false-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-assigned-null-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-assigned-number-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-assigned-string-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-assigned-symbol-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-assigned-true-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-assigned-undefined-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-no-close.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-returns-false-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-returns-null-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-returns-number-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-returns-string-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-returns-symbol-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-returns-true-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-returns-undefined-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-step-err-no-close.js59
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/iter-step-err-reject.js56
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/length.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/name.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/new-resolve-function.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/not-a-constructor.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/prop-desc.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/reject-deferred.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/reject-ignored-deferred.js59
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/reject-ignored-immed.js49
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/reject-immed.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit-from-same.js75
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit.js71
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-element-function-extensible.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-element-function-length.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-element-function-name.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-element-function-nonconstructor.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-element-function-property-order.js32
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-element-function-prototype.js32
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-from-same-thenable.js81
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection-deferred.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-non-callable.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-non-thenable.js76
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js29
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-poisoned-then.js72
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/resolve-thenable.js74
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/same-reject-function.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/all/species-get-error.js29
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element-after-return.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element-items.js61
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/capability-executor-called-twice.js108
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/capability-executor-not-callable.js109
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/capability-resolve-throws-no-close.js66
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/capability-resolve-throws-reject.js60
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/ctx-ctor-throws.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/ctx-ctor.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/ctx-non-ctor.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/ctx-non-object.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/does-not-invoke-array-setters.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-error-close.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-error-reject.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-error-reject.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-error.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-once-multiple-calls.js49
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-once-no-calls.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-custom.js44
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-promise.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-values-every-iteration-of-promise.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-return.js44
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-error-close.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-error-reject.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-get-error-close.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-get-error-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/invoke-then.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/is-function.js12
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-false-reject.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-null-reject.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-number-reject.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-poisoned.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-string-resolve.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-symbol-reject.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-true-reject.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-undefined-reject.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-false-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-null-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-number-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-string-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-symbol-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-true-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-undefined-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-next-err-reject.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-next-val-err-no-close.js58
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-next-val-err-reject.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-false-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-null-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-number-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-string-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-symbol-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-true-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-undefined-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-step-err-no-close.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/iter-step-err-reject.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/length.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/name.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/new-reject-function.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/new-resolve-function.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/not-a-constructor.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/prop-desc.js23
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-deferred.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-extensible.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-length.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-multiple-calls.js56
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-name.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-nonconstructor.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-property-order.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-prototype.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-ignored-deferred.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-ignored-immed.js44
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/reject-immed.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-before-loop-exit-from-same.js85
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-before-loop-exit.js81
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-extensible.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-length.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-name.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-nonconstructor.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-property-order.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-prototype.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-from-same-thenable.js91
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-ignores-late-rejection-deferred.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-ignores-late-rejection.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-non-callable.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-non-thenable.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-not-callable-reject-with-typeerror.js29
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-poisoned-then.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolve-thenable.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-fulfilled.js65
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-mixed.js78
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-rejected.js65
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolved-immed.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-extra-ticks.js48
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-mixed.js63
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-with-rejections.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolved-then-catch-finally.js70
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolves-empty-array.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/resolves-to-array.js29
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/returns-promise.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/allSettled/species-get-error.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/call-reject-element-after-return.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/call-reject-element-items.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/capability-executor-called-twice.js108
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/capability-executor-not-callable.js109
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/capability-reject-throws-no-close.js69
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/capability-resolve-throws-no-close.js69
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/capability-resolve-throws-reject.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/ctx-ctor-throws.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/ctx-ctor.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/ctx-non-ctor.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/ctx-non-object.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-error-close.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-error-reject.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-error-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-error.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-once-multiple-calls.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-once-no-calls.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-custom.js44
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-promise.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-custom.js44
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-promise.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve-return.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-resolve.js32
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-then-error-close.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-then-error-reject.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-then-get-error-close.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-then-get-error-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-then-on-promises-every-iteration.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/invoke-then.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/is-function.js12
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-empty-iterable-reject.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-empty-string-reject.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-error-object-reject.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-false-reject.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-null-reject.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-number-reject.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-poisoned.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-string-resolve.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-symbol-reject.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-true-reject.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-arg-is-undefined-reject.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-assigned-false-reject.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-assigned-null-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-assigned-number-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-assigned-string-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-assigned-symbol-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-assigned-true-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-assigned-undefined-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-next-val-err-no-close.js64
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-next-val-err-reject.js58
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-returns-false-reject.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-returns-null-reject.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-returns-number-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-returns-string-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-returns-symbol-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-returns-true-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-returns-undefined-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-step-err-no-close.js61
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/iter-step-err-reject.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/length.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/name.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/new-reject-function.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/not-a-constructor.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/prop-desc.js23
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-all-mixed.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-deferred.js32
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-element-function-extensible.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-element-function-length.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-element-function-name.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-element-function-nonconstructor.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-element-function-property-order.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-element-function-prototype.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-from-same-thenable.js70
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-ignored-deferred.js69
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-ignored-immed.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/reject-immed.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-before-loop-exit-from-same.js101
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-before-loop-exit.js102
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-from-reject-catch.js23
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-from-resolve-reject-catch.js23
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-from-same-thenable.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-ignores-late-rejection-deferred.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-ignores-late-rejection.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-non-callable.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-non-thenable.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolve-not-callable-reject-with-typeerror.js29
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolved-sequence-extra-ticks.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolved-sequence-mixed.js70
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolved-sequence-with-rejections.js65
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/resolved-sequence.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/returns-promise.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/any/species-get-error.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/constructor.js11
-rw-r--r--js/src/tests/test262/built-ins/Promise/create-resolving-functions-reject.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/create-resolving-functions-resolve.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/exception-after-resolve-in-executor.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/exception-after-resolve-in-thenable-job.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/exec-args.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/executor-call-context-sloppy.js24
-rw-r--r--js/src/tests/test262/built-ins/Promise/executor-call-context-strict-strict.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/executor-function-extensible.js23
-rw-r--r--js/src/tests/test262/built-ins/Promise/executor-function-length.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/executor-function-name.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/executor-function-not-a-constructor.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/executor-function-property-order.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/executor-function-prototype.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/executor-not-callable.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/get-prototype-abrupt-executor-not-callable.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/get-prototype-abrupt.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/is-a-constructor.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/length.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/name.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/promise.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/property-order.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/proto-from-ctor-realm.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/S25.4.4.2_A1.1_T1.js18
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/S25.4.5_A3.1_T1.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/Symbol.toStringTag.js23
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A1.1_T1.js16
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A2.1_T1.js19
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A3.1_T1.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A3.1_T2.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/invokes-then.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/length.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/name.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/not-a-constructor.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/prop-desc.js19
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-non-object.js32
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-obj-coercible.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-not-callable.js75
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-poisoned.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-throws.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-function.js69
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-non-function.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-function.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-method.js18
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/length.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/name.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/not-a-constructor.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/prop-desc.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls-PromiseResolve.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls-argument.js69
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-no-fulfill.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-override-with-throw.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/resolution-value-no-override.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls-PromiseResolve.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls-argument.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/species-constructor.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-reject-count.js24
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-resolve-count.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-reject-count.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-resolve-count.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-non-object.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-proxy.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-not-callable.js56
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-poisoned.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-throws.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-thenable.js19
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/no-promise-state.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/prop-desc.js16
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/proto.js16
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A1.1_T1.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T1.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T2.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T3.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A1.1_T1.js16
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A1.1_T2.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A2.1_T1.js18
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A2.1_T2.js20
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.1_T1.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.1_T2.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.2_T1.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.2_T2.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.1_T1.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.2_T1.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.3_T1.js49
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/capability-executor-called-twice.js99
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/capability-executor-not-callable.js104
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/context-check-on-entry.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/ctor-access-count.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/ctor-custom.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/ctor-null.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/ctor-poisoned.js29
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/ctor-throws.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/ctor-undef.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/deferred-is-resolved-value.js68
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/length.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/name.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/not-a-constructor.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/prfm-fulfilled.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/prfm-pending-fulfulled.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/prfm-pending-rejected.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/prfm-rejected.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/prop-desc.js19
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/reject-pending-fulfilled.js49
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/reject-pending-rejected.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/reject-settled-fulfilled.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/reject-settled-rejected.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-obj.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-thenable.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-poisoned-then.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-prms-cstm-then.js61
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-self.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-thenable.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-non-obj.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-non-thenable.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-poisoned-then.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-prms-cstm-then.js62
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-self.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-thenable.js58
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-obj.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-thenable.js58
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-poisoned-then.js58
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-prms-cstm-then.js65
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-self.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-thenable.js61
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-non-obj.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-non-thenable.js58
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-poisoned-then.js58
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-prms-cstm-then.js65
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-self.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-thenable.js61
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-invoke-nonstrict.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-invoke-strict-strict.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next-abrupt.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-return-abrupt.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-return-normal.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-identity.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-invoke-nonstrict.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-invoke-strict-strict.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-next-abrupt.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-next.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-return-abrupt.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-return-normal.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-thrower.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/prototype/then/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A1.1_T1.js12
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.1_T1.js15
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T1.js19
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T2.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T3.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A3.1_T1.js20
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A3.1_T2.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A4.1_T1.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A4.1_T2.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A5.1_T1.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A6.1_T1.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A6.2_T1.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T1.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T2.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T3.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.2_T1.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.3_T1.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.3_T2.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/capability-executor-called-twice.js101
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/capability-executor-not-callable.js85
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/ctx-ctor-throws.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/ctx-ctor.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/ctx-non-ctor.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/ctx-non-object.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-error-close.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-error-reject.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-error-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-error.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-once-multiple-calls.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-once-no-calls.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-custom.js44
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-promise.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-values-every-iteration-of-promise.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve-return.js49
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-resolve.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-then-error-close.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-then-error-reject.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-then-get-error-close.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-then-get-error-reject.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/invoke-then.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-arg-is-false-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-arg-is-null-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-arg-is-number-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-arg-is-string-resolve.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-arg-is-symbol-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-arg-is-true-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-arg-is-undefined-reject.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-assigned-false-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-assigned-null-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-assigned-number-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-assigned-string-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-assigned-symbol-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-assigned-true-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-assigned-undefined-reject.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-next-val-err-no-close.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-next-val-err-reject.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-returns-false-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-returns-null-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-returns-number-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-returns-string-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-returns-symbol-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-returns-true-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-returns-undefined-reject.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-step-err-no-close.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/iter-step-err-reject.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/length.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/name.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/not-a-constructor.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/prop-desc.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/reject-deferred.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/reject-from-same-thenable.js65
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/reject-ignored-deferred.js57
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/reject-ignored-immed.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/reject-immed.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-from-same-thenable.js62
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-ignores-late-rejection-deferred.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-ignores-late-rejection.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-non-callable.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-non-obj.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-non-thenable.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-poisoned-then.js49
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-prms-cstm-then.js56
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-self.js59
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolve-thenable.js54
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolved-sequence-extra-ticks.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolved-sequence-mixed.js49
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolved-sequence-with-rejections.js53
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolved-sequence.js52
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/resolved-then-catch-finally.js40
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/same-reject-function.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/same-resolve-function.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/race/species-get-error.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-function-extensible.js20
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-function-length.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-function-name.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-function-nonconstructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-function-property-order.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-function-prototype.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-ignored-via-abrupt.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-ignored-via-fn-deferred.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-ignored-via-fn-immed.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-via-abrupt-queue.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-via-abrupt.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-via-fn-deferred-queue.js63
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-via-fn-deferred.js41
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-via-fn-immed-queue.js60
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject-via-fn-immed.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A1.1_T1.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A2.1_T1.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A3.1_T1.js18
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/capability-executor-called-twice.js81
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/capability-executor-not-callable.js85
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/capability-invocation-error.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/capability-invocation.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/ctx-ctor-throws.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/ctx-ctor.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/ctx-non-ctor.js18
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/ctx-non-object.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/length.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/name.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/not-a-constructor.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/prop-desc.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/reject/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-function-extensible.js20
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-function-length.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-function-name.js30
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-function-nonconstructor.js24
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-function-property-order.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-function-prototype.js22
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-ignored-via-fn-deferred.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-ignored-via-fn-immed.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-non-obj-deferred.js39
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-non-obj-immed.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-non-thenable-deferred.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-non-thenable-immed.js44
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-poisoned-then-deferred.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-poisoned-then-immed.js43
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-prms-cstm-then-deferred.js55
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-prms-cstm-then-immed.js62
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-self.js45
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-thenable-deferred.js51
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve-thenable-immed.js47
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A1.1_T1.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.1_T1.js15
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.2_T1.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.3_T1.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A3.1_T1.js56
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A4.1_T1.js25
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_1.js24
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_2.js46
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/arg-non-thenable.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/arg-poisoned-then.js37
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/arg-uniq-ctor.js29
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/capability-executor-called-twice.js81
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/capability-executor-not-callable.js85
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/capability-invocation-error.js33
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/context-non-object-with-promise.js50
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/ctx-ctor-throws.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/ctx-ctor.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/ctx-non-ctor.js18
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/ctx-non-object.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/length.js27
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/name.js28
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/not-a-constructor.js31
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/prop-desc.js21
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/resolve-from-promise-capability.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/resolve-non-obj.js29
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/resolve-non-thenable.js35
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/resolve-poisoned-then.js38
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/resolve-prms-cstm-then.js44
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/resolve-self.js48
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/resolve-thenable.js42
-rw-r--r--js/src/tests/test262/built-ins/Promise/resolve/shell.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/shell.js101
-rw-r--r--js/src/tests/test262/built-ins/Promise/undefined-newtarget.js26
-rw-r--r--js/src/tests/test262/built-ins/Promise/withResolvers/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Promise/withResolvers/ctx-ctor.js18
-rw-r--r--js/src/tests/test262/built-ins/Promise/withResolvers/ctx-non-ctor.js14
-rw-r--r--js/src/tests/test262/built-ins/Promise/withResolvers/ctx-non-object.js34
-rw-r--r--js/src/tests/test262/built-ins/Promise/withResolvers/promise.js17
-rw-r--r--js/src/tests/test262/built-ins/Promise/withResolvers/resolvers.js18
-rw-r--r--js/src/tests/test262/built-ins/Promise/withResolvers/result.js36
-rw-r--r--js/src/tests/test262/built-ins/Promise/withResolvers/shell.js0
645 files changed, 25556 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Promise/Symbol.species/browser.js b/js/src/tests/test262/built-ins/Promise/Symbol.species/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/Symbol.species/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/Symbol.species/length.js b/js/src/tests/test262/built-ins/Promise/Symbol.species/length.js
new file mode 100644
index 0000000000..a2556d0a44
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/Symbol.species/length.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.6
+description: >
+ get Promise [ @@species ].length is 0.
+info: |
+ get Promise [ @@species ]
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Symbol.species]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(Promise, Symbol.species);
+
+assert.sameValue(desc.get.length, 0);
+
+verifyNotEnumerable(desc.get, "length");
+verifyNotWritable(desc.get, "length");
+verifyConfigurable(desc.get, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/Symbol.species/prop-desc.js b/js/src/tests/test262/built-ins/Promise/Symbol.species/prop-desc.js
new file mode 100644
index 0000000000..13904b6a3a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/Symbol.species/prop-desc.js
@@ -0,0 +1,27 @@
+// 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.4.6
+description: Promise `Symbol.species` property
+info: |
+ Promise[@@species] is an accessor property whose set accessor function is
+ undefined.
+
+ ES6 Section 17:
+
+ Every accessor property described in clauses 18 through 26 and in Annex B.2
+ has the attributes {[[Enumerable]]: false, [[Configurable]]: true } unless
+ otherwise specified.
+features: [Symbol.species]
+includes: [propertyHelper.js]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(Promise, Symbol.species);
+
+assert.sameValue(desc.set, undefined);
+assert.sameValue(typeof desc.get, 'function');
+
+verifyNotEnumerable(Promise, Symbol.species);
+verifyConfigurable(Promise, Symbol.species);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/Symbol.species/return-value.js b/js/src/tests/test262/built-ins/Promise/Symbol.species/return-value.js
new file mode 100644
index 0000000000..f4298bc6ab
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/Symbol.species/return-value.js
@@ -0,0 +1,16 @@
+// 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.4.6
+description: Promise `Symbol.species` accessor function return value
+info: |
+ 1. Return the this value.
+features: [Symbol.species]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(Promise, Symbol.species);
+var thisValue = {};
+
+assert.sameValue(desc.get.call(thisValue), thisValue);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/Symbol.species/shell.js b/js/src/tests/test262/built-ins/Promise/Symbol.species/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/Symbol.species/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/Symbol.species/symbol-species-name.js b/js/src/tests/test262/built-ins/Promise/Symbol.species/symbol-species-name.js
new file mode 100644
index 0000000000..30f74b923b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/Symbol.species/symbol-species-name.js
@@ -0,0 +1,22 @@
+// 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.4.6
+description: >
+ Promise[Symbol.species] accessor property get name
+info: |
+ 25.4.4.6 get Promise [ @@species ]
+
+ ...
+ The value of the name property of this function is "get [Symbol.species]".
+features: [Symbol.species]
+---*/
+
+var descriptor = Object.getOwnPropertyDescriptor(Promise, Symbol.species);
+
+assert.sameValue(
+ descriptor.get.name,
+ 'get [Symbol.species]'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/Symbol.species/symbol-species.js b/js/src/tests/test262/built-ins/Promise/Symbol.species/symbol-species.js
new file mode 100644
index 0000000000..24da4e82ee
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/Symbol.species/symbol-species.js
@@ -0,0 +1,20 @@
+// Copyright 2015 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise has a property at `Symbol.species`
+es6id: 6.1.5.1
+author: Sam Mikes
+description: Promise[Symbol.species] exists per spec
+includes: [propertyHelper.js]
+features: [Symbol.species]
+---*/
+
+assert.sameValue(Promise[Symbol.species], Promise, "Promise[Symbol.species] is Promise");
+
+verifyNotWritable(Promise, Symbol.species, Symbol.species);
+verifyNotEnumerable(Promise, Symbol.species);
+verifyConfigurable(Promise, Symbol.species);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A1.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A1.1_T1.js
new file mode 100644
index 0000000000..1cf29b6a21
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A1.1_T1.js
@@ -0,0 +1,12 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.all is callable
+es6id: 25.4.4.1_A1.1_T1
+author: Sam Mikes
+description: Promise.all is callable
+---*/
+assert.sameValue(typeof Promise.all, "function", 'The value of `typeof Promise.all` is expected to be "function"');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.1_T1.js
new file mode 100644
index 0000000000..5d27aaab35
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.1_T1.js
@@ -0,0 +1,14 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.all([]) is a Promise
+es6id: 25.4.4.1_A2.1_T1
+author: Sam Mikes
+description: Promise.all returns a Promise
+---*/
+
+var p = Promise.all([]);
+assert(!!(p instanceof Promise), 'The value of !!(p instanceof Promise) is expected to be true');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.2_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.2_T1.js
new file mode 100644
index 0000000000..8a3eaceae9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.2_T1.js
@@ -0,0 +1,28 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.all([]) is resolved immediately
+es6id: 25.4.4.1_A2.2_T1
+author: Sam Mikes
+includes: [promiseHelper.js]
+description: Promise.all([]) returns immediately
+flags: [async]
+---*/
+
+var sequence = [];
+
+Promise.all([]).then(function() {
+ sequence.push(2);
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ sequence.push(3);
+}).then(function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, "Promises resolved in unexpected sequence");
+}).then($DONE, $DONE);
+
+sequence.push(1);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T1.js
new file mode 100644
index 0000000000..c737bb4f99
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T1.js
@@ -0,0 +1,17 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.all([]) returns a promise for a new empty array
+es6id: 25.4.4.1_A2.3_T1
+author: Sam Mikes
+description: Promise.all([]) returns a promise for an array
+flags: [async]
+---*/
+
+var arg = [];
+
+Promise.all(arg).then(function(result) {
+ assert(!!(result instanceof Array), 'The value of !!(result instanceof Array) is expected to be true');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T2.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T2.js
new file mode 100644
index 0000000000..ad9bfa6c48
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T2.js
@@ -0,0 +1,17 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.all is resolved with a new empty array
+es6id: 25.4.4.1_A2.3_T2
+author: Sam Mikes
+description: Promise.all([]) returns a Promise for an empty array
+flags: [async]
+---*/
+
+var arg = [];
+
+Promise.all(arg).then(function(result) {
+ assert.sameValue(result.length, 0, 'The value of result.length is expected to be 0');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T3.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T3.js
new file mode 100644
index 0000000000..09b598f3fc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A2.3_T3.js
@@ -0,0 +1,17 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.all([]) is resolved with Promise for a new empty array
+es6id: 25.4.4.1_A2.3_T3
+author: Sam Mikes
+description: Promise.all([]) is resolved with a Promise for a new array
+flags: [async]
+---*/
+
+var arg = [];
+
+Promise.all(arg).then(function(result) {
+ assert.notSameValue(result, arg, 'The value of result is expected to not equal the value of `arg`');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T1.js
new file mode 100644
index 0000000000..88e7558c3d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T1.js
@@ -0,0 +1,22 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.all expects an iterable argument;
+ ref 7.4.1 non-Object fails CheckIterable
+ ref 7.4.2 GetIterator throws TypeError if CheckIterable fails
+es6id: 25.4.4.1_A3.1_T1
+author: Sam Mikes
+description: Promise.all(3) returns Promise rejected with TypeError
+flags: [async]
+---*/
+
+var nonIterable = 3;
+
+Promise.all(nonIterable).then(function() {
+ throw new Test262Error('Promise unexpectedly resolved: Promise.all(nonIterable) should throw TypeError');
+}, function(err) {
+ assert(!!(err instanceof TypeError), 'The value of !!(err instanceof TypeError) is expected to be true');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T2.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T2.js
new file mode 100644
index 0000000000..23c5d8390d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T2.js
@@ -0,0 +1,21 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.all expects an iterable argument;
+ fails if recieves an abrupt completion
+ ref 7.4.1 non-Object fails CheckIterable
+ ref 7.4.2 GetIterator throws TypeError if CheckIterable fails
+es6id: S25.4.4.1_A3.1_T2
+author: Sam Mikes
+description: Promise.all(new Error()) returns Promise rejected with TypeError
+flags: [async]
+---*/
+
+Promise.all(new Error("abrupt")).then(function() {
+ throw new Test262Error('Promise unexpectedly resolved: Promise.all(abruptCompletion) should throw TypeError');
+}, function(err) {
+ assert(!!(err instanceof TypeError), 'The value of !!(err instanceof TypeError) is expected to be true');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T3.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T3.js
new file mode 100644
index 0000000000..9a93d8bd9f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A3.1_T3.js
@@ -0,0 +1,27 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.all expects an iterable argument;
+ fails if GetIterator returns an abrupt completion.
+es6id: S25.4.4.1_A3.1_T3
+author: Sam Mikes
+description: Promise.all((throw on GetIterator)) returns Promise rejected with TypeError
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+var iterThrows = {};
+Object.defineProperty(iterThrows, Symbol.iterator, {
+ get: function() {
+ throw new Error("abrupt completion");
+ }
+});
+
+Promise.all(iterThrows).then(function() {
+ throw new Test262Error('Promise unexpectedly fulfilled: Promise.all(iterThrows) should throw TypeError');
+}, function(err) {
+ assert(!!(err instanceof Error), 'The value of !!(err instanceof Error) is expected to be true');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A4.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A4.1_T1.js
new file mode 100644
index 0000000000..e63ccb33c7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A4.1_T1.js
@@ -0,0 +1,18 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.all should throw if 'this' does not conform to Promise constructor
+es6id: S25.4.4.1_A4.1_T1
+description: this must conform to Promise constructor in Promise.all
+author: Sam Mikes
+---*/
+
+function ZeroArgConstructor() {}
+
+assert.throws(TypeError, function() {
+ Promise.all.call(ZeroArgConstructor, []);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A5.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A5.1_T1.js
new file mode 100644
index 0000000000..b670d9e937
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A5.1_T1.js
@@ -0,0 +1,30 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.all expects an iterable argument;
+ rejects if IteratorStep() throws
+es6id: S25.4.4.1_A5.1_T1
+author: Sam Mikes
+description: iterator.next throws, causing Promise.all to reject
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+var iterThrows = {};
+var error = new Test262Error();
+iterThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ throw error;
+ }
+ };
+};
+
+Promise.all(iterThrows).then(function() {
+ throw new Test262Error('Promise unexpectedly resolved: Promise.all(iterThrows) should throw TypeError');
+}, function(reason) {
+ assert.sameValue(reason, error, 'The value of reason is expected to equal the value of error');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.1_T1.js
new file mode 100644
index 0000000000..0cc08b3f2a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.1_T1.js
@@ -0,0 +1,24 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.all with 1-element array
+ should accept an array with settled promise
+es6id: S25.4.4.1_A6.1_T2
+author: Sam Mikes
+description: Promise.all([p1]) is resolved with a promise for a one-element array
+flags: [async]
+---*/
+
+var p1 = Promise.resolve(3);
+
+var pAll = Promise.all([p1]);
+
+pAll.then(function(result) {
+ assert(!!(pAll instanceof Promise), 'The value of !!(pAll instanceof Promise) is expected to be true');
+ assert(!!(result instanceof Array), 'The value of !!(result instanceof Array) is expected to be true');
+ assert.sameValue(result.length, 1, 'The value of result.length is expected to be 1');
+ assert.sameValue(result[0], 3, 'The value of result[0] is expected to be 3');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.2_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.2_T1.js
new file mode 100644
index 0000000000..19e00ba2a4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A7.2_T1.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.all with 1-element array
+ should accept an array with settled promise
+es6id: S25.4.4.1_A7.2_T1
+author: Sam Mikes
+description: Promise.all() accepts a one-element array
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var p1 = new Promise(function(resolve) {
+ resolve({});
+});
+
+sequence.push(1);
+
+Promise.all([p1]).then(function(resolved) {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, "Expected Promise.all().then to queue second");
+}).catch($DONE);
+
+p1.then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, "Expected p1.then to queue first");
+}).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, "Expected final then to queue last");
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.1_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.1_T1.js
new file mode 100644
index 0000000000..89e246e08e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.1_T1.js
@@ -0,0 +1,42 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.1_A8.1_T1
+author: Sam Mikes
+description: Promise.all([p1, p2]) resolution functions are called in predictable sequence
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var p1 = new Promise(function(resolve) {
+ resolve(1);
+});
+var p2 = new Promise(function(resolve) {
+ resolve(2);
+});
+
+sequence.push(1);
+
+p1.then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, "Expected to be called first.");
+}).catch($DONE);
+
+Promise.all([p1, p2]).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, "Expected to be called third.");
+}).then($DONE, $DONE);
+
+p2.then(function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, "Expected to be called second.");
+}).catch($DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T1.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T1.js
new file mode 100644
index 0000000000..d5ffb354d8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T1.js
@@ -0,0 +1,26 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.all with 2-element array
+es6id: S25.4.4.1_A8.1_T1
+author: Sam Mikes
+description: Promise.all() rejects when a promise in its array rejects
+flags: [async]
+---*/
+
+var rejectP1,
+ p1 = new Promise(function(resolve, reject) {
+ rejectP1 = reject;
+ }),
+ p2 = Promise.resolve(2);
+
+Promise.all([p1, p2]).then(function(resolve) {
+ throw new Test262Error("Did not expect promise to be fulfilled.");
+}, function(rejected) {
+ assert.sameValue(rejected, 1, 'The value of rejected is expected to be 1');
+}).then($DONE, $DONE);
+
+rejectP1(1);
diff --git a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T2.js b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T2.js
new file mode 100644
index 0000000000..71390b4c71
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T2.js
@@ -0,0 +1,26 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.all with 2-element array
+es6id: S25.4.4.1_A8.2_T2
+author: Sam Mikes
+description: Promise.all() rejects when second promise in array rejects
+flags: [async]
+---*/
+
+var rejectP2,
+ p1 = Promise.resolve(1),
+ p2 = new Promise(function(resolve, reject) {
+ rejectP2 = reject;
+ });
+
+Promise.all([p1, p2]).then(function() {
+ throw new Test262Error("Did not expect promise to be fulfilled.");
+}, function(rejected) {
+ assert.sameValue(rejected, 2, 'The value of rejected is expected to be 2');
+}).then($DONE, $DONE);
+
+rejectP2(2);
diff --git a/js/src/tests/test262/built-ins/Promise/all/browser.js b/js/src/tests/test262/built-ins/Promise/all/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-after-return.js b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-after-return.js
new file mode 100644
index 0000000000..0204c9b790
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-after-return.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.2
+description: >
+ Cannot change result value of resolved Promise.all element after Promise.all() returned.
+info: |
+ Promise.all Resolve Element Functions
+
+ 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ 2. If alreadyCalled.[[value]] is true, return undefined.
+ 3. Set alreadyCalled.[[value]] to true.
+ ...
+---*/
+
+var callCount = 0;
+var valuesArray;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ valuesArray = values;
+ assert(Array.isArray(values), "values is array");
+ assert.sameValue(values.length, 1, "values.length");
+ assert.sameValue(values[0], "expectedValue", "values[0]");
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1OnFulfilled;
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ p1OnFulfilled = onFulfilled;
+ onFulfilled("expectedValue");
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to all()");
+
+Promise.all.call(Constructor, [p1]);
+
+assert.sameValue(callCount, 1, "callCount after call to all()");
+assert.sameValue(valuesArray[0], "expectedValue", "valuesArray after call to all()");
+
+p1OnFulfilled("unexpectedValue");
+
+assert.sameValue(callCount, 1, "callCount after call to onFulfilled()");
+assert.sameValue(valuesArray[0], "expectedValue", "valuesArray after call to onFulfilled()");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-items.js b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-items.js
new file mode 100644
index 0000000000..19d0ad3f45
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element-items.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.2
+description: >
+ Cannot change result value of resolved Promise.all elements.
+info: |
+ Promise.all Resolve Element Functions
+
+ 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ 2. If alreadyCalled.[[value]] is true, return undefined.
+ 3. Set alreadyCalled.[[value]] to true.
+ ...
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ assert(Array.isArray(values), "values is array");
+ assert.sameValue(values.length, 2, "values length");
+ assert.sameValue(values[0], "expectedValue-p1", "values[0]");
+ assert.sameValue(values[1], "expectedValue-p2", "values[1]");
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ onFulfilled("expectedValue-p1");
+ onFulfilled("unexpectedValue-p1");
+ }
+};
+var p2 = {
+ then: function(onFulfilled, onRejected) {
+ onFulfilled("expectedValue-p2");
+ onFulfilled("unexpectedValue-p2");
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to all()");
+
+Promise.all.call(Constructor, [p1, p2]);
+
+assert.sameValue(callCount, 1, "callCount after call to all()");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/call-resolve-element.js b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element.js
new file mode 100644
index 0000000000..c559e30e8d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/call-resolve-element.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.2
+description: >
+ Cannot change result value of resolved Promise.all element.
+info: |
+ Promise.all Resolve Element Functions
+
+ 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ 2. If alreadyCalled.[[value]] is true, return undefined.
+ 3. Set alreadyCalled.[[value]] to true.
+ ...
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ assert(Array.isArray(values), "values is array");
+ assert.sameValue(values.length, 1, "values length");
+ assert.sameValue(values[0], "expectedValue", "values[0]");
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ onFulfilled("expectedValue");
+ onFulfilled("unexpectedValue");
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to all()");
+
+Promise.all.call(Constructor, [p1]);
+
+assert.sameValue(callCount, 1, "callCount after call to all()");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/capability-executor-called-twice.js b/js/src/tests/test262/built-ins/Promise/all/capability-executor-called-twice.js
new file mode 100644
index 0000000000..992f6cb1c2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/capability-executor-called-twice.js
@@ -0,0 +1,104 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Throws a TypeError if capabilities executor already called with non-undefined values.
+info: |
+ Promise.all ( iterable )
+
+ ...
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ 7. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ GetCapabilitiesExecutor Functions
+ ...
+ 3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
+ 4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
+ 5. Set promiseCapability.[[Resolve]] to resolve.
+ 6. Set promiseCapability.[[Reject]] to reject.
+ ...
+
+ PerformPromiseAll ( iteratorRecord, constructor, resultCapability )
+
+ ...
+ 1. Let promiseResolve be ? Get(constructor, `"resolve"`).
+ 1. If IsCallable(promiseResolve) is *false*, throw a *TypeError* exception.
+ ...
+---*/
+
+var checkPoint = "";
+function fn1(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+fn1.resolve = function() {};
+Promise.all.call(fn1, []);
+assert.sameValue(checkPoint, "abc", "executor initially called with no arguments");
+
+checkPoint = "";
+function fn2(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+fn2.resolve = function() {};
+Promise.all.call(fn2, []);
+assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)");
+
+checkPoint = "";
+function fn3(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+Object.defineProperty(fn3, 'resolve', {
+ get() { throw new Test262Error; }
+});
+assert.throws(TypeError, function() {
+ Promise.all.call(fn3, []);
+}, "executor initially called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)");
+
+checkPoint = "";
+function fn4(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+Object.defineProperty(fn4, 'resolve', {
+ get() { throw new Test262Error; }
+});
+assert.throws(TypeError, function() {
+ Promise.all.call(fn4, []);
+}, "executor initially called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)");
+
+checkPoint = "";
+function fn5(executor) {
+ checkPoint += "a";
+ executor("invalid value", 123);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+Object.defineProperty(fn5, 'resolve', {
+ get() { throw new Test262Error; }
+});
+assert.throws(TypeError, function() {
+ Promise.all.call(fn5, []);
+}, "executor initially called with (String, Number)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/capability-executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/all/capability-executor-not-callable.js
new file mode 100644
index 0000000000..7b2d1c1312
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/capability-executor-not-callable.js
@@ -0,0 +1,109 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1
+description: >
+ Throws a TypeError if either resolve or reject capability is not callable.
+info: |
+ Promise.all ( iterable )
+
+ ...
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ 7. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ 25.4.1.5 NewPromiseCapability ( C )
+ ...
+ 4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1).
+ 5. Set the [[Capability]] internal slot of executor to promiseCapability.
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+ 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
+ 9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
+ ...
+---*/
+
+var checkPoint = "";
+function fn1(executor) {
+ checkPoint += "a";
+}
+Object.defineProperty(fn1, 'resolve', {
+ get() { throw new Test262Error; }
+});
+assert.throws(TypeError, function() {
+ Promise.all.call(fn1, []);
+}, "executor not called at all");
+assert.sameValue(checkPoint, "a", "executor not called at all");
+
+checkPoint = "";
+function fn2(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+}
+Object.defineProperty(fn2, 'resolve', {
+ get() { throw new Test262Error; }
+});
+assert.throws(TypeError, function() {
+ Promise.all.call(fn2, []);
+}, "executor called with no arguments");
+assert.sameValue(checkPoint, "ab", "executor called with no arguments");
+
+checkPoint = "";
+function fn3(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+}
+Object.defineProperty(fn3, 'resolve', {
+ get() { throw new Test262Error; }
+});
+assert.throws(TypeError, function() {
+ Promise.all.call(fn3, []);
+}, "executor called with (undefined, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, undefined)");
+
+checkPoint = "";
+function fn4(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+}
+Object.defineProperty(fn4, 'resolve', {
+ get() { throw new Test262Error; }
+});
+assert.throws(TypeError, function() {
+ Promise.all.call(fn4, []);
+}, "executor called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, function)");
+
+checkPoint = "";
+function fn5(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+}
+Object.defineProperty(fn5, 'resolve', {
+ get() { throw new Test262Error; }
+});
+assert.throws(TypeError, function() {
+ Promise.all.call(fn5, []);
+}, "executor called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (function, undefined)");
+
+checkPoint = "";
+function fn6(executor) {
+ checkPoint += "a";
+ executor(123, "invalid value");
+ checkPoint += "b";
+}
+Object.defineProperty(fn6, 'resolve', {
+ get() { throw new Test262Error; }
+});
+assert.throws(TypeError, function() {
+ Promise.all.call(fn6, []);
+}, "executor called with (Number, String)");
+assert.sameValue(checkPoint, "ab", "executor called with (Number, String)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-no-close.js b/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-no-close.js
new file mode 100644
index 0000000000..2be75cf0ca
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-no-close.js
@@ -0,0 +1,79 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.all
+description: >
+ Iterator is not closed when the "resolve" capability returns an abrupt
+ completion.
+info: |
+ 1. Let C be the this value.
+ [...]
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ [...]
+ 7. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 8. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ d. If next is false, then
+ [...]
+ iii. If remainingElementsCount.[[Value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, «
+ valuesArray »).
+
+ 25.4.1.1.1 IfAbruptRejectPromise
+
+ IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that
+ use a PromiseCapability Record. An algorithm step of the form:
+
+ 1. IfAbruptRejectPromise(value, capability).
+
+ means the same thing as:
+
+ 1. If value is an abrupt completion, then
+ a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
+ b. Return capability.[[Promise]].
+ 2. Else if value is a Completion Record, let value be value.[[Value]].
+features: [Symbol.iterator]
+---*/
+
+var nextCount = 0;
+var returnCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ nextCount += 1;
+ return {
+ done: true
+ };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+var P = function(executor) {
+ return new Promise(function(_, reject) {
+ executor(function() {
+ throw new Test262Error();
+ }, reject);
+ });
+};
+
+P.resolve = Promise.resolve;
+
+Promise.all.call(P, iter);
+
+assert.sameValue(nextCount, 1);
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-reject.js b/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-reject.js
new file mode 100644
index 0000000000..cae47e18f8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/capability-resolve-throws-reject.js
@@ -0,0 +1,68 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.all
+description: >
+ Promise is rejected when the "resolve" capability returns an abrupt
+ completion.
+info: |
+ 1. Let C be the this value.
+ [...]
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ [...]
+ 7. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 8. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ d. If next is false, then
+ [...]
+ iii. If remainingElementsCount.[[Value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, «
+ valuesArray »).
+
+ 25.4.1.1.1 IfAbruptRejectPromise
+
+ IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that
+ use a PromiseCapability Record. An algorithm step of the form:
+
+ 1. IfAbruptRejectPromise(value, capability).
+
+ means the same thing as:
+
+ 1. If value is an abrupt completion, then
+ a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
+ b. Return capability.[[Promise]].
+ 2. Else if value is a Completion Record, let value be value.[[Value]].
+flags: [async]
+---*/
+
+var thrown = new Test262Error();
+var P = function(executor) {
+ return new Promise(function(_, reject) {
+ executor(function() {
+ throw thrown;
+ }, reject);
+ });
+};
+
+P.resolve = Promise.resolve;
+
+Promise.all.call(P, [])
+ .then(function() {
+ $DONE('Promise incorrectly fulfilled.');
+ }, function(reason) {
+ if (reason !== thrown) {
+ $DONE('Promise rejected with incorrect "reason."');
+ return;
+ }
+ $DONE();
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/all/ctx-ctor-throws.js b/js/src/tests/test262/built-ins/Promise/all/ctx-ctor-throws.js
new file mode 100644
index 0000000000..13de0ef9ca
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/ctx-ctor-throws.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.all` invoked on a constructor value that throws an error
+es6id: 25.4.4.1
+info: |
+ 1. Let C be the this value.
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ 7. ReturnIfAbrupt(promiseCapability).
+
+ 25.4.1.5 NewPromiseCapability
+ [...]
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+---*/
+
+var CustomPromise = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ Promise.all.call(CustomPromise);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/ctx-ctor.js b/js/src/tests/test262/built-ins/Promise/all/ctx-ctor.js
new file mode 100644
index 0000000000..b6fd1068a3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/ctx-ctor.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.all` invoked on a constructor value
+es6id: 25.4.4.1
+info: |
+ 1. Let C be the this value.
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 10. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ [...]
+ 13. Return Completion(result).
+features: [class]
+---*/
+
+var executor = null;
+var callCount = 0;
+
+class SubPromise extends Promise {
+ constructor(a) {
+ super(a);
+ executor = a;
+ callCount += 1;
+ }
+}
+
+var instance = Promise.all.call(SubPromise, []);
+
+assert.sameValue(instance.constructor, SubPromise);
+assert.sameValue(instance instanceof SubPromise, true);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(typeof executor, 'function');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/ctx-non-ctor.js b/js/src/tests/test262/built-ins/Promise/all/ctx-non-ctor.js
new file mode 100644
index 0000000000..d7206e5efb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/ctx-non-ctor.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.all` invoked on a non-constructor value
+es6id: 25.4.4.1
+info: |
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ 7. ReturnIfAbrupt(promiseCapability).
+
+ 25.4.1.5 NewPromiseCapability ( C )
+
+ 1. If IsConstructor(C) is false, throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.all.call(eval);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/ctx-non-object.js b/js/src/tests/test262/built-ins/Promise/all/ctx-non-object.js
new file mode 100644
index 0000000000..decd8ad556
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/ctx-non-object.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.all` invoked on a non-object value
+es6id: 25.4.4.1
+info: |
+ 1. Let C be the this value.
+ 2. If Type(C) is not Object, throw a TypeError exception.
+features: [Symbol]
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.all.call(undefined, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.all.call(null, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.all.call(86, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.all.call('string', []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.all.call(true, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.all.call(Symbol(), []);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/does-not-invoke-array-setters.js b/js/src/tests/test262/built-ins/Promise/all/does-not-invoke-array-setters.js
new file mode 100644
index 0000000000..9a7c4c3fde
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/does-not-invoke-array-setters.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.1
+description: >
+ Indexed setter properties on Array.prototype are not invoked.
+info: |
+ Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability)
+
+ ...
+ 4. Let remainingElementsCount be a new Record { [[value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0,
+ 1. Let valuesArray be CreateArrayFromList(values).
+ ...
+ ...
+
+ 7.3.16 CreateArrayFromList (elements)
+ ...
+ 4. For each element e of elements
+ a. Let status be CreateDataProperty(array, ToString(n), e).
+ b. Assert: status is true.
+ ...
+flags: [async]
+---*/
+
+Object.defineProperty(Array.prototype, 0, {
+ set: function() {
+ throw new Test262Error("Setter on Array.prototype called");
+ }
+});
+
+Promise.all([42]).then(function() {
+ $DONE();
+}, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-close.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-close.js
new file mode 100644
index 0000000000..58c50705d6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-close.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Explicit iterator closing in response to error
+esid: sec-promise.all
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»).
+ j. ReturnIfAbrupt(nextPromise ).
+features: [Symbol.iterator]
+---*/
+
+var iterDoneSpy = {};
+var callCount = 0;
+iterDoneSpy[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return {
+ value: null,
+ done: false
+ };
+ },
+ return: function() {
+ callCount += 1;
+ }
+ };
+};
+
+Promise.resolve = function() {
+ throw new Test262Error();
+};
+
+Promise.all(iterDoneSpy);
+
+assert.sameValue(callCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-reject.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-reject.js
new file mode 100644
index 0000000000..e6a968cffe
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-error-reject.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise rejection in response to error
+esid: sec-promise.all
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»).
+ j. ReturnIfAbrupt(nextPromise ).
+flags: [async]
+---*/
+
+var thrown = new Test262Error();
+Promise.resolve = function() {
+ throw thrown;
+};
+
+Promise.all([1])
+ .then(function() {
+ throw new Test262Error('The promise should not be fulfilled.');
+ }, function(reason) {
+ if (reason !== thrown) {
+ throw new Test262Error('The promise should be rejected with the thrown error object');
+ }
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error-reject.js
new file mode 100644
index 0000000000..037b999b71
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error-reject.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error retrieving the constructor's `resolve` method (rejecting promise)
+esid: sec-performpromiseall
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ Runtime Semantics: PerformPromiseAll
+
+ ...
+ 1. Let promiseResolve be ? Get(constructor, `"resolve"`).
+ ...
+ 1. Repeat,
+ 1. Let next be IteratorStep(iteratorRecord).
+ ...
+ 1. Let nextPromise be ? Call(promiseResolve, constructor, < nextValue >).
+flags: [async]
+---*/
+
+var error = new Test262Error();
+Object.defineProperty(Promise, 'resolve', {
+ get: function() {
+ throw error;
+ }
+});
+
+Promise.all([new Promise(function() {})]).then(function() {
+ throw new Test262Error('The promise should be rejected');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error.js
new file mode 100644
index 0000000000..4bfc0a8afb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-error.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Promise.resolve is retrieved before GetIterator call (abrupt lookup).
+info: |
+ Promise.all ( iterable )
+
+ [...]
+ 3. Let promiseResolve be GetPromiseResolve(C).
+ 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
+
+ GetPromiseResolve ( promiseConstructor )
+
+ [...]
+ 2. Let promiseResolve be ? Get(promiseConstructor, "resolve").
+flags: [async]
+features: [Symbol.iterator]
+---*/
+
+const iter = {
+ get [Symbol.iterator]() {
+ throw new Test262Error('unreachable');
+ },
+};
+
+const resolveError = { name: 'MyError' };
+Object.defineProperty(Promise, 'resolve', {
+ get() {
+ throw resolveError;
+ },
+});
+
+Promise.all(iter).then(() => {
+ throw new Test262Error('The promise should be rejected, but it was resolved');
+}, (reason) => {
+ assert.sameValue(reason, resolveError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js
new file mode 100644
index 0000000000..1789a4a30b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-multiple-calls.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Gets constructor's `resolve` method once from zero to many invocations.
+esid: sec-promise.all
+info: |
+ Runtime Semantics: PerformPromiseAll
+
+ 1. Let promiseResolve be ? Get(constructor, `"resolve"`).
+ 1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+ ...
+ 1. Repeat,
+ ...
+ 1. Let nextPromise be ? Call(promiseResolve, constructor, &laquo; nextValue &raquo;).
+---*/
+
+var p1 = Promise.resolve(1);
+var p2 = Promise.resolve(1);
+var p3 = Promise.reject(1);
+var p4 = Promise.resolve(1);
+var resolve = Promise.resolve;
+var getCount = 0;
+var callCount = 0;
+
+Object.defineProperty(Promise, 'resolve', {
+ configurable: true,
+ get() {
+ getCount += 1;
+ return function() {
+ callCount += 1;
+ return resolve.apply(Promise, arguments);
+ };
+ }
+});
+
+Promise.all([p1, p2, p3, p4]);
+
+assert.sameValue(
+ getCount, 1, 'Got `resolve` only once for each iterated value'
+);
+assert.sameValue(
+ callCount, 4, '`resolve` invoked once for each iterated value'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js
new file mode 100644
index 0000000000..ec86fba799
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-get-once-no-calls.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Gets constructor's `resolve` method once from zero to many invocations.
+esid: sec-promise.all
+info: |
+ Runtime Semantics: PerformPromiseAll
+
+ 1. Let promiseResolve be ? Get(constructor, `"resolve"`).
+ 1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+ ...
+ 1. Repeat,
+ ...
+ 1. Let nextPromise be ? Call(promiseResolve, constructor, &laquo; nextValue &raquo;).
+---*/
+
+var resolve = Promise.resolve;
+var getCount = 0;
+var callCount = 0;
+
+Object.defineProperty(Promise, 'resolve', {
+ configurable: true,
+ get() {
+ getCount += 1;
+ return function() {
+ callCount += 1;
+ return resolve.apply(Promise, arguments);
+ };
+ }
+});
+
+Promise.all([]);
+
+assert.sameValue(
+ getCount, 1, 'Got `resolve` only once for each iterated value'
+);
+assert.sameValue(
+ callCount, 0, '`resolve` not called for empty iterator'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js
new file mode 100644
index 0000000000..84855dc903
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-custom.js
@@ -0,0 +1,44 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with promise values
+esid: sec-promise.all
+info: |
+ Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAll
+
+ Repeat
+ ...
+ Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [class, arrow-function]
+---*/
+class Custom extends Promise {}
+
+let values = [1, 1, 1];
+let cresolveCallCount = 0;
+let presolveCallCount = 0;
+let boundCustomResolve = Custom.resolve.bind(Custom);
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Custom.resolve = function(...args) {
+ cresolveCallCount += 1;
+ return boundCustomResolve(...args);
+};
+
+Promise.resolve = function(...args) {
+ presolveCallCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.all.call(Custom, values)
+ .then(() => {
+ assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked');
+ assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every iterated promise');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-promise.js
new file mode 100644
index 0000000000..14f562465a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-promises-every-iteration-of-promise.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with promise values
+esid: sec-promise.all
+info: |
+ Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAll
+
+ Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [arrow-function]
+---*/
+
+let values = [1,1,1];
+let callCount = 0;
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Promise.resolve = function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.all(values)
+ .then(() => {
+ assert.sameValue(callCount, 3, '`then` invoked once for every iterated promise');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js
new file mode 100644
index 0000000000..2e5b928f51
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-on-values-every-iteration-of-promise.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with non-promise values
+esid: sec-promise.all
+info: |
+ Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAll
+
+ Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [arrow-function]
+---*/
+
+let values = [1, 2, 3];
+let callCount = 0;
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Promise.resolve = function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.all(values)
+ .then(() => {
+ assert.sameValue(callCount, 3, '`Promise.resolve` invoked once for every iterated value');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-return.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-return.js
new file mode 100644
index 0000000000..6f63505b7a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve-return.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: Use of the value returned by the constructor's `resolve` method.
+es6id: 25.4.4.1
+info: |
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C).
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+ [...]
+ 6. Repeat
+ [...]
+ i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»).
+ [...]
+ r. Let result be Invoke(nextPromise, "then", resolveElement,
+ promiseCapability.[[Reject]]»).
+ [...]
+---*/
+
+var originalCallCount = 0;
+var newCallCount = 0;
+var P = function(executor) {
+ executor(function() {}, function() {});
+};
+P.resolve = function() {
+ return newThenable;
+};
+
+var originalThenable = {
+ then: function() {
+ originalCallCount += 1;
+ }
+};
+var newThenable = {
+ then: function() {
+ newCallCount += 1;
+ }
+};
+
+Promise.all.call(P, [originalThenable]);
+
+assert.sameValue(originalCallCount, 0, 'original `then` method not invoked');
+assert.sameValue(newCallCount, 1, 'new `then` method invoked exactly once');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-resolve.js b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve.js
new file mode 100644
index 0000000000..448bf9e22e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-resolve.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method
+es6id: 25.4.4.1
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ i. Let nextPromise be Invoke(constructor, "resolve", «nextValue»).
+---*/
+
+var p1 = new Promise(function() {});
+var p2 = new Promise(function() {});
+var p3 = new Promise(function() {});
+var resolve = Promise.resolve;
+var callCount = 0;
+var current = p1;
+var next = p2;
+var afterNext = p3;
+
+Promise.resolve = function(nextValue) {
+ assert.sameValue(
+ nextValue, current, '`resolve` invoked with next iterated value'
+ );
+ assert.sameValue(
+ arguments.length, 1, '`resolve` invoked with a single argument'
+ );
+ assert.sameValue(this, Promise, '`this` value is the constructor');
+
+ current = next;
+ next = afterNext;
+ afterNext = null;
+
+ callCount += 1;
+
+ return resolve.apply(Promise, arguments);
+};
+
+Promise.all([p1, p2, p3]);
+
+assert.sameValue(
+ callCount, 3, '`resolve` invoked once for each iterated value'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-close.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-close.js
new file mode 100644
index 0000000000..fffd528d2d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-close.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: >
+ Error thrown when invoking the instance's `then` method (closing iterator)
+esid: sec-performpromiseall
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ r. Let result be Invoke(nextPromise, "then", «resolveElement,
+ resultCapability.[[Reject]]»).
+ s. ReturnIfAbrupt(result).
+features: [Symbol.iterator]
+---*/
+
+var promise = new Promise(function() {});
+var returnCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return {
+ done: false,
+ value: promise
+ };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+promise.then = function() {
+ throw new Test262Error();
+};
+
+Promise.all(iter);
+
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-reject.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-reject.js
new file mode 100644
index 0000000000..4e91208d87
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then-error-reject.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error thrown when invoking the instance's `then` method (rejecting Promise)
+esid: sec-performpromiseall
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ r. Let result be Invoke(nextPromise, "then", «resolveElement,
+ resultCapability.[[Reject]]»).
+ s. ReturnIfAbrupt(result).
+flags: [async]
+---*/
+
+var promise = new Promise(function() {});
+var error = new Test262Error();
+
+promise.then = function() {
+ throw error;
+};
+
+Promise.all([promise]).then(function() {
+ throw new Test262Error('The promise should be rejected');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-close.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-close.js
new file mode 100644
index 0000000000..7a5b7ce446
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-close.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: >
+ Error thrown when accesing the instance's `then` method (closing iterator)
+esid: sec-performpromiseall
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ r. Let result be Invoke(nextPromise, "then", «resolveElement,
+ resultCapability.[[Reject]]»).
+ s. ReturnIfAbrupt(result).
+features: [Symbol.iterator]
+---*/
+
+var promise = new Promise(function() {});
+var returnCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return {
+ done: false,
+ value: promise
+ };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+Object.defineProperty(promise, 'then', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+Promise.all(iter);
+
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-reject.js
new file mode 100644
index 0000000000..6f5fa60bf2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then-get-error-reject.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Error thrown when accessing the instance's `then` method (rejecting Promise)
+esid: sec-performpromiseall
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ r. Let result be Invoke(nextPromise, "then", «resolveElement,
+ resultCapability.[[Reject]]»).
+ s. ReturnIfAbrupt(result).
+flags: [async]
+---*/
+
+var promise = new Promise(function() {});
+var error = new Test262Error();
+
+Object.defineProperty(promise, 'then', {
+ get: function() {
+ throw error;
+ }
+});
+
+Promise.all([promise]).then(function() {
+ throw new Test262Error('The promise should be rejected');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/invoke-then.js b/js/src/tests/test262/built-ins/Promise/all/invoke-then.js
new file mode 100644
index 0000000000..80113deb33
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/invoke-then.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the instance's `then` method
+es6id: 25.4.4.1
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ r. Let result be Invoke(nextPromise, "then", «resolveElement,
+ resultCapability.[[Reject]]»).
+---*/
+
+var p1 = new Promise(function() {});
+var p2 = new Promise(function() {});
+var p3 = new Promise(function() {});
+var callCount = 0;
+var currentThis = p1;
+var nextThis = p2;
+var afterNextThis = p3;
+
+p1.then = p2.then = p3.then = function(a, b) {
+ assert.sameValue(typeof a, 'function', 'type of first argument');
+ assert.sameValue(
+ a.length,
+ 1,
+ 'ES6 25.4.1.3.2: The length property of a promise resolve function is 1.'
+ );
+ assert.sameValue(typeof b, 'function', 'type of second argument');
+ assert.sameValue(
+ b.length,
+ 1,
+ 'ES6 25.4.1.3.1: The length property of a promise reject function is 1.'
+ );
+ assert.sameValue(arguments.length, 2, '`then` invoked with two arguments');
+ assert.sameValue(this, currentThis, '`this` value');
+
+ currentThis = nextThis;
+ nextThis = afterNextThis;
+ afterNextThis = null;
+
+ callCount += 1;
+};
+
+Promise.all([p1, p2, p3]);
+
+assert.sameValue(callCount, 3, '`then` invoked once for every iterated value');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-false-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-false-reject.js
new file mode 100644
index 0000000000..258cc45054
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-false-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument is `false`
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all(false).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-null-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-null-reject.js
new file mode 100644
index 0000000000..a527580294
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-null-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument is `null`
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all(null).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-number-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-number-reject.js
new file mode 100644
index 0000000000..0bfee0b2f7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-number-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument is a number
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all(1).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-string-resolve.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-string-resolve.js
new file mode 100644
index 0000000000..c20288b677
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-string-resolve.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Resolve when argument is a string
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all("").then(function(v) {
+ assert.sameValue(v.length, 0);
+ }, function() {
+ $DONE('The promise should be resolved, but was rejected');
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be resolved, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-symbol-reject.js
new file mode 100644
index 0000000000..b3c22c06de
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-symbol-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument is a symbol
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all(Symbol()).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-true-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-true-reject.js
new file mode 100644
index 0000000000..9c62656960
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-true-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument is `true`
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all(true).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-undefined-reject.js
new file mode 100644
index 0000000000..9e9459776a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-arg-is-undefined-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument is `undefined`
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all(undefined).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-false-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-false-reject.js
new file mode 100644
index 0000000000..09f3b39bf3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-false-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator property has the value false
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]: false
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-null-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-null-reject.js
new file mode 100644
index 0000000000..ce77efa446
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-null-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator property has the value null
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]: null
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-number-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-number-reject.js
new file mode 100644
index 0000000000..4c63977bc0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-number-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator property has the value 1
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]: 1
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-string-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-string-reject.js
new file mode 100644
index 0000000000..8f23475cd4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-string-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator property has the value ""
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]: ""
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-symbol-reject.js
new file mode 100644
index 0000000000..1eaa109428
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-symbol-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator property has the value Symbol()
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]: Symbol()
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-true-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-true-reject.js
new file mode 100644
index 0000000000..172235e9ef
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-true-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator property has the value true
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]: true
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-assigned-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-undefined-reject.js
new file mode 100644
index 0000000000..9d8e741728
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-assigned-undefined-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator property has the value undefined
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]: undefined
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-no-close.js b/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-no-close.js
new file mode 100644
index 0000000000..ad0d763ace
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-no-close.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Error when accessing an iterator result's `value` property (not closing
+ iterator)
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ e. Let nextValue be IteratorValue(next).
+ f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ g. ReturnIfAbrupt(nextValue).
+features: [Symbol.iterator]
+---*/
+
+var iterNextValThrows = {};
+var returnCount = 0;
+var poisonedVal = {
+ done: false
+};
+var error = new Test262Error();
+Object.defineProperty(poisonedVal, 'value', {
+ get: function() {
+ throw error;
+ }
+});
+iterNextValThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedVal;
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+Promise.all(iterNextValThrows);
+
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-reject.js
new file mode 100644
index 0000000000..b8dabaa0d8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-next-val-err-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Error when accessing an iterator result's `value` property (rejecting
+ promise)
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ [...]
+ e. Let nextValue be IteratorValue(next).
+ f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ g. ReturnIfAbrupt(nextValue).
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+var iterNextValThrows = {};
+var poisonedVal = {
+ done: false
+};
+var error = new Test262Error();
+Object.defineProperty(poisonedVal, 'value', {
+ get: function() {
+ throw error;
+ }
+});
+iterNextValThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedVal;
+ }
+ };
+};
+
+Promise.all(iterNextValThrows).then(function() {
+ $DONE('The promise should be rejected.');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-false-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-false-reject.js
new file mode 100644
index 0000000000..68c9b42031
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-false-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator returns false
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]() {
+ return false;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-null-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-null-reject.js
new file mode 100644
index 0000000000..f0f8c80cc3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-null-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator returns null
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]() {
+ return null;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-number-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-number-reject.js
new file mode 100644
index 0000000000..0b130ef77e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-number-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator returns a number
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]() {
+ return 1;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-string-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-string-reject.js
new file mode 100644
index 0000000000..37dd3692b0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-string-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator returns a string
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]() {
+ return "";
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-symbol-reject.js
new file mode 100644
index 0000000000..023ef1f66a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-symbol-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator returns a symbol
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]() {
+ return Symbol();
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-true-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-true-reject.js
new file mode 100644
index 0000000000..4211c8d1ed
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-true-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator returns true
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]() {
+ return true;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-returns-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-returns-undefined-reject.js
new file mode 100644
index 0000000000..3ed1c633d2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-returns-undefined-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Reject when argument's Symbol.iterator returns undefined
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.all({
+ [Symbol.iterator]() {
+ return undefined;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-step-err-no-close.js b/js/src/tests/test262/built-ins/Promise/all/iter-step-err-no-close.js
new file mode 100644
index 0000000000..e0f9b679aa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-step-err-no-close.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Error when advancing the provided iterable (not closing iterator)
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ c. ReturnIfAbrupt(next).
+features: [Symbol.iterator]
+---*/
+
+var iterStepThrows = {};
+var poisonedDone = {};
+var returnCount = 0;
+var error = new Test262Error();
+Object.defineProperty(poisonedDone, 'done', {
+ get: function() {
+ throw error;
+ }
+});
+Object.defineProperty(poisonedDone, 'value', {
+ get: function() {
+ throw new Test262Error('The `value` property should not be accessed.');
+ }
+});
+
+iterStepThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedDone;
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+Promise.all(iterStepThrows);
+
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/iter-step-err-reject.js b/js/src/tests/test262/built-ins/Promise/all/iter-step-err-reject.js
new file mode 100644
index 0000000000..0f927aac75
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/iter-step-err-reject.js
@@ -0,0 +1,56 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Error when advancing the provided iterable (rejecting promise)
+info: |
+ 11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+
+ [...]
+ 6. Repeat
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ c. ReturnIfAbrupt(next).
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+var iterStepThrows = {};
+var poisonedDone = {};
+var error = new Test262Error();
+Object.defineProperty(poisonedDone, 'done', {
+ get: function() {
+ throw error;
+ }
+});
+Object.defineProperty(poisonedDone, 'value', {
+ get: function() {
+ $DONE('The `value` property should not be accessed.');
+ }
+});
+
+iterStepThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedDone;
+ }
+ };
+};
+
+Promise.all(iterStepThrows).then(function() {
+ $DONE('The promise should be rejected.');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/length.js b/js/src/tests/test262/built-ins/Promise/all/length.js
new file mode 100644
index 0000000000..7769497c7c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/length.js
@@ -0,0 +1,27 @@
+// 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.4.1
+description: Promise.all `length` property
+info: |
+ ES6 Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.all.length, 1);
+
+verifyNotEnumerable(Promise.all, 'length');
+verifyNotWritable(Promise.all, 'length');
+verifyConfigurable(Promise.all, 'length');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/name.js b/js/src/tests/test262/built-ins/Promise/all/name.js
new file mode 100644
index 0000000000..552ba841dd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/name.js
@@ -0,0 +1,28 @@
+// 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.4.1
+description: Promise.all `name` property
+info: |
+ ES6 Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.all.name, 'all');
+
+verifyNotEnumerable(Promise.all, 'name');
+verifyNotWritable(Promise.all, 'name');
+verifyConfigurable(Promise.all, 'name');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/new-resolve-function.js b/js/src/tests/test262/built-ins/Promise/all/new-resolve-function.js
new file mode 100644
index 0000000000..9d668f67e2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/new-resolve-function.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.1
+description: >
+ Each Promise.all element is called with a new Promise.all Resolve Element function.
+info: |
+ Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability)
+
+ ...
+ k. Let resolveElement be a new built-in function object as defined in Promise.all Resolve Element Functions.
+ ...
+ r. Let result be Invoke(nextPromise, "then", «resolveElement, resultCapability.[[Reject]]»).
+ ...
+---*/
+
+function resolveFunction() {}
+
+function Constructor(executor) {
+ executor(resolveFunction, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var callCount1 = 0,
+ callCount2 = 0;
+var p1OnFulfilled;
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ callCount1 += 1;
+ p1OnFulfilled = onFulfilled;
+ assert.notSameValue(onFulfilled, resolveFunction, "p1.then");
+ }
+};
+var p2 = {
+ then: function(onFulfilled, onRejected) {
+ callCount2 += 1;
+ assert.notSameValue(onFulfilled, resolveFunction, "p2.then");
+ assert.notSameValue(onFulfilled, p1OnFulfilled, "p1.onFulfilled != p2.onFulfilled");
+ }
+};
+
+Promise.all.call(Constructor, [p1, p2]);
+
+assert.sameValue(callCount1, 1, "p1.then call count");
+assert.sameValue(callCount2, 1, "p2.then call count");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/all/not-a-constructor.js
new file mode 100644
index 0000000000..9ab0f8e49e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/not-a-constructor.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Promise.all does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(Promise.all), false, 'isConstructor(Promise.all) must return false');
+
+assert.throws(TypeError, () => {
+ new Promise.all([]);
+}, '`new Promise.all([])` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/prop-desc.js b/js/src/tests/test262/built-ins/Promise/all/prop-desc.js
new file mode 100644
index 0000000000..b40599802b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/prop-desc.js
@@ -0,0 +1,21 @@
+// Copyright 2015 Jordan Harband. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: 25.4.4.1_A1.3_T1
+author: Jordan Harband
+description: Promise.all property descriptor
+info: |
+ ES6 Section 17
+
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(Promise, 'all');
+verifyWritable(Promise, 'all');
+verifyConfigurable(Promise, 'all');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/reject-deferred.js b/js/src/tests/test262/built-ins/Promise/all/reject-deferred.js
new file mode 100644
index 0000000000..c439bcaf75
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/reject-deferred.js
@@ -0,0 +1,43 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting through deferred invocation of the provided resolving function
+es6id: 25.4.4.1
+info: |
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C).
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+ [...]
+ 6. Repeat
+ [...]
+ r. Let result be Invoke(nextPromise, "then", resolveElement,
+ promiseCapability.[[Reject]]»).
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var thenable = {
+ then: function(_, reject) {
+ new Promise(function(resolve) {
+ resolve();
+ })
+ .then(function() {
+ reject();
+ });
+ }
+};
+
+Promise.all([thenable])
+ .then(function() {
+ $DONE('The promise should not be fulfilled.');
+ }, function(x) {
+ $DONE();
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/all/reject-ignored-deferred.js b/js/src/tests/test262/built-ins/Promise/all/reject-ignored-deferred.js
new file mode 100644
index 0000000000..482a48b0a3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/reject-ignored-deferred.js
@@ -0,0 +1,59 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Resolved promises ignore rejections through deferred invocation of the
+ provided resolving function
+es6id: 25.4.4.1
+info: |
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C).
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+ [...]
+ 6. Repeat
+ [...]
+ r. Let result be Invoke(nextPromise, "then", resolveElement,
+ promiseCapability.[[Reject]]»).
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 2. Let promise be the value of F's [[Promise]] internal slot.
+ 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal
+ slot.
+ 4. If alreadyResolved.[[value]] is true, return undefined.
+flags: [async]
+---*/
+
+var fulfiller = {
+ then: function(resolve) {
+ new Promise(function(resolve) {
+ resolve();
+ })
+ .then(function() {
+ resolve();
+ });
+ }
+};
+var rejector = {
+ then: function(resolve, reject) {
+ new Promise(function(resolve) {
+ resolve();
+ })
+ .then(function() {
+ resolve();
+ reject();
+ });
+ }
+};
+
+Promise.all([fulfiller, rejector])
+ .then(function() {
+ $DONE();
+ }, function() {
+ $DONE('The promise should not be rejected.');
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/all/reject-ignored-immed.js b/js/src/tests/test262/built-ins/Promise/all/reject-ignored-immed.js
new file mode 100644
index 0000000000..3a8b8ebd62
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/reject-ignored-immed.js
@@ -0,0 +1,49 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Resolved promises ignore rejections through immediate invocation of the
+ provided resolving function
+es6id: 25.4.4.1
+info: |
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C).
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+ [...]
+ 6. Repeat
+ [...]
+ r. Let result be Invoke(nextPromise, "then", resolveElement,
+ promiseCapability.[[Reject]]»).
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 2. Let promise be the value of F's [[Promise]] internal slot.
+ 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal
+ slot.
+ 4. If alreadyResolved.[[value]] is true, return undefined.
+flags: [async]
+---*/
+
+var fulfiller = {
+ then: function(resolve) {
+ resolve();
+ }
+};
+var lateRejector = {
+ then: function(resolve, reject) {
+ resolve();
+ reject();
+ }
+};
+
+Promise.all([fulfiller, lateRejector])
+ .then(function() {
+ $DONE();
+ }, function() {
+ $DONE('The promise should not be rejected.');
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/all/reject-immed.js b/js/src/tests/test262/built-ins/Promise/all/reject-immed.js
new file mode 100644
index 0000000000..4c476081ae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/reject-immed.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting through immediate invocation of the provided resolving function
+es6id: 25.4.4.1
+info: |
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 11. Let result be PerformPromiseAll(iteratorRecord, promiseCapability, C).
+ [...]
+
+ 25.4.4.1.1 Runtime Semantics: PerformPromiseAll
+ [...]
+ 6. Repeat
+ [...]
+ r. Let result be Invoke(nextPromise, "then", resolveElement,
+ promiseCapability.[[Reject]]»).
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var thenable = {
+ then: function(_, reject) {
+ reject();
+ }
+};
+
+Promise.all([thenable])
+ .then(function() {
+ $DONE('The promise should not be fulfilled.');
+ }, function(x) {
+ $DONE();
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit-from-same.js b/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit-from-same.js
new file mode 100644
index 0000000000..54705cb2fe
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit-from-same.js
@@ -0,0 +1,75 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.1
+description: >
+ Cannot tamper remainingElementsCount when Promise.all resolve element function is called twice in a row.
+info: |
+ Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability)
+
+ ...
+ 4. Let remainingElementsCount be a new Record { [[value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0,
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Let resolveResult be Call(resultCapability.[[Resolve]], undefined, «valuesArray»).
+ 3. ReturnIfAbrupt(resolveResult).
+ ...
+
+ 25.4.4.1.2 Promise.all Resolve Element Functions
+ 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ 2. If alreadyCalled.[[value]] is true, return undefined.
+ 3. Set alreadyCalled.[[value]] to true.
+ ...
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ assert(Array.isArray(values), "values is array");
+ assert.sameValue(values.length, 3, "values length");
+ assert.sameValue(values[0], "p1-fulfill", "values[0]");
+ assert.sameValue(values[1], "p2-fulfill", "values[1]");
+ assert.sameValue(values[2], "p3-fulfill", "values[2]");
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1OnFulfilled;
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ p1OnFulfilled = onFulfilled;
+ }
+};
+var p2 = {
+ then: function(onFulfilled, onRejected) {
+ onFulfilled("p2-fulfill");
+ onFulfilled("p2-fulfill-unexpected");
+ }
+};
+var p3 = {
+ then: function(onFulfilled, onRejected) {
+ onFulfilled("p3-fulfill");
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to all()");
+
+Promise.all.call(Constructor, [p1, p2, p3]);
+
+assert.sameValue(callCount, 0, "callCount after call to all()");
+
+p1OnFulfilled("p1-fulfill");
+
+assert.sameValue(callCount, 1, "callCount after resolving p1");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit.js b/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit.js
new file mode 100644
index 0000000000..7ba90e2d9a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-before-loop-exit.js
@@ -0,0 +1,71 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.1
+description: >
+ Cannot tamper remainingElementsCount when two Promise.all resolve element functions are called in succession.
+info: |
+ Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability)
+
+ ...
+ 4. Let remainingElementsCount be a new Record { [[value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0,
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Let resolveResult be Call(resultCapability.[[Resolve]], undefined, «valuesArray»).
+ 3. ReturnIfAbrupt(resolveResult).
+ ...
+
+ 25.4.4.1.2 Promise.all Resolve Element Functions
+ 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ 2. If alreadyCalled.[[value]] is true, return undefined.
+ 3. Set alreadyCalled.[[value]] to true.
+ ...
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ assert(Array.isArray(values), "values is array");
+ assert.sameValue(values.length, 3, "values length");
+ assert.sameValue(values[0], "p1-fulfill", "values[0]");
+ assert.sameValue(values[1], "p2-fulfill", "values[1]");
+ assert.sameValue(values[2], "p3-fulfill", "values[2]");
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1OnFulfilled;
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ p1OnFulfilled = onFulfilled;
+ }
+};
+var p2 = {
+ then: function(onFulfilled, onRejected) {
+ p1OnFulfilled("p1-fulfill");
+ onFulfilled("p2-fulfill");
+ }
+};
+var p3 = {
+ then: function(onFulfilled, onRejected) {
+ onFulfilled("p3-fulfill");
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to all()");
+
+Promise.all.call(Constructor, [p1, p2, p3]);
+
+assert.sameValue(callCount, 1, "callCount after call to all()");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-extensible.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-extensible.js
new file mode 100644
index 0000000000..5b0a6b0218
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-extensible.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.2
+description: The [[Extensible]] slot of Promise.all Resolve Element functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless specified otherwise, the [[Extensible]] internal slot
+ of a built-in object initially has the value true.
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then: function(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.all.call(NotPromise, [thenable]);
+
+assert(Object.isExtensible(resolveElementFunction));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-length.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-length.js
new file mode 100644
index 0000000000..6a3568870b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-length.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.2
+description: The `length` property of Promise.all Resolve Element functions
+info: |
+ The length property of a Promise.all resolve element function is 1.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then: function(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.all.call(NotPromise, [thenable]);
+
+assert.sameValue(resolveElementFunction.length, 1);
+
+verifyNotEnumerable(resolveElementFunction, "length");
+verifyNotWritable(resolveElementFunction, "length");
+verifyConfigurable(resolveElementFunction, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-name.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-name.js
new file mode 100644
index 0000000000..cb30b5a007
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-name.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all-resolve-element-functions
+description: The `name` property of Promise.all Resolve Element functions
+info: |
+ A promise resolve function is an anonymous built-in function.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in function object, including constructors, has a `name`
+ property whose value is a String. Functions that are identified as
+ anonymous functions use the empty string as the value of the `name`
+ property.
+ Unless otherwise specified, the `name` property of a built-in function
+ object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
+ [[Configurable]]: *true* }.
+includes: [propertyHelper.js]
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then: function(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.all.call(NotPromise, [thenable]);
+
+verifyProperty(resolveElementFunction, "name", {
+ value: "", writable: false, enumerable: false, configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-nonconstructor.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-nonconstructor.js
new file mode 100644
index 0000000000..14c832f80c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-nonconstructor.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.2
+description: Promise.all Resolve Element functions are not constructors
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified
+ in the description of a particular function.
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then: function(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.all.call(NotPromise, [thenable]);
+
+assert.sameValue(Object.prototype.hasOwnProperty.call(resolveElementFunction, "prototype"), false);
+assert.throws(TypeError, function() {
+ new resolveElementFunction();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-property-order.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-property-order.js
new file mode 100644
index 0000000000..a8bcc951de
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-property-order.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createbuiltinfunction
+description: Promise.all resolve element function property order
+info: |
+ Set order: "length", "name"
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then: function(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.all.call(NotPromise, [thenable]);
+
+var propNames = Object.getOwnPropertyNames(resolveElementFunction);
+var lengthIndex = propNames.indexOf("length");
+var nameIndex = propNames.indexOf("name");
+
+assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1,
+ "The `length` property comes before the `name` property on built-in functions");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-prototype.js b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-prototype.js
new file mode 100644
index 0000000000..7daca24a61
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-element-function-prototype.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.2
+description: The [[Prototype]] of Promise.all Resolve Element functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified every built-in function and every built-in
+ constructor has the Function prototype object, which is the initial
+ value of the expression Function.prototype (19.2.3), as the value of
+ its [[Prototype]] internal slot.
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then: function(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.all.call(NotPromise, [thenable]);
+
+assert.sameValue(Object.getPrototypeOf(resolveElementFunction), Function.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-from-same-thenable.js b/js/src/tests/test262/built-ins/Promise/all/resolve-from-same-thenable.js
new file mode 100644
index 0000000000..1a788c624c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-from-same-thenable.js
@@ -0,0 +1,81 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.1
+description: >
+ Cannot tamper remainingElementsCount when Promise.all resolve element function is called multiple times.
+info: |
+ Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability)
+
+ ...
+ 4. Let remainingElementsCount be a new Record { [[value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0,
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Let resolveResult be Call(resultCapability.[[Resolve]], undefined, «valuesArray»).
+ 3. ReturnIfAbrupt(resolveResult).
+ ...
+
+ 25.4.4.1.2 Promise.all Resolve Element Functions
+ 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ 2. If alreadyCalled.[[value]] is true, return undefined.
+ 3. Set alreadyCalled.[[value]] to true.
+ ...
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ assert(Array.isArray(values, "values is array"));
+ assert.sameValue(values.length, 3, "values length");
+ assert.sameValue(values[0], "p1-fulfill", "values[0]");
+ assert.sameValue(values[1], "p2-fulfill", "values[1]");
+ assert.sameValue(values[2], "p3-fulfill", "values[2]");
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1OnFulfilled, p2OnFulfilled, p3OnFulfilled;
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ p1OnFulfilled = onFulfilled;
+ }
+};
+var p2 = {
+ then: function(onFulfilled, onRejected) {
+ p2OnFulfilled = onFulfilled;
+ }
+};
+var p3 = {
+ then: function(onFulfilled, onRejected) {
+ p3OnFulfilled = onFulfilled;
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to all()");
+
+Promise.all.call(Constructor, [p1, p2, p3]);
+
+assert.sameValue(callCount, 0, "callCount after call to all()");
+
+p1OnFulfilled("p1-fulfill");
+p1OnFulfilled("p1-fulfill-unexpected-1");
+p1OnFulfilled("p1-fulfill-unexpected-2");
+
+assert.sameValue(callCount, 0, "callCount after resolving p1");
+
+p2OnFulfilled("p2-fulfill");
+p3OnFulfilled("p3-fulfill");
+
+assert.sameValue(callCount, 1, "callCount after resolving all elements");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection-deferred.js b/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection-deferred.js
new file mode 100644
index 0000000000..3b8f52a09a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection-deferred.js
@@ -0,0 +1,43 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through deferred invocation of the
+ provided resolving function
+esid: sec-promise.any
+info: |
+ Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAll
+
+ Repeat
+ ...
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [arrow-function]
+---*/
+
+var resolver = {
+ then(resolve) {
+ new Promise((resolve) => resolve())
+ .then(() => resolve(42));
+ }
+};
+var lateRejector = {
+ then(resolve, reject) {
+ new Promise((resolve) => resolve())
+ .then(() => {
+ resolve(9);
+ reject();
+ });
+ }
+};
+
+Promise.all([resolver, lateRejector])
+ .then(resolution => {
+ assert.sameValue(resolution[0], 42);
+ assert.sameValue(resolution[1], 9);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection.js b/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection.js
new file mode 100644
index 0000000000..cb830c90ff
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-ignores-late-rejection.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through immediate invocation of the
+ provided resolving function
+esid: sec-promise.all
+info: |
+ Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAll
+
+ Repeat
+ ...
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [arrow-function]
+---*/
+
+var resolver = {
+ then(resolve) {
+ resolve(42);
+ }
+};
+var lateRejector = {
+ then(resolve, reject) {
+ resolve(33);
+ reject();
+ }
+};
+
+Promise.all([resolver, lateRejector])
+ .then(resolution => {
+ assert.sameValue(resolution[0], 42);
+ assert.sameValue(resolution[1], 33);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-non-callable.js b/js/src/tests/test262/built-ins/Promise/all/resolve-non-callable.js
new file mode 100644
index 0000000000..8807b8fc60
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-non-callable.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2020 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ Promise.resolve is retrieved before GetIterator call (non-callable).
+info: |
+ Promise.all ( iterable )
+
+ [...]
+ 3. Let promiseResolve be GetPromiseResolve(C).
+ 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
+
+ GetPromiseResolve ( promiseConstructor )
+
+ [...]
+ 2. Let promiseResolve be ? Get(promiseConstructor, "resolve").
+ 3. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+flags: [async]
+features: [Symbol.iterator]
+---*/
+
+const iter = { 
+ get [Symbol.iterator]() {
+ throw new Test262Error("unreachable");
+ },
+};
+
+Promise.resolve = "certainly not callable";
+
+Promise.all(iter).then(() => {
+ throw new Test262Error("The promise should be rejected, but it was resolved");
+}, (reason) => {
+ assert(reason instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-non-thenable.js b/js/src/tests/test262/built-ins/Promise/all/resolve-non-thenable.js
new file mode 100644
index 0000000000..76c1781fd5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-non-thenable.js
@@ -0,0 +1,76 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js b/js/src/tests/test262/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js
new file mode 100644
index 0000000000..c310818802
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-not-callable-reject-with-typeerror.js
@@ -0,0 +1,29 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.all
+description: >
+ If the constructor's `resolve` method is not callable, reject with a TypeError.
+info: |
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ Let promiseResolve be ? Get(constructor, "resolve").
+ If ! IsCallable(promiseResolve) is false, throw a TypeError exception.
+
+flags: [async]
+features: [arrow-function]
+---*/
+
+Promise.resolve = null;
+
+Promise.all([1])
+ .then(
+ () => $DONE('The promise should not be resolved.'),
+ error => {
+ assert(error instanceof TypeError);
+ }
+ ).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/all/resolve-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/all/resolve-poisoned-then.js
new file mode 100644
index 0000000000..d877f7d3da
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-poisoned-then.js
@@ -0,0 +1,72 @@
+// |reftest| async
+// 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]]).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/all/resolve-thenable.js b/js/src/tests/test262/built-ins/Promise/all/resolve-thenable.js
new file mode 100644
index 0000000000..5fd1b42ee0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/resolve-thenable.js
@@ -0,0 +1,74 @@
+// |reftest| async
+// 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»)
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/all/same-reject-function.js b/js/src/tests/test262/built-ins/Promise/all/same-reject-function.js
new file mode 100644
index 0000000000..4112672a03
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/same-reject-function.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.1.1
+description: >
+ Each Promise.all element is called with the same reject function.
+info: |
+ Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability)
+
+ ...
+ r. Let result be Invoke(nextPromise, "then", «resolveElement, resultCapability.[[Reject]]»).
+ ...
+---*/
+
+function rejectFunction() {}
+
+function Constructor(executor) {
+ executor(Test262Error.thrower, rejectFunction);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var callCount1 = 0,
+ callCount2 = 0;
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ callCount1 += 1;
+ assert.sameValue(onRejected, rejectFunction, "p1.then");
+ }
+};
+var p2 = {
+ then: function(onFulfilled, onRejected) {
+ callCount2 += 1;
+ assert.sameValue(onRejected, rejectFunction, "p2.then");
+ }
+};
+
+Promise.all.call(Constructor, [p1, p2]);
+
+assert.sameValue(callCount1, 1, "p1.then call count");
+assert.sameValue(callCount2, 1, "p2.then call count");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/all/shell.js b/js/src/tests/test262/built-ins/Promise/all/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/all/species-get-error.js b/js/src/tests/test262/built-ins/Promise/all/species-get-error.js
new file mode 100644
index 0000000000..2c4597bcab
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/all/species-get-error.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.all() does not retrieve `Symbol.species` property of the `this` value
+es6id: 25.4.4.1
+info: |
+ 1. Let C be the this value.
+ 2. If Type(C) is not Object, throw a TypeError exception.
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+features: [Symbol.species]
+---*/
+
+function C(executor) {
+ executor(function() {}, function() {});
+}
+
+C.resolve = function() {};
+Object.defineProperty(C, Symbol.species, {
+ get: function() {
+ throw new Test262Error("Getter for Symbol.species called");
+ }
+});
+
+Promise.all.call(C, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/browser.js b/js/src/tests/test262/built-ins/Promise/allSettled/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element-after-return.js b/js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element-after-return.js
new file mode 100644
index 0000000000..bfc4795f8d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element-after-return.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-resolve-element-functions
+description: >
+ Cannot change result value of resolved Promise.allSettled element after Promise.allSettled() returned.
+info: |
+ Promise.allSettled Resolve Element Functions
+
+ 1. Let F be the active function object.
+ 2. Let alreadyCalled be F.[[AlreadyCalled]].
+ 3. If alreadyCalled.[[Value]] is true, return undefined.
+ 4. Set alreadyCalled.[[Value]] to true.
+ ...
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var callCount = 0;
+var valuesArray;
+var expected = [{ status: 'fulfilled', value: 'expectedValue' }];
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ valuesArray = values;
+ checkSettledPromises(values, expected, 'values');
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1OnFulfilled;
+
+var p1 = {
+ then(onFulfilled, onRejected) {
+ p1OnFulfilled = onFulfilled;
+ onFulfilled('expectedValue');
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to all()');
+
+Promise.allSettled.call(Constructor, [p1]);
+
+assert.sameValue(callCount, 1, 'callCount after call to all()');
+checkSettledPromises(valuesArray, expected, 'valuesArray after call to all()');
+
+p1OnFulfilled('unexpectedValue');
+
+assert.sameValue(callCount, 1, 'callCount after call to onFulfilled()');
+checkSettledPromises(valuesArray, expected, 'valuesArray after call to onFulfilled()');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element-items.js b/js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element-items.js
new file mode 100644
index 0000000000..a49adfa8e5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element-items.js
@@ -0,0 +1,61 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-resolve-element-functions
+description: >
+ Cannot change result value of resolved Promise.allSettled elements.
+info: |
+ Promise.allSettled Resolve Element Functions
+
+ 1. Let F be the active function object.
+ 2. Let alreadyCalled be F.[[AlreadyCalled]].
+ 3. If alreadyCalled.[[Value]] is true, return undefined.
+ 4. Set alreadyCalled.[[Value]] to true.
+ ...
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ checkSettledPromises(values, [
+ {
+ status: 'fulfilled',
+ value: 'expectedValue-p1'
+ },
+ {
+ status: 'fulfilled',
+ value: 'expectedValue-p2'
+ }
+ ], 'values');
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1 = {
+ then(onFulfilled, onRejected) {
+ onFulfilled('expectedValue-p1');
+ onFulfilled('unexpectedValue-p1');
+ }
+};
+var p2 = {
+ then(onFulfilled, onRejected) {
+ onFulfilled('expectedValue-p2');
+ onFulfilled('unexpectedValue-p2');
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to all()');
+
+Promise.allSettled.call(Constructor, [p1, p2]);
+
+assert.sameValue(callCount, 1, 'callCount after call to all()');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element.js b/js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element.js
new file mode 100644
index 0000000000..511b3a14b1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/call-resolve-element.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-resolve-element-functions
+description: >
+ Cannot change result value of resolved Promise.allSettled element.
+info: |
+ Promise.allSettled Resolve Element Functions
+
+ 1. Let F be the active function object.
+ 2. Let alreadyCalled be F.[[AlreadyCalled]].
+ 3. If alreadyCalled.[[Value]] is true, return undefined.
+ 4. Set alreadyCalled.[[Value]] to true.
+ ...
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ checkSettledPromises(values, [
+ {
+ status: 'fulfilled',
+ value: 'expectedValue'
+ }
+ ], 'values');
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1 = {
+ then(onFulfilled, onRejected) {
+ onFulfilled('expectedValue');
+ onFulfilled('unexpectedValue');
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to all()');
+
+Promise.allSettled.call(Constructor, [p1]);
+
+assert.sameValue(callCount, 1, 'callCount after call to all()');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/capability-executor-called-twice.js b/js/src/tests/test262/built-ins/Promise/allSettled/capability-executor-called-twice.js
new file mode 100644
index 0000000000..9380bda0f5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/capability-executor-called-twice.js
@@ -0,0 +1,108 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Throws a TypeError if capabilities executor already called with non-undefined values.
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+
+ GetCapabilitiesExecutor Functions
+
+ ...
+ 4. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
+ 5. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
+ 6. Set promiseCapability.[[Resolve]] to resolve.
+ 7. Set promiseCapability.[[Reject]] to reject.
+ ...
+features: [Promise.allSettled]
+---*/
+
+var checkPoint = '';
+function fn1(executor) {
+ checkPoint += 'a';
+ executor();
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+fn1.resolve = function() {
+ throw new Test262Error();
+};
+Promise.allSettled.call(fn1, []);
+assert.sameValue(checkPoint, 'abc', 'executor initially called with no arguments');
+
+checkPoint = '';
+function fn2(executor) {
+ checkPoint += 'a';
+ executor(undefined, undefined);
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+fn2.resolve = function() {
+ throw new Test262Error();
+};
+Promise.allSettled.call(fn2, []);
+assert.sameValue(checkPoint, 'abc', 'executor initially called with (undefined, undefined)');
+
+checkPoint = '';
+function fn3(executor) {
+ checkPoint += 'a';
+ executor(undefined, function() {});
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+Object.defineProperty(fn3, 'resolve', {
+ get() {
+ throw new Test262Error();
+ }
+});
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(fn3, []);
+}, 'executor initially called with (undefined, function)');
+assert.sameValue(checkPoint, 'ab', 'executor initially called with (undefined, function)');
+
+checkPoint = '';
+function fn4(executor) {
+ checkPoint += 'a';
+ executor(function() {}, undefined);
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+Object.defineProperty(fn4, 'resolve', {
+ get() {
+ throw new Test262Error();
+ }
+});
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(fn4, []);
+}, 'executor initially called with (function, undefined)');
+assert.sameValue(checkPoint, 'ab', 'executor initially called with (function, undefined)');
+
+checkPoint = '';
+function fn5(executor) {
+ checkPoint += 'a';
+ executor('invalid value', 123);
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+Object.defineProperty(fn5, 'resolve', {
+ get() {
+ throw new Test262Error();
+ }
+});
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(fn5, []);
+}, 'executor initially called with (String, Number)');
+assert.sameValue(checkPoint, 'ab', 'executor initially called with (String, Number)');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/capability-executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/allSettled/capability-executor-not-callable.js
new file mode 100644
index 0000000000..02a29909b0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/capability-executor-not-callable.js
@@ -0,0 +1,109 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Throws a TypeError if either resolve or reject capability is not callable.
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+
+ NewPromiseCapability ( C )
+
+ ...
+ 5. Let executor be CreateBuiltinFunction(steps, « [[Capability]] »).
+ 6. Set executor.[[Capability]] to promiseCapability.
+ 7. Let promise be ? Construct(C, « executor »).
+ 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
+ 9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
+ ...
+features: [Promise.allSettled]
+---*/
+
+var checkPoint = '';
+function fn1(executor) {
+ checkPoint += 'a';
+}
+Object.defineProperty(fn1, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(fn1, []);
+}, 'executor not called at all');
+assert.sameValue(checkPoint, 'a', 'executor not called at all');
+
+checkPoint = '';
+function fn2(executor) {
+ checkPoint += 'a';
+ executor();
+ checkPoint += 'b';
+}
+Object.defineProperty(fn2, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(fn2, []);
+}, 'executor called with no arguments');
+assert.sameValue(checkPoint, 'ab', 'executor called with no arguments');
+
+checkPoint = '';
+function fn3(executor) {
+ checkPoint += 'a';
+ executor(undefined, undefined);
+ checkPoint += 'b';
+}
+Object.defineProperty(fn3, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(fn3, []);
+}, 'executor called with (undefined, undefined)');
+assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, undefined)');
+
+checkPoint = '';
+function fn4(executor) {
+ checkPoint += 'a';
+ executor(undefined, function() {});
+ checkPoint += 'b';
+}
+Object.defineProperty(fn4, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(fn4, []);
+}, 'executor called with (undefined, function)');
+assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, function)');
+
+checkPoint = '';
+function fn5(executor) {
+ checkPoint += 'a';
+ executor(function() {}, undefined);
+ checkPoint += 'b';
+}
+Object.defineProperty(fn5, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(fn5, []);
+}, 'executor called with (function, undefined)');
+assert.sameValue(checkPoint, 'ab', 'executor called with (function, undefined)');
+
+checkPoint = '';
+function fn6(executor) {
+ checkPoint += 'a';
+ executor(123, 'invalid value');
+ checkPoint += 'b';
+}
+Object.defineProperty(fn6, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(fn6, []);
+}, 'executor called with (Number, String)');
+assert.sameValue(checkPoint, 'ab', 'executor called with (Number, String)');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/capability-resolve-throws-no-close.js b/js/src/tests/test262/built-ins/Promise/allSettled/capability-resolve-throws-no-close.js
new file mode 100644
index 0000000000..e59ca8916e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/capability-resolve-throws-no-close.js
@@ -0,0 +1,66 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.allsettled
+description: >
+ Iterator is not closed when the "resolve" capability returns an abrupt
+ completion.
+info: |
+ ...
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+ 8. Return Completion(result).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ ...
+ 6. Repeat
+ ...
+ d. If next is false, then
+ ...
+ iii. If remainingElementsCount.[[Value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+
+ IfAbruptRejectPromise
+
+ 1. IfAbruptRejectPromise(value, capability).
+features: [Promise.allSettled, Symbol.iterator]
+---*/
+
+var returnCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next() {
+ return {
+ done: true
+ };
+ },
+ return() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+var P = function(executor) {
+ return new Promise(function(_, reject) {
+ executor(function() {
+ throw new Test262Error();
+ }, reject);
+ });
+};
+
+P.resolve = function() {
+ throw new Test262Error();
+};
+
+Promise.allSettled.call(P, iter);
+
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/capability-resolve-throws-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/capability-resolve-throws-reject.js
new file mode 100644
index 0000000000..5e02b835d4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/capability-resolve-throws-reject.js
@@ -0,0 +1,60 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.allsettled
+description: >
+ Promise is rejected when the "resolve" capability returns an abrupt
+ completion.
+info: |
+ ...
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+ 8. Return Completion(result).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ ...
+ 6. Repeat
+ ...
+ d. If next is false, then
+ ...
+ iii. If remainingElementsCount.[[Value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+
+
+ IfAbruptRejectPromise
+
+ 1. IfAbruptRejectPromise(value, capability).
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var thrown = new Test262Error();
+var P = function(executor) {
+ return new Promise(function(_, reject) {
+ executor(function() {
+ throw thrown;
+ }, reject);
+ });
+};
+
+P.resolve = function() {
+ throw new Test262Error();
+};
+
+Promise.allSettled.call(P, [])
+ .then(function() {
+ $DONE('Promise incorrectly fulfilled.');
+ }, function(reason) {
+ if (reason !== thrown) {
+ $DONE('Promise rejected with incorrect "reason."');
+ return;
+ }
+ $DONE();
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/ctx-ctor-throws.js b/js/src/tests/test262/built-ins/Promise/allSettled/ctx-ctor-throws.js
new file mode 100644
index 0000000000..322690025e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/ctx-ctor-throws.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.allSettled invoked on a constructor value that throws an error
+esid: sec-promise.allsettled
+info: |
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+
+ NewPromiseCapability
+
+ ...
+ 7. Let promise be ? Construct(C, « executor »).
+features: [Promise.allSettled]
+---*/
+
+var CustomPromise = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ Promise.allSettled.call(CustomPromise);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/ctx-ctor.js b/js/src/tests/test262/built-ins/Promise/allSettled/ctx-ctor.js
new file mode 100644
index 0000000000..66fa8d387b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/ctx-ctor.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.allSettled invoked on a constructor value
+esid: sec-promise.allsettled
+info: |
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ ...
+ 8. Return Completion(result).
+features: [Promise.allSettled, class]
+---*/
+
+var executor = null;
+var callCount = 0;
+
+class SubPromise extends Promise {
+ constructor(a) {
+ super(a);
+ executor = a;
+ callCount += 1;
+ }
+}
+
+var instance = Promise.allSettled.call(SubPromise, []);
+
+assert.sameValue(instance.constructor, SubPromise);
+assert.sameValue(instance instanceof SubPromise, true);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(typeof executor, 'function');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/ctx-non-ctor.js b/js/src/tests/test262/built-ins/Promise/allSettled/ctx-non-ctor.js
new file mode 100644
index 0000000000..3850884632
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/ctx-non-ctor.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.allSettled invoked on a non-constructor value
+esid: sec-promise.allsettled
+info: |
+ ...
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+
+ NewPromiseCapability ( C )
+
+ 1. If IsConstructor(C) is false, throw a TypeError exception.
+features: [Promise.allSettled]
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(eval);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/ctx-non-object.js b/js/src/tests/test262/built-ins/Promise/allSettled/ctx-non-object.js
new file mode 100644
index 0000000000..a44e2ba28b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/ctx-non-object.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.allSettled invoked on a non-object value
+esid: sec-promise.allsettled
+info: |
+ 1. Let C be the this value.
+ 2. If Type(C) is not Object, throw a TypeError exception.
+features: [Promise.allSettled, Symbol]
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(undefined, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(null, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(86, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.allSettled.call('string', []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(true, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.allSettled.call(Symbol(), []);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/does-not-invoke-array-setters.js b/js/src/tests/test262/built-ins/Promise/allSettled/does-not-invoke-array-setters.js
new file mode 100644
index 0000000000..7105446411
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/does-not-invoke-array-setters.js
@@ -0,0 +1,47 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiseallsettled
+description: >
+ Indexed setter properties on Array.prototype are not invoked.
+info: |
+ Promise.allSettled ( iterable )
+
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b, IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ ...
+ 4. Let remainingElementsCount be a new Record { [[value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0,
+ 1. Let valuesArray be CreateArrayFromList(values).
+ ...
+ ...
+
+ 7.3.16 CreateArrayFromList (elements)
+ ...
+ 4. For each element e of elements
+ a. Let status be CreateDataProperty(array, ToString(n), e).
+ b. Assert: status is true.
+ ...
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+Object.defineProperty(Array.prototype, 0, {
+ set() {
+ throw new Test262Error('Setter on Array.prototype called');
+ }
+});
+
+Promise.allSettled([42]).then(function() {
+ $DONE();
+}, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-error-close.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-error-close.js
new file mode 100644
index 0000000000..8855a5e989
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-error-close.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Explicit iterator closing in response to error
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ ...
+ i. Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
+features: [Promise.allSettled, Symbol.iterator]
+---*/
+
+var iterDoneSpy = {};
+var callCount = 0;
+iterDoneSpy[Symbol.iterator] = function() {
+ return {
+ next() {
+ return {
+ value: null,
+ done: false
+ };
+ },
+ return() {
+ callCount += 1;
+ }
+ };
+};
+
+Promise.resolve = function() {
+ throw new Error();
+};
+
+Promise.allSettled(iterDoneSpy);
+
+assert.sameValue(callCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-error-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-error-reject.js
new file mode 100644
index 0000000000..8d44515c1c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-error-reject.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise rejection in response to error
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ ...
+ i. Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var thrown = new Test262Error();
+Promise.resolve = function() {
+ throw thrown;
+};
+
+Promise.allSettled([1])
+ .then(function() {
+ throw new Test262Error('The promise should not be fulfilled.');
+ }, function(reason) {
+ if (reason !== thrown) {
+ throw new Test262Error('The promise should be rejected with the thrown error object');
+ }
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-error-reject.js
new file mode 100644
index 0000000000..ffc8525c37
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-error-reject.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error retrieving the constructor's `resolve` method (rejecting promise)
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ ...
+ i. Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var error = new Test262Error();
+Object.defineProperty(Promise, 'resolve', {
+ get() {
+ throw error;
+ }
+});
+
+Promise.allSettled([new Promise(function() {})]).then(function() {
+ throw new Test262Error('The promise should be rejected');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-error.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-error.js
new file mode 100644
index 0000000000..c4e560b61e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-error.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Promise.resolve is retrieved before GetIterator call (abrupt lookup).
+info: |
+ Promise.allSettled ( iterable )
+
+ [...]
+ 3. Let promiseResolve be GetPromiseResolve(C).
+ 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
+
+ GetPromiseResolve ( promiseConstructor )
+
+ [...]
+ 2. Let promiseResolve be ? Get(promiseConstructor, "resolve").
+flags: [async]
+features: [Promise.allSettled, Symbol.iterator]
+---*/
+
+const iter = {
+ get [Symbol.iterator]() {
+ throw new Test262Error('unreachable');
+ },
+};
+
+const resolveError = { name: 'MyError' };
+Object.defineProperty(Promise, 'resolve', {
+ get() {
+ throw resolveError;
+ },
+});
+
+Promise.allSettled(iter).then(() => {
+ throw new Test262Error('The promise should be rejected, but it was resolved');
+}, (reason) => {
+ assert.sameValue(reason, resolveError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-once-multiple-calls.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-once-multiple-calls.js
new file mode 100644
index 0000000000..9dc562bb57
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-once-multiple-calls.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Gets constructor's `resolve` method once from zero to many invocations.
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Let promiseResolve be ? Get(constructor, `"resolve"`).
+ 7. 1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+features: [Promise.allSettled]
+---*/
+
+var p1 = Promise.resolve(1);
+var p2 = Promise.resolve(1);
+var p3 = Promise.reject(1);
+var p4 = Promise.resolve(1);
+var resolve = Promise.resolve;
+var getCount = 0;
+var callCount = 0;
+
+Object.defineProperty(Promise, 'resolve', {
+ configurable: true,
+ get() {
+ getCount += 1;
+ return function() {
+ callCount += 1;
+ return resolve.apply(Promise, arguments);
+ };
+ }
+});
+
+Promise.allSettled([p1, p2, p3, p4]);
+
+assert.sameValue(
+ getCount, 1, 'Got `resolve` only once for each iterated value'
+);
+assert.sameValue(
+ callCount, 4, '`resolve` invoked once for each iterated value'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-once-no-calls.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-once-no-calls.js
new file mode 100644
index 0000000000..1be9e774be
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-get-once-no-calls.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Gets constructor's `resolve` method once from zero to many invocations.
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Let promiseResolve be ? Get(constructor, `"resolve"`).
+ 7. 1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+features: [Promise.allSettled]
+---*/
+
+var resolve = Promise.resolve;
+var getCount = 0;
+var callCount = 0;
+
+Object.defineProperty(Promise, 'resolve', {
+ configurable: true,
+ get() {
+ getCount += 1;
+ return function() {
+ callCount += 1;
+ return resolve.apply(Promise, arguments);
+ };
+ }
+});
+
+Promise.allSettled([]);
+
+assert.sameValue(
+ getCount, 1, 'Got `resolve` only once for each iterated value'
+);
+assert.sameValue(
+ callCount, 0, '`resolve` not called for empty iterator'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-custom.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-custom.js
new file mode 100644
index 0000000000..46502e00ab
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-custom.js
@@ -0,0 +1,44 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with promise values
+esid: sec-promise.allSettled
+info: |
+ 7. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 7. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.allSettled, class, arrow-function]
+---*/
+class Custom extends Promise {}
+
+let values = [1, 1, 1];
+let cresolveCallCount = 0;
+let presolveCallCount = 0;
+let boundCustomResolve = Custom.resolve.bind(Custom);
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Custom.resolve = function(...args) {
+ cresolveCallCount += 1;
+ return boundCustomResolve(...args);
+};
+
+Promise.resolve = function(...args) {
+ presolveCallCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.allSettled.call(Custom, values)
+ .then(() => {
+ assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked');
+ assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every iterated promise');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-promise.js
new file mode 100644
index 0000000000..52e8992abb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-promises-every-iteration-of-promise.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with promise values
+esid: sec-promise.allSettled
+info: |
+ 7. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 7. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.allSettled, arrow-function]
+---*/
+
+let values = [1,1,1];
+let callCount = 0;
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Promise.resolve = function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.allSettled(values)
+ .then(() => {
+ assert.sameValue(callCount, 3, '`then` invoked once for every iterated promise');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-values-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-values-every-iteration-of-promise.js
new file mode 100644
index 0000000000..2c8678c381
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-on-values-every-iteration-of-promise.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with non-promise values
+esid: sec-promise.allSettled
+info: |
+ 5. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.allSettled, arrow-function]
+---*/
+
+let values = [1, 2, 3];
+let callCount = 0;
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Promise.resolve = function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.allSettled(values)
+ .then(() => {
+ assert.sameValue(callCount, 3, '`Promise.resolve` invoked once for every iterated value');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-return.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-return.js
new file mode 100644
index 0000000000..99d28cde15
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve-return.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Use of the value returned by the constructor's `resolve` method.
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ ...
+ i. Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+features: [Promise.allSettled]
+---*/
+
+var originalCallCount = 0;
+var newCallCount = 0;
+var P = function(executor) {
+ executor(function() {}, function() {});
+};
+P.resolve = function() {
+ return newThenable;
+};
+
+var originalThenable = {
+ then() {
+ originalCallCount += 1;
+ }
+};
+var newThenable = {
+ then() {
+ newCallCount += 1;
+ }
+};
+
+Promise.allSettled.call(P, [originalThenable]);
+
+assert.sameValue(originalCallCount, 0, 'original `then` method not invoked');
+assert.sameValue(newCallCount, 1, 'new `then` method invoked exactly once');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve.js
new file mode 100644
index 0000000000..c7f500609f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-resolve.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ ...
+ i. Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+features: [Promise.allSettled]
+---*/
+
+var p1 = new Promise(function() {});
+var p2 = new Promise(function() {});
+var p3 = new Promise(function() {});
+var resolve = Promise.resolve;
+var callCount = 0;
+var current = p1;
+var next = p2;
+var afterNext = p3;
+
+Promise.resolve = function(nextValue) {
+ assert.sameValue(
+ nextValue, current, '`resolve` invoked with next iterated value'
+ );
+ assert.sameValue(
+ arguments.length, 1, '`resolve` invoked with a single argument'
+ );
+ assert.sameValue(this, Promise, '`this` value is the constructor');
+
+ current = next;
+ next = afterNext;
+ afterNext = null;
+
+ callCount += 1;
+
+ return resolve.apply(Promise, arguments);
+};
+
+Promise.allSettled([p1, p2, p3]);
+
+assert.sameValue(
+ callCount, 3, '`resolve` invoked once for each iterated value'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-error-close.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-error-close.js
new file mode 100644
index 0000000000..68134047a7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-error-close.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Error thrown when invoking the instance's `then` method (closing iterator)
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+features: [Promise.allSettled, Symbol.iterator]
+---*/
+
+var promise = new Promise(function() {});
+var returnCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next() {
+ return {
+ done: false,
+ value: promise
+ };
+ },
+ return() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+promise.then = function() {
+ throw new Test262Error();
+};
+
+Promise.allSettled(iter);
+
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-error-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-error-reject.js
new file mode 100644
index 0000000000..a6b1e70670
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-error-reject.js
@@ -0,0 +1,33 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error thrown when invoking the instance's `then` method (rejecting Promise)
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var promise = new Promise(function() {});
+var error = new Test262Error();
+
+promise.then = function() {
+ throw error;
+};
+
+Promise.allSettled([promise]).then(function() {
+ throw new Test262Error('The promise should be rejected');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-get-error-close.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-get-error-close.js
new file mode 100644
index 0000000000..e5bf42c056
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-get-error-close.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Error thrown when accesing the instance's `then` method (closing iterator)
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+features: [Promise.allSettled, Symbol.iterator]
+---*/
+
+var promise = new Promise(function() {});
+var returnCount = 0;
+var iter = {};
+iter[Symbol.iterator] = function() {
+ return {
+ next() {
+ return {
+ done: false,
+ value: promise
+ };
+ },
+ return() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+Object.defineProperty(promise, 'then', {
+ get() {
+ throw new Test262Error();
+ }
+});
+
+Promise.allSettled(iter);
+
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-get-error-reject.js
new file mode 100644
index 0000000000..53fc2ab99d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then-get-error-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Error thrown when accessing the instance's `then` method (rejecting Promise)
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var promise = new Promise(function() {});
+var error = new Test262Error();
+
+Object.defineProperty(promise, 'then', {
+ get() {
+ throw error;
+ }
+});
+
+Promise.allSettled([promise]).then(function() {
+ throw new Test262Error('The promise should be rejected');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then.js b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then.js
new file mode 100644
index 0000000000..e042be9470
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/invoke-then.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the instance's `then` method
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+features: [Promise.allSettled]
+---*/
+
+var p1 = new Promise(function() {});
+var p2 = new Promise(function() {});
+var p3 = new Promise(function() {});
+var callCount = 0;
+var currentThis = p1;
+var nextThis = p2;
+var afterNextThis = p3;
+
+p1.then = p2.then = p3.then = function(a, b) {
+ assert.sameValue(typeof a, 'function', 'type of first argument');
+ assert.sameValue(
+ a.length,
+ 1,
+ 'The length property of a promise resolve function is 1.'
+ );
+ assert.sameValue(typeof b, 'function', 'type of second argument');
+ assert.sameValue(
+ b.length,
+ 1,
+ 'The length property of a promise reject function is 1.'
+ );
+ assert.sameValue(arguments.length, 2, '`then` invoked with two arguments');
+ assert.sameValue(this, currentThis, '`this` value');
+
+ currentThis = nextThis;
+ nextThis = afterNextThis;
+ afterNextThis = null;
+
+ callCount += 1;
+};
+
+Promise.allSettled([p1, p2, p3]);
+
+assert.sameValue(callCount, 3, '`then` invoked once for every iterated value');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/is-function.js b/js/src/tests/test262/built-ins/Promise/allSettled/is-function.js
new file mode 100644
index 0000000000..daf7e13c23
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/is-function.js
@@ -0,0 +1,12 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Promise.allSettled is callable
+features: [Promise.allSettled]
+---*/
+
+assert.sameValue(typeof Promise.allSettled, 'function');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-false-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-false-reject.js
new file mode 100644
index 0000000000..922a04af41
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-false-reject.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument is `false`
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled(false).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-null-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-null-reject.js
new file mode 100644
index 0000000000..b168fd1bb9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-null-reject.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument is `null`
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled(null).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-number-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-number-reject.js
new file mode 100644
index 0000000000..1acd2b92f4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-number-reject.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument is a number
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled(1).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-poisoned.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-poisoned.js
new file mode 100644
index 0000000000..0062464619
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-poisoned.js
@@ -0,0 +1,43 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject with abrupt completion from GetIterator
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ ...
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+var poison = [];
+var error = new Test262Error();
+Object.defineProperty(poison, Symbol.iterator, {
+ get() {
+ throw error;
+ }
+});
+
+try {
+ Promise.allSettled(poison).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(err) {
+ assert.sameValue(err, error);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-string-resolve.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-string-resolve.js
new file mode 100644
index 0000000000..44b36a28b1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-string-resolve.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Resolve when argument is a string
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled('').then(function(v) {
+ assert.sameValue(v.length, 0);
+ }, function() {
+ $DONE('The promise should be resolved, but was rejected');
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be resolved, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-symbol-reject.js
new file mode 100644
index 0000000000..d5a8f6ab23
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-symbol-reject.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument is a symbol
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled(Symbol()).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-true-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-true-reject.js
new file mode 100644
index 0000000000..938a896bed
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-true-reject.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument is `true`
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled(true).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-undefined-reject.js
new file mode 100644
index 0000000000..fb06afbe2b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-arg-is-undefined-reject.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument is `undefined`
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled(undefined).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-false-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-false-reject.js
new file mode 100644
index 0000000000..f6f0480626
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-false-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator property has the value false
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ i. Set method to ? GetMethod(obj, @@asyncIterator).
+ ii. If method is undefined, then
+ 1. Let syncMethod be ? GetMethod(obj, @@iterator).
+ 2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod).
+ ...
+ 4. Let iterator be ? Call(method, obj).
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]: false
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-null-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-null-reject.js
new file mode 100644
index 0000000000..920c1014ba
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-null-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator property has the value null
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]: null
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-number-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-number-reject.js
new file mode 100644
index 0000000000..6aa69307e2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-number-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator property has the value 1
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]: 1
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-string-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-string-reject.js
new file mode 100644
index 0000000000..4154d30463
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-string-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator property has the value ""
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]: ''
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-symbol-reject.js
new file mode 100644
index 0000000000..63797534c2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-symbol-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator property has the value Symbol()
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]: Symbol()
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-true-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-true-reject.js
new file mode 100644
index 0000000000..e7edd2e6c5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-true-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator property has the value true
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]: true
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-undefined-reject.js
new file mode 100644
index 0000000000..6ab397c63d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-assigned-undefined-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator property has the value undefined
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]: undefined
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-next-err-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-next-err-reject.js
new file mode 100644
index 0000000000..11c0bc77ec
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-next-err-reject.js
@@ -0,0 +1,55 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Error when call an iterator next step (rejecting promise)
+info: |
+ Promise.allSettled ( iterable )
+
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ ...
+ 6. Repeat
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ c. ReturnIfAbrupt(next).
+ ...
+
+ IteratorStep ( iteratorRecord )
+
+ 1. Let result be ? IteratorNext(iteratorRecord).
+
+ IteratorNext ( iteratorRecord [ , value ] )
+
+ 1. If value is not present, then
+ a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « »).
+ 2. Else,
+ a. Let result be ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « value »).
+ ...
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+var iterNextValThrows = {};
+var error = new Test262Error();
+iterNextValThrows[Symbol.iterator] = function() {
+ return {
+ next() {
+ throw error;
+ }
+ };
+};
+
+Promise.allSettled(iterNextValThrows).then(function() {
+ $DONE('The promise should be rejected.');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-next-val-err-no-close.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-next-val-err-no-close.js
new file mode 100644
index 0000000000..368c72d590
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-next-val-err-no-close.js
@@ -0,0 +1,58 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Error when accessing an iterator result's `value` property (not closing
+ iterator)
+info: |
+ Promise.allSettled ( iterable )
+
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ ...
+ 6. Repeat
+ ...
+ e. Let nextValue be IteratorValue(next).
+ f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ g. ReturnIfAbrupt(nextValue).
+features: [Promise.allSettled, Symbol.iterator]
+---*/
+
+var iterNextValThrows = {};
+var returnCount = 0;
+var nextCount = 0;
+var poisonedVal = {
+ done: false
+};
+var error = new Test262Error();
+Object.defineProperty(poisonedVal, 'value', {
+ get() {
+ throw error;
+ }
+});
+iterNextValThrows[Symbol.iterator] = function() {
+ return {
+ next() {
+ nextCount += 1;
+ return poisonedVal;
+ },
+ return() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+Promise.allSettled(iterNextValThrows);
+
+assert.sameValue(returnCount, 0);
+assert.sameValue(nextCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-next-val-err-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-next-val-err-reject.js
new file mode 100644
index 0000000000..a5855e5efb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-next-val-err-reject.js
@@ -0,0 +1,51 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Error when accessing an iterator result's `value` property (rejecting promise)
+info: |
+ Promise.allSettled ( iterable )
+
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ ...
+ 6. Repeat
+ ...
+ e. Let nextValue be IteratorValue(next).
+ f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ g. ReturnIfAbrupt(nextValue).
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+var iterNextValThrows = {};
+var poisonedVal = {
+ done: false
+};
+var error = new Test262Error();
+Object.defineProperty(poisonedVal, 'value', {
+ get() {
+ throw error;
+ }
+});
+iterNextValThrows[Symbol.iterator] = function() {
+ return {
+ next() {
+ return poisonedVal;
+ }
+ };
+};
+
+Promise.allSettled(iterNextValThrows).then(function() {
+ $DONE('The promise should be rejected.');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-false-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-false-reject.js
new file mode 100644
index 0000000000..61ade03c35
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-false-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator returns false
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]() {
+ return false;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-null-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-null-reject.js
new file mode 100644
index 0000000000..06772c0d74
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-null-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator returns null
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]() {
+ return null;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-number-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-number-reject.js
new file mode 100644
index 0000000000..4a49159127
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-number-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator returns a number
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]() {
+ return 1;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-string-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-string-reject.js
new file mode 100644
index 0000000000..85094a5763
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-string-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator returns a string
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]() {
+ return '';
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-symbol-reject.js
new file mode 100644
index 0000000000..2a31e898f5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-symbol-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator returns a symbol
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]() {
+ return Symbol();
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-true-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-true-reject.js
new file mode 100644
index 0000000000..4a31be5163
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-true-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator returns true
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]() {
+ return true;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-undefined-reject.js
new file mode 100644
index 0000000000..48dd3c1ba7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-returns-undefined-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Reject when argument's Symbol.iterator returns undefined
+info: |
+ Promise.allSettled ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.allSettled({
+ [Symbol.iterator]() {
+ return undefined;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-step-err-no-close.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-step-err-no-close.js
new file mode 100644
index 0000000000..c7c988138b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-step-err-no-close.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Error when advancing the provided iterable (not closing iterator)
+info: |
+ Promise.allSettled ( iterable )
+
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+features: [Promise.allSettled, Symbol.iterator]
+---*/
+
+var iterStepThrows = {};
+var poisonedDone = {};
+var returnCount = 0;
+var error = new Test262Error();
+Object.defineProperty(poisonedDone, 'done', {
+ get() {
+ throw error;
+ }
+});
+Object.defineProperty(poisonedDone, 'value', {
+ get() {}
+});
+
+iterStepThrows[Symbol.iterator] = function() {
+ return {
+ next() {
+ return poisonedDone;
+ },
+ return() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+Promise.allSettled(iterStepThrows);
+
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/iter-step-err-reject.js b/js/src/tests/test262/built-ins/Promise/allSettled/iter-step-err-reject.js
new file mode 100644
index 0000000000..874f3018e1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/iter-step-err-reject.js
@@ -0,0 +1,53 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Error when advancing the provided iterable (rejecting promise)
+info: |
+ Promise.allSettled ( iterable )
+
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+features: [Promise.allSettled, Symbol.iterator]
+flags: [async]
+---*/
+
+var iterStepThrows = {};
+var poisonedDone = {};
+var error = new Test262Error();
+Object.defineProperty(poisonedDone, 'done', {
+ get() {
+ throw error;
+ }
+});
+Object.defineProperty(poisonedDone, 'value', {
+ get() {
+ $DONE('The `value` property should not be accessed.');
+ }
+});
+
+iterStepThrows[Symbol.iterator] = function() {
+ return {
+ next() {
+ return poisonedDone;
+ }
+ };
+};
+
+Promise.allSettled(iterStepThrows).then(function() {
+ $DONE('The promise should be rejected.');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/length.js b/js/src/tests/test262/built-ins/Promise/allSettled/length.js
new file mode 100644
index 0000000000..c0ffb02fb5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/length.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Promise.allSettled `length` property
+info: |
+ ES Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Promise.allSettled]
+---*/
+
+verifyProperty(Promise.allSettled, 'length', {
+ configurable: true,
+ writable: false,
+ enumerable: false,
+ value: 1,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/name.js b/js/src/tests/test262/built-ins/Promise/allSettled/name.js
new file mode 100644
index 0000000000..fe9c2497d4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/name.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Promise.allSettled `name` property
+info: |
+ ES Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Promise.allSettled]
+---*/
+
+verifyProperty(Promise.allSettled, 'name', {
+ configurable: true,
+ writable: false,
+ enumerable: false,
+ value: 'allSettled',
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/new-reject-function.js b/js/src/tests/test262/built-ins/Promise/allSettled/new-reject-function.js
new file mode 100644
index 0000000000..16e4ed0e2d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/new-reject-function.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiseallsettled
+description: >
+ Each Promise.allSettled element is called with a new Promise.allSettled Reject Element function.
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+ ...
+features: [Promise.allSettled]
+---*/
+
+function rejectFunction() {}
+
+function Constructor(executor) {
+ executor(rejectFunction, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var callCount1 = 0,
+ callCount2 = 0;
+var p1OnRejected;
+
+var p1 = {
+ then(_, onRejected) {
+ callCount1 += 1;
+ p1OnRejected = onRejected;
+ assert.notSameValue(onRejected, rejectFunction, 'p1.then');
+ }
+};
+var p2 = {
+ then(_, onRejected) {
+ callCount2 += 1;
+ assert.notSameValue(onRejected, rejectFunction, 'p2.then');
+ assert.notSameValue(onRejected, p1OnRejected, 'p1.onRejected != p2.onRejected');
+ }
+};
+
+Promise.allSettled.call(Constructor, [p1, p2]);
+
+assert.sameValue(callCount1, 1, 'p1.then call count');
+assert.sameValue(callCount2, 1, 'p2.then call count');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/new-resolve-function.js b/js/src/tests/test262/built-ins/Promise/allSettled/new-resolve-function.js
new file mode 100644
index 0000000000..048d664dc2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/new-resolve-function.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiseallsettled
+description: >
+ Each Promise.allSettled element is called with a new Promise.allSettled Resolve Element function.
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ ...
+ k Let resolveElement be ! CreateBuiltinFunction(steps, « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+ ...
+features: [Promise.allSettled]
+---*/
+
+function resolveFunction() {}
+
+function Constructor(executor) {
+ executor(resolveFunction, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var callCount1 = 0,
+ callCount2 = 0;
+var p1OnFulfilled;
+
+var p1 = {
+ then(onFulfilled, onRejected) {
+ callCount1 += 1;
+ p1OnFulfilled = onFulfilled;
+ assert.notSameValue(onFulfilled, resolveFunction, 'p1.then');
+ }
+};
+var p2 = {
+ then(onFulfilled, onRejected) {
+ callCount2 += 1;
+ assert.notSameValue(onFulfilled, resolveFunction, 'p2.then');
+ assert.notSameValue(onFulfilled, p1OnFulfilled, 'p1.onFulfilled != p2.onFulfilled');
+ }
+};
+
+Promise.allSettled.call(Constructor, [p1, p2]);
+
+assert.sameValue(callCount1, 1, 'p1.then call count');
+assert.sameValue(callCount2, 1, 'p2.then call count');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/allSettled/not-a-constructor.js
new file mode 100644
index 0000000000..98dc3d6401
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/not-a-constructor.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Promise.allSettled does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, Promise.allSettled, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(Promise.allSettled), false, 'isConstructor(Promise.allSettled) must return false');
+
+assert.throws(TypeError, () => {
+ new Promise.allSettled();
+}, '`new Promise.allSettled()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/prop-desc.js b/js/src/tests/test262/built-ins/Promise/allSettled/prop-desc.js
new file mode 100644
index 0000000000..46ae80be70
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/prop-desc.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Promise.allSettled property descriptor
+info: |
+ ES Section 17
+
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [Promise.allSettled]
+---*/
+
+verifyProperty(Promise, 'allSettled', {
+ configurable: true,
+ writable: true,
+ enumerable: false,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-deferred.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-deferred.js
new file mode 100644
index 0000000000..6eec5d809b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-deferred.js
@@ -0,0 +1,47 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting through deferred invocation of the provided resolving function
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+
+ Promise.allSettled Reject Element Functions
+
+ 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
+ 10. Perform ! CreateDataProperty(obj, "status", "rejected").
+ 11. Perform ! CreateDataProperty(obj, "reason", x).
+ 12. Set values[index] to be obj.
+ 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var simulation = {};
+var thenable = {
+ then(_, reject) {
+ new Promise(function(resolve) {
+ resolve();
+ })
+ .then(function() {
+ reject(simulation);
+ });
+ }
+};
+
+Promise.allSettled([thenable])
+ .then((settleds) => {
+ assert.sameValue(settleds.length, 1);
+ assert.sameValue(settleds[0].status, 'rejected');
+ assert.sameValue(settleds[0].reason, simulation);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-extensible.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-extensible.js
new file mode 100644
index 0000000000..5672b6e9dc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-extensible.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-reject-element-functions
+description: The [[Extensible]] slot of Promise.allSettled Reject Element functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless specified otherwise, the [[Extensible]] internal slot
+ of a built-in object initially has the value true.
+features: [Promise.allSettled]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+assert(Object.isExtensible(rejectElementFunction));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-length.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-length.js
new file mode 100644
index 0000000000..9c92566180
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-length.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-reject-element-functions
+description: The `length` property of Promise.allSettled Reject Element functions
+info: |
+ The length property of a Promise.allSettled Reject Element function is 1.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+assert.sameValue(rejectElementFunction.length, 1);
+
+verifyProperty(rejectElementFunction, 'length', {
+ value: 1,
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-multiple-calls.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-multiple-calls.js
new file mode 100644
index 0000000000..2cbc89007d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-multiple-calls.js
@@ -0,0 +1,56 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiseallsettled
+description: >
+ Cannot tamper with remainingElementsCount when Promise.allSettled reject element function is called multiple times.
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability, )
+
+ If alreadyCalled.[[Value]] is true, return undefined.
+
+features: [Promise.allSettled]
+---*/
+
+let rejectCallCount = 0;
+let returnValue = {};
+let error = new Test262Error();
+
+function Constructor(executor) {
+ function reject(value) {
+ assert.sameValue(value, error);
+ rejectCallCount += 1;
+ return returnValue;
+ }
+ executor(() => {throw error}, reject);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+Constructor.reject = function(v) {
+ return v;
+};
+
+let pOnRejected;
+
+let p = {
+ then(onResolved, onRejected) {
+ pOnRejected = onRejected;
+ onResolved();
+ }
+};
+
+assert.sameValue(rejectCallCount, 0, 'rejectCallCount before call to allSettled()');
+
+Promise.allSettled.call(Constructor, [p]);
+
+assert.sameValue(rejectCallCount, 1, 'rejectCallCount after call to allSettled()');
+assert.sameValue(pOnRejected(), undefined);
+assert.sameValue(rejectCallCount, 1, 'rejectCallCount after call to pOnRejected()');
+pOnRejected();
+assert.sameValue(rejectCallCount, 1, 'rejectCallCount after call to pOnRejected()');
+
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-name.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-name.js
new file mode 100644
index 0000000000..dce6efeb06
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-name.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-reject-element-functions
+description: The `name` property of Promise.allSettled Reject Element functions
+info: |
+ A promise resolve function is an anonymous built-in function.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in function object, including constructors, has a `name`
+ property whose value is a String. Functions that are identified as
+ anonymous functions use the empty string as the value of the `name`
+ property.
+ Unless otherwise specified, the `name` property of a built-in function
+ object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
+ [[Configurable]]: *true* }.
+includes: [propertyHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+verifyProperty(rejectElementFunction, "name", {
+ value: "", writable: false, enumerable: false, configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-nonconstructor.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-nonconstructor.js
new file mode 100644
index 0000000000..e6803c37cf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-nonconstructor.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-reject-element-functions
+description: Promise.allSettled Reject Element functions are not constructors
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified
+ in the description of a particular function.
+features: [Promise.allSettled]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+assert.sameValue(Object.prototype.hasOwnProperty.call(rejectElementFunction, 'prototype'), false);
+assert.throws(TypeError, function() {
+ new rejectElementFunction();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-property-order.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-property-order.js
new file mode 100644
index 0000000000..44a71240e7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-property-order.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createbuiltinfunction
+description: Promise.allSettled reject element function property order
+info: |
+ Set order: "length", "name"
+features: [Promise.allSettled]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then: function(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+var propNames = Object.getOwnPropertyNames(rejectElementFunction);
+var lengthIndex = propNames.indexOf("length");
+var nameIndex = propNames.indexOf("name");
+
+assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1,
+ "The `length` property comes before the `name` property on built-in functions");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-prototype.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-prototype.js
new file mode 100644
index 0000000000..79067c1e53
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-element-function-prototype.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-reject-element-functions
+description: The [[Prototype]] of Promise.allSettled Reject Element functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified every built-in function and every built-in
+ constructor has the Function prototype object, which is the initial
+ value of the expression Function.prototype (19.2.3), as the value of
+ its [[Prototype]] internal slot.
+features: [Promise.allSettled]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+assert.sameValue(Object.getPrototypeOf(rejectElementFunction), Function.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-ignored-deferred.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-ignored-deferred.js
new file mode 100644
index 0000000000..c249c2cfe8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-ignored-deferred.js
@@ -0,0 +1,53 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through deferred invocation of the
+ provided resolving function
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var simulation = {};
+
+var fulfiller = {
+ then(resolve) {
+ new Promise(function(resolve) {
+ resolve();
+ })
+ .then(function() {
+ resolve(42);
+ });
+ }
+};
+var rejector = {
+ then(resolve, reject) {
+ new Promise(function(resolve) {
+ resolve();
+ })
+ .then(function() {
+ resolve(simulation);
+ reject();
+ });
+ }
+};
+
+Promise.allSettled([fulfiller, rejector])
+ .then((settleds) => {
+ assert.sameValue(settleds.length, 2);
+ assert.sameValue(settleds[0].status, 'fulfilled');
+ assert.sameValue(settleds[0].value, 42);
+ assert.sameValue(settleds[1].status, 'fulfilled');
+ assert.sameValue(settleds[1].value, simulation);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-ignored-immed.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-ignored-immed.js
new file mode 100644
index 0000000000..d06df2b019
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-ignored-immed.js
@@ -0,0 +1,44 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through immediate invocation of the
+ provided resolving function
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var simulation = {};
+
+var fulfiller = {
+ then(resolve) {
+ resolve(42);
+ }
+};
+
+var lateRejector = {
+ then(resolve, reject) {
+ resolve(simulation);
+ reject();
+ }
+};
+
+Promise.allSettled([fulfiller, lateRejector])
+ .then((settleds) => {
+ assert.sameValue(settleds.length, 2);
+ assert.sameValue(settleds[0].status, 'fulfilled');
+ assert.sameValue(settleds[0].value, 42);
+ assert.sameValue(settleds[1].status, 'fulfilled');
+ assert.sameValue(settleds[1].value, simulation);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/reject-immed.js b/js/src/tests/test262/built-ins/Promise/allSettled/reject-immed.js
new file mode 100644
index 0000000000..aa5fff5c59
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/reject-immed.js
@@ -0,0 +1,31 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Rejecting through immediate invocation of the provided resolving function
+esid: sec-promise.allsettled
+info: |
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var simulation = {};
+var thenable = {
+ then(_, reject) {
+ reject(simulation);
+ }
+};
+
+Promise.allSettled([thenable])
+ .then((settleds) => {
+ checkSettledPromises(settleds, [{ status: 'rejected', reason: simulation }]);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-before-loop-exit-from-same.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-before-loop-exit-from-same.js
new file mode 100644
index 0000000000..d5bc9325e0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-before-loop-exit-from-same.js
@@ -0,0 +1,85 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiseallsettled
+description: >
+ Cannot tamper remainingElementsCount when Promise.allSettled resolve element function is called twice in a row.
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+
+ Promise.allSettled Resolve Element Functions
+
+ 2. Let alreadyCalled be F.[[AlreadyCalled]].
+ 3. If alreadyCalled.[[Value]] is true, return undefined.
+ 4. Set alreadyCalled.[[Value]] to true.
+ ...
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ checkSettledPromises(values, [
+ {
+ status: 'fulfilled',
+ value: 'p1-fulfill'
+ },
+ {
+ status: 'fulfilled',
+ value: 'p2-fulfill'
+ },
+ {
+ status: 'fulfilled',
+ value: 'p3-fulfill'
+ }
+ ], 'values');
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1OnFulfilled;
+
+var p1 = {
+ then(onFulfilled, onRejected) {
+ p1OnFulfilled = onFulfilled;
+ }
+};
+var p2 = {
+ then(onFulfilled, onRejected) {
+ onFulfilled('p2-fulfill');
+ onFulfilled('p2-fulfill-unexpected');
+ }
+};
+var p3 = {
+ then(onFulfilled, onRejected) {
+ onFulfilled('p3-fulfill');
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to all()');
+
+Promise.allSettled.call(Constructor, [p1, p2, p3]);
+
+assert.sameValue(callCount, 0, 'callCount after call to all()');
+
+p1OnFulfilled('p1-fulfill');
+
+assert.sameValue(callCount, 1, 'callCount after resolving p1');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-before-loop-exit.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-before-loop-exit.js
new file mode 100644
index 0000000000..159168f2eb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-before-loop-exit.js
@@ -0,0 +1,81 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiseallsettled
+description: >
+ Cannot tamper remainingElementsCount when two Promise.allSettled resolve element functions are called in succession.
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+
+ Promise.allSettled Resolve Element Functions
+
+ 2. Let alreadyCalled be F.[[AlreadyCalled]].
+ 3. If alreadyCalled.[[Value]] is true, return undefined.
+ 4. Set alreadyCalled.[[Value]] to true.
+ ...
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ checkSettledPromises(values, [
+ {
+ status: 'fulfilled',
+ value: 'p1-fulfill'
+ },
+ {
+ status: 'fulfilled',
+ value: 'p2-fulfill'
+ },
+ {
+ status: 'fulfilled',
+ value: 'p3-fulfill'
+ }
+ ], 'values');
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1OnFulfilled;
+
+var p1 = {
+ then(onFulfilled, onRejected) {
+ p1OnFulfilled = onFulfilled;
+ }
+};
+var p2 = {
+ then(onFulfilled, onRejected) {
+ p1OnFulfilled('p1-fulfill');
+ onFulfilled('p2-fulfill');
+ }
+};
+var p3 = {
+ then(onFulfilled, onRejected) {
+ onFulfilled('p3-fulfill');
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to all()');
+
+Promise.allSettled.call(Constructor, [p1, p2, p3]);
+
+assert.sameValue(callCount, 1, 'callCount after call to all()');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-extensible.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-extensible.js
new file mode 100644
index 0000000000..0a469e3f67
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-extensible.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-resolve-element-functions
+description: The [[Extensible]] slot of Promise.allSettled Resolve Element functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless specified otherwise, the [[Extensible]] internal slot
+ of a built-in object initially has the value true.
+features: [Promise.allSettled]
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+assert(Object.isExtensible(resolveElementFunction));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-length.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-length.js
new file mode 100644
index 0000000000..16cfbe3219
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-length.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-resolve-element-functions
+description: The `length` property of Promise.allSettled Resolve Element functions
+info: |
+ The length property of a Promise.allSettled resolve element function is 1.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+verifyProperty(resolveElementFunction, 'length', {
+ value: 1,
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-name.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-name.js
new file mode 100644
index 0000000000..eb6a7d1ddc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-name.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-resolve-element-functions
+description: The `name` property of Promise.allSettled Resolve Element functions
+info: |
+ A promise resolve function is an anonymous built-in function.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in function object, including constructors, has a `name`
+ property whose value is a String. Functions that are identified as
+ anonymous functions use the empty string as the value of the `name`
+ property.
+ Unless otherwise specified, the `name` property of a built-in function
+ object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
+ [[Configurable]]: *true* }.
+includes: [propertyHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+verifyProperty(resolveElementFunction, "name", {
+ value: "", writable: false, enumerable: false, configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-nonconstructor.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-nonconstructor.js
new file mode 100644
index 0000000000..5c1ca93aa5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-nonconstructor.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-resolve-element-functions
+description: Promise.allSettled Resolve Element functions are not constructors
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified
+ in the description of a particular function.
+features: [Promise.allSettled]
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+assert.sameValue(Object.prototype.hasOwnProperty.call(resolveElementFunction, 'prototype'), false);
+assert.throws(TypeError, function() {
+ new resolveElementFunction();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-property-order.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-property-order.js
new file mode 100644
index 0000000000..5914500a1e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-property-order.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createbuiltinfunction
+description: Promise.allSettled resolve element function property order
+info: |
+ Set order: "length", "name"
+features: [Promise.allSettled]
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then: function(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+var propNames = Object.getOwnPropertyNames(resolveElementFunction);
+var lengthIndex = propNames.indexOf("length");
+var nameIndex = propNames.indexOf("name");
+
+assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1,
+ "The `length` property comes before the `name` property on built-in functions");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-prototype.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-prototype.js
new file mode 100644
index 0000000000..fc3a86235d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-element-function-prototype.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled-resolve-element-functions
+description: The [[Prototype]] of Promise.allSettled Resolve Element functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified every built-in function and every built-in
+ constructor has the Function prototype object, which is the initial
+ value of the expression Function.prototype (19.2.3), as the value of
+ its [[Prototype]] internal slot.
+features: [Promise.allSettled]
+---*/
+
+var resolveElementFunction;
+var thenable = {
+ then(fulfill) {
+ resolveElementFunction = fulfill;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.allSettled.call(NotPromise, [thenable]);
+
+assert.sameValue(Object.getPrototypeOf(resolveElementFunction), Function.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-from-same-thenable.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-from-same-thenable.js
new file mode 100644
index 0000000000..f51b3406f1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-from-same-thenable.js
@@ -0,0 +1,91 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiseallsettled
+description: >
+ Cannot tamper remainingElementsCount when Promise.allSettled resolve element function is called multiple times.
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+
+ Promise.allSettled Resolve Element Functions
+
+ 2. Let alreadyCalled be F.[[AlreadyCalled]].
+ 3. If alreadyCalled.[[Value]] is true, return undefined.
+ 4. Set alreadyCalled.[[Value]] to true.
+ ...
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var callCount = 0;
+
+function Constructor(executor) {
+ function resolve(values) {
+ callCount += 1;
+ checkSettledPromises(values, [
+ {
+ status: 'fulfilled',
+ value: 'p1-fulfill'
+ },
+ {
+ status: 'fulfilled',
+ value: 'p2-fulfill'
+ },
+ {
+ status: 'fulfilled',
+ value: 'p3-fulfill'
+ }
+ ], 'values');
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var p1OnFulfilled, p2OnFulfilled, p3OnFulfilled;
+
+var p1 = {
+ then(onFulfilled, onRejected) {
+ p1OnFulfilled = onFulfilled;
+ }
+};
+var p2 = {
+ then(onFulfilled, onRejected) {
+ p2OnFulfilled = onFulfilled;
+ }
+};
+var p3 = {
+ then(onFulfilled, onRejected) {
+ p3OnFulfilled = onFulfilled;
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to allSettled()');
+
+Promise.allSettled.call(Constructor, [p1, p2, p3]);
+
+assert.sameValue(callCount, 0, 'callCount after call to allSettled()');
+
+p1OnFulfilled('p1-fulfill');
+p1OnFulfilled('p1-fulfill-unexpected-1');
+p1OnFulfilled('p1-fulfill-unexpected-2');
+
+assert.sameValue(callCount, 0, 'callCount after resolving p1');
+
+p2OnFulfilled('p2-fulfill');
+p3OnFulfilled('p3-fulfill');
+
+assert.sameValue(callCount, 1, 'callCount after resolving all elements');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-ignores-late-rejection-deferred.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-ignores-late-rejection-deferred.js
new file mode 100644
index 0000000000..1697045af9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-ignores-late-rejection-deferred.js
@@ -0,0 +1,45 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through deferred invocation of the
+ provided resolving function
+esid: sec-promise.allSettled
+info: |
+ Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ Repeat
+ ...
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.allSettled, arrow-function]
+---*/
+
+var resolver = {
+ then(resolve) {
+ new Promise((resolve) => resolve())
+ .then(() => resolve(42));
+ }
+};
+var lateRejector = {
+ then(resolve, reject) {
+ new Promise((resolve) => resolve())
+ .then(() => {
+ resolve(9);
+ reject();
+ });
+ }
+};
+
+Promise.allSettled([resolver, lateRejector])
+ .then(resolution => {
+ assert.sameValue(resolution[0].value, 42);
+ assert.sameValue(resolution[0].status, 'fulfilled');
+ assert.sameValue(resolution[1].value, 9);
+ assert.sameValue(resolution[1].status, 'fulfilled');
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-ignores-late-rejection.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-ignores-late-rejection.js
new file mode 100644
index 0000000000..d7847a7b6d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-ignores-late-rejection.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through immediate invocation of the
+ provided resolving function
+esid: sec-promise.allSettled
+info: |
+ Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ Repeat
+ ...
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.allSettled, arrow-function]
+---*/
+
+var resolver = {
+ then(resolve) {
+ resolve(42);
+ }
+};
+var lateRejector = {
+ then(resolve, reject) {
+ resolve(33);
+ reject();
+ }
+};
+
+Promise.allSettled([resolver, lateRejector])
+ .then(resolution => {
+ assert.sameValue(resolution[0].value, 42);
+ assert.sameValue(resolution[0].status, 'fulfilled');
+ assert.sameValue(resolution[1].value, 33);
+ assert.sameValue(resolution[1].status, 'fulfilled');
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-non-callable.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-non-callable.js
new file mode 100644
index 0000000000..ebc4350938
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-non-callable.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2020 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Promise.resolve is retrieved before GetIterator call (non-callable).
+info: |
+ Promise.allSettled ( iterable )
+
+ [...]
+ 3. Let promiseResolve be GetPromiseResolve(C).
+ 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
+
+ GetPromiseResolve ( promiseConstructor )
+
+ [...]
+ 2. Let promiseResolve be ? Get(promiseConstructor, "resolve").
+ 3. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+flags: [async]
+features: [Promise.allSettled, Symbol.iterator]
+---*/
+
+const iter = { 
+ get [Symbol.iterator]() {
+ throw new Test262Error("unreachable");
+ },
+};
+
+Promise.resolve = "certainly not callable";
+
+Promise.allSettled(iter).then(() => {
+ throw new Test262Error("The promise should be rejected, but it was resolved");
+}, (reason) => {
+ assert(reason instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-non-thenable.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-non-thenable.js
new file mode 100644
index 0000000000..389ea47977
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-non-thenable.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-thenable object value
+esid: sec-promise.allsettled
+info: |
+ Promise.allSettled Resolve Element Functions
+
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be ! CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var v1 = {};
+var v2 = {};
+var v3 = {};
+
+Promise.allSettled([v1, v2, v3])
+ .then(function(values) {
+ checkSettledPromises(values, [
+ {
+ status: 'fulfilled',
+ value: v1
+ },
+ {
+ status: 'fulfilled',
+ value: v2
+ },
+ {
+ status: 'fulfilled',
+ value: v3
+ }
+ ], 'values');
+ }, function() {
+ $DONE('The promise should not be rejected.');
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-not-callable-reject-with-typeerror.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-not-callable-reject-with-typeerror.js
new file mode 100644
index 0000000000..c6f9c19173
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-not-callable-reject-with-typeerror.js
@@ -0,0 +1,29 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allSettled
+description: >
+ If the constructor's `resolve` method is not callable, reject with a TypeError.
+info: |
+ Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAllSettled
+
+ Let promiseResolve be ? Get(constructor, "resolve").
+ If ! IsCallable(promiseResolve) is false, throw a TypeError exception.
+
+flags: [async]
+features: [Promise.allSettled, arrow-function]
+---*/
+
+Promise.resolve = null;
+
+Promise.allSettled([1])
+ .then(
+ () => $DONE('The promise should not be resolved.'),
+ error => {
+ assert(error instanceof TypeError);
+ }
+ ).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolve-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-poisoned-then.js
new file mode 100644
index 0000000000..7d37bfa2c5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-poisoned-then.js
@@ -0,0 +1,47 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. 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
+esid: sec-promise.allsettled
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var value = {};
+var promise;
+
+try {
+ Object.defineProperty(Array.prototype, 'then', {
+ get() {
+ throw value;
+ },
+ configurable: true
+ });
+
+ promise = Promise.allSettled([]);
+} 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/js/src/tests/test262/built-ins/Promise/allSettled/resolve-thenable.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-thenable.js
new file mode 100644
index 0000000000..008e9525e9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolve-thenable.js
@@ -0,0 +1,30 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a thenable object value
+esid: sec-promise.allsettled
+info: |
+ Let promiseCapability be NewPromiseCapability(C).
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var value = {};
+var promise;
+
+try {
+ Array.prototype.then = function(resolve) {
+ resolve(value);
+ };
+
+ promise = Promise.allSettled([]);
+} finally {
+ delete Array.prototype.then;
+}
+
+promise.then(function(val) {
+ assert.sameValue(val, value);
+}, function() {
+ $DONE('The promise should not be rejected.');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-fulfilled.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-fulfilled.js
new file mode 100644
index 0000000000..cfface3843
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-fulfilled.js
@@ -0,0 +1,65 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Resolution is a collection of all the settled values (all fulfilled)
+info: |
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat,
+ ...
+ j. Let steps be the algorithm steps defined in Promise.allSettled Resolve Element Functions.
+ k. Let resolveElement be ! CreateBuiltinFunction(steps, « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+ ...
+ r. Let rejectSteps be the algorithm steps defined in Promise.allSettled Reject Element Functions.
+ s. Let rejectElement be ! CreateBuiltinFunction(rejectSteps, « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+
+ Promise.allSettled Resolve Element Functions
+
+ 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
+ 10. Perform ! CreateDataProperty(obj, "status", "fulfilled").
+ 11. Perform ! CreateDataProperty(obj, "value", x).
+ 12. Set values[index] to be obj.
+ 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be ! CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+
+ Promise.allSettled Reject Element Functions
+
+ 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
+ 10. Perform ! CreateDataProperty(obj, "status", "rejected").
+ 11. Perform ! CreateDataProperty(obj, "reason", x).
+ 12. Set values[index] to be obj.
+ 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var obj = {};
+var p1 = new Promise(function(resolve) {
+ resolve(1);
+});
+var p2 = new Promise(function(resolve) {
+ resolve('test262');
+});
+var p3 = new Promise(function(resolve) {
+ resolve(obj);
+});
+
+Promise.allSettled([p1, p2, p3]).then(function(settled) {
+ checkSettledPromises(settled, [
+ { status: 'fulfilled', value: 1 },
+ { status: 'fulfilled', value: 'test262' },
+ { status: 'fulfilled', value: obj }
+ ], 'settled');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-mixed.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-mixed.js
new file mode 100644
index 0000000000..8a598f77a3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-mixed.js
@@ -0,0 +1,78 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Resolution is a collection of all the settled values (fulfilled and rejected)
+info: |
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat,
+ ...
+ j. Let steps be the algorithm steps defined in Promise.allSettled Resolve Element Functions.
+ k. Let resolveElement be ! CreateBuiltinFunction(steps, « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+ ...
+ r. Let rejectSteps be the algorithm steps defined in Promise.allSettled Reject Element Functions.
+ s. Let rejectElement be ! CreateBuiltinFunction(rejectSteps, « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+
+ Promise.allSettled Resolve Element Functions
+
+ 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
+ 10. Perform ! CreateDataProperty(obj, "status", "fulfilled").
+ 11. Perform ! CreateDataProperty(obj, "value", x).
+ 12. Set values[index] to be obj.
+ 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be ! CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+
+ Promise.allSettled Reject Element Functions
+
+ 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
+ 10. Perform ! CreateDataProperty(obj, "status", "rejected").
+ 11. Perform ! CreateDataProperty(obj, "reason", x).
+ 12. Set values[index] to be obj.
+ 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var obj1 = {};
+var obj2 = {};
+var r1 = new Promise(function(_, reject) {
+ reject(1);
+});
+var f1 = new Promise(function(resolve) {
+ resolve(2);
+});
+var f2 = new Promise(function(resolve) {
+ resolve('tc39');
+});
+var r2 = new Promise(function(_, reject) {
+ reject('test262');
+});
+var r3 = new Promise(function(_, reject) {
+ reject(obj1);
+});
+var f3 = new Promise(function(resolve) {
+ resolve(obj2);
+});
+
+Promise.allSettled([r1, f1, f2, r2, r3, f3]).then(function(settled) {
+ checkSettledPromises(settled, [
+ { status: 'rejected', reason: 1 },
+ { status: 'fulfilled', value: 2 },
+ { status: 'fulfilled', value: 'tc39' },
+ { status: 'rejected', reason: 'test262' },
+ { status: 'rejected', reason: obj1 },
+ { status: 'fulfilled', value: obj2 }
+ ], 'settled');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-rejected.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-rejected.js
new file mode 100644
index 0000000000..943b98c01f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-all-rejected.js
@@ -0,0 +1,65 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Resolution is a collection of all the settled values (fulfiled and rejected promises)
+info: |
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat,
+ ...
+ j. Let steps be the algorithm steps defined in Promise.allSettled Resolve Element Functions.
+ k. Let resolveElement be ! CreateBuiltinFunction(steps, « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+ ...
+ r. Let rejectSteps be the algorithm steps defined in Promise.allSettled Reject Element Functions.
+ s. Let rejectElement be ! CreateBuiltinFunction(rejectSteps, « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+
+ Promise.allSettled Resolve Element Functions
+
+ 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
+ 10. Perform ! CreateDataProperty(obj, "status", "fulfilled").
+ 11. Perform ! CreateDataProperty(obj, "value", x).
+ 12. Set values[index] to be obj.
+ 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be ! CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+
+ Promise.allSettled Reject Element Functions
+
+ 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
+ 10. Perform ! CreateDataProperty(obj, "status", "rejected").
+ 11. Perform ! CreateDataProperty(obj, "reason", x).
+ 12. Set values[index] to be obj.
+ 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var obj = {};
+var p1 = new Promise(function(_, reject) {
+ reject(1);
+});
+var p2 = new Promise(function(_, reject) {
+ reject('test262');
+});
+var p3 = new Promise(function(_, reject) {
+ reject(obj);
+});
+
+Promise.allSettled([p1, p2, p3]).then(function(settled) {
+ checkSettledPromises(settled, [
+ { status: 'rejected', reason: 1 },
+ { status: 'rejected', reason: 'test262' },
+ { status: 'rejected', reason: obj }
+ ], 'settled');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolved-immed.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-immed.js
new file mode 100644
index 0000000000..c6c2d4fcb4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-immed.js
@@ -0,0 +1,27 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Promise.allSettled([]) returns immediately
+includes: [promiseHelper.js]
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var sequence = [];
+
+Promise.allSettled([]).then(function() {
+ sequence.push(2);
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ sequence.push(3);
+}).then(function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+checkSequence(sequence, 'Promises resolved in unexpected sequence');
+}).then($DONE, $DONE);
+
+sequence.push(1);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-extra-ticks.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-extra-ticks.js
new file mode 100644
index 0000000000..e52ea2a348
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-extra-ticks.js
@@ -0,0 +1,48 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Resolution ticks are set in a predictable sequence with extra then calls
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var sequence = [];
+
+var p1 = new Promise(function(resolve) {
+ resolve({});
+});
+
+sequence.push(1);
+
+Promise.allSettled([p1]).then(function(resolved) {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, 'Expected Promise.allSettled().then to queue second');
+}).catch($DONE);
+
+p1.then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, 'Expected p1.then to queue first');
+}).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, 'Expected final then to queue last');
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-mixed.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-mixed.js
new file mode 100644
index 0000000000..27bd4bcf3b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-mixed.js
@@ -0,0 +1,63 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Resolution ticks are set in a predictable sequence of mixed fulfilled and rejected promises
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var sequence = [];
+
+var p1 = new Promise(function(_, reject) {
+ reject('');
+});
+var p2 = new Promise(function(resolve) {
+ resolve('');
+});
+var p3 = new Promise(function(_, reject) {
+ reject('');
+});
+
+sequence.push(1);
+
+p1.catch(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, 'Expected to be called first.');
+});
+
+Promise.allSettled([p1, p2, p3]).then(function() {
+ sequence.push(6);
+ assert.sameValue(sequence.length, 6);
+ checkSequence(sequence, 'Expected to be called fourth.');
+}).then($DONE, $DONE);
+
+p2.then(function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, 'Expected to be called second.');
+});
+
+sequence.push(2);
+
+p3.catch(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, 'Expected to be called third.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-with-rejections.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-with-rejections.js
new file mode 100644
index 0000000000..959cbb40d1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence-with-rejections.js
@@ -0,0 +1,53 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Resolution ticks are set in a predictable sequence
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var sequence = [];
+
+var p1 = new Promise(function(_, reject) {
+ reject('foo');
+});
+var p2 = new Promise(function(_, reject) {
+ reject('bar');
+});
+
+sequence.push(1);
+
+p1.catch(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, 'Expected to be called first.');
+}).catch($DONE);
+
+Promise.allSettled([p1, p2]).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, 'Expected to be called third.');
+}).then($DONE, $DONE);
+
+p2.catch(function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, 'Expected to be called second.');
+}).catch($DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence.js
new file mode 100644
index 0000000000..879d234c1c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-sequence.js
@@ -0,0 +1,53 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Resolution ticks are set in a predictable sequence
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var sequence = [];
+
+var p1 = new Promise(function(resolve) {
+ resolve(1);
+});
+var p2 = new Promise(function(resolve) {
+ resolve(2);
+});
+
+sequence.push(1);
+
+p1.then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, 'Expected to be called first.');
+}).catch($DONE);
+
+Promise.allSettled([p1, p2]).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, 'Expected to be called third.');
+}).then($DONE, $DONE);
+
+p2.then(function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, 'Expected to be called second.');
+}).catch($DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolved-then-catch-finally.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-then-catch-finally.js
new file mode 100644
index 0000000000..15a987cb7c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolved-then-catch-finally.js
@@ -0,0 +1,70 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: >
+ Resolution is a collection of all the settled values (all fulfilled)
+info: |
+ Runtime Semantics: PerformPromiseAllSettled
+
+ 6. Repeat,
+ ...
+ j. Let steps be the algorithm steps defined in Promise.allSettled Resolve Element Functions.
+ k. Let resolveElement be ! CreateBuiltinFunction(steps, « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+ ...
+ r. Let rejectSteps be the algorithm steps defined in Promise.allSettled Reject Element Functions.
+ s. Let rejectElement be ! CreateBuiltinFunction(rejectSteps, « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
+ ...
+ z. Perform ? Invoke(nextPromise, "then", « resolveElement, rejectElement »).
+
+ Promise.allSettled Resolve Element Functions
+
+ 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
+ 10. Perform ! CreateDataProperty(obj, "status", "fulfilled").
+ 11. Perform ! CreateDataProperty(obj, "value", x).
+ 12. Set values[index] to be obj.
+ 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be ! CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+
+ Promise.allSettled Reject Element Functions
+
+ 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
+ 10. Perform ! CreateDataProperty(obj, "status", "rejected").
+ 11. Perform ! CreateDataProperty(obj, "reason", x).
+ 12. Set values[index] to be obj.
+ 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ 14. If remainingElementsCount.[[Value]] is 0, then
+ a. Let valuesArray be CreateArrayFromList(values).
+ b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var p0 = Promise.resolve(2).then(v => v + 1);
+var p1 = Promise.reject(21).catch(v => v * 2);
+var p2 = Promise.resolve('nope').then(() => { throw 'foo' });
+var p3 = Promise.reject('yes').then(() => { throw 'nope'; });
+var p4 = Promise.resolve('here').finally(() => 'nope');
+var p5 = Promise.reject('here too').finally(() => 'nope');
+var p6 = Promise.resolve('nope').finally(() => { throw 'finally'; });
+var p7 = Promise.reject('nope').finally(() => { throw 'finally after rejected'; });
+var p8 = Promise.reject(1).then(() => 'nope', () => 0);
+
+Promise.allSettled([p0, p1, p2, p3, p4, p5, p6, p7, p8]).then(function(settled) {
+ checkSettledPromises(settled, [
+ { status: 'fulfilled', value: 3 },
+ { status: 'fulfilled', value: 42 },
+ { status: 'rejected', reason: 'foo' },
+ { status: 'rejected', reason: 'yes' },
+ { status: 'fulfilled', value: 'here' },
+ { status: 'rejected', reason: 'here too' },
+ { status: 'rejected', reason: 'finally' },
+ { status: 'rejected', reason: 'finally after rejected' },
+ { status: 'fulfilled', value: 0 },
+ ], 'settled');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolves-empty-array.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolves-empty-array.js
new file mode 100644
index 0000000000..4ca58b35a9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolves-empty-array.js
@@ -0,0 +1,28 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Promise.allSettled([]) returns a Promise for an empty array
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.allSettled]
+---*/
+
+var arg = [];
+
+Promise.allSettled(arg).then(function(result) {
+ checkSettledPromises(result, []);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/resolves-to-array.js b/js/src/tests/test262/built-ins/Promise/allSettled/resolves-to-array.js
new file mode 100644
index 0000000000..27f3419b9c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/resolves-to-array.js
@@ -0,0 +1,29 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Promise.allSettled returned a promise resolves into an array
+info: |
+ Runtime Semantics: PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
+
+ 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ 1. Let valuesArray be CreateArrayFromList(values).
+ 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
+ ...
+flags: [async]
+features: [Promise.allSettled]
+---*/
+
+var arg = [];
+
+Promise.allSettled([]).then(function(result) {
+ assert(Array.isArray(result));
+ assert.sameValue(Object.getPrototypeOf(result), Array.prototype);
+ assert.notSameValue(result, arg, 'the resolved array is a new array');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/returns-promise.js b/js/src/tests/test262/built-ins/Promise/allSettled/returns-promise.js
new file mode 100644
index 0000000000..4a57525a6f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/returns-promise.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.allsettled
+description: Promise.allSettled returns a Promise
+info: |
+ Promise.allSettled ( iterable )
+
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ 6. Let result be PerformPromiseAllSettled(iteratorRecord, C, promiseCapability).
+ 7. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+ 8. Return Completion(result).
+features: [Promise.allSettled]
+---*/
+
+var p = Promise.allSettled([]);
+
+assert(p instanceof Promise);
+assert.sameValue(Object.getPrototypeOf(p), Promise.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/shell.js b/js/src/tests/test262/built-ins/Promise/allSettled/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/allSettled/species-get-error.js b/js/src/tests/test262/built-ins/Promise/allSettled/species-get-error.js
new file mode 100644
index 0000000000..5f2bf79d86
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/allSettled/species-get-error.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.allSettled() does not retrieve `Symbol.species` property of the `this` value
+esid: sec-promise.allsettled
+info: |
+ 1. Let C be the this value.
+ 2. If Type(C) is not Object, throw a TypeError exception.
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+features: [Promise.allSettled, Symbol.species]
+---*/
+
+function C(executor) {
+ executor(function() {}, function() {});
+}
+Object.defineProperty(C, Symbol.species, {
+ get() {
+ throw new Test262Error('Getter for Symbol.species called');
+ }
+});
+
+C.resolve = function() {
+ throw new Test262Error();
+};
+
+Promise.allSettled.call(C, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/browser.js b/js/src/tests/test262/built-ins/Promise/any/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/any/call-reject-element-after-return.js b/js/src/tests/test262/built-ins/Promise/any/call-reject-element-after-return.js
new file mode 100644
index 0000000000..ac713bac2e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/call-reject-element-after-return.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any-reject-element-functions
+description: >
+ Cannot change result value of rejected Promise.any element after Promise.any() returned.
+info: |
+ Promise.any Reject Element Functions
+
+ Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ If alreadyCalled.[[value]] is true, return undefined.
+ Set alreadyCalled.[[value]] to true.
+
+features: [Promise.any]
+---*/
+
+let callCount = 0;
+let errorArray;
+
+function Constructor(executor) {
+ executor(Test262Error.thrower, (error) => {
+ callCount++;
+ errorArray = error.errors;
+ });
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+let p1OnRejected;
+
+let p1 = {
+ then(onFulfilled, onRejected) {
+ p1OnRejected = onRejected;
+ onRejected("onRejectedValue");
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to any()");
+
+Promise.any.call(Constructor, [p1]);
+
+assert.sameValue(callCount, 1, "callCount after call to any()");
+assert.sameValue(errorArray[0], "onRejectedValue", "errorArray after call to any()");
+
+p1OnRejected("unexpectedonRejectedValue");
+
+assert.sameValue(errorArray[0], "onRejectedValue", "errorArray[0] === 'onRejectedValue', after call to p1OnRejected()");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/call-reject-element-items.js b/js/src/tests/test262/built-ins/Promise/any/call-reject-element-items.js
new file mode 100644
index 0000000000..bef67aa505
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/call-reject-element-items.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any-reject-element-functions
+description: >
+ Cannot change result value of rejected Promise.any elements.
+info: |
+ Promise.any Reject Element Functions
+
+ Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ If alreadyCalled.[[value]] is true, return undefined.
+ Set alreadyCalled.[[value]] to true.
+
+features: [Promise.any]
+---*/
+
+let callCount = 0;
+
+function Constructor(executor) {
+ function reject(error) {
+ callCount += 1;
+ assert(Array.isArray(error.errors), "error.errors is array");
+ assert.sameValue(error.errors.length, 2, "error.errors length");
+ assert.sameValue(error.errors[0], "expectedValue-p1", "error.errors[0]");
+ assert.sameValue(error.errors[1], "expectedValue-p2", "error.errors[1]");
+ }
+ executor(Test262Error.thrower, reject);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+let p1 = {
+ then(onFulfilled, onRejected) {
+ onRejected("expectedValue-p1");
+ onRejected("unexpectedValue-p1");
+ }
+};
+let p2 = {
+ then(onFulfilled, onRejected) {
+ onRejected("expectedValue-p2");
+ onRejected("unexpectedValue-p2");
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to any()");
+
+Promise.any.call(Constructor, [p1, p2]);
+
+assert.sameValue(callCount, 1, "callCount after call to any()");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/capability-executor-called-twice.js b/js/src/tests/test262/built-ins/Promise/any/capability-executor-called-twice.js
new file mode 100644
index 0000000000..3fae3ad0b9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/capability-executor-called-twice.js
@@ -0,0 +1,108 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Throws a TypeError if capabilities executor already called with non-undefined values.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 2. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+
+ GetCapabilitiesExecutor Functions
+
+ ...
+ 4. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
+ 5. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
+ 6. Set promiseCapability.[[Resolve]] to resolve.
+ 7. Set promiseCapability.[[Reject]] to reject.
+ ...
+features: [Promise.any]
+---*/
+
+var checkPoint = '';
+function fn1(executor) {
+ checkPoint += 'a';
+ executor();
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+fn1.resolve = function() {
+ throw new Test262Error();
+};
+Promise.any.call(fn1, []);
+assert.sameValue(checkPoint, 'abc', 'executor initially called with no arguments');
+
+checkPoint = '';
+function fn2(executor) {
+ checkPoint += 'a';
+ executor(undefined, undefined);
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+fn2.resolve = function() {
+ throw new Test262Error();
+};
+Promise.any.call(fn2, []);
+assert.sameValue(checkPoint, 'abc', 'executor initially called with (undefined, undefined)');
+
+checkPoint = '';
+function fn3(executor) {
+ checkPoint += 'a';
+ executor(undefined, function() {});
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+Object.defineProperty(fn3, 'resolve', {
+ get() {
+ throw new Test262Error();
+ }
+});
+assert.throws(TypeError, function() {
+ Promise.any.call(fn3, []);
+}, 'executor initially called with (undefined, function)');
+assert.sameValue(checkPoint, 'ab', 'executor initially called with (undefined, function)');
+
+checkPoint = '';
+function fn4(executor) {
+ checkPoint += 'a';
+ executor(function() {}, undefined);
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+Object.defineProperty(fn4, 'resolve', {
+ get() {
+ throw new Test262Error();
+ }
+});
+assert.throws(TypeError, function() {
+ Promise.any.call(fn4, []);
+}, 'executor initially called with (function, undefined)');
+assert.sameValue(checkPoint, 'ab', 'executor initially called with (function, undefined)');
+
+checkPoint = '';
+function fn5(executor) {
+ checkPoint += 'a';
+ executor('invalid value', 123);
+ checkPoint += 'b';
+ executor(function() {}, function() {});
+ checkPoint += 'c';
+}
+Object.defineProperty(fn5, 'resolve', {
+ get() {
+ throw new Test262Error();
+ }
+});
+assert.throws(TypeError, function() {
+ Promise.any.call(fn5, []);
+}, 'executor initially called with (String, Number)');
+assert.sameValue(checkPoint, 'ab', 'executor initially called with (String, Number)');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/capability-executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/any/capability-executor-not-callable.js
new file mode 100644
index 0000000000..cc3df69a44
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/capability-executor-not-callable.js
@@ -0,0 +1,109 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Throws a TypeError if either resolve or reject capability is not callable.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 2. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+
+ NewPromiseCapability ( C )
+
+ ...
+ 5. Let executor be ! CreateBuiltinFunction(steps, « [[Capability]] »).
+ 6. Set executor.[[Capability]] to promiseCapability.
+ 7. Let promise be ? Construct(C, « executor »).
+ 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
+ 9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
+ ...
+features: [Promise.any]
+---*/
+
+var checkPoint = '';
+function fn1(executor) {
+ checkPoint += 'a';
+}
+Object.defineProperty(fn1, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.any.call(fn1, []);
+}, 'executor not called at all');
+assert.sameValue(checkPoint, 'a', 'executor not called at all');
+
+checkPoint = '';
+function fn2(executor) {
+ checkPoint += 'a';
+ executor();
+ checkPoint += 'b';
+}
+Object.defineProperty(fn2, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.any.call(fn2, []);
+}, 'executor called with no arguments');
+assert.sameValue(checkPoint, 'ab', 'executor called with no arguments');
+
+checkPoint = '';
+function fn3(executor) {
+ checkPoint += 'a';
+ executor(undefined, undefined);
+ checkPoint += 'b';
+}
+Object.defineProperty(fn3, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.any.call(fn3, []);
+}, 'executor called with (undefined, undefined)');
+assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, undefined)');
+
+checkPoint = '';
+function fn4(executor) {
+ checkPoint += 'a';
+ executor(undefined, function() {});
+ checkPoint += 'b';
+}
+Object.defineProperty(fn4, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.any.call(fn4, []);
+}, 'executor called with (undefined, function)');
+assert.sameValue(checkPoint, 'ab', 'executor called with (undefined, function)');
+
+checkPoint = '';
+function fn5(executor) {
+ checkPoint += 'a';
+ executor(function() {}, undefined);
+ checkPoint += 'b';
+}
+Object.defineProperty(fn5, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.any.call(fn5, []);
+}, 'executor called with (function, undefined)');
+assert.sameValue(checkPoint, 'ab', 'executor called with (function, undefined)');
+
+checkPoint = '';
+function fn6(executor) {
+ checkPoint += 'a';
+ executor(123, 'invalid value');
+ checkPoint += 'b';
+}
+Object.defineProperty(fn6, 'resolve', {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.any.call(fn6, []);
+}, 'executor called with (Number, String)');
+assert.sameValue(checkPoint, 'ab', 'executor called with (Number, String)');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/capability-reject-throws-no-close.js b/js/src/tests/test262/built-ins/Promise/any/capability-reject-throws-no-close.js
new file mode 100644
index 0000000000..ce2a3074f1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/capability-reject-throws-no-close.js
@@ -0,0 +1,69 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.any
+description: >
+ Iterator is not closed when the "resolve" capability returns an abrupt
+ completion.
+info: |
+ Let C be the this value.
+ Let promiseCapability be ? NewPromiseCapability(C).
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ If result is an abrupt completion, then
+ If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ IfAbruptRejectPromise(result, promiseCapability).
+ Return Completion(result).
+
+flags: [async]
+features: [Promise.any, Symbol.iterator]
+---*/
+let callCount = 0;
+let nextCount = 0;
+let returnCount = 0;
+let iter = {
+ [Symbol.iterator]() {
+ callCount++;
+ return {
+ next() {
+ callCount++
+ nextCount++;
+ return {
+ done: true
+ };
+ },
+ return() {
+ callCount++;
+ returnCount++;
+ return {};
+ }
+ };
+ }
+};
+
+function P(executor) {
+ callCount++;
+ return new Promise((_, reject) => {
+ callCount++;
+ executor(() => {
+ callCount++;
+ throw new Test262Error();
+ }, () => {
+ callCount++;
+ reject(new Test262Error('reject throws'));
+ });
+ });
+};
+
+P.resolve = Promise.resolve;
+
+Promise.any.call(P, iter).then(
+ () => {
+ $DONE('The promise should be rejected.');
+}, (reason) => {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 0);
+ assert.sameValue(callCount, 5);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/capability-resolve-throws-no-close.js b/js/src/tests/test262/built-ins/Promise/any/capability-resolve-throws-no-close.js
new file mode 100644
index 0000000000..16ac4d2f0c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/capability-resolve-throws-no-close.js
@@ -0,0 +1,69 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.any
+description: >
+ Iterator is not closed when the "resolve" capability returns an abrupt
+ completion.
+info: |
+ Let C be the this value.
+ Let promiseCapability be ? NewPromiseCapability(C).
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ If result is an abrupt completion, then
+ If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ IfAbruptRejectPromise(result, promiseCapability).
+ Return Completion(result).
+
+flags: [async]
+features: [Promise.any, Symbol.iterator]
+---*/
+let callCount = 0;
+let nextCount = 0;
+let returnCount = 0;
+let iter = {
+ [Symbol.iterator]() {
+ callCount++;
+ return {
+ next() {
+ callCount++;
+ nextCount += 1;
+ return {
+ done: true
+ };
+ },
+ return() {
+ callCount++;
+ returnCount += 1;
+ return {};
+ }
+ };
+ }
+};
+
+function P(executor) {
+ callCount++;
+ return new Promise((_, reject) => {
+ callCount++;
+ executor(() => {
+ callCount++;
+ throw new Test262Error();
+ }, (...args) => {
+ callCount++;
+ reject(...args);
+ });
+ });
+};
+
+P.resolve = Promise.resolve;
+
+Promise.any.call(P, iter).then(
+ () => {
+ $DONE('The promise should be rejected.');
+}, (reason) => {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 0);
+ assert.sameValue(callCount, 5);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/capability-resolve-throws-reject.js b/js/src/tests/test262/built-ins/Promise/any/capability-resolve-throws-reject.js
new file mode 100644
index 0000000000..0022473869
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/capability-resolve-throws-reject.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.any
+description: >
+ Iterator is not closed when the "resolve" capability returns an abrupt
+ completion.
+info: |
+ Let C be the this value.
+ Let promiseCapability be ? NewPromiseCapability(C).
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ If result is an abrupt completion, then
+ If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ IfAbruptRejectPromise(result, promiseCapability).
+ Return Completion(result).
+
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+let callCount = 0;
+let thrown = new Test262Error();
+function P(executor) {
+ callCount++;
+ return new Promise((_, reject) => {
+ callCount++;
+ executor(() => {
+ callCount++;
+ throw thrown;
+ }, (...args) => {
+ callCount++;
+ reject(...args);
+ });
+ });
+};
+P.resolve = Promise.resolve;
+
+Promise.any.call(P, [1])
+ .then(() => {
+ $DONE('Promise incorrectly fulfilled.');
+ }, (error) => {
+ // The error was not the result of promise
+ // resolution, so will not be an AggregateError
+ assert.sameValue(thrown, error);
+ assert.sameValue(callCount, 6);
+ }).then($DONE, $DONE);
+
+
diff --git a/js/src/tests/test262/built-ins/Promise/any/ctx-ctor-throws.js b/js/src/tests/test262/built-ins/Promise/any/ctx-ctor-throws.js
new file mode 100644
index 0000000000..213ddb1822
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/ctx-ctor-throws.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.any invoked on a constructor value that throws an error
+esid: sec-promise.any
+info: |
+ 2. Let promiseCapability be ? NewPromiseCapability(C).
+
+ NewPromiseCapability
+
+ ...
+ 7. Let promise be ? Construct(C, « executor »).
+
+features: [Promise.any]
+---*/
+
+function CustomPromise() {
+ throw new Test262Error();
+}
+
+assert.throws(Test262Error, function() {
+ Promise.any.call(CustomPromise);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/ctx-ctor.js b/js/src/tests/test262/built-ins/Promise/any/ctx-ctor.js
new file mode 100644
index 0000000000..6331f05194
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/ctx-ctor.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.any invoked on a constructor value
+esid: sec-promise.any
+info: |
+ 2. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ ...
+ 7. Return Completion(result).
+features: [Promise.any, class]
+---*/
+
+var executor = null;
+var callCount = 0;
+
+class SubPromise extends Promise {
+ constructor(a) {
+ super(a);
+ executor = a;
+ callCount += 1;
+ }
+}
+
+var instance = Promise.any.call(SubPromise, []);
+
+assert.sameValue(instance.constructor, SubPromise);
+assert.sameValue(instance instanceof SubPromise, true);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(typeof executor, 'function');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/ctx-non-ctor.js b/js/src/tests/test262/built-ins/Promise/any/ctx-non-ctor.js
new file mode 100644
index 0000000000..6901fb55e8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/ctx-non-ctor.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.any invoked on a non-constructor value
+esid: sec-promise.any
+info: |
+ ...
+ 2. Let promiseCapability be ? NewPromiseCapability(C).
+
+ NewPromiseCapability ( C )
+
+ 1. If IsConstructor(C) is false, throw a TypeError exception.
+
+features: [Promise.any, Symbol]
+---*/
+
+assert.sameValue(typeof Promise.any, 'function');
+
+assert.throws(TypeError, function() {
+ Promise.any.call(eval);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/ctx-non-object.js b/js/src/tests/test262/built-ins/Promise/any/ctx-non-object.js
new file mode 100644
index 0000000000..1633081d7b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/ctx-non-object.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.any invoked on a non-object value
+esid: sec-promise.any
+info: |
+ ...
+ 2. Let promiseCapability be ? NewPromiseCapability(C).
+
+ NewPromiseCapability ( C )
+
+ 1. If IsConstructor(C) is false, throw a TypeError exception.
+
+features: [Promise.any, Symbol]
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.any.call(undefined, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.any.call(null, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.any.call(86, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.any.call('string', []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.any.call(true, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.any.call(Symbol(), []);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-error-close.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-error-close.js
new file mode 100644
index 0000000000..fd9d4b2d34
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-error-close.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Explicit iterator closing in response to error
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+flags: [async]
+features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function]
+---*/
+
+let error = new Test262Error();
+let nextCount = 0;
+let returnCount = 0;
+let iter = {
+ [Symbol.iterator]() {
+ return {
+ next() {
+ nextCount += 1;
+ return {
+ value: null,
+ done: false
+ };
+ },
+ return() {
+ returnCount += 1;
+ }
+ };
+ }
+};
+
+Promise.resolve = function() {
+ throw error;
+};
+
+Promise.any(iter).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (reason) => {
+ assert.sameValue(nextCount, 1);
+ assert.sameValue(returnCount, 1);
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-error-reject.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-error-reject.js
new file mode 100644
index 0000000000..9248d0e87e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-error-reject.js
@@ -0,0 +1,33 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise rejection in response to error
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let error = new Test262Error();
+Promise.resolve = function() {
+ throw error;
+};
+
+Promise.any([1]).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+ }, (reason) => {
+ assert.sameValue(reason, error);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-error-reject.js
new file mode 100644
index 0000000000..175660e0c7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-error-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error retrieving the constructor's `resolve` method (rejecting promise)
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let error = new Test262Error();
+Object.defineProperty(Promise, 'resolve', {
+ get() {
+ throw error;
+ }
+});
+
+Promise.any([1]).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+ }, (reason) => {
+ assert.sameValue(reason, error);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-error.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-error.js
new file mode 100644
index 0000000000..976571edad
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-error.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.resolve is retrieved before GetIterator call (abrupt lookup).
+info: |
+ Promise.any ( iterable )
+
+ [...]
+ 3. Let promiseResolve be GetPromiseResolve(C).
+ 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
+
+ GetPromiseResolve ( promiseConstructor )
+
+ [...]
+ 2. Let promiseResolve be ? Get(promiseConstructor, "resolve").
+flags: [async]
+features: [Promise.any, Symbol.iterator]
+---*/
+
+const iter = {
+ get [Symbol.iterator]() {
+ throw new Test262Error('unreachable');
+ },
+};
+
+const resolveError = { name: 'MyError' };
+Object.defineProperty(Promise, 'resolve', {
+ get() {
+ throw resolveError;
+ },
+});
+
+Promise.any(iter).then(() => {
+ throw new Test262Error('The promise should be rejected, but it was resolved');
+}, (reason) => {
+ assert.sameValue(reason, resolveError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-once-multiple-calls.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-once-multiple-calls.js
new file mode 100644
index 0000000000..1db5628464
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-once-multiple-calls.js
@@ -0,0 +1,55 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Gets constructor's `resolve` method once from zero to many invocations.
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 6. Let promiseResolve be ? Get(constructor, "resolve").
+ 7. If ! IsCallable(promiseResolve) is false, throw a TypeError exception.
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.any, arrow-function, destructuring-binding]
+---*/
+
+let promises = [
+ Promise.reject(1),
+ Promise.reject(1),
+ Promise.reject(1),
+];
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+let getCount = 0;
+let callCount = 0;
+
+Object.defineProperty(Promise, 'resolve', {
+ configurable: true,
+ get() {
+ getCount += 1;
+ return function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+ };
+ }
+});
+
+Promise.any(promises).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+ }, ({errors}) => {
+ assert.sameValue(getCount, 1);
+ assert.sameValue(callCount, 3);
+ assert.sameValue(errors.length, 3);
+ }).then($DONE, $DONE);
+
+
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-once-no-calls.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-once-no-calls.js
new file mode 100644
index 0000000000..28ad29b19f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-get-once-no-calls.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Gets constructor's `resolve` method once from zero to many invocations.
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 6. Let promiseResolve be ? Get(constructor, "resolve").
+ 7. If ! IsCallable(promiseResolve) is false, throw a TypeError exception.
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.any, arrow-function, destructuring-binding]
+---*/
+
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+let getCount = 0;
+let callCount = 0;
+
+Object.defineProperty(Promise, 'resolve', {
+ configurable: true,
+ get() {
+ getCount += 1;
+ return function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+ };
+ }
+});
+
+Promise.any([]).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+ }, ({errors}) => {
+ assert.sameValue(getCount, 1);
+ assert.sameValue(callCount, 0);
+ assert.sameValue(errors.length, 0);
+ }).then($DONE, $DONE);
+
+
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-custom.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-custom.js
new file mode 100644
index 0000000000..5a8e758a57
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-custom.js
@@ -0,0 +1,44 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with promise values
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.any, class, arrow-function]
+---*/
+class Custom extends Promise {}
+
+let values = [1, 1, 1];
+let cresolveCallCount = 0;
+let presolveCallCount = 0;
+let boundCustomResolve = Custom.resolve.bind(Custom);
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Custom.resolve = function(...args) {
+ cresolveCallCount += 1;
+ return boundCustomResolve(...args);
+};
+
+Promise.resolve = function(...args) {
+ presolveCallCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.any.call(Custom, values)
+ .then(() => {
+ assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked');
+ assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every iterated promise');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-promise.js
new file mode 100644
index 0000000000..337fcbd903
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-promises-every-iteration-of-promise.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with promise values
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let values = [1,1,1];
+let callCount = 0;
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Promise.resolve = function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.any(values)
+ .then(() => {
+ assert.sameValue(callCount, 3, '`then` invoked once for every iterated promise');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-custom.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-custom.js
new file mode 100644
index 0000000000..83955852c6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-custom.js
@@ -0,0 +1,44 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with non-promise values
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.any, class, arrow-function]
+---*/
+class Custom extends Promise {}
+
+let values = [1, 2, 3];
+let cresolveCallCount = 0;
+let presolveCallCount = 0;
+let boundCustomResolve = Custom.resolve.bind(Custom);
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Custom.resolve = function(...args) {
+ cresolveCallCount += 1;
+ return boundCustomResolve(...args);
+};
+
+Promise.resolve = function(...args) {
+ presolveCallCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.any.call(Custom, values)
+ .then(() => {
+ assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked');
+ assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every iterated promise');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-promise.js
new file mode 100644
index 0000000000..c4babbf46b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-on-values-every-iteration-of-promise.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with non-promise values
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let values = [1, 2, 3];
+let callCount = 0;
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Promise.resolve = function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.any(values)
+ .then(() => {
+ assert.sameValue(callCount, 3, '`Promise.resolve` invoked once for every iterated value');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-return.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-return.js
new file mode 100644
index 0000000000..ba5bd6be67
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve-return.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Use of the value returned by the constructor's `resolve` method.
+esid: sec-promise.any
+info: |
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ PerformPromiseAny
+
+ Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+ ...
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+features: [Promise.any]
+---*/
+
+let originalCallCount = 0;
+let newCallCount = 0;
+let P = function(executor) {
+ executor(function() {}, function() {});
+};
+P.resolve = function() {
+ return newThenable;
+};
+
+let originalThenable = {
+ then() {
+ originalCallCount += 1;
+ }
+};
+let newThenable = {
+ then() {
+ newCallCount += 1;
+ }
+};
+
+Promise.any.call(P, [originalThenable]);
+
+assert.sameValue(originalCallCount, 0, 'original `then` method not invoked');
+assert.sameValue(newCallCount, 1, 'new `then` method invoked exactly once');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-resolve.js b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve.js
new file mode 100644
index 0000000000..0fcabbf684
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-resolve.js
@@ -0,0 +1,32 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+ ...
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Promise.resolve = function(...args) {
+ assert.sameValue(args.length, 1, '`resolve` invoked with a single argument');
+ assert.sameValue(this, Promise, '`this` value is the constructor');
+ return boundPromiseResolve(...args);
+};
+
+Promise.any([1]).then(() => $DONE(), $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-then-error-close.js b/js/src/tests/test262/built-ins/Promise/any/invoke-then-error-close.js
new file mode 100644
index 0000000000..716430d349
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-then-error-close.js
@@ -0,0 +1,51 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Error thrown when invoking the instance's `then` method (closing iterator)
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any, Symbol.iterator, arrow-function, computed-property-names, Symbol]
+---*/
+
+let error = new Test262Error();
+let promise = Promise.resolve();
+let returnCount = 0;
+let iter = {
+ [Symbol.iterator]() {
+ return {
+ next() {
+ return {
+ done: false,
+ value: promise
+ };
+ },
+ return() {
+ returnCount += 1;
+ return {};
+ }
+ };
+ }
+};
+
+promise.then = function() {
+ throw error;
+};
+
+Promise.any(iter).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (reason) => {
+ assert.sameValue(returnCount, 1);
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-then-error-reject.js b/js/src/tests/test262/built-ins/Promise/any/invoke-then-error-reject.js
new file mode 100644
index 0000000000..ca7ab8054c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-then-error-reject.js
@@ -0,0 +1,33 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error thrown when invoking the instance's `then` method (rejecting Promise)
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+let error = new Test262Error();
+let promise = Promise.resolve();
+
+promise.then = function() {
+ throw error;
+};
+
+Promise.any([promise]).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (reason) => {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-then-get-error-close.js b/js/src/tests/test262/built-ins/Promise/any/invoke-then-get-error-close.js
new file mode 100644
index 0000000000..c40020e48b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-then-get-error-close.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Error thrown when accesing the instance's `then` method (closing iterator)
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any, Symbol.iterator, arrow-function, computed-property-names, Symbol]
+---*/
+let error = new Test262Error();
+let promise = Promise.resolve();
+let returnCount = 0;
+let iter = {
+ [Symbol.iterator]() {
+ return {
+ next() {
+ return {
+ done: false,
+ value: promise
+ };
+ },
+ return() {
+ returnCount += 1;
+ return {};
+ }
+ };
+ }
+};
+
+Object.defineProperty(promise, 'then', {
+ get() {
+ throw error;
+ }
+});
+
+Promise.any(iter).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (reason) => {
+ assert.sameValue(returnCount, 1);
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-then-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/any/invoke-then-get-error-reject.js
new file mode 100644
index 0000000000..9c42b8a7a2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-then-get-error-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Error thrown when accessing the instance's `then` method (rejecting Promise)
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+let error = new Test262Error();
+let promise = Promise.resolve();
+
+Object.defineProperty(promise, 'then', {
+ get() {
+ throw error;
+ }
+});
+
+Promise.any([promise]).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (reason) => {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-then-on-promises-every-iteration.js b/js/src/tests/test262/built-ins/Promise/any/invoke-then-on-promises-every-iteration.js
new file mode 100644
index 0000000000..5b12329106
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-then-on-promises-every-iteration.js
@@ -0,0 +1,42 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the instance's `then` method
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let promises = [
+ Promise.resolve(),
+ Promise.resolve(),
+ Promise.resolve(),
+];
+let callCount = 0;
+
+promises.forEach(promise => {
+ let boundThen = promise.then.bind(promise);
+ promise.then = function(...args) {
+ assert.sameValue(this, promises[callCount]);
+ callCount += 1;
+ return boundThen(...args);
+ };
+});
+
+Promise.any(promises)
+ .then(() => {
+ assert.sameValue(callCount, 3, '`then` invoked once for every iterated value');
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/invoke-then.js b/js/src/tests/test262/built-ins/Promise/any/invoke-then.js
new file mode 100644
index 0000000000..5674ea8ecb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/invoke-then.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the instance's `then` method
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let promise = Promise.resolve();
+let boundThen = promise.then.bind(promise);
+let callCount = 0;
+
+promise.then = function(resolver, rejectElement) {
+ assert.sameValue(this, promise);
+ assert.sameValue(typeof resolver, 'function');
+ assert.sameValue(resolver.length, 1, 'resolver.length is 1');
+ assert.sameValue(typeof rejectElement, 'function');
+ assert.sameValue(rejectElement.length, 1, 'rejectElement.length is 0');
+ callCount++;
+ return boundThen(resolver, rejectElement);
+};
+
+Promise.any([promise]).then(() => {
+ assert.sameValue(callCount, 1);
+ $DONE();
+}, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/is-function.js b/js/src/tests/test262/built-ins/Promise/any/is-function.js
new file mode 100644
index 0000000000..4abe039b5d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/is-function.js
@@ -0,0 +1,12 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: Promise.any is callable
+features: [Promise.any]
+---*/
+
+assert.sameValue(typeof Promise.any, 'function');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-empty-iterable-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-empty-iterable-reject.js
new file mode 100644
index 0000000000..d9f9eba172
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-empty-iterable-reject.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any([]) rejects with AggregateError, empty errors array.
+info: |
+ Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
+
+ ...
+ 3. Let errors be a new empty List.
+ ...
+ 8. Repeat,
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, then
+ i. Set iteratorRecord.[[Done]] to true.
+ ii. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ iii. If remainingElementsCount.[[Value]] is 0, then
+ 1. Let error be a newly created AggregateError object.
+ 2. Set error.[[AggregateErrors]] to errors.
+ 3. Return ThrowCompletion(error).
+ ...
+
+flags: [async]
+features: [AggregateError, Promise.any, arrow-function]
+---*/
+
+Promise.any([])
+ .then(
+ () => $DONE('The promise should be rejected, but was resolved'),
+ error => {
+ assert.sameValue(Object.getPrototypeOf(error), AggregateError.prototype);
+ assert(error instanceof AggregateError);
+ assert.sameValue(error.errors.length, 0);
+ }
+ ).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-empty-string-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-empty-string-reject.js
new file mode 100644
index 0000000000..0c2eeabd2f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-empty-string-reject.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any('') rejects with AggregateError, empty errors array.
+info: |
+ Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
+
+ ...
+ 3. Let errors be a new empty List.
+ ...
+ 8. Repeat,
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ c. ReturnIfAbrupt(next).
+ d. If next is false, then
+ i. Set iteratorRecord.[[Done]] to true.
+ ii. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ iii. If remainingElementsCount.[[Value]] is 0, then
+ 1. Let error be a newly created AggregateError object.
+ 2. Set error.[[AggregateErrors]] to errors.
+ 3. Return ThrowCompletion(error).
+ ...
+
+features: [AggregateError, Promise.any, arrow-function]
+flags: [async]
+---*/
+
+Promise.any('')
+ .then(
+ () => $DONE('The promise should be rejected, but was resolved'),
+ error => {
+ assert.sameValue(Object.getPrototypeOf(error), AggregateError.prototype);
+ assert(error instanceof AggregateError);
+ assert.sameValue(error.errors.length, 0);
+ }
+ ).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-error-object-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-error-object-reject.js
new file mode 100644
index 0000000000..b24b240e8d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-error-object-reject.js
@@ -0,0 +1,45 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any(new Test262Error()) rejects with TypeError.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any]
+flags: [async]
+---*/
+
+try {
+ Promise.any(new Test262Error()).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+ }, (error) => {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-false-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-false-reject.js
new file mode 100644
index 0000000000..b0f288363a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-false-reject.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any(false) rejects with TypeError.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 3. Let iteratorRecord be GetIterator(iterable).
+ 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.any]
+flags: [async]
+---*/
+
+try {
+ Promise.any(false).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-null-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-null-reject.js
new file mode 100644
index 0000000000..9497e08423
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-null-reject.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any(null) rejects with TypeError.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 3. Let iteratorRecord be GetIterator(iterable).
+ 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.any]
+flags: [async]
+---*/
+
+try {
+ Promise.any(null).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-number-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-number-reject.js
new file mode 100644
index 0000000000..011b1c996a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-number-reject.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any(number) rejects with TypeError.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 3. Let iteratorRecord be GetIterator(iterable).
+ 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.any]
+flags: [async]
+---*/
+
+try {
+ Promise.any(1).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-poisoned.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-poisoned.js
new file mode 100644
index 0000000000..6c45a22dd1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-poisoned.js
@@ -0,0 +1,43 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any(poisoned iterable) rejects with whatever error is thrown.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 3. Let iteratorRecord be GetIterator(iterable).
+ 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ ...
+features: [Promise.any, Symbol, Symbol.iterator, arrow-function]
+flags: [async]
+---*/
+
+var poison = [];
+Object.defineProperty(poison, Symbol.iterator, {
+ get() {
+ throw new Test262Error();
+ }
+});
+
+try {
+ Promise.any(poison).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+ }, (error) => {
+ assert.sameValue(Object.getPrototypeOf(error), Test262Error.prototype);
+ assert(error instanceof Test262Error);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-string-resolve.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-string-resolve.js
new file mode 100644
index 0000000000..f2009851b4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-string-resolve.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any('non-empty-string') resolves with the first character in the non-empty string
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 3. Let iteratorRecord be GetIterator(iterable).
+ 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.any, arrow-function]
+flags: [async]
+---*/
+
+try {
+ Promise.any('xyz').then(v => {
+ assert.sameValue(v, 'x');
+ assert.sameValue(v.length, 1);
+ }, error => {
+ $DONE(`The promise should be resolved, but was rejected with error: ${error.message}`);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be resolved, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-symbol-reject.js
new file mode 100644
index 0000000000..563fc47b95
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-symbol-reject.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any(Symbol()) rejects with TypeError.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 3. Let iteratorRecord be GetIterator(iterable).
+ 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any, Symbol]
+flags: [async]
+---*/
+
+try {
+ Promise.any(Symbol()).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-true-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-true-reject.js
new file mode 100644
index 0000000000..7986819d06
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-true-reject.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any(true) rejects with TypeError.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 3. Let iteratorRecord be GetIterator(iterable).
+ 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any]
+flags: [async]
+---*/
+
+try {
+ Promise.any(true).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-undefined-reject.js
new file mode 100644
index 0000000000..1fc2f71b7e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-arg-is-undefined-reject.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any(undefined) rejects with TypeError.
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 3. Let iteratorRecord be GetIterator(iterable).
+ 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any]
+flags: [async]
+---*/
+
+try {
+ Promise.any(undefined).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-assigned-false-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-false-reject.js
new file mode 100644
index 0000000000..3bbbea0929
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-false-reject.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator property has the value false
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ i. Set method to ? GetMethod(obj, @@asyncIterator).
+ ii. If method is undefined, then
+ 1. Let syncMethod be ? GetMethod(obj, @@iterator).
+ 2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod).
+ ...
+ 4. Let iterator be ? Call(method, obj).
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
+flags: [async]
+---*/
+
+try {
+ Promise.any({
+ [Symbol.iterator]: false
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-assigned-null-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-null-reject.js
new file mode 100644
index 0000000000..f7d25a88fe
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-null-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator property has the value null
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
+flags: [async]
+---*/
+
+try {
+ Promise.any({
+ [Symbol.iterator]: null
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-assigned-number-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-number-reject.js
new file mode 100644
index 0000000000..f304043058
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-number-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator property has the value 1
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
+flags: [async]
+---*/
+
+try {
+ Promise.any({
+ [Symbol.iterator]: 1
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-assigned-string-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-string-reject.js
new file mode 100644
index 0000000000..f5444280cf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-string-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator property has the value ""
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
+flags: [async]
+---*/
+
+try {
+ Promise.any({
+ [Symbol.iterator]: ''
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-assigned-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-symbol-reject.js
new file mode 100644
index 0000000000..748b8b780a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-symbol-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator property has the value Symbol()
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any, Symbol, Symbol.iterator, computed-property-names]
+flags: [async]
+---*/
+
+try {
+ Promise.any({
+ [Symbol.iterator]: Symbol()
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-assigned-true-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-true-reject.js
new file mode 100644
index 0000000000..32871ce869
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-true-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator property has the value true
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
+flags: [async]
+---*/
+
+try {
+ Promise.any({
+ [Symbol.iterator]: true
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-assigned-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-undefined-reject.js
new file mode 100644
index 0000000000..48918756b3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-assigned-undefined-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator property has the value undefined
+info: |
+ Promise.any ( iterable )
+
+ ...
+ 4. Let iteratorRecord be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ 3. If method is not present, then
+ a. If hint is async, then
+ ...
+ b. Otherwise, set method to ? GetMethod(obj, @@iterator).
+ 4. Let iterator be ? Call(method, obj).
+ 5. If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+ GetMethod
+
+ 2. Let func be ? GetV(V, P).
+ 3. If func is either undefined or null, return undefined.
+ 4. If IsCallable(func) is false, throw a TypeError exception.
+
+ Call ( F, V [ , argumentsList ] )
+
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+features: [Promise.any, Symbol.iterator, Symbol, computed-property-names]
+flags: [async]
+---*/
+
+try {
+ Promise.any({
+ [Symbol.iterator]: undefined
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert.sameValue(Object.getPrototypeOf(error), TypeError.prototype);
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-next-val-err-no-close.js b/js/src/tests/test262/built-ins/Promise/any/iter-next-val-err-no-close.js
new file mode 100644
index 0000000000..73bd0c5724
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-next-val-err-no-close.js
@@ -0,0 +1,64 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Error when accessing an iterator result's `value` property (not closing
+ iterator)
+info: |
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ If result is an abrupt completion, then
+ If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ IfAbruptRejectPromise(result, promiseCapability).
+
+ ...
+
+ Runtime Semantics: PerformPromiseAny
+
+ ...
+ Repeat
+ Let nextValue be IteratorValue(next).
+ If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(nextValue).
+
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+let callCount = 0;
+let returnCount = 0;
+let error = new Test262Error();
+let poisoned = {
+ done: false
+};
+Object.defineProperty(poisoned, 'value', {
+ get() {
+ callCount++;
+ throw error;
+ }
+});
+let iterNextValThrows = {
+ [Symbol.iterator]() {
+ callCount++;
+ return {
+ next() {
+ callCount++;
+ return poisoned;
+ },
+ return() {
+ returnCount++;
+ return {};
+ }
+ };
+ }
+};
+
+Promise.any(iterNextValThrows).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (reason) => {
+ assert(error instanceof Test262Error);
+ assert.sameValue(reason, error);
+ assert.sameValue(callCount, 3, 'callCount === 3');
+ assert.sameValue(returnCount, 0);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-next-val-err-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-next-val-err-reject.js
new file mode 100644
index 0000000000..fe36877a63
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-next-val-err-reject.js
@@ -0,0 +1,58 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Error when accessing an iterator result's `value` property (rejecting
+ promise)
+info: |
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ If result is an abrupt completion, then
+ If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ IfAbruptRejectPromise(result, promiseCapability).
+
+ ...
+
+ Runtime Semantics: PerformPromiseAny
+
+ ...
+ Repeat
+ Let nextValue be IteratorValue(next).
+ If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(nextValue).
+
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+let callCount = 0;
+let error = new Test262Error();
+let poisoned = {
+ done: false
+};
+Object.defineProperty(poisoned, 'value', {
+ get() {
+ callCount++;
+ throw error;
+ }
+});
+let iterNextValThrows = {
+ [Symbol.iterator]() {
+ callCount++;
+ return {
+ next() {
+ callCount++;
+ return poisoned;
+ }
+ };
+ }
+};
+
+Promise.any(iterNextValThrows).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (reason) => {
+ assert(error instanceof Test262Error);
+ assert.sameValue(reason, error);
+ assert.sameValue(callCount, 3, 'callCount === 3');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-returns-false-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-returns-false-reject.js
new file mode 100644
index 0000000000..19657b6ceb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-returns-false-reject.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator returns false
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+
+let callCount = 0;
+Promise.any({
+ [Symbol.iterator]() {
+ callCount++;
+ return false;
+ }
+}).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (error) => {
+ assert.sameValue(callCount, 1, 'callCount === 1');
+ assert(error instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-returns-null-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-returns-null-reject.js
new file mode 100644
index 0000000000..de20333f61
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-returns-null-reject.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator returns null
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+
+let callCount = 0;
+Promise.any({
+ [Symbol.iterator]() {
+ callCount++;
+ return null;
+ }
+}).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (error) => {
+ assert.sameValue(callCount, 1, 'callCount === 1');
+ assert(error instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-returns-number-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-returns-number-reject.js
new file mode 100644
index 0000000000..c6a68b81e6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-returns-number-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator returns number
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+
+let callCount = 0;
+Promise.any({
+ [Symbol.iterator]() {
+ callCount++;
+ return 1;
+ }
+}).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (error) => {
+ assert.sameValue(callCount, 1, 'callCount === 1');
+ assert(error instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-returns-string-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-returns-string-reject.js
new file mode 100644
index 0000000000..645a021a1a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-returns-string-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator returns string
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+
+let callCount = 0;
+Promise.any({
+ [Symbol.iterator]() {
+ callCount++;
+ return '';
+ }
+}).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (error) => {
+ assert.sameValue(callCount, 1, 'callCount === 1');
+ assert(error instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-returns-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-returns-symbol-reject.js
new file mode 100644
index 0000000000..b581992441
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-returns-symbol-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator returns symbol
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+
+let callCount = 0;
+Promise.any({
+ [Symbol.iterator]() {
+ callCount++;
+ return Symbol();
+ }
+}).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (error) => {
+ assert.sameValue(callCount, 1, 'callCount === 1');
+ assert(error instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-returns-true-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-returns-true-reject.js
new file mode 100644
index 0000000000..9fe8abd861
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-returns-true-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator returns true
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+
+let callCount = 0;
+Promise.any({
+ [Symbol.iterator]() {
+ callCount++;
+ return true;
+ }
+}).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (error) => {
+ assert.sameValue(callCount, 1, 'callCount === 1');
+ assert(error instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-returns-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-returns-undefined-reject.js
new file mode 100644
index 0000000000..9d74e6a485
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-returns-undefined-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Reject when argument's Symbol.iterator returns undefined
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Promise.any, Symbol.iterator]
+flags: [async]
+---*/
+
+let callCount = 0;
+Promise.any({
+ [Symbol.iterator]() {
+ callCount++;
+ return undefined;
+ }
+}).then(() => {
+ $DONE('The promise should be rejected, but was resolved');
+}, (error) => {
+ assert.sameValue(callCount, 1, 'callCount === 1');
+ assert(error instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-step-err-no-close.js b/js/src/tests/test262/built-ins/Promise/any/iter-step-err-no-close.js
new file mode 100644
index 0000000000..5dd1fd162e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-step-err-no-close.js
@@ -0,0 +1,61 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Error when advancing the provided iterable (not closing iterator)
+info: |
+ Promise.any ( iterable )
+
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+
+flags: [async]
+features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function]
+---*/
+
+let returnCount = 0;
+let poisonedDone = {};
+let error = new Test262Error();
+Object.defineProperties(poisonedDone, {
+ done: {
+ get() {
+ throw error;
+ }
+ },
+ value: {
+ get() {}
+ }
+});
+let iterStepThrows = {
+ [Symbol.iterator]() {
+ return {
+ next() {
+ return poisonedDone;
+ },
+ return() {
+ returnCount += 1;
+ return {};
+ }
+ };
+ }
+};
+
+Promise.any(iterStepThrows).then(
+ () => {
+ $DONE('The promise should be rejected.');
+}, (reason) => {
+ assert.sameValue(reason, error);
+ assert.sameValue(returnCount, 0);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/iter-step-err-reject.js b/js/src/tests/test262/built-ins/Promise/any/iter-step-err-reject.js
new file mode 100644
index 0000000000..7f3fbe4ad9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/iter-step-err-reject.js
@@ -0,0 +1,57 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Error when advancing the provided iterable (rejecting promise)
+info: |
+ Promise.any ( iterable )
+
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ a. Let next be IteratorStep(iteratorRecord).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+
+flags: [async]
+features: [Promise.any, Symbol.iterator, computed-property-names, Symbol, arrow-function]
+---*/
+
+let poisonedDone = {};
+let error = new Test262Error();
+Object.defineProperties(poisonedDone, {
+ done: {
+ get() {
+ throw error;
+ }
+ },
+ value: {
+ get() {
+ $DONE('The `value` property should not be accessed.');
+ }
+ }
+});
+let iterStepThrows = {
+ [Symbol.iterator]() {
+ return {
+ next() {
+ return poisonedDone;
+ }
+ };
+ }
+};
+
+Promise.any(iterStepThrows).then(
+ () => {
+ $DONE('The promise should be rejected.');
+}, (reason) => {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/length.js b/js/src/tests/test262/built-ins/Promise/any/length.js
new file mode 100644
index 0000000000..85316c7bdc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/length.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: Promise.any `length` property
+info: |
+ ES Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Promise.any]
+---*/
+
+verifyProperty(Promise.any, 'length', {
+ configurable: true,
+ writable: false,
+ enumerable: false,
+ value: 1,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/name.js b/js/src/tests/test262/built-ins/Promise/any/name.js
new file mode 100644
index 0000000000..f55f11b358
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/name.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: Promise.any `name` property
+info: |
+ ES Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Promise.any]
+---*/
+
+verifyProperty(Promise.any, 'name', {
+ configurable: true,
+ writable: false,
+ enumerable: false,
+ value: 'any',
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/new-reject-function.js b/js/src/tests/test262/built-ins/Promise/any/new-reject-function.js
new file mode 100644
index 0000000000..e99d027281
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/new-reject-function.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiseany
+description: >
+ Each Promise.any element is called with a new Promise.any Reject Element function.
+info: |
+ Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
+
+ ...
+ k. Let rejectElement be ! CreateBuiltinFunction(steps, « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »).
+ ...
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+ ...
+
+features: [Promise.any]
+---*/
+
+function rejectFunction() {}
+
+function Constructor(executor) {
+ executor(rejectFunction, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var callCount1 = 0;
+var callCount2 = 0;
+var p1OnRejected;
+
+var p1 = {
+ then(_, onRejected) {
+ callCount1 += 1;
+ p1OnRejected = onRejected;
+ assert.notSameValue(onRejected, rejectFunction, 'p1.then');
+ }
+};
+var p2 = {
+ then(_, onRejected) {
+ callCount2 += 1;
+ assert.notSameValue(onRejected, rejectFunction, 'p2.then');
+ assert.notSameValue(onRejected, p1OnRejected, 'p1.onRejected != p2.onRejected');
+ }
+};
+
+Promise.any.call(Constructor, [p1, p2]);
+assert.sameValue(callCount1, 1, 'p1.then call count');
+assert.sameValue(callCount2, 1, 'p2.then call count');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/any/not-a-constructor.js
new file mode 100644
index 0000000000..94e37ef3ba
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/not-a-constructor.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Promise.any does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, Promise.any, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(Promise.any), false, 'isConstructor(Promise.any) must return false');
+
+assert.throws(TypeError, () => {
+ new Promise.any([1]);
+}, '`new Promise.any([1])` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/prop-desc.js b/js/src/tests/test262/built-ins/Promise/any/prop-desc.js
new file mode 100644
index 0000000000..89af2db227
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/prop-desc.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: Promise.any property descriptor
+info: |
+ ES Section 17
+
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [Promise.any]
+---*/
+
+verifyProperty(Promise, 'any', {
+ configurable: true,
+ writable: true,
+ enumerable: false,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-all-mixed.js b/js/src/tests/test262/built-ins/Promise/any/reject-all-mixed.js
new file mode 100644
index 0000000000..0a4da17aa3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-all-mixed.js
@@ -0,0 +1,27 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any rejection reasons from various rejections are all present
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let rejections = [
+ Promise.reject('a'),
+ new Promise((_, reject) => reject('b')),
+ Promise.all([Promise.reject('c')]),
+ Promise.resolve(Promise.reject('d')),
+];
+
+Promise.any(rejections)
+ .then(
+ () => $DONE('The promise should be rejected, but was resolved'),
+ error => {
+ assert.sameValue(error.errors.length, rejections.length);
+ assert.sameValue(error.errors.join(''), 'abcd');
+ }
+ ).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-deferred.js b/js/src/tests/test262/built-ins/Promise/any/reject-deferred.js
new file mode 100644
index 0000000000..66206ac8f8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-deferred.js
@@ -0,0 +1,32 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.any
+description: Rejecting through deferred invocation of the provided resolving function
+info: |
+ ...
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ ...
+
+
+flags: [async]
+features: [AggregateError, Promise.any, arrow-function]
+---*/
+
+var rejection = {};
+var thenable = {
+ then(_, reject) {
+ new Promise((resolve) => resolve())
+ .then(() => reject(rejection));
+ }
+};
+
+Promise.any([thenable])
+ .then(() => {
+ $DONE('The promise should be rejected.');
+ }, (aggregate) => {
+ assert(aggregate instanceof AggregateError);
+ assert.sameValue(aggregate.errors.length, 1);
+ assert.sameValue(aggregate.errors[0], rejection);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-element-function-extensible.js b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-extensible.js
new file mode 100644
index 0000000000..806e937f37
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-extensible.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any-reject-element-functions
+description: The [[Extensible]] slot of Promise.any Reject Element functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless specified otherwise, the [[Extensible]] internal slot
+ of a built-in object initially has the value true.
+features: [Promise.any]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.any.call(NotPromise, [thenable]);
+
+assert(Object.isExtensible(rejectElementFunction));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-element-function-length.js b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-length.js
new file mode 100644
index 0000000000..dce2b491c8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-length.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any-reject-element-functions
+description: The `length` property of Promise.any Reject Element functions
+info: |
+ The length property of a Promise.any Reject Element function is 1.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Promise.any]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.any.call(NotPromise, [thenable]);
+
+assert.sameValue(rejectElementFunction.length, 1);
+
+verifyProperty(rejectElementFunction, 'length', {
+ value: 1,
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-element-function-name.js b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-name.js
new file mode 100644
index 0000000000..e7b71509e9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-name.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any-reject-element-functions
+description: The `name` property of Promise.any Reject Element functions
+info: |
+ A promise resolve function is an anonymous built-in function.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in function object, including constructors, has a `name`
+ property whose value is a String. Functions that are identified as
+ anonymous functions use the empty string as the value of the `name`
+ property.
+ Unless otherwise specified, the `name` property of a built-in function
+ object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
+ [[Configurable]]: *true* }.
+includes: [propertyHelper.js]
+features: [Promise.any]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.any.call(NotPromise, [thenable]);
+
+verifyProperty(rejectElementFunction, "name", {
+ value: "", writable: false, enumerable: false, configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-element-function-nonconstructor.js b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-nonconstructor.js
new file mode 100644
index 0000000000..c11012de84
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-nonconstructor.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any-reject-element-functions
+description: Promise.any Reject Element functions are not constructors
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified
+ in the description of a particular function.
+features: [Promise.any]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.any.call(NotPromise, [thenable]);
+
+assert.sameValue(Object.prototype.hasOwnProperty.call(rejectElementFunction, 'prototype'), false);
+assert.throws(TypeError, function() {
+ new rejectElementFunction();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-element-function-property-order.js b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-property-order.js
new file mode 100644
index 0000000000..a463bde468
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-property-order.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createbuiltinfunction
+description: Promise.any resolve element function property order
+info: |
+ Set order: "length", "name"
+features: [Promise.any]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then: function(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.any.call(NotPromise, [thenable]);
+
+var propNames = Object.getOwnPropertyNames(rejectElementFunction);
+var lengthIndex = propNames.indexOf("length");
+var nameIndex = propNames.indexOf("name");
+
+assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1,
+ "The `length` property comes before the `name` property on built-in functions");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-element-function-prototype.js b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-prototype.js
new file mode 100644
index 0000000000..a6b147ec0e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-element-function-prototype.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any-reject-element-functions
+description: The [[Prototype]] of Promise.any Reject Element functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified every built-in function and every built-in
+ constructor has the Function prototype object, which is the initial
+ value of the expression Function.prototype (19.2.3), as the value of
+ its [[Prototype]] internal slot.
+features: [Promise.any]
+---*/
+
+var rejectElementFunction;
+var thenable = {
+ then(_, reject) {
+ rejectElementFunction = reject;
+ }
+};
+
+function NotPromise(executor) {
+ executor(function() {}, function() {});
+}
+NotPromise.resolve = function(v) {
+ return v;
+};
+Promise.any.call(NotPromise, [thenable]);
+
+assert.sameValue(Object.getPrototypeOf(rejectElementFunction), Function.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-from-same-thenable.js b/js/src/tests/test262/built-ins/Promise/any/reject-from-same-thenable.js
new file mode 100644
index 0000000000..9c55285599
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-from-same-thenable.js
@@ -0,0 +1,70 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting with a non-thenable object value
+esid: sec-promise.any
+info: |
+ PerformPromiseAny
+
+ Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+ Promise.any Reject Element Functions
+
+ Let alreadyCalled be F.[[AlreadyCalled]].
+ If alreadyCalled.[[Value]] is true, return undefined.
+ Set alreadyCalled.[[Value]] to true.
+ ...
+features: [Promise.any]
+---*/
+
+let callCount = 0;
+let error;
+
+function Constructor(executor) {
+ function reject(result) {
+ callCount += 1;
+ error = result;
+ }
+ executor(() => {throw new Test262Error()}, reject);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+let p1OnRejected, p2OnRejected, p3OnRejected;
+
+let p1 = {
+ then(_, onRejected) {
+ p1OnRejected = onRejected;
+ }
+};
+let p2 = {
+ then(_, onRejected) {
+ p2OnRejected = onRejected;
+ }
+};
+let p3 = {
+ then(_, onRejected) {
+ p3OnRejected = onRejected;
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to any()');
+
+Promise.any.call(Constructor, [p1, p2, p3]);
+
+assert.sameValue(callCount, 0, 'callCount after call to any()');
+
+p1OnRejected('p1-rejection');
+p1OnRejected('p1-rejection-unexpected-1');
+p1OnRejected('p1-rejection-unexpected-2');
+
+assert.sameValue(callCount, 0, 'callCount after resolving p1');
+
+p2OnRejected('p2-rejection');
+p3OnRejected('p3-rejection');
+
+assert.sameValue(callCount, 1, 'callCount after resolving all elements');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-ignored-deferred.js b/js/src/tests/test262/built-ins/Promise/any/reject-ignored-deferred.js
new file mode 100644
index 0000000000..4e98e1ab01
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-ignored-deferred.js
@@ -0,0 +1,69 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.any
+description: >
+ Resolved promises ignore rejections through deferred invocation of the
+ provided resolving function
+info: |
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ ...
+ Let remainingElementsCount be a new Record { [[value]]: 1 }.
+ ...
+ 8.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0,
+ 1. Let error be a newly created AggregateError object.
+ 2. Perform ! DefinePropertyOrThrow(error, "errors", Property Descriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: errors }).
+ 3. Return ThrowCompletion(error).
+ ...
+
+ Promise.any Reject Element Functions
+ ...
+ Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ If alreadyCalled.[[value]] is true, return undefined.
+ Set alreadyCalled.[[value]] to true.
+ ...
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let callCount = 0;
+let fulfiller = {
+ then(resolve) {
+ new Promise((resolve) => {
+ callCount++;
+ resolve();
+ })
+ .then(() => {
+ callCount++;
+ resolve();
+ });
+ }
+};
+let rejector = {
+ then(resolve, reject) {
+ new Promise((resolve) => {
+ callCount++;
+ resolve();
+ })
+ .then(() => {
+ callCount++;
+ resolve();
+ reject();
+ });
+ }
+};
+
+Promise.all([fulfiller, rejector])
+ .then(() => {
+ assert.sameValue(callCount, 4, "callCount === 4");
+ $DONE();
+ }, () => {
+ $DONE("The promise should not be rejected.");
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-ignored-immed.js b/js/src/tests/test262/built-ins/Promise/any/reject-ignored-immed.js
new file mode 100644
index 0000000000..11b6976871
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-ignored-immed.js
@@ -0,0 +1,53 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.any
+description: >
+ Resolved promises ignore rejections through immediate invocation of the
+ provided resolving function
+info: |
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ ...
+ Let remainingElementsCount be a new Record { [[value]]: 1 }.
+ ...
+ 8.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0,
+ 1. Let error be a newly created AggregateError object.
+ 2. Perform ! DefinePropertyOrThrow(error, "errors", Property Descriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: errors }).
+ 3. Return ThrowCompletion(error).
+ ...
+
+ Promise.any Reject Element Functions
+ ...
+ Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ If alreadyCalled.[[value]] is true, return undefined.
+ Set alreadyCalled.[[value]] to true.
+ ...
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let fulfiller = {
+ then(resolve) {
+ resolve();
+ }
+};
+let lateRejector = {
+ then(resolve, reject) {
+ resolve();
+ reject();
+ }
+};
+
+Promise.any([fulfiller, lateRejector])
+ .then(() => {
+ $DONE();
+ }, () => {
+ $DONE('The promise should not be rejected.');
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/any/reject-immed.js b/js/src/tests/test262/built-ins/Promise/any/reject-immed.js
new file mode 100644
index 0000000000..33d445e1de
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/reject-immed.js
@@ -0,0 +1,45 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.any
+description: Rejecting through immediate invocation of the provided resolving function
+info: |
+ ...
+ Let promiseCapability be NewPromiseCapability(C).
+ ...
+ Let result be PerformPromiseAny(iteratorRecord, promiseCapability, C).
+ ...
+
+ Runtime Semantics: PerformPromiseAny
+ ...
+ 8. Repeat
+ ...
+ r. Perform ? Invoke(nextPromise, "then",
+ « resultCapability.[[Resolve]], rejectElement »).
+
+
+ Promise.any Reject Element Functions
+ ...
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let callCount = 0;
+let thenable = {
+ then(_, reject) {
+ callCount++;
+ reject('reason');
+ }
+};
+
+Promise.any([thenable])
+ .then(() => {
+ $DONE('The promise should not be fulfilled.');
+ }, (error) => {
+ assert.sameValue(callCount, 1, "callCount === 1");
+ assert(error instanceof AggregateError, "error instanceof AggregateError");
+ assert.sameValue(error.errors[0], "reason", "error.errors[0] === 'reason'");
+ $DONE();
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-before-loop-exit-from-same.js b/js/src/tests/test262/built-ins/Promise/any/resolve-before-loop-exit-from-same.js
new file mode 100644
index 0000000000..19e2e3779e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-before-loop-exit-from-same.js
@@ -0,0 +1,101 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Cannot tamper remainingElementsCount when Promise.all resolve element function is called twice in a row.
+info: |
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ ...
+ Let remainingElementsCount be a new Record { [[value]]: 1 }.
+ ...
+ 8.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0,
+ 1. Let error be a newly created AggregateError object.
+ 2. Perform ! DefinePropertyOrThrow(error, "errors", Property Descriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: errors }).
+ 3. Return ThrowCompletion(error).
+ ...
+
+ Promise.any Reject Element Functions
+ ...
+ Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ If alreadyCalled.[[value]] is true, return undefined.
+ Set alreadyCalled.[[value]] to true.
+ ...
+
+features: [Promise.any, arrow-function]
+---*/
+
+let callCount = 0;
+let errorArray;
+
+function Constructor(executor) {
+ function reject(error) {
+ callCount += 1;
+ errorArray = error.errors;
+
+ assert(Array.isArray(error.errors), "error is array");
+ assert.sameValue(error.errors.length, 3, "error.length");
+ assert.sameValue(error.errors[0], "p1-rejection", "error.errors[0] === 'p1-rejection'");
+ assert.sameValue(error.errors[1], "p2-rejection", "error.errors[1] === 'p2-rejection'");
+ assert.sameValue(error.errors[2], "p3-rejection", "error.errors[2] === 'p3-rejection'");
+ assert(error instanceof AggregateError, "error instanceof AggregateError");
+ }
+ executor(Test262Error.thrower, reject);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+let p1OnRejected;
+
+let p1 = {
+ then(onResolved, onRejected) {
+ p1OnRejected = onRejected;
+ }
+};
+let p2 = {
+ then(onResolved, onRejected) {
+ onRejected("p2-rejection");
+ onRejected("unexpectedonRejectedValue");
+ }
+};
+let p3 = {
+ then(onResolved, onRejected) {
+ onRejected("p3-rejection");
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to any()");
+
+Promise.any.call(Constructor, [p1, p2, p3]);
+
+assert.sameValue(callCount, 0, "callCount after call to any()");
+
+p1OnRejected("p1-rejection");
+
+assert.sameValue(callCount, 1, "callCount after call to p1OnRejected()");
+assert.sameValue(
+ errorArray[0],
+ "p1-rejection",
+ "errorArray[0] === 'p1-rejection', after call to p1OnRejected(...)"
+);
+assert.sameValue(
+ errorArray[1],
+ "p2-rejection",
+ "errorArray[1] === 'p2-rejection', after call to p1OnRejected(...)"
+);
+assert.sameValue(
+ errorArray[2],
+ "p3-rejection",
+ "errorArray[2] === 'p3-rejection', after call to p1OnRejected(...)"
+);
+
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-before-loop-exit.js b/js/src/tests/test262/built-ins/Promise/any/resolve-before-loop-exit.js
new file mode 100644
index 0000000000..07daaa55dd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-before-loop-exit.js
@@ -0,0 +1,102 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Cannot tamper remainingElementsCount when two Promise.any Reject Element Function are called in succession.
+info: |
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ ...
+ Let remainingElementsCount be a new Record { [[value]]: 1 }.
+ ...
+ 8.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0,
+ 1. Let error be a newly created AggregateError object.
+ 2. Perform ! DefinePropertyOrThrow(error, "errors", Property Descriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: errors }).
+ 3. Return ThrowCompletion(error).
+ ...
+
+ Promise.any Reject Element Functions
+ ...
+ Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
+ If alreadyCalled.[[value]] is true, return undefined.
+ Set alreadyCalled.[[value]] to true.
+ ...
+
+features: [Promise.any, arrow-function]
+---*/
+
+let callCount = 0;
+let errorArray;
+
+function Constructor(executor) {
+ function reject(error) {
+ callCount += 1;
+ errorArray = error.errors;
+
+ assert(Array.isArray(error.errors), "error is array");
+ assert.sameValue(error.errors.length, 3, "error.length");
+ assert.sameValue(error.errors[0], "p1-rejection", "error.errors[0] === 'p1-rejection'");
+ assert.sameValue(error.errors[1], "p2-rejection", "error.errors[1] === 'p2-rejection'");
+ assert.sameValue(error.errors[2], "p3-rejection", "error.errors[2] === 'p3-rejection'");
+ assert(error instanceof AggregateError, "error instanceof AggregateError");
+ }
+ executor(Test262Error.thrower, reject);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+let p1OnRejected;
+
+let p1 = {
+ then(onResolved, onRejected) {
+ p1OnRejected = onRejected;
+ }
+};
+let p2 = {
+ then(onResolved, onRejected) {
+ p1OnRejected("p1-rejection");
+ onRejected("p2-rejection");
+ }
+};
+let p3 = {
+ then(onResolved, onRejected) {
+ onRejected("p3-rejection");
+ }
+};
+
+assert.sameValue(callCount, 0, "callCount before call to any()");
+
+Promise.any.call(Constructor, [p1, p2, p3]);
+
+assert.sameValue(callCount, 1, "callCount after call to any()");
+assert.sameValue(errorArray[0], "p1-rejection", "errorArray[0] === 'p1-rejection'");
+assert.sameValue(errorArray[1], "p2-rejection", "errorArray[1] === 'p2-rejection'");
+assert.sameValue(errorArray[2], "p3-rejection", "errorArray[2] === 'p3-rejection'");
+
+p1OnRejected("unexpectedonRejectedValue");
+
+assert.sameValue(callCount, 1, "callCount after call to p1OnRejected()");
+assert.sameValue(
+ errorArray[0],
+ "p1-rejection",
+ "errorArray[0] === 'p1-rejection', after call to p1OnRejected(...)"
+);
+assert.sameValue(
+ errorArray[1],
+ "p2-rejection",
+ "errorArray[1] === 'p2-rejection', after call to p1OnRejected(...)"
+);
+assert.sameValue(
+ errorArray[2],
+ "p3-rejection",
+ "errorArray[2] === 'p3-rejection', after call to p1OnRejected(...)"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-from-reject-catch.js b/js/src/tests/test262/built-ins/Promise/any/resolve-from-reject-catch.js
new file mode 100644
index 0000000000..6aee6c9155
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-from-reject-catch.js
@@ -0,0 +1,23 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any resolves with the first item that does not reject.
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let fulfillables = [
+ Promise.reject('a'),
+ new Promise((resolve, reject) => reject('b')),
+ Promise.all([Promise.reject('c')]),
+ Promise.reject('d').catch(v => v),
+];
+
+Promise.any(fulfillables)
+ .then((resolution) => {
+ assert.sameValue(resolution, 'd');
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-from-resolve-reject-catch.js b/js/src/tests/test262/built-ins/Promise/any/resolve-from-resolve-reject-catch.js
new file mode 100644
index 0000000000..e5c6534b03
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-from-resolve-reject-catch.js
@@ -0,0 +1,23 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.any resolves with the first item that does not reject.
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+let fulfillables = [
+ Promise.reject('a'),
+ new Promise((resolve, reject) => reject('b')),
+ Promise.all([Promise.reject('c')]),
+ Promise.resolve(Promise.reject('d').catch(v => v)),
+];
+
+Promise.any(fulfillables)
+ .then((resolution) => {
+ assert.sameValue(resolution, 'd');
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-from-same-thenable.js b/js/src/tests/test262/built-ins/Promise/any/resolve-from-same-thenable.js
new file mode 100644
index 0000000000..3066d969ad
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-from-same-thenable.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiseany
+description: >
+ Promise.any does not prevent resolve from being called multiple times.
+features: [Promise.any, arrow-function]
+includes: [promiseHelper.js]
+---*/
+let callCount = 0;
+let sequence = [];
+
+function Constructor(executor) {
+ function resolve(value) {
+ callCount += 1;
+ sequence.push(value);
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+let pResolve;
+let a = {
+ then(resolver, rejector) {
+ pResolve = resolver;
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to any()');
+
+Promise.any.call(Constructor, [a]);
+
+assert.sameValue(callCount, 0, 'callCount after call to any()');
+
+pResolve(1);
+pResolve(2);
+pResolve(3);
+
+assert.sameValue(callCount, 3, 'callCount after resolving a');
+assert.sameValue(sequence.length, 3);
+checkSequence(sequence);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-ignores-late-rejection-deferred.js b/js/src/tests/test262/built-ins/Promise/any/resolve-ignores-late-rejection-deferred.js
new file mode 100644
index 0000000000..89339379fa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-ignores-late-rejection-deferred.js
@@ -0,0 +1,42 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through deferred invocation of the
+ provided resolving function
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+var resolver = {
+ then(resolve) {
+ new Promise((resolve) => resolve())
+ .then(() => resolve(42));
+ }
+};
+var lateRejector = {
+ then(resolve, reject) {
+ new Promise((resolve) => resolve())
+ .then(() => {
+ resolve(9);
+ reject();
+ });
+ }
+};
+
+Promise.any([resolver, lateRejector])
+ .then(resolution => {
+ assert.sameValue(resolution, 42);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-ignores-late-rejection.js b/js/src/tests/test262/built-ins/Promise/any/resolve-ignores-late-rejection.js
new file mode 100644
index 0000000000..446a12191f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-ignores-late-rejection.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2019 Leo Balter, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through immediate invocation of the
+ provided resolving function
+esid: sec-promise.any
+info: |
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ 8. Repeat
+ ...
+ r. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+var resolver = {
+ then(resolve) {
+ resolve(42);
+ }
+};
+var lateRejector = {
+ then(resolve, reject) {
+ resolve(33);
+ reject();
+ }
+};
+
+Promise.any([resolver, lateRejector])
+ .then(resolution => {
+ assert.sameValue(resolution, 42);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-non-callable.js b/js/src/tests/test262/built-ins/Promise/any/resolve-non-callable.js
new file mode 100644
index 0000000000..4baf72bb66
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-non-callable.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2020 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Promise.resolve is retrieved before GetIterator call (non-callable).
+info: |
+ Promise.any ( iterable )
+
+ [...]
+ 3. Let promiseResolve be GetPromiseResolve(C).
+ 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
+
+ GetPromiseResolve ( promiseConstructor )
+
+ [...]
+ 2. Let promiseResolve be ? Get(promiseConstructor, "resolve").
+ 3. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+flags: [async]
+features: [Promise.any, Symbol.iterator]
+---*/
+
+const iter = { 
+ get [Symbol.iterator]() {
+ throw new Test262Error("unreachable");
+ },
+};
+
+Promise.resolve = "certainly not callable";
+
+Promise.any(iter).then(() => {
+ throw new Test262Error("The promise should be rejected, but it was resolved");
+}, (reason) => {
+ assert(reason instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-non-thenable.js b/js/src/tests/test262/built-ins/Promise/any/resolve-non-thenable.js
new file mode 100644
index 0000000000..e7fb6b4417
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-non-thenable.js
@@ -0,0 +1,26 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolving with a non-thenable object value
+esid: sec-promise.any
+info: |
+ PerformPromiseAny
+
+ Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
+
+flags: [async]
+features: [Promise.any]
+---*/
+
+const a = {};
+const b = {};
+const c = {};
+
+Promise.any([a, b, c])
+ .then((value) => {
+ assert.sameValue(value, a);
+ }, () => {
+ $DONE('The promise should not be rejected.');
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolve-not-callable-reject-with-typeerror.js b/js/src/tests/test262/built-ins/Promise/any/resolve-not-callable-reject-with-typeerror.js
new file mode 100644
index 0000000000..6623f8c160
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolve-not-callable-reject-with-typeerror.js
@@ -0,0 +1,29 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ If the constructor's `resolve` method is not callable, reject with a TypeError.
+info: |
+ Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+
+ Runtime Semantics: PerformPromiseAny
+
+ Let promiseResolve be ? Get(constructor, "resolve").
+ If ! IsCallable(promiseResolve) is false, throw a TypeError exception.
+
+flags: [async]
+features: [Promise.any, arrow-function]
+---*/
+
+Promise.resolve = null;
+
+Promise.any([1])
+ .then(
+ () => $DONE('The promise should not be resolved.'),
+ error => {
+ assert(error instanceof TypeError);
+ }
+ ).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolved-sequence-extra-ticks.js b/js/src/tests/test262/built-ins/Promise/any/resolved-sequence-extra-ticks.js
new file mode 100644
index 0000000000..fcb54a8457
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolved-sequence-extra-ticks.js
@@ -0,0 +1,55 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: Resolution ticks are set in a predictable sequence with extra then calls
+info: |
+ Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
+
+ Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+
+ Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ If remainingElementsCount.[[Value]] is 0, then
+ Let error be a newly created AggregateError object.
+ Perform ! DefinePropertyOrThrow(error, "errors",
+ Property Descriptor {
+ [[Configurable]]: true,
+ [[Enumerable]]: false,
+ [[Writable]]: true,
+ [[Value]]: errors
+ }).
+ Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
+ ...
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.any]
+---*/
+
+let sequence = [];
+
+let p1 = new Promise(resolve => {
+ resolve({});
+});
+
+sequence.push(1);
+
+Promise.any([p1]).then((resolved) => {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, 'Expected Promise.any().then to queue second');
+}).catch($DONE);
+
+p1.then(() => {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, 'Expected p1.then to queue first');
+}).then(() => {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, 'Expected final then to queue last');
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolved-sequence-mixed.js b/js/src/tests/test262/built-ins/Promise/any/resolved-sequence-mixed.js
new file mode 100644
index 0000000000..b993f5776b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolved-sequence-mixed.js
@@ -0,0 +1,70 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: >
+ Resolution ticks are set in a predictable sequence of mixed fulfilled and rejected promises
+info: |
+ Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
+
+ Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+
+ Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ If remainingElementsCount.[[Value]] is 0, then
+ Let error be a newly created AggregateError object.
+ Perform ! DefinePropertyOrThrow(error, "errors",
+ Property Descriptor {
+ [[Configurable]]: true,
+ [[Enumerable]]: false,
+ [[Writable]]: true,
+ [[Value]]: errors
+ }).
+ Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
+ ...
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.any]
+---*/
+
+let sequence = [];
+
+let p1 = new Promise((_, reject) => {
+ reject('');
+});
+let p2 = new Promise(resolve => {
+ resolve('');
+});
+let p3 = new Promise((_, reject) => {
+ reject('');
+});
+
+sequence.push(1);
+
+p1.catch(() => {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, 'Expected to be called first.');
+}).catch($DONE);
+
+Promise.any([p1, p2, p3]).then(() => {
+ sequence.push(6);
+ assert.sameValue(sequence.length, 6);
+ checkSequence(sequence, 'Expected to be called fourth.');
+}).then($DONE, $DONE);
+
+p2.then(() => {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, 'Expected to be called second.');
+}).catch($DONE);
+
+sequence.push(2);
+
+p3.catch(() => {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, 'Expected to be called third.');
+}).catch($DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolved-sequence-with-rejections.js b/js/src/tests/test262/built-ins/Promise/any/resolved-sequence-with-rejections.js
new file mode 100644
index 0000000000..5562617df6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolved-sequence-with-rejections.js
@@ -0,0 +1,65 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: Resolution ticks are set in a predictable sequence
+info: |
+ Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
+
+ Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+
+ Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
+ If remainingElementsCount.[[Value]] is 0, then
+ Let error be a newly created AggregateError object.
+ Perform ! DefinePropertyOrThrow(error, "errors",
+ Property Descriptor {
+ [[Configurable]]: true,
+ [[Enumerable]]: false,
+ [[Writable]]: true,
+ [[Value]]: errors
+ }).
+ Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
+ ...
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.any]
+---*/
+
+let sequence = [];
+
+let p1 = new Promise((_, reject) => {
+ reject('foo');
+});
+let p2 = new Promise((_, reject) => {
+ reject('bar');
+});
+
+sequence.push(1);
+
+p1.catch(() => {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, 'Expected to be called first.');
+}).catch($DONE);
+
+Promise.any([p1, p2]).then(() => {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, 'Expected to be called third.');
+}).then($DONE, outcome => {
+ assert(outcome instanceof AggregateError);
+ assert.sameValue(outcome.errors.length, 2);
+ assert.sameValue(outcome.errors[0], 'foo');
+ assert.sameValue(outcome.errors[1], 'bar');
+}).then($DONE, $DONE);
+
+p2.catch(() => {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, 'Expected to be called second.');
+}).catch($DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/any/resolved-sequence.js b/js/src/tests/test262/built-ins/Promise/any/resolved-sequence.js
new file mode 100644
index 0000000000..75be407c35
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/resolved-sequence.js
@@ -0,0 +1,55 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: Resolution ticks are set in a predictable sequence
+info: |
+ Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
+
+ Let remainingElementsCount be a new Record { [[Value]]: 1 }.
+ ...
+ 6.d ...
+ ii. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
+ iii. If remainingElementsCount.[[value]] is 0, then
+ Let error be a newly created AggregateError object.
+ Perform ! DefinePropertyOrThrow(error, "errors",
+ Property Descriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: errors }).
+ Return ThrowCompletion(error).
+ ...
+flags: [async]
+includes: [promiseHelper.js]
+features: [Promise.any]
+---*/
+
+var sequence = [];
+
+var p1 = new Promise(resolve => {
+ resolve(1);
+});
+var p2 = new Promise(resolve => {
+ resolve(2);
+});
+
+sequence.push(1);
+
+p1.then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+checkSequence(sequence, 'Expected to be called first.');
+}).catch($DONE);
+
+Promise.any([p1, p2]).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, 'Expected to be called third.');
+}).then($DONE, $DONE);
+
+p2.then(function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, 'Expected to be called second.');
+}).catch($DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/any/returns-promise.js b/js/src/tests/test262/built-ins/Promise/any/returns-promise.js
new file mode 100644
index 0000000000..cbcd937b63
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/returns-promise.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2019 Sergey Rubanov. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.any
+description: Promise.any returns a Promise
+info: |
+ Promise.any ( iterable )
+
+ 2. Let promiseCapability be ? NewPromiseCapability(C).
+ 3. Let iteratorRecord be GetIterator(iterable).
+ 4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ 5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
+ 6. If result is an abrupt completion, then
+ a. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+ 7. Return Completion(result).
+features: [Promise.any]
+---*/
+
+var p = Promise.any([]);
+
+assert(p instanceof Promise);
+assert.sameValue(Object.getPrototypeOf(p), Promise.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/any/shell.js b/js/src/tests/test262/built-ins/Promise/any/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/any/species-get-error.js b/js/src/tests/test262/built-ins/Promise/any/species-get-error.js
new file mode 100644
index 0000000000..24ce52bd69
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/any/species-get-error.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.any() does not access a `Symbol.species` property of the `this` value
+info: |
+ Let C be the this value.
+ Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+
+features: [Promise.any, Symbol.species]
+---*/
+function C(executor) {
+ executor(() => {}, () => {});
+}
+
+Object.defineProperty(C, Symbol.species, {
+ get() {
+ throw new Test262Error("Getter for Symbol.species called");
+ }
+});
+
+C.resolve = function() {
+ throw new Test262Error("C.resolve called unexpectedly");
+};
+
+Promise.any.call(C, [1]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/browser.js b/js/src/tests/test262/built-ins/Promise/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/constructor.js b/js/src/tests/test262/built-ins/Promise/constructor.js
new file mode 100644
index 0000000000..79e15dab44
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/constructor.js
@@ -0,0 +1,11 @@
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise-executor
+description: >
+ The Promise constructor is a built-in function
+---*/
+
+assert.sameValue(typeof Promise, 'function');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/create-resolving-functions-reject.js b/js/src/tests/test262/built-ins/Promise/create-resolving-functions-reject.js
new file mode 100644
index 0000000000..05297b7993
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/create-resolving-functions-reject.js
@@ -0,0 +1,33 @@
+// |reftest| async
+// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createresolvingfunctions
+description: >
+ reject is anonymous built-in function with length of 1.
+info: |
+ CreateResolvingFunctions ( promise )
+
+ ...
+ 7. Let reject be ! CreateBuiltinFunction(stepsReject, « [[Promise]], [[AlreadyResolved]] »).
+features: [Reflect.construct, arrow-function]
+includes: [isConstructor.js]
+flags: [async]
+---*/
+
+Promise.resolve(1).then(function() {
+ return Promise.resolve();
+}).then($DONE, $DONE);
+
+var then = Promise.prototype.then;
+Promise.prototype.then = function(resolve, reject) {
+ assert.sameValue(isConstructor(reject), false, 'isConstructor(reject) must return false');
+ assert.throws(TypeError, () => {
+ new reject();
+ }, '`new reject()` throws TypeError');
+
+ assert.sameValue(reject.length, 1, 'The value of reject.length is 1');
+ assert.sameValue(reject.name, '', 'The value of reject.name is ""');
+
+ return then.call(this, resolve, reject);
+};
diff --git a/js/src/tests/test262/built-ins/Promise/create-resolving-functions-resolve.js b/js/src/tests/test262/built-ins/Promise/create-resolving-functions-resolve.js
new file mode 100644
index 0000000000..c2c4dc60d2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/create-resolving-functions-resolve.js
@@ -0,0 +1,33 @@
+// |reftest| async
+// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createresolvingfunctions
+description: >
+ resolve is anonymous built-in function with length of 1.
+info: |
+ CreateResolvingFunctions ( promise )
+
+ ...
+ 3. Let resolve be ! CreateBuiltinFunction(stepsResolve, « [[Promise]], [[AlreadyResolved]] »).
+features: [Reflect.construct, arrow-function]
+includes: [isConstructor.js]
+flags: [async]
+---*/
+
+Promise.resolve(1).then(function() {
+ return Promise.resolve();
+}).then($DONE, $DONE);
+
+var then = Promise.prototype.then;
+Promise.prototype.then = function(resolve, reject) {
+ assert.sameValue(isConstructor(resolve), false, 'isConstructor(resolve) must return false');
+ assert.throws(TypeError, () => {
+ new resolve();
+ }, '`new resolve()` throws TypeError');
+
+ assert.sameValue(resolve.length, 1, 'The value of resolve.length is 1');
+ assert.sameValue(resolve.name, '', 'The value of resolve.name is ""');
+
+ return then.call(this, resolve, reject);
+};
diff --git a/js/src/tests/test262/built-ins/Promise/exception-after-resolve-in-executor.js b/js/src/tests/test262/built-ins/Promise/exception-after-resolve-in-executor.js
new file mode 100644
index 0000000000..a33d887ca6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/exception-after-resolve-in-executor.js
@@ -0,0 +1,33 @@
+// |reftest| async
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.3.1
+description: >
+ Already resolved promise is not rejected when executor throws an exception.
+info: |
+ Promise ( executor )
+
+ ...
+ 8. Let resolvingFunctions be CreateResolvingFunctions(promise).
+ 9. Let completion be Call(executor, undefined, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 10. If completion is an abrupt completion, then
+ a. Let status be Call(resolvingFunctions.[[Reject]], undefined, «completion.[[value]]»).
+ b. ReturnIfAbrupt(status).
+ ...
+flags: [async]
+---*/
+
+var thenable = {
+ then: function(resolve) {
+ resolve();
+ }
+};
+
+function executor(resolve, reject) {
+ resolve(thenable);
+ throw new Error("ignored exception");
+}
+
+new Promise(executor).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/exception-after-resolve-in-thenable-job.js b/js/src/tests/test262/built-ins/Promise/exception-after-resolve-in-thenable-job.js
new file mode 100644
index 0000000000..b1ca3168de
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/exception-after-resolve-in-thenable-job.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.2.2
+description: >
+ Already resolved promise is not rejected when then() function throws an exception.
+info: |
+ PromiseResolveThenableJob ( promiseToResolve, thenable, then )
+
+ 1. Let resolvingFunctions be CreateResolvingFunctions(promiseToResolve).
+ 2. Let thenCallResult be Call(then, thenable, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 3. If thenCallResult is an abrupt completion,
+ a. Let status be Call(resolvingFunctions.[[Reject]], undefined, «thenCallResult.[[value]]»)
+ b. NextJob Completion(status).
+ ...
+flags: [async]
+---*/
+
+var thenable = {
+ then: function(resolve) {
+ resolve();
+ }
+};
+
+var thenableWithError = {
+ then: function(resolve) {
+ resolve(thenable);
+ throw new Error("ignored exception");
+ }
+};
+
+function executor(resolve, reject) {
+ resolve(thenableWithError);
+}
+
+new Promise(executor).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/exec-args.js b/js/src/tests/test262/built-ins/Promise/exec-args.js
new file mode 100644
index 0000000000..a2b23f1137
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/exec-args.js
@@ -0,0 +1,35 @@
+// 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.3.1
+description: Promise executor is invoked synchronously
+info: |
+ 9. Let completion be Call(executor, undefined,
+ «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+
+ 25.4.1.3.2 Promise Resolve Functions
+
+ The length property of a promise resolve function is 1.
+
+ 25.4.1.3.1 Promise Reject Functions
+
+ The length property of a promise reject function is 1.
+---*/
+
+var callCount = 0;
+var resolve, reject, argCount;
+
+new Promise(function(a, b) {
+ resolve = a;
+ reject = b;
+ argCount = arguments.length;
+});
+
+assert.sameValue(typeof resolve, 'function', 'type of first argument');
+assert.sameValue(resolve.length, 1, 'length of first argument');
+assert.sameValue(typeof reject, 'function', 'type of second argument');
+assert.sameValue(reject.length, 1, 'length of second argument');
+assert.sameValue(argCount, 2);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/executor-call-context-sloppy.js b/js/src/tests/test262/built-ins/Promise/executor-call-context-sloppy.js
new file mode 100644
index 0000000000..6151199642
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/executor-call-context-sloppy.js
@@ -0,0 +1,24 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise-executor
+author: Sam Mikes
+description: >
+ Promise executor is called in global object context in sloppy mode.
+info: |
+ 25.6.3.1 Promise ( executor )
+
+ [...]
+ 9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »).
+flags: [noStrict]
+---*/
+
+var _this;
+
+new Promise(function() {
+ _this = this;
+});
+
+assert.sameValue(_this, this);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/executor-call-context-strict-strict.js b/js/src/tests/test262/built-ins/Promise/executor-call-context-strict-strict.js
new file mode 100644
index 0000000000..e6eec27aac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/executor-call-context-strict-strict.js
@@ -0,0 +1,25 @@
+'use strict';
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise-executor
+author: Sam Mikes
+description: >
+ Promise executor is called in `undefined` context in strict mode.
+info: |
+ 25.6.3.1 Promise ( executor )
+
+ [...]
+ 9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »).
+flags: [onlyStrict]
+---*/
+
+var _this;
+
+new Promise(function() {
+ _this = this;
+});
+
+assert.sameValue(_this, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/executor-function-extensible.js b/js/src/tests/test262/built-ins/Promise/executor-function-extensible.js
new file mode 100644
index 0000000000..901795ecac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/executor-function-extensible.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.5.1
+description: The [[Extensible]] slot of GetCapabilitiesExecutor functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless specified otherwise, the [[Extensible]] internal slot
+ of a built-in object initially has the value true.
+---*/
+
+var executorFunction;
+
+function NotPromise(executor) {
+ executorFunction = executor;
+ executor(function() {}, function() {});
+}
+Promise.resolve.call(NotPromise);
+
+assert(Object.isExtensible(executorFunction));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/executor-function-length.js b/js/src/tests/test262/built-ins/Promise/executor-function-length.js
new file mode 100644
index 0000000000..1aa7f25e45
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/executor-function-length.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.5.1
+description: The `length` property of GetCapabilitiesExecutor functions
+info: |
+ The length property of a GetCapabilitiesExecutor function is 2.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+var executorFunction;
+
+function NotPromise(executor) {
+ executorFunction = executor;
+ executor(function() {}, function() {});
+}
+Promise.resolve.call(NotPromise);
+
+assert.sameValue(executorFunction.length, 2);
+
+verifyNotEnumerable(executorFunction, "length");
+verifyNotWritable(executorFunction, "length");
+verifyConfigurable(executorFunction, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/executor-function-name.js b/js/src/tests/test262/built-ins/Promise/executor-function-name.js
new file mode 100644
index 0000000000..dc38f24ef4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/executor-function-name.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-getcapabilitiesexecutor-functions
+description: The `name` property of GetCapabilitiesExecutor functions
+info: |
+ A GetCapabilitiesExecutor function is an anonymous built-in function.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in function object, including constructors, has a `name`
+ property whose value is a String. Functions that are identified as
+ anonymous functions use the empty string as the value of the `name`
+ property.
+ Unless otherwise specified, the `name` property of a built-in function
+ object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
+ [[Configurable]]: *true* }.
+includes: [propertyHelper.js]
+---*/
+
+var executorFunction;
+
+function NotPromise(executor) {
+ executorFunction = executor;
+ executor(function() {}, function() {});
+}
+Promise.resolve.call(NotPromise);
+
+verifyProperty(executorFunction, "name", {
+ value: "", writable: false, enumerable: false, configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/executor-function-not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/executor-function-not-a-constructor.js
new file mode 100644
index 0000000000..5e1f360112
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/executor-function-not-a-constructor.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-getcapabilitiesexecutor-functions
+description: GetCapabilitiesExecutor function is not constructor
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified
+ in the description of a particular function.
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+var executorFunction;
+
+function NotPromise(executor) {
+ executorFunction = executor;
+ executor(function() {}, function() {});
+}
+Promise.resolve.call(NotPromise);
+
+assert.sameValue(
+ Object.prototype.hasOwnProperty.call(executorFunction, "prototype"),
+ false,
+ 'Object.prototype.hasOwnProperty.call(executorFunction, "prototype") must return false'
+);
+assert.sameValue(isConstructor(executorFunction), false, 'isConstructor(executorFunction) must return false');
+
+assert.throws(TypeError, () => {
+ new executorFunction();
+}, '`new executorFunction()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/executor-function-property-order.js b/js/src/tests/test262/built-ins/Promise/executor-function-property-order.js
new file mode 100644
index 0000000000..207dd3b6f0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/executor-function-property-order.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createbuiltinfunction
+description: Promise executor function property order
+info: |
+ Set order: "length", "name"
+---*/
+
+var executorFunction;
+
+function NotPromise(executor) {
+ executorFunction = executor;
+ executor(function() {}, function() {});
+}
+Promise.resolve.call(NotPromise);
+
+var propNames = Object.getOwnPropertyNames(executorFunction);
+var lengthIndex = propNames.indexOf("length");
+var nameIndex = propNames.indexOf("name");
+
+assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1,
+ "The `length` property comes before the `name` property on built-in functions");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/executor-function-prototype.js b/js/src/tests/test262/built-ins/Promise/executor-function-prototype.js
new file mode 100644
index 0000000000..e01753b9e1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/executor-function-prototype.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.5.1
+description: The [[Prototype]] of GetCapabilitiesExecutor functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified every built-in function and every built-in
+ constructor has the Function prototype object, which is the initial
+ value of the expression Function.prototype (19.2.3), as the value of
+ its [[Prototype]] internal slot.
+---*/
+
+var executorFunction;
+
+function NotPromise(executor) {
+ executorFunction = executor;
+ executor(function() {}, function() {});
+}
+Promise.resolve.call(NotPromise);
+
+assert.sameValue(Object.getPrototypeOf(executorFunction), Function.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/executor-not-callable.js
new file mode 100644
index 0000000000..76478606f4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/executor-not-callable.js
@@ -0,0 +1,31 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise-executor
+author: Sam Mikes
+description: >
+ Promise constructor throws TypeError if executor is not callable.
+info: |
+ 25.6.3.1 Promise ( executor )
+
+ [...]
+ 2. If IsCallable(executor) is false, throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() {
+ new Promise('not callable');
+});
+
+assert.throws(TypeError, function() {
+ new Promise(1);
+});
+
+assert.throws(TypeError, function() {
+ new Promise(null);
+});
+
+assert.throws(TypeError, function() {
+ new Promise({});
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/get-prototype-abrupt-executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/get-prototype-abrupt-executor-not-callable.js
new file mode 100644
index 0000000000..5a31248bdc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/get-prototype-abrupt-executor-not-callable.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise-executor
+description: >
+ Promise constructor gets prototype after checking that executor is callable.
+info: |
+ 25.6.3.1 Promise ( executor )
+
+ [...]
+ 2. If IsCallable(executor) is false, throw a TypeError exception.
+ 3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget, "%PromisePrototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »).
+
+ 9.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
+
+ [...]
+ 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
+
+ 9.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )
+
+ [...]
+ 3. Let proto be ? Get(constructor, "prototype").
+features: [Reflect, Reflect.construct]
+---*/
+
+var bound = (function() {}).bind();
+Object.defineProperty(bound, 'prototype', {
+ get: function() {
+ throw new Test262Error();
+ },
+});
+
+assert.throws(TypeError, function() {
+ Reflect.construct(Promise, [], bound);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/get-prototype-abrupt.js b/js/src/tests/test262/built-ins/Promise/get-prototype-abrupt.js
new file mode 100644
index 0000000000..5cbf716e9c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/get-prototype-abrupt.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise-executor
+description: >
+ Abrupt completion from "prototype" property access
+info: |
+ 25.6.3.1 Promise ( executor )
+
+ [...]
+ 3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget, "%PromisePrototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »).
+
+ 9.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
+
+ [...]
+ 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
+
+ 9.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )
+
+ [...]
+ 3. Let proto be ? Get(constructor, "prototype").
+features: [Reflect, Reflect.construct]
+---*/
+
+var bound = (function() {}).bind();
+Object.defineProperty(bound, 'prototype', {
+ get: function() {
+ throw new Test262Error();
+ },
+});
+
+assert.throws(Test262Error, function() {
+ Reflect.construct(Promise, [function() {}], bound);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/is-a-constructor.js b/js/src/tests/test262/built-ins/Promise/is-a-constructor.js
new file mode 100644
index 0000000000..4b6dbe371e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/is-a-constructor.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ The Promise constructor implements [[Construct]]
+info: |
+ IsConstructor ( argument )
+
+ The abstract operation IsConstructor takes argument argument (an ECMAScript language value).
+ It determines if argument is a function object with a [[Construct]] internal method.
+ It performs the following steps when called:
+
+ If Type(argument) is not Object, return false.
+ If argument has a [[Construct]] internal method, return true.
+ Return false.
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(Promise), true, 'isConstructor(Promise) must return true');
+new Promise(() => {});
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/length.js b/js/src/tests/test262/built-ins/Promise/length.js
new file mode 100644
index 0000000000..52923a039c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/length.js
@@ -0,0 +1,27 @@
+// 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.3.1
+description: Promise `length` property
+info: |
+ ES6 Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.length, 1);
+
+verifyNotEnumerable(Promise, 'length');
+verifyNotWritable(Promise, 'length');
+verifyConfigurable(Promise, 'length');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/name.js b/js/src/tests/test262/built-ins/Promise/name.js
new file mode 100644
index 0000000000..715bc448f2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/name.js
@@ -0,0 +1,28 @@
+// 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.3.1
+description: Promise `name` property
+info: |
+ ES6 Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.name, 'Promise');
+
+verifyNotEnumerable(Promise, 'name');
+verifyNotWritable(Promise, 'name');
+verifyConfigurable(Promise, 'name');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/promise.js b/js/src/tests/test262/built-ins/Promise/promise.js
new file mode 100644
index 0000000000..5c8ce7ac4c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/promise.js
@@ -0,0 +1,27 @@
+// Copyright 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise-constructor
+description: >
+ Property descriptor of Promise
+info: |
+ 25.6.3 The Promise Constructor
+
+ * is the initial value of the Promise property of the global object.
+
+ 17 ECMAScript Standard Built-in Objects
+
+ Every other data property described in clauses 18 through 26 and in Annex B.2
+ has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(this, 'Promise', {
+ value: Promise,
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/property-order.js b/js/src/tests/test262/built-ins/Promise/property-order.js
new file mode 100644
index 0000000000..7f156d9196
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/property-order.js
@@ -0,0 +1,17 @@
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createbuiltinfunction
+description: Promise constructor property order
+info: |
+ Set order: "length", "name", ...
+---*/
+
+var propNames = Object.getOwnPropertyNames(Promise);
+var lengthIndex = propNames.indexOf("length");
+var nameIndex = propNames.indexOf("name");
+
+assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1,
+ "The `length` property comes before the `name` property on built-in functions");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/proto-from-ctor-realm.js b/js/src/tests/test262/built-ins/Promise/proto-from-ctor-realm.js
new file mode 100644
index 0000000000..8cba0cff9c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/proto-from-ctor-realm.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.
+/*---
+esid: sec-promise-executor
+description: Default [[Prototype]] value derived from realm of the newTarget
+info: |
+ [...]
+ 3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget,
+ "%PromisePrototype%", « [[PromiseState]], [[PromiseResult]],
+ [[PromiseFulfillReactions]], [[PromiseRejectReactions]],
+ [[PromiseIsHandled]] »).
+ [...]
+
+ 9.1.14 GetPrototypeFromConstructor
+
+ [...]
+ 3. Let proto be ? Get(constructor, "prototype").
+ 4. If Type(proto) is not Object, then
+ a. Let realm be ? GetFunctionRealm(constructor).
+ b. Let proto be realm's intrinsic object named intrinsicDefaultProto.
+ [...]
+features: [cross-realm, Reflect]
+---*/
+
+var other = $262.createRealm().global;
+var C = new other.Function();
+C.prototype = null;
+
+var o = Reflect.construct(Promise, [function() {}], C);
+
+assert.sameValue(Object.getPrototypeOf(o), other.Promise.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/S25.4.4.2_A1.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/S25.4.4.2_A1.1_T1.js
new file mode 100644
index 0000000000..3c08a74243
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/S25.4.4.2_A1.1_T1.js
@@ -0,0 +1,18 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise prototype object exists, is object, not enumerable, writable,
+ or configurable
+es6id: S25.4.4.2_A1.1_T1
+author: Sam Mikes
+description: Promise prototype exists
+---*/
+assert.notSameValue(
+ Promise.prototype,
+ undefined,
+ 'The value of Promise.prototype is expected to not equal ``undefined``'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/S25.4.5_A3.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/S25.4.5_A3.1_T1.js
new file mode 100644
index 0000000000..5095976ce7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/S25.4.5_A3.1_T1.js
@@ -0,0 +1,17 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.prototype.constructor is the Promise constructor
+es6id: S25.4.5_A3.1_T1
+author: Sam Mikes
+description: Promise.prototype.constructor is the Promise constructor
+---*/
+assert.sameValue(
+ Promise.prototype.constructor,
+ Promise,
+ 'The value of Promise.prototype.constructor is expected to equal the value of Promise'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/Symbol.toStringTag.js b/js/src/tests/test262/built-ins/Promise/prototype/Symbol.toStringTag.js
new file mode 100644
index 0000000000..0d7d71d804
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/Symbol.toStringTag.js
@@ -0,0 +1,23 @@
+// 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.4
+description: >
+ `Symbol.toStringTag` property descriptor
+info: |
+ The initial value of the @@toStringTag property is the String value
+ "Promise".
+
+ This property has the attributes { [[Writable]]: false, [[Enumerable]]:
+ false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Symbol.toStringTag]
+---*/
+
+assert.sameValue(Promise.prototype[Symbol.toStringTag], 'Promise');
+
+verifyNotEnumerable(Promise.prototype, Symbol.toStringTag);
+verifyNotWritable(Promise.prototype, Symbol.toStringTag);
+verifyConfigurable(Promise.prototype, Symbol.toStringTag);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/browser.js b/js/src/tests/test262/built-ins/Promise/prototype/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A1.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A1.1_T1.js
new file mode 100644
index 0000000000..0f145ac2b2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A1.1_T1.js
@@ -0,0 +1,16 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise prototype.catch is a function
+es6id: S25.4.5.1_A1.1_T1
+author: Sam Mikes
+description: Promise.prototype.catch is a function
+---*/
+assert(
+ !!(Promise.prototype.catch instanceof Function),
+ 'The value of !!(Promise.prototype.catch instanceof Function) is expected to be true'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A2.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A2.1_T1.js
new file mode 100644
index 0000000000..efdf80c4a8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A2.1_T1.js
@@ -0,0 +1,19 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ catch is a method on a Promise
+es6id: S25.4.5.1_A2.1_T1
+author: Sam Mikes
+description: catch is a method on a Promise
+---*/
+
+var p = Promise.resolve(3);
+
+assert(
+ !!(p.catch instanceof Function),
+ 'The value of !!(p.catch instanceof Function) is expected to be true'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A3.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A3.1_T1.js
new file mode 100644
index 0000000000..415daf47ab
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A3.1_T1.js
@@ -0,0 +1,22 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ catch(arg) is equivalent to then(undefined, arg)
+es6id: S25.4.5.1_A3.1_T1
+author: Sam Mikes
+description: catch is implemented in terms of then
+flags: [async]
+---*/
+
+var arg = {};
+
+var p = Promise.resolve(arg);
+
+p.catch(function() {
+ throw new Test262Error("Should not be called - promise is fulfilled");
+}).then(function(result) {
+ assert.sameValue(result, arg, 'The value of result is expected to equal the value of arg');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A3.1_T2.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A3.1_T2.js
new file mode 100644
index 0000000000..df555fd774
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/S25.4.5.1_A3.1_T2.js
@@ -0,0 +1,22 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ catch(arg) is equivalent to then(undefined, arg)
+es6id: S25.4.5.1_A3.1_T2
+author: Sam Mikes
+description: catch is implemented in terms of then
+flags: [async]
+---*/
+
+var arg = {};
+
+var p = Promise.reject(arg);
+
+p.then(function() {
+ throw new Test262Error("Should not be called: did not expect promise to be fulfilled");
+}).catch(function(result) {
+ assert.sameValue(result, arg, 'The value of result is expected to equal the value of arg');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/browser.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/invokes-then.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/invokes-then.js
new file mode 100644
index 0000000000..e02959e8db
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/invokes-then.js
@@ -0,0 +1,54 @@
+// 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.1
+description: Promise.prototype.catch invokes `then` method
+info: |
+ 1. Let promise be the this value.
+ 2. Return Invoke(promise, "then", «undefined, onRejected»).
+---*/
+
+var target = {};
+var returnValue = {};
+var callCount = 0;
+var thisValue = null;
+var argCount = null;
+var firstArg = null;
+var secondArg = null;
+var result = null;
+
+target.then = function(a, b) {
+ callCount += 1;
+
+ thisValue = this;
+ argCount = arguments.length;
+ firstArg = a;
+ secondArg = b;
+
+ return returnValue;
+};
+
+result = Promise.prototype.catch.call(target, 1, 2, 3);
+
+assert.sameValue(callCount, 1, 'Invokes `then` method exactly once');
+assert.sameValue(
+ thisValue,
+ target,
+ 'Invokes `then` method with the instance as the `this` value'
+);
+assert.sameValue(
+ argCount, 2, 'Invokes `then` method with exactly two single arguments'
+);
+assert.sameValue(
+ firstArg,
+ undefined,
+ 'Invokes `then` method with `undefined` as the first argument'
+);
+assert.sameValue(
+ secondArg, 1, 'Invokes `then` method with the provided argument'
+);
+assert.sameValue(
+ result, returnValue, 'Returns the result of the invocation of `then`'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/length.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/length.js
new file mode 100644
index 0000000000..1b487e62d9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/length.js
@@ -0,0 +1,27 @@
+// 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.1
+description: Promise.prototype.catch `length` property
+info: |
+ ES6 Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.prototype.catch.length, 1);
+
+verifyNotEnumerable(Promise.prototype.catch, 'length');
+verifyNotWritable(Promise.prototype.catch, 'length');
+verifyConfigurable(Promise.prototype.catch, 'length');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/name.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/name.js
new file mode 100644
index 0000000000..25a93a3bb9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/name.js
@@ -0,0 +1,28 @@
+// 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.1
+description: Promise.prototype.catch `name` property
+info: |
+ ES6 Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.prototype.catch.name, 'catch');
+
+verifyNotEnumerable(Promise.prototype.catch, 'name');
+verifyNotWritable(Promise.prototype.catch, 'name');
+verifyConfigurable(Promise.prototype.catch, 'name');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/not-a-constructor.js
new file mode 100644
index 0000000000..2ff5558742
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/not-a-constructor.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Promise.prototype.catch does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(Promise.prototype.catch),
+ false,
+ 'isConstructor(Promise.prototype.catch) must return false'
+);
+
+assert.throws(TypeError, () => {
+ let p = new Promise(() => {}); new p.catch();
+}, '`let p = new Promise(() => {}); new p.catch()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/prop-desc.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/prop-desc.js
new file mode 100644
index 0000000000..2866aaa2d4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/prop-desc.js
@@ -0,0 +1,19 @@
+// 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.1
+description: Promise.prototype.catch property descriptor
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(typeof Promise.prototype.catch, 'function');
+
+verifyNotEnumerable(Promise.prototype, 'catch');
+verifyWritable(Promise.prototype, 'catch');
+verifyConfigurable(Promise.prototype, 'catch');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/shell.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-non-object.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-non-object.js
new file mode 100644
index 0000000000..888c8b39f5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-non-object.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.prototype.catch
+description: >
+ Promise.prototype.catch called with a non-object-coercible `this` value
+info: |
+ 1. Let promise be the this value.
+ 2. Return ? Invoke(promise, "then", «undefined, onRejected»).
+
+ 7.3.18 Invoke
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. If argumentsList was not passed, let argumentsList be a new empty List.
+ 3. Let func be ? GetV(V, P).
+ 4. Return ? Call(func, V, argumentsList).
+
+ 7.3.2 GetV
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. Let O be ? ToObject(V).
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.prototype.catch.call(undefined);
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+ Promise.prototype.catch.call(null);
+}, 'null');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-obj-coercible.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-obj-coercible.js
new file mode 100644
index 0000000000..4f71abec7a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-obj-coercible.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.
+/*---
+esid: sec-promise.prototype.catch
+description: >
+ Promise.prototype.catch called with an object-coercible `this` value
+info: |
+ 1. Let promise be the this value.
+ 2. Return ? Invoke(promise, "then", «undefined, onRejected»).
+
+ 7.3.18 Invoke
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. If argumentsList was not passed, let argumentsList be a new empty List.
+ 3. Let func be ? GetV(V, P).
+ 4. Return ? Call(func, V, argumentsList).
+
+ 7.3.2 GetV
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. Let O be ? ToObject(V).
+features: [Symbol]
+---*/
+
+var booleanCount = 0;
+Boolean.prototype.then = function() {
+ booleanCount += 1;
+};
+Promise.prototype.catch.call(true);
+assert.sameValue(booleanCount, 1, 'boolean');
+
+var numberCount = 0;
+Number.prototype.then = function() {
+ numberCount += 1;
+};
+Promise.prototype.catch.call(34);
+assert.sameValue(numberCount, 1, 'number');
+
+var stringCount = 0;
+String.prototype.then = function() {
+ stringCount += 1;
+};
+Promise.prototype.catch.call('');
+assert.sameValue(stringCount, 1, 'string');
+
+var symbolCount = 0;
+Symbol.prototype.then = function() {
+ symbolCount += 1;
+};
+Promise.prototype.catch.call(Symbol());
+assert.sameValue(symbolCount, 1, 'symbol');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-not-callable.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-not-callable.js
new file mode 100644
index 0000000000..861f78bd9a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-not-callable.js
@@ -0,0 +1,75 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.prototype.catch
+description: >
+ Promise.prototype.catch called with a `this` value that does not define a
+ callable `this` property
+info: |
+ 1. Let promise be the this value.
+ 2. Return ? Invoke(promise, "then", «undefined, onRejected»).
+
+ 7.3.18 Invoke
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. If argumentsList was not passed, let argumentsList be a new empty List.
+ 3. Let func be ? GetV(V, P).
+ 4. Return ? Call(func, V, argumentsList).
+
+ 7.3.2 GetV
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. Let O be ? ToObject(V).
+ 3. Return ? O.[[Get]](P, V).
+
+ 7.3.12 Call (F, V [ , argumentsList ])
+
+ 1. If argumentsList was not passed, let argumentsList be a new empty List.
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+ 3. Return ? F.[[Call]](V, argumentsList).
+features: [Symbol]
+---*/
+
+var symbol = Symbol();
+
+assert.throws(TypeError, function() {
+ Promise.prototype.catch.call({});
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+ Promise.prototype.catch.call({
+ then: null
+ });
+}, 'null');
+
+assert.throws(TypeError, function() {
+ Promise.prototype.catch.call({
+ then: 1
+ });
+}, 'number');
+
+assert.throws(TypeError, function() {
+ Promise.prototype.catch.call({
+ then: ''
+ });
+}, 'string');
+
+assert.throws(TypeError, function() {
+ Promise.prototype.catch.call({
+ then: true
+ });
+}, 'boolean');
+
+assert.throws(TypeError, function() {
+ Promise.prototype.catch.call({
+ then: symbol
+ });
+}, 'symbol');
+
+assert.throws(TypeError, function() {
+ Promise.prototype.catch.call({
+ then: {}
+ });
+}, 'ordinary object');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-poisoned.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-poisoned.js
new file mode 100644
index 0000000000..190776f246
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-poisoned.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.prototype.catch
+description: >
+ Promise.prototype.catch called with a `this` value whose `then` property is
+ an accessor property that returns an abrupt completion
+info: |
+ 1. Let promise be the this value.
+ 2. Return ? Invoke(promise, "then", «undefined, onRejected»).
+
+ 7.3.18 Invoke
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. If argumentsList was not passed, let argumentsList be a new empty List.
+ 3. Let func be ? GetV(V, P).
+
+ 7.3.2 GetV
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. Let O be ? ToObject(V).
+ 3. Return ? O.[[Get]](P, V).
+---*/
+
+var poisonedThen = Object.defineProperty({}, 'then', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ Promise.prototype.catch.call(poisonedThen);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-throws.js b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-throws.js
new file mode 100644
index 0000000000..39cd7cf5de
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/catch/this-value-then-throws.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.
+/*---
+esid: sec-promise.prototype.catch
+description: >
+ Promise.prototype.catch called with a `this` value that defines a `then`
+ method which returns an abrupt completion.
+info: |
+ 1. Let promise be the this value.
+ 2. Return ? Invoke(promise, "then", «undefined, onRejected»).
+
+ 7.3.18 Invoke
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. If argumentsList was not passed, let argumentsList be a new empty List.
+ 3. Let func be ? GetV(V, P).
+ 4. Return ? Call(func, V, argumentsList).
+
+ 7.3.2 GetV
+
+ 1. Assert: IsPropertyKey(P) is true.
+ 2. Let O be ? ToObject(V).
+ 3. Return ? O.[[Get]](P, V).
+
+ 7.3.12 Call (F, V [ , argumentsList ])
+
+ 1. If argumentsList was not passed, let argumentsList be a new empty List.
+ 2. If IsCallable(F) is false, throw a TypeError exception.
+ 3. Return ? F.[[Call]](V, argumentsList).
+---*/
+
+var thrower = {
+ then: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ Promise.prototype.catch.call(thrower);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/browser.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-function.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-function.js
new file mode 100644
index 0000000000..c4597f9cb8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-function.js
@@ -0,0 +1,69 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise.prototype.finally invokes `then` method
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally, Reflect.construct, arrow-function]
+includes: [isConstructor.js]
+---*/
+
+var target = new Promise(function() {});
+var returnValue = {};
+var callCount = 0;
+var thisValue = null;
+var argCount = null;
+var resolve = null;
+var reject = null;
+
+target.then = function(a, b) {
+ callCount += 1;
+
+ thisValue = this;
+ argCount = arguments.length;
+ resolve = a;
+ reject = b;
+
+ return returnValue;
+};
+
+var originalFinallyHandler = function() {};
+var result = Promise.prototype.finally.call(target, originalFinallyHandler, 2, 3);
+
+assert.sameValue(callCount, 1, 'The value of `callCount` is 1');
+assert.sameValue(
+ thisValue,
+ target,
+ 'The value of `thisValue` is expected to equal the value of target'
+);
+assert.sameValue(argCount, 2, 'The value of `argCount` is 2');
+assert.sameValue(
+ typeof resolve,
+ 'function',
+ 'The value of `typeof resolve` is "function"'
+);
+assert.notSameValue(resolve, originalFinallyHandler, 'The value of `resolve` is expected to not equal the value of `originalFinallyHandler`');
+assert.sameValue(resolve.length, 1, 'The value of resolve.length is 1');
+assert.sameValue(resolve.name, '', 'The value of resolve.name is ""');
+assert.sameValue(isConstructor(resolve), false, 'isConstructor(resolve) must return false');
+assert.throws(TypeError, () => {
+ new resolve();
+}, '`new resolve()` throws TypeError');
+
+
+assert.sameValue(
+ typeof reject,
+ 'function',
+ 'The value of `typeof reject` is "function"'
+);
+assert.notSameValue(reject, originalFinallyHandler, 'The value of `reject` is expected to not equal the value of `originalFinallyHandler`');
+assert.sameValue(reject.length, 1, 'The value of reject.length is 1');
+assert.sameValue(reject.name, '', 'The value of reject.name is ""');
+assert.sameValue(isConstructor(reject), false, 'isConstructor(reject) must return false');
+assert.throws(TypeError, () => {
+ new reject();
+}, '`new reject()` throws TypeError');
+
+assert.sameValue(result, returnValue, 'The value of `result` is expected to equal the value of returnValue');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-non-function.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-non-function.js
new file mode 100644
index 0000000000..ca7b36445c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-non-function.js
@@ -0,0 +1,51 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise.prototype.finally invokes `then` method
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+var target = new Promise(function() {});
+var returnValue = {};
+var callCount = 0;
+var thisValue = null;
+var argCount = null;
+var firstArg = null;
+var secondArg = null;
+var result = null;
+
+target.then = function(a, b) {
+ callCount += 1;
+
+ thisValue = this;
+ argCount = arguments.length;
+ firstArg = a;
+ secondArg = b;
+
+ return returnValue;
+};
+
+result = Promise.prototype.finally.call(target, 1, 2, 3);
+
+assert.sameValue(callCount, 1, 'Invokes `then` method exactly once');
+assert.sameValue(
+ thisValue,
+ target,
+ 'Invokes `then` method with the instance as the `this` value'
+);
+assert.sameValue(argCount, 2, 'Invokes `then` method with exactly two single arguments');
+assert.sameValue(
+ firstArg,
+ 1,
+ 'Invokes `then` method with the provided non-callable first argument'
+);
+assert.sameValue(
+ secondArg,
+ 1,
+ 'Invokes `then` method with the provided non-callable first argument'
+);
+assert.sameValue(result, returnValue, 'Returns the result of the invocation of `then`');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-function.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-function.js
new file mode 100644
index 0000000000..19abfde2fa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-function.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise.prototype.finally is a function
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+assert.sameValue(
+ Promise.prototype.finally instanceof Function,
+ true,
+ 'Expected Promise.prototype.finally to be instanceof Function'
+);
+
+assert.sameValue(
+ typeof Promise.prototype.finally,
+ 'function',
+ 'Expected Promise.prototype.finally to be a function'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-method.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-method.js
new file mode 100644
index 0000000000..741b127248
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/is-a-method.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally is a method on a Promise
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+var p = Promise.resolve(3);
+
+assert.sameValue(
+ p.finally,
+ Promise.prototype.finally,
+ 'Expected the `finally` method on a Promise to be `Promise.prototype.finally`'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/length.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/length.js
new file mode 100644
index 0000000000..1146a91f1d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/length.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise.prototype.finally `length` property
+esid: sec-promise.prototype.finally
+info: |
+ ES6 Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Promise.prototype.finally]
+---*/
+
+verifyProperty(Promise.prototype.finally, "length", {
+ value: 1,
+ enumerable: false,
+ configurable: true,
+ writable: false,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/name.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/name.js
new file mode 100644
index 0000000000..82020c1381
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/name.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise.prototype.finally `name` property
+esid: sec-promise.prototype.finally
+info: |
+ ES Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Promise.prototype.finally]
+---*/
+
+assert.sameValue(Promise.prototype.finally.name, 'finally');
+
+verifyNotEnumerable(Promise.prototype.finally, 'name');
+verifyNotWritable(Promise.prototype.finally, 'name');
+verifyConfigurable(Promise.prototype.finally, 'name');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/not-a-constructor.js
new file mode 100644
index 0000000000..25bb9a6554
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/not-a-constructor.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Promise.prototype.finally does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, Promise.prototype.finally, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(Promise.prototype.finally),
+ false,
+ 'isConstructor(Promise.prototype.finally) must return false'
+);
+
+assert.throws(TypeError, () => {
+ let p = new Promise(() => {}); new p.finally();
+}, '`let p = new Promise(() => {}); new p.finally()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/prop-desc.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/prop-desc.js
new file mode 100644
index 0000000000..47d2f64fdd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/prop-desc.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise.prototype.finally property descriptor
+esid: sec-promise.prototype.finally
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [Promise.prototype.finally]
+---*/
+
+assert.sameValue(typeof Promise.prototype.finally, 'function');
+
+verifyNotEnumerable(Promise.prototype, 'finally');
+verifyWritable(Promise.prototype, 'finally');
+verifyConfigurable(Promise.prototype, 'finally');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls-PromiseResolve.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls-PromiseResolve.js
new file mode 100644
index 0000000000..ecdbbdd164
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls-PromiseResolve.js
@@ -0,0 +1,57 @@
+// |reftest| async
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-catchfinallyfunctions
+description: >
+ PromiseResolve() avoids extra Promise capability creation.
+info: |
+ Catch Finally Functions
+
+ [...]
+ 7. Let promise be ? PromiseResolve(C, result).
+ 8. Let thrower be equivalent to a function that throws reason.
+ 9. Return ? Invoke(promise, "then", « thrower »).
+
+ PromiseResolve ( C, x )
+
+ 1. Assert: Type(C) is Object.
+ 2. If IsPromise(x) is true, then
+ a. Let xConstructor be ? Get(x, "constructor").
+ b. If SameValue(xConstructor, C) is true, return x.
+features: [Promise.prototype.finally]
+flags: [async]
+---*/
+
+class MyPromise extends Promise {}
+
+var mp1Value = {};
+var mp1 = MyPromise.reject(mp1Value);
+var mp2 = MyPromise.reject(42);
+
+var thenCalls = [];
+var then = Promise.prototype.then;
+Promise.prototype.then = function(resolve, reject) {
+ thenCalls.push({promise: this, resolve, reject});
+ return then.call(this, resolve, reject);
+};
+
+mp1.finally(() => mp2).then(value => {
+ throw new Test262Error("Expected the promise to be rejected, got resolved with " + value);
+}, () => {
+ assert.sameValue(thenCalls.length, 5);
+
+ var mp2Calls = thenCalls.filter(c => c.promise === mp2);
+ assert.sameValue(mp2Calls.length, 1);
+ assert.sameValue(mp2Calls[0].reject, undefined);
+
+ var thrown = false;
+ try {
+ mp2Calls[0].resolve();
+ } catch (error) {
+ thrown = true;
+ assert.sameValue(error, mp1Value);
+ }
+
+ assert(thrown, "Expected resolve() to throw, but it didn't");
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls-argument.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls-argument.js
new file mode 100644
index 0000000000..4d183bf248
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls-argument.js
@@ -0,0 +1,69 @@
+// |reftest| async
+// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-catchfinallyfunctions
+description: >
+ thrower is anonymous built-in function with length of 1 that throws reason.
+info: |
+ Catch Finally Functions
+
+ ...
+ 8. Let thrower be equivalent to a function that throws reason.
+ 9. Return ? Invoke(promise, "then", « thrower »).
+
+ The "length" property of a Catch Finally function is 1.
+features: [Promise.prototype.finally, Reflect.construct, class, arrow-function]
+includes: [isConstructor.js]
+flags: [async]
+---*/
+
+class MyError extends Error {}
+
+var myError = new MyError();
+Promise.reject(myError)
+ .finally(function() {})
+ .then(function(value) {
+ $DONE('Expected promise to be rejected, got fulfilled with ' + value);
+ }, function(reason) {
+ if (reason === myError) {
+ $DONE();
+ } else {
+ $DONE(reason);
+ }
+ });
+
+var calls = 0;
+var expected = [
+ { length: 0, name: '' },
+ { length: 1, name: '' }
+];
+
+var then = Promise.prototype.then;
+Promise.prototype.then = function(resolve, reject) {
+
+ assert.sameValue(
+ resolve.length,
+ expected[calls].length,
+ 'The value of resolve.length is expected to equal the value of expected[calls].length'
+ );
+ assert.sameValue(
+ resolve.name,
+ expected[calls].name,
+ 'The value of resolve.name is expected to equal the value of expected[calls].name'
+ );
+ if (calls === 0) {
+ assert.throws(MyError, resolve, '`resolve()` throws `MyError`');
+ assert.sameValue(arguments.length, 1, '`then` invoked with one argument');
+ } else {
+ assert.sameValue(isConstructor(reject), false, 'isConstructor(reject) must return false');
+ assert.throws(TypeError, () => {
+ new reject();
+ }, '`new reject()` throws TypeError');
+ assert.sameValue(arguments.length, 2, '`then` invoked with two arguments');
+ }
+
+ calls += 1;
+
+ return then.call(this, resolve, reject);
+};
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls.js
new file mode 100644
index 0000000000..2d4dd9caaf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally observably calls .then
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+includes: [promiseHelper.js]
+---*/
+var sequence = [];
+var noReason = {};
+var no = Promise.reject(noReason);
+no.then = function() {
+ sequence.push(1);
+ return Promise.prototype.then.apply(this, arguments);
+};
+
+var yesValue = {};
+var yes = Promise.resolve(yesValue);
+yes.then = function() {
+ sequence.push(4);
+ return Promise.prototype.then.apply(this, arguments);
+};
+
+no.catch(function(e) {
+ sequence.push(2);
+ assert.sameValue(e, noReason);
+ throw e;
+}).finally(function() {
+ sequence.push(3);
+ return yes;
+}).catch(function(e) {
+ sequence.push(5);
+ assert.sameValue(e, noReason);
+}).then(function() {
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, "All expected callbacks called in correct order");
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-no-fulfill.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-no-fulfill.js
new file mode 100644
index 0000000000..3903e7778b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-no-fulfill.js
@@ -0,0 +1,30 @@
+// |reftest| async
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally on a rejected promise can not convert to a fulfillment
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+includes: [promiseHelper.js]
+---*/
+var sequence = [];
+var original = {};
+var replacement = {};
+
+var p = Promise.reject(original);
+
+p.finally(function() {
+ sequence.push(1);
+ assert.sameValue(arguments.length, 0, 'onFinally receives zero args');
+ return replacement;
+}).then(function() {
+ throw new Test262Error('promise is rejected pre-finally; onFulfill should not be called');
+}).catch(function(reason) {
+ sequence.push(2);
+ assert.sameValue(reason, original, 'onFinally can not override the rejection value by returning');
+}).then(function() {
+ assert.sameValue(sequence.length, 2);
+ checkSequence(sequence, "All expected callbacks called in correct order");
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-override-with-throw.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-override-with-throw.js
new file mode 100644
index 0000000000..66b6a468b3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/rejection-reason-override-with-throw.js
@@ -0,0 +1,30 @@
+// |reftest| async
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally on a rejected promise can override the rejection reason
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+includes: [promiseHelper.js]
+---*/
+var sequence = [];
+var original = {};
+var thrown = {};
+
+var p = Promise.reject(original);
+
+p.finally(function() {
+ sequence.push(1);
+ assert.sameValue(arguments.length, 0, 'onFinally receives zero args');
+ throw thrown;
+}).then(function() {
+ throw new Test262Error('promise is rejected; onFulfill should not be called');
+}).catch(function(reason) {
+ sequence.push(2);
+ assert.sameValue(reason, thrown, 'onFinally can override the rejection reason by throwing');
+}).then(function() {
+ assert.sameValue(sequence.length, 2);
+ checkSequence(sequence, "All expected callbacks called in correct order");
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/resolution-value-no-override.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolution-value-no-override.js
new file mode 100644
index 0000000000..4951119385
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolution-value-no-override.js
@@ -0,0 +1,26 @@
+// |reftest| async
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally on a fulfilled promise can not override the resolution value
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+includes: [promiseHelper.js]
+---*/
+var sequence = [];
+var obj = {};
+var p = Promise.resolve(obj);
+
+p.finally(function() {
+ sequence.push(1);
+ assert.sameValue(arguments.length, 0, 'onFinally receives zero args');
+ return {};
+}).then(function(x) {
+ sequence.push(2);
+ assert.sameValue(x, obj, 'onFinally can not override the resolution value');
+}).then(function() {
+ assert.sameValue(sequence.length, 2);
+ checkSequence(sequence, "All expected callbacks called in correct order");
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls-PromiseResolve.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls-PromiseResolve.js
new file mode 100644
index 0000000000..137448ae6f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls-PromiseResolve.js
@@ -0,0 +1,46 @@
+// |reftest| async
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-thenfinallyfunctions
+description: >
+ PromiseResolve() avoids extra Promise capability creation.
+info: |
+ Then Finally Functions
+
+ [...]
+ 7. Let promise be ? PromiseResolve(C, result).
+ 8. Let valueThunk be equivalent to a function that returns value.
+ 9. Return ? Invoke(promise, "then", « valueThunk »).
+
+ PromiseResolve ( C, x )
+
+ 1. Assert: Type(C) is Object.
+ 2. If IsPromise(x) is true, then
+ a. Let xConstructor be ? Get(x, "constructor").
+ b. If SameValue(xConstructor, C) is true, return x.
+features: [Promise.prototype.finally]
+flags: [async]
+---*/
+
+class MyPromise extends Promise {}
+
+var mp1Value = {};
+var mp1 = MyPromise.resolve(mp1Value);
+var mp2 = MyPromise.resolve(42);
+
+var thenCalls = [];
+var then = Promise.prototype.then;
+Promise.prototype.then = function(resolve, reject) {
+ thenCalls.push({promise: this, resolve, reject});
+ return then.call(this, resolve, reject);
+};
+
+mp1.finally(() => mp2).then(() => {
+ assert.sameValue(thenCalls.length, 5);
+
+ var mp2Calls = thenCalls.filter(c => c.promise === mp2);
+ assert.sameValue(mp2Calls.length, 1);
+ assert.sameValue(mp2Calls[0].reject, undefined);
+ assert.sameValue(mp2Calls[0].resolve(), mp1Value);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls-argument.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls-argument.js
new file mode 100644
index 0000000000..ab7eedb192
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls-argument.js
@@ -0,0 +1,55 @@
+// |reftest| async
+// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-thenfinallyfunctions
+description: >
+ valueThunk is anonymous built-in function with length of 1 that returns value.
+info: |
+ Then Finally Functions
+
+ ...
+ 8. Let valueThunk be equivalent to a function that returns value.
+ 9. Return ? Invoke(promise, "then", « valueThunk »).
+
+ The "length" property of a Then Finally function is 1.
+features: [Promise.prototype.finally, Reflect.construct, arrow-function]
+includes: [isConstructor.js]
+flags: [async]
+---*/
+
+var value = {};
+
+Promise.resolve(value)
+ .finally(function() {})
+ .then(() => $DONE(), $DONE);
+
+var calls = 0;
+var expected = [
+ { length: 0, name: '' },
+ { length: 1, name: '' }
+];
+
+var then = Promise.prototype.then;
+Promise.prototype.then = function(resolve) {
+ assert.sameValue(isConstructor(resolve), false, 'isConstructor(resolve) must return false');
+ assert.throws(TypeError, () => {
+ new resolve();
+ }, '`new resolve()` throws TypeError');
+
+ assert.sameValue(
+ resolve.length,
+ expected[calls].length,
+ 'The value of resolve.length is expected to equal the value of expected[calls].length'
+ );
+ assert.sameValue(
+ resolve.name,
+ expected[calls].name,
+ 'The value of resolve.name is expected to equal the value of expected[calls].name'
+ );
+ if (calls === 0) {
+ assert.sameValue(resolve(), value, 'resolve() must return the value of value');
+ }
+ calls += 1;
+ return then.call(this, resolve);
+};
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls.js
new file mode 100644
index 0000000000..4f2341bfb0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally observably calls .then
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+includes: [promiseHelper.js]
+---*/
+var sequence = [];
+var yesValue = {};
+var yes = Promise.resolve(yesValue);
+yes.then = function() {
+ sequence.push(1);
+ return Promise.prototype.then.apply(this, arguments);
+};
+
+var noReason = {};
+var no = Promise.reject(noReason);
+no.then = function() {
+ sequence.push(4);
+ return Promise.prototype.then.apply(this, arguments);
+};
+
+yes.then(function(x) {
+ sequence.push(2);
+ assert.sameValue(x, yesValue);
+ return x;
+}).finally(function() {
+ sequence.push(3);
+ return no;
+}).catch(function(e) {
+ sequence.push(5);
+ assert.sameValue(e, noReason);
+}).then(function() {
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, "All expected callbacks called in correct order");
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/shell.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/species-constructor.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/species-constructor.js
new file mode 100644
index 0000000000..00c1127836
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/species-constructor.js
@@ -0,0 +1,25 @@
+// |reftest| async
+// Copyright (C) 2017 V8. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Sathya Gunasekaran
+description: finally calls the SpeciesConstructor and creates the right amount of promises
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+---*/
+
+
+var count = 0;
+class FooPromise extends Promise {
+ constructor(resolve, reject) {
+ count++;
+ return super(resolve, reject);
+ }
+}
+
+new FooPromise(r => r())
+ .finally(() => {})
+ .then(() => {
+ assert.sameValue(count, 7, "7 new promises were created");
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-reject-count.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-reject-count.js
new file mode 100644
index 0000000000..6bf6504a22
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-reject-count.js
@@ -0,0 +1,24 @@
+// |reftest| async
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise subclass finally on rejected creates the proper number of subclassed promises
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+---*/
+
+var count = 0;
+class FooPromise extends Promise {
+ constructor(resolve, reject) {
+ count++;
+ return super(resolve, reject);
+ }
+}
+
+FooPromise.reject().finally(() => {}).then(value => {
+ throw new Test262Error("Expected Promise to be rejected, got: resolved with " + value);
+}, () => {
+ assert.sameValue(count, 7);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-resolve-count.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-resolve-count.js
new file mode 100644
index 0000000000..6af753fa66
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-resolve-count.js
@@ -0,0 +1,22 @@
+// |reftest| async
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise subclass finally on resolved creates the proper number of subclassed promises
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+---*/
+
+var count = 0;
+class FooPromise extends Promise {
+ constructor(resolve, reject) {
+ count++;
+ return super(resolve, reject);
+ }
+}
+
+FooPromise.resolve().finally(() => {}).then(() => {
+ assert.sameValue(count, 7);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-reject-count.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-reject-count.js
new file mode 100644
index 0000000000..9e9995fc91
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-reject-count.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally on rejected Promise calls the SpeciesConstructor
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+class FooPromise extends Promise {
+ static get[Symbol.species]() {
+ return Promise;
+ }
+}
+
+var p = Promise.reject().finally(() => FooPromise.reject());
+
+assert.sameValue(p instanceof Promise, true);
+assert.sameValue(p instanceof FooPromise, false);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-resolve-count.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-resolve-count.js
new file mode 100644
index 0000000000..e5049b7349
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-resolve-count.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally on resolved Promise calls the SpeciesConstructor
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+class FooPromise extends Promise {
+ static get[Symbol.species]() {
+ return Promise;
+ }
+}
+
+var p = Promise.resolve().finally(() => FooPromise.resolve());
+
+assert.sameValue(p instanceof Promise, true);
+assert.sameValue(p instanceof FooPromise, false);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-non-object.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-non-object.js
new file mode 100644
index 0000000000..8c9ec2e7bd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-non-object.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: >
+ Promise.prototype.finally called with a non-object-coercible `this` value
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+assert.sameValue(typeof Promise.prototype.finally, 'function');
+
+assert.throws(TypeError, function() {
+ Promise.prototype.finally.call(undefined);
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+ Promise.prototype.finally.call(null);
+}, 'null');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-proxy.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-proxy.js
new file mode 100644
index 0000000000..15ca9b1d7c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-proxy.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: >
+ Promise.prototype.finally called with a non-branded Promise does not throw
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+var called = false;
+var p = new Proxy(Promise.resolve(), {});
+var oldThen = Promise.prototype.then;
+Promise.prototype.then = () => {
+ called = true;
+};
+Promise.prototype.finally.call(p);
+assert.sameValue(called, true);
+Promise.prototype.then = oldThen;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-not-callable.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-not-callable.js
new file mode 100644
index 0000000000..ad5c687d6b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-not-callable.js
@@ -0,0 +1,56 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: >
+ Promise.prototype.finally called with a `this` value that does not define a
+ callable `then` property
+esid: sec-promise.prototype.finally
+features: [Symbol, Promise.prototype.finally]
+---*/
+assert.sameValue(typeof Promise.prototype.finally, 'function');
+
+var symbol = Symbol();
+
+var thrower = function() {
+ throw new Test262Error('this should never happen');
+};
+
+var p = new Promise(function() {});
+
+p.then = undefined;
+assert.throws(TypeError, function() {
+ Promise.prototype.finally.call(p, thrower);
+}, 'undefined');
+
+p.then = null;
+assert.throws(TypeError, function() {
+ Promise.prototype.finally.call(p, thrower);
+}, 'null');
+
+p.then = 1;
+assert.throws(TypeError, function() {
+ Promise.prototype.finally.call(p, thrower);
+}, 'number');
+
+p.then = '';
+assert.throws(TypeError, function() {
+ Promise.prototype.finally.call(p, thrower);
+}, 'string');
+
+p.then = true;
+assert.throws(TypeError, function() {
+ Promise.prototype.finally.call(p, thrower);
+}, 'boolean');
+
+p.then = symbol;
+assert.throws(TypeError, function() {
+ Promise.prototype.finally.call(p, thrower);
+}, 'symbol');
+
+p.then = {};
+assert.throws(TypeError, function() {
+ Promise.prototype.finally.call(p, thrower);
+}, 'ordinary object');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-poisoned.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-poisoned.js
new file mode 100644
index 0000000000..44e4173989
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-poisoned.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: >
+ Promise.prototype.finally called with a `this` value whose `then` property is
+ an accessor property that returns an abrupt completion
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+var poisonedThen = Object.defineProperty(new Promise(function() {}), 'then', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ Promise.prototype.finally.call(poisonedThen);
+});
+
+assert.throws(Test262Error, function() {
+ poisonedThen.finally();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-throws.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-throws.js
new file mode 100644
index 0000000000..536ed24171
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-then-throws.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2017 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: >
+ Promise.prototype.finally called with a `this` value that defines a `then`
+ method which returns an abrupt completion.
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+var thrower = new Promise(function() {});
+thrower.then = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ Promise.prototype.finally.call(thrower);
+});
+
+assert.throws(Test262Error, function() {
+ thrower.finally();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-thenable.js b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-thenable.js
new file mode 100644
index 0000000000..dccb5be50c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-thenable.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.prototype.finally
+description: >
+ Promise.prototype.finally invoked on thenable returns result of "then" call.
+features: [Promise.prototype.finally]
+---*/
+
+var thenResult = {};
+var Thenable = function() {};
+Thenable.prototype.then = function() { return thenResult; };
+
+assert.sameValue(
+ Promise.prototype.finally.call(new Thenable()),
+ thenResult
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/no-promise-state.js b/js/src/tests/test262/built-ins/Promise/prototype/no-promise-state.js
new file mode 100644
index 0000000000..096249ac1d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/no-promise-state.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-properties-of-the-promise-prototype-object
+description: Promise.prototype does not have a [[PromiseState]] internal slot
+info: |
+ The Promise prototype object is the intrinsic object %PromisePrototype%. The
+ value of the [[Prototype]] internal slot of the Promise prototype object is
+ the intrinsic object %ObjectPrototype%. The Promise prototype object is an
+ ordinary object. It does not have a [[PromiseState]] internal slot or any of
+ the other internal slots of Promise instances.
+
+ 25.4.5.3 Promise.prototype.then
+
+ 1. Let promise be the this value.
+ 2. If IsPromise(promise) is false, throw a TypeError exception.
+
+ 25.4.1.6 IsPromise
+
+ 1. If Type(x) is not Object, return false.
+ 2. If x does not have a [[PromiseState]] internal slot, return false.
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.prototype.then.call(Promise.prototype, function() {}, function() {});
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/prop-desc.js b/js/src/tests/test262/built-ins/Promise/prototype/prop-desc.js
new file mode 100644
index 0000000000..b369a731ad
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/prop-desc.js
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise.prototype
+description: Property descriptor of 'prototype' property
+info: |
+ This property has the attributes { [[Writable]]: false, [[Enumerable]]:
+ false, [[Configurable]]: false }.
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(Promise, 'prototype');
+verifyNotWritable(Promise, 'prototype');
+verifyNotConfigurable(Promise, 'prototype');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/proto.js b/js/src/tests/test262/built-ins/Promise/prototype/proto.js
new file mode 100644
index 0000000000..d0fb702c39
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/proto.js
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-properties-of-the-promise-prototype-object
+description: Promise.prototype [[Prototype]] is %ObjectPrototype%
+info: |
+ The Promise prototype object is the intrinsic object %PromisePrototype%. The
+ value of the [[Prototype]] internal slot of the Promise prototype object is
+ the intrinsic object %ObjectPrototype%. The Promise prototype object is an
+ ordinary object. It does not have a [[PromiseState]] internal slot or any of
+ the other internal slots of Promise instances.
+---*/
+
+assert.sameValue(Object.getPrototypeOf(Promise.prototype), Object.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/shell.js b/js/src/tests/test262/built-ins/Promise/prototype/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A1.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A1.1_T1.js
new file mode 100644
index 0000000000..30133bb896
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A1.1_T1.js
@@ -0,0 +1,42 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Misc sequencing tests
+ inspired by https://github.com/getify/native-promise-only/issues/34#issuecomment-54282002
+es6id: S25.4.2.1_A3.2_T2
+author: Sam Mikes
+description: Promise onResolved functions are called in predictable sequence
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var p = new Promise(function(resolve, reject) {
+ sequence.push(1);
+ resolve("");
+});
+
+p.then(function() {
+ sequence.push(3);
+}).then(function() {
+ sequence.push(5);
+}).then(function() {
+ sequence.push(7);
+});
+
+p.then(function() {
+ sequence.push(4);
+}).then(function() {
+ sequence.push(6);
+}).then(function() {
+ sequence.push(8);
+}).then(function() {
+ assert.sameValue(sequence.length, 8);
+ checkSequence(sequence, "Sequence should be as expected");
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T1.js
new file mode 100644
index 0000000000..2b504506bb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T1.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Misc sequencing tests
+ inspired by https://github.com/promises-aplus/promises-tests/issues/61
+ Case "T1"
+es6id: S25.4.4_A2.1_T1
+author: Sam Mikes
+description: Promise onResolved functions are called in predictable sequence
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var resolveP1, rejectP2, sequence = [];
+
+(new Promise(function(resolve, reject) {
+ resolveP1 = resolve;
+})).then(function(msg) {
+ sequence.push(msg);
+}).then(function() {
+ assert.sameValue(sequence.length, 3);
+checkSequence(sequence, "Expected 1,2,3");
+}).then($DONE, $DONE);
+
+(new Promise(function(resolve, reject) {
+ rejectP2 = reject;
+})).catch(function(msg) {
+ sequence.push(msg);
+});
+
+rejectP2(2);
+resolveP1(3);
+
+sequence.push(1);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T2.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T2.js
new file mode 100644
index 0000000000..c689e07f99
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T2.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Misc sequencing tests
+ inspired by https://github.com/promises-aplus/promises-tests/issues/61
+ Case "T2a"
+es6id: S25.4.4_A2.1_T2
+author: Sam Mikes
+description: Promise onResolved functions are called in predictable sequence
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var resolveP1, rejectP2, p1, p2,
+ sequence = [];
+
+p1 = new Promise(function(resolve, reject) {
+ resolveP1 = resolve;
+});
+p2 = new Promise(function(resolve, reject) {
+ rejectP2 = reject;
+});
+
+rejectP2(3);
+resolveP1(2);
+
+p1.then(function(msg) {
+ sequence.push(msg);
+});
+
+p2.catch(function(msg) {
+ sequence.push(msg);
+}).then(function() {
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, "Expected 1,2,3");
+}).then($DONE, $DONE);
+
+sequence.push(1);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T3.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T3.js
new file mode 100644
index 0000000000..dc1f0d7233
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.4_A2.1_T3.js
@@ -0,0 +1,43 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Misc sequencing tests
+ inspired by https://github.com/promises-aplus/promises-tests/issues/61
+ Case "T2b"
+es6id: S25.4.4_A2.1_T3
+author: Sam Mikes
+description: Promise onResolved functions are called in predictable sequence
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var resolveP1, rejectP2, p1, p2,
+ sequence = [];
+
+p1 = new Promise(function(resolve, reject) {
+ resolveP1 = resolve;
+});
+p2 = new Promise(function(resolve, reject) {
+ rejectP2 = reject;
+});
+
+rejectP2(3);
+resolveP1(2);
+
+Promise.resolve().then(function() {
+ p1.then(function(msg) {
+ sequence.push(msg);
+ });
+
+ p2.catch(function(msg) {
+ sequence.push(msg);
+ }).then(function() {
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, "Expected 1,2,3");
+ }).then($DONE, $DONE);
+});
+
+sequence.push(1);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A1.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A1.1_T1.js
new file mode 100644
index 0000000000..959bc284dc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A1.1_T1.js
@@ -0,0 +1,16 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.prototype.then is a function of two arguments
+es6id: S25.4.5.3_A1.1_T1
+author: Sam Mikes
+description: Promise.prototype.then is a function of two arguments
+---*/
+assert(
+ !!(Promise.prototype.then instanceof Function),
+ 'The value of !!(Promise.prototype.then instanceof Function) is expected to be true'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A1.1_T2.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A1.1_T2.js
new file mode 100644
index 0000000000..c89023e083
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A1.1_T2.js
@@ -0,0 +1,17 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.prototype.then is a function of two arguments
+es6id: S25.4.5.3_A1.1_T2
+author: Sam Mikes
+description: Promise.prototype.then is a function of two arguments
+---*/
+
+var p = new Promise(function() {});
+
+assert(!!(p.then instanceof Function), 'The value of !!(p.then instanceof Function) is expected to be true');
+assert.sameValue(p.then.length, 2, 'The value of p.then.length is expected to be 2');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A2.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A2.1_T1.js
new file mode 100644
index 0000000000..a4e20bae96
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A2.1_T1.js
@@ -0,0 +1,18 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.prototype.then expects a constructor conforming to Promise as 'this'
+es6id: S25.4.5.3_A2.1_T1
+author: Sam Mikes
+description: Promise.prototype.then throw if 'this' is non-Object
+---*/
+
+var p = new Promise(function() {});
+
+assert.throws(TypeError, function() {
+ p.then.call(3, function() {}, function() {});
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A2.1_T2.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A2.1_T2.js
new file mode 100644
index 0000000000..4a982b5675
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A2.1_T2.js
@@ -0,0 +1,20 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.prototype.then expects a Promise as 'this'
+es6id: S25.4.5.3_A2.1_T2
+author: Sam Mikes
+description: Promise.prototype.then throw if 'this' is non-Promise Object
+---*/
+
+function ZeroArgConstructor() {}
+
+var z = new ZeroArgConstructor();
+
+assert.throws(TypeError, function() {
+ Promise.then.call(z, function() {}, function() {});
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.1_T1.js
new file mode 100644
index 0000000000..8fc66ab964
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.1_T1.js
@@ -0,0 +1,21 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ PerformPromiseThen
+ Ref 25.4.5.3.1
+es6id: S25.4.5.3_A4.1_T1
+author: Sam Mikes
+description: Promise.prototype.then accepts 'undefined' as arg1, arg2
+flags: [async]
+---*/
+
+var arg = {};
+var p = Promise.resolve(arg);
+
+p.then(undefined, undefined)
+ .then(function(result) {
+ assert.sameValue(result, arg, 'The value of result is expected to equal the value of arg');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.1_T2.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.1_T2.js
new file mode 100644
index 0000000000..3aeca23d95
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.1_T2.js
@@ -0,0 +1,22 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ PerformPromiseThen
+ Ref 25.4.5.3.1
+es6id: S25.4.5.3_A4.1_T2
+author: Sam Mikes
+description: Promise.prototype.then accepts 'undefined' as arg1, arg2
+flags: [async]
+---*/
+
+var arg = {};
+var p = Promise.reject(arg);
+
+p.then(undefined, undefined).then(function() {
+ throw new Test262Error("Should not be called -- promise was rejected.");
+}, function(result) {
+ assert.sameValue(result, arg, 'The value of result is expected to equal the value of arg');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.2_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.2_T1.js
new file mode 100644
index 0000000000..5b1ac21b27
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.2_T1.js
@@ -0,0 +1,21 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ PerformPromiseThen
+ Ref 25.4.5.3.1
+es6id: S25.4.5.3_A4.2_T1
+author: Sam Mikes
+description: Promise.prototype.then treats non-callable arg1, arg2 as undefined
+flags: [async]
+---*/
+
+var arg = {};
+var p = Promise.resolve(arg);
+
+p.then(3, 5)
+ .then(function(result) {
+ assert.sameValue(result, arg, 'The value of result is expected to equal the value of arg');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.2_T2.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.2_T2.js
new file mode 100644
index 0000000000..5efe836020
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A4.2_T2.js
@@ -0,0 +1,22 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ PerformPromiseThen
+ Ref 25.4.5.3.1
+es6id: S25.4.5.3_A4.2_T2
+author: Sam Mikes
+description: Promise.prototype.then treats non-callable arg1, arg2 as undefined
+flags: [async]
+---*/
+
+var arg = {};
+var p = Promise.reject(arg);
+
+p.then(3, 5).then(function() {
+ throw new Test262Error("Should not be called -- promise was rejected.");
+}, function(result) {
+ assert.sameValue(result, arg, 'The value of result is expected to equal the value of arg');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.1_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.1_T1.js
new file mode 100644
index 0000000000..2f0b062fae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.1_T1.js
@@ -0,0 +1,43 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ PerformPromiseThen
+ Ref 25.4.5.3.1
+es6id: S25.4.5.3_A5.1_T1
+author: Sam Mikes
+description: Promise.prototype.then enqueues handler if pending
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [],
+ pResolve,
+ p = new Promise(function(resolve, reject) {
+ pResolve = resolve;
+ });
+
+sequence.push(1);
+
+p.then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, "Should be second");
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ // enqueue another then-handler
+ p.then(function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, "Should be third");
+ }).then($DONE, $DONE);
+
+ sequence.push(2);
+ assert.sameValue(sequence.length, 2);
+ checkSequence(sequence, "Should be first");
+
+ pResolve();
+}).catch($DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.2_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.2_T1.js
new file mode 100644
index 0000000000..6e09de73a1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.2_T1.js
@@ -0,0 +1,45 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ PerformPromiseThen
+ Ref 25.4.5.3.1
+es6id: S25.4.5.3_A5.2_T1
+author: Sam Mikes
+description: Promise.prototype.then immediately queues handler if fulfilled
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [],
+ pResolve,
+ p = new Promise(function(resolve, reject) {
+ pResolve = resolve;
+ });
+
+sequence.push(1);
+
+pResolve();
+
+p.then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+checkSequence(sequence, "Should be first");
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ // enqueue another then-handler
+ p.then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+checkSequence(sequence, "Should be third");
+ }).then($DONE, $DONE);
+
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+checkSequence(sequence, "Should be second");
+}).catch($DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.3_T1.js b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.3_T1.js
new file mode 100644
index 0000000000..87a2b2271b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/S25.4.5.3_A5.3_T1.js
@@ -0,0 +1,49 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ PerformPromiseThen
+ Ref 25.4.5.3.1
+es6id: S25.4.5.3_A5.3_T1
+author: Sam Mikes
+description: Promise.prototype.then immediately queues handler if rejected
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [],
+ pReject,
+ p = new Promise(function(resolve, reject) {
+ pReject = reject;
+ });
+
+sequence.push(1);
+
+pReject();
+
+p.then(function() {
+ throw new Test262Error("Should not be called -- Promise rejected.");
+}, function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3, 'The value of sequence.length is expected to be 3');
+ checkSequence(sequence, "Should be first");
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ // enqueue another then-handler
+ p.then(function() {
+ throw new Test262Error("Should not be called (2) -- Promise rejected.");
+ }, function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5, 'The value of sequence.length is expected to be 5');
+ checkSequence(sequence, "Should be third");
+ }).then($DONE, $DONE);
+
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4, 'The value of sequence.length is expected to be 4');
+ checkSequence(sequence, "Should be second");
+}).catch($DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/browser.js b/js/src/tests/test262/built-ins/Promise/prototype/then/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/capability-executor-called-twice.js b/js/src/tests/test262/built-ins/Promise/prototype/then/capability-executor-called-twice.js
new file mode 100644
index 0000000000..de6cea8025
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/capability-executor-called-twice.js
@@ -0,0 +1,99 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.5.3
+description: >
+ Throws a TypeError if capabilities executor already called with non-undefined values.
+info: |
+ Promise.prototype.then ( onFulfilled , onRejected )
+
+ ...
+ 5. Let promiseCapability be NewPromiseCapability(C).
+ 6. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ 25.4.1.5.1 GetCapabilitiesExecutor Functions
+ ...
+ 3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
+ 4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
+ 5. Set promiseCapability.[[Resolve]] to resolve.
+ 6. Set promiseCapability.[[Reject]] to reject.
+ ...
+features: [class]
+---*/
+
+var constructorFunction;
+
+var promise = new class extends Promise {
+ constructor(executor) {
+ if (constructorFunction) {
+ constructorFunction(executor);
+ return {};
+ }
+ return super(executor);
+ }
+}(function() {});
+
+var checkPoint = "";
+constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+};
+promise.then();
+assert.sameValue(checkPoint, "abc", "executor initially called with no arguments");
+
+var checkPoint = "";
+constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+};
+promise.then();
+assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+ };
+ promise.then();
+}, "executor initially called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+ };
+ promise.then();
+}, "executor initially called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor("invalid value", 123);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+ };
+ promise.then();
+}, "executor initially called with (String, Number)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/capability-executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/prototype/then/capability-executor-not-callable.js
new file mode 100644
index 0000000000..ed3dee89ae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/capability-executor-not-callable.js
@@ -0,0 +1,104 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.5.3
+description: >
+ Throws a TypeError if either resolve or reject capability is not callable.
+info: |
+ Promise.prototype.then ( onFulfilled , onRejected )
+
+ ...
+ 5. Let promiseCapability be NewPromiseCapability(C).
+ 6. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ 25.4.1.5 NewPromiseCapability ( C )
+ ...
+ 4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1).
+ 5. Set the [[Capability]] internal slot of executor to promiseCapability.
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+ 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
+ 9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
+ ...
+features: [class]
+---*/
+
+var constructorFunction;
+
+var promise = new class extends Promise {
+ constructor(executor) {
+ if (constructorFunction) {
+ constructorFunction(executor);
+ return {};
+ }
+ return super(executor);
+ }
+}(function() {});
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ constructorFunction = function(executor) {
+ checkPoint += "a";
+ };
+ promise.then();
+}, "executor not called at all");
+assert.sameValue(checkPoint, "a", "executor not called at all");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+ };
+ promise.then();
+}, "executor called with no arguments");
+assert.sameValue(checkPoint, "ab", "executor called with no arguments");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+ };
+ promise.then();
+}, "executor called with (undefined, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+ };
+ promise.then();
+}, "executor called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, function)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+ };
+ promise.then();
+}, "executor called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (function, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ constructorFunction = function(executor) {
+ checkPoint += "a";
+ executor(123, "invalid value");
+ checkPoint += "b";
+ };
+ promise.then();
+}, "executor called with (Number, String)");
+assert.sameValue(checkPoint, "ab", "executor called with (Number, String)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/context-check-on-entry.js b/js/src/tests/test262/built-ins/Promise/prototype/then/context-check-on-entry.js
new file mode 100644
index 0000000000..794407fa72
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/context-check-on-entry.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.5.3
+description: >
+ Throws a TypeError if `this` is not a Promise object.
+info: |
+ Promise.prototype.then ( onFulfilled , onRejected )
+
+ 1. Let promise be the this value.
+ 2. If IsPromise(promise) is false, throw a TypeError exception.
+ ...
+---*/
+
+var object = {
+ get constructor() {
+ throw new Test262Error("get constructor called");
+ }
+};
+
+assert.throws(TypeError, function() {
+ Promise.prototype.then.call(object);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-access-count.js b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-access-count.js
new file mode 100644
index 0000000000..9c54c46ac4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-access-count.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2016 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 instance's `constructor` property is accessed exactly once
+info: |
+ 1. Let promise be the this value.
+ 2. If IsPromise(promise) is false, throw a TypeError exception.
+ 3. Let C be SpeciesConstructor(promise, %Promise%).
+ 4. ReturnIfAbrupt(C).
+ 5. Let resultCapability be NewPromiseCapability(C).
+ 6. ReturnIfAbrupt(resultCapability).
+ 7. Return PerformPromiseThen(promise, onFulfilled, onRejected,
+ resultCapability).
+
+ 7.3.20 SpeciesConstructor ( O, defaultConstructor )
+
+ 1. Assert: Type(O) is Object.
+ 2. Let C be Get(O, "constructor").
+ 3. ReturnIfAbrupt(C).
+ 4. If C is undefined, return defaultConstructor.
+ 5. If Type(C) is not Object, throw a TypeError exception.
+ 6. Let S be Get(C, @@species).
+ 7. ReturnIfAbrupt(S).
+ 8. If S is either undefined or null, return defaultConstructor.
+ 9. If IsConstructor(S) is true, return S.
+ 10. Throw a TypeError exception.
+flags: [async]
+---*/
+
+var callCount = 0;
+var prms = new Promise(function(resolve) {
+ resolve();
+});
+Object.defineProperty(prms, 'constructor', {
+ get: function() {
+ callCount += 1;
+ return Promise;
+ }
+});
+
+prms.then(function() {
+ if (callCount !== 1) {
+ $DONE('Expected constructor access count: 1. Actual: ' + callCount);
+ return;
+ }
+
+ $DONE();
+}, function() {
+ $DONE('The promise should not be rejected.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-custom.js b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-custom.js
new file mode 100644
index 0000000000..0ad80c7513
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-custom.js
@@ -0,0 +1,51 @@
+// 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 constructor defined by Symbol.species takes precedence
+info: |
+ 1. Let promise be the this value.
+ 2. If IsPromise(promise) is false, throw a TypeError exception.
+ 3. Let C be SpeciesConstructor(promise, %Promise%).
+ 4. ReturnIfAbrupt(C).
+ 5. Let resultCapability be NewPromiseCapability(C).
+features: [Symbol.species, class]
+---*/
+
+var callCount = 0;
+var thisValue, firstArg, argLength, getCapabilitiesExecutor;
+var executor = function() {};
+var p1 = new Promise(function() {});
+var SpeciesConstructor = class extends Promise {
+ constructor(a) {
+ super(a);
+ callCount += 1;
+ thisValue = this;
+ getCapabilitiesExecutor = a;
+ argLength = arguments.length;
+ }
+};
+var p2;
+
+p1.constructor = function() {};
+p1.constructor[Symbol.species] = SpeciesConstructor;
+
+p2 = p1.then();
+
+assert.sameValue(callCount, 1, 'The constructor is invoked exactly once');
+assert(thisValue instanceof SpeciesConstructor);
+assert.sameValue(
+ argLength, 1, 'The constructor is invoked with a single argument'
+);
+assert.sameValue(typeof getCapabilitiesExecutor, 'function');
+assert.sameValue(
+ getCapabilitiesExecutor.length,
+ 2,
+ 'ES6 25.4.1.5.1: The length property of a GetCapabilitiesExecutor function is 2.'
+);
+assert(
+ p2 instanceof SpeciesConstructor,
+ 'The returned object is an instance of the constructor'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-null.js b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-null.js
new file mode 100644
index 0000000000..a0b6df2a9e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-null.js
@@ -0,0 +1,22 @@
+// 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: >
+ A TypeError is thrown when the `this` value has a non-object `constructor` property
+info: |
+ 1. Let promise be the this value.
+ 2. If IsPromise(promise) is false, throw a TypeError exception.
+ 3. Let C be SpeciesConstructor(promise, %Promise%).
+ 4. ReturnIfAbrupt(C).
+ 5. Let resultCapability be NewPromiseCapability(C).
+---*/
+
+var p = new Promise(function() {});
+p.constructor = null;
+
+assert.throws(TypeError, function() {
+ p.then();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-poisoned.js b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-poisoned.js
new file mode 100644
index 0000000000..c0bb06362d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-poisoned.js
@@ -0,0 +1,29 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.prototype.then throws TypeError if Get(promise, "constructor") throws
+ Ref 25.4.5.3 step 4 ReturnIfAbrupt(C)
+es6id: S25.4.5.3_A3.1_T1
+author: Sam Mikes
+description: Promise.prototype.then throws if Get(promise, "constructor") throws
+---*/
+
+var p = Promise.resolve("foo");
+
+Object.defineProperty(p, "constructor", {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ p.then(function() {
+ throw new Test262Error("Should never be called.");
+ }, function() {
+ throw new Test262Error("Should never be called.");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-throws.js b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-throws.js
new file mode 100644
index 0000000000..d54621103e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-throws.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: >
+ `Promise.prototype.then` invoked on a constructor value that throws an
+ error
+es6id: 25.4.5.3
+info: |
+ 1. Let promise be the this value.
+ [...]
+ 3. Let C be SpeciesConstructor(promise, %Promise%).
+ [...]
+ 5. Let resultCapability be NewPromiseCapability(C).
+ 6. ReturnIfAbrupt(resultCapability).
+
+ 25.4.1.5 NewPromiseCapability
+ [...]
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+ features: [Symbol.species]
+---*/
+
+var BadCtor = function() {
+ throw new Test262Error();
+};
+var originalSpecies = Object.getOwnPropertyDescriptor(Promise, Symbol.species);
+
+Object.defineProperty(Promise, Symbol.species, {
+ value: BadCtor
+});
+
+try {
+ var p = new Promise(function(resolve) {
+ resolve();
+ });
+
+ assert.throws(Test262Error, function() {
+ p.then();
+ });
+} finally {
+ Object.defineProperty(Promise, Symbol.species, originalSpecies);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-undef.js b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-undef.js
new file mode 100644
index 0000000000..513f9d6cb6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/ctor-undef.js
@@ -0,0 +1,22 @@
+// 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 Promise built-in is used when the `this` value has no `constructor` property
+info: |
+ 1. Let promise be the this value.
+ 2. If IsPromise(promise) is false, throw a TypeError exception.
+ 3. Let C be SpeciesConstructor(promise, %Promise%).
+ 4. ReturnIfAbrupt(C).
+ 5. Let resultCapability be NewPromiseCapability(C).
+---*/
+
+var p1 = new Promise(function() {});
+delete p1.constructor;
+
+var p2 = p1.then();
+
+assert(p2 instanceof Promise);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/deferred-is-resolved-value.js b/js/src/tests/test262/built-ins/Promise/prototype/then/deferred-is-resolved-value.js
new file mode 100644
index 0000000000..fd2f6f1cf5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/deferred-is-resolved-value.js
@@ -0,0 +1,68 @@
+// |reftest| async
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.5.3
+description: >
+ Promise reaction jobs do not check for cyclic resolutions.
+info: |
+ Promise.prototype.then ( onFulfilled , onRejected )
+
+ ...
+ 5. Let resultCapability be NewPromiseCapability(C).
+ 6. ReturnIfAbrupt(resultCapability).
+ 7. Return PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability).
+
+ 25.4.5.3.1 PerformPromiseThen ( promise, onFulfilled, onRejected, resultCapability )
+ ...
+ 3. If IsCallable(onFulfilled) is false, then
+ a. Let onFulfilled be "Identity".
+ 4. If IsCallable(onRejected) is false, then
+ a. Let onRejected be "Thrower".
+ 5. Let fulfillReaction be the PromiseReaction { [[Capabilities]]: resultCapability, [[Handler]]: onFulfilled }.
+ 6. Let rejectReaction be the PromiseReaction { [[Capabilities]]: resultCapability, [[Handler]]: onRejected}.
+ ...
+ 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.2.1 PromiseReactionJob ( reaction, argument )
+ ...
+ 4. If handler is "Identity", let handlerResult be NormalCompletion(argument).
+ ...
+ 8. Let status be Call(promiseCapability.[[Resolve]], undefined, «handlerResult.[[value]]»).
+ 9. NextJob Completion(status).
+features: [class]
+flags: [async]
+---*/
+
+var createBadPromise = false;
+var object = {};
+
+class P extends Promise {
+ constructor(executor) {
+ if (createBadPromise) {
+ executor(
+ function(v) {
+ assert.sameValue(v, object);
+ $DONE();
+ },
+ function(e) {
+ $DONE(e);
+ }
+ );
+ return object;
+ }
+ return super(executor);
+ }
+}
+
+var p = P.resolve(object);
+
+createBadPromise = true;
+var q = p.then();
+createBadPromise = false;
+
+assert.sameValue(q, object, "then() returns object");
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/length.js b/js/src/tests/test262/built-ins/Promise/prototype/then/length.js
new file mode 100644
index 0000000000..1e865b0460
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/length.js
@@ -0,0 +1,27 @@
+// 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: Promise.prototype.then `length` property
+info: |
+ ES6 Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.prototype.then.length, 2);
+
+verifyNotEnumerable(Promise.prototype.then, 'length');
+verifyNotWritable(Promise.prototype.then, 'length');
+verifyConfigurable(Promise.prototype.then, 'length');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/name.js b/js/src/tests/test262/built-ins/Promise/prototype/then/name.js
new file mode 100644
index 0000000000..b1c97f9956
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/name.js
@@ -0,0 +1,28 @@
+// 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: Promise.prototype.then `name` property
+info: |
+ ES6 Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.prototype.then.name, 'then');
+
+verifyNotEnumerable(Promise.prototype.then, 'name');
+verifyNotWritable(Promise.prototype.then, 'name');
+verifyConfigurable(Promise.prototype.then, 'name');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/prototype/then/not-a-constructor.js
new file mode 100644
index 0000000000..d943772f86
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/not-a-constructor.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Promise.prototype.then does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(Promise.prototype.then),
+ false,
+ 'isConstructor(Promise.prototype.then) must return false'
+);
+
+assert.throws(TypeError, () => {
+ let p = new Promise(() => {}); new p.then();
+}, '`let p = new Promise(() => {}); new p.then()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-fulfilled.js b/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-fulfilled.js
new file mode 100644
index 0000000000..89d5e2de5f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-fulfilled.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2016 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: PerformPromiseThen on 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»).
+ [...]
+flags: [async]
+---*/
+
+var value = {};
+var p = new Promise(function(resolve) {
+ resolve(value);
+});
+
+p.then(function(x) {
+ if (x !== value) {
+ $DONE('The `onFulfilled` handler should be invoked with the promise result.');
+ return;
+ }
+ $DONE();
+}, function() {
+ $DONE('The `onRejected` handler should not be invoked.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-pending-fulfulled.js b/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-pending-fulfulled.js
new file mode 100644
index 0000000000..93204370cd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-pending-fulfulled.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// Copyright (C) 2016 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: PerformPromiseThen on a pending promise that is later fulfilled
+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.
+ b. Append rejectReaction as the last element of the List that is the
+ value of promise's [[PromiseRejectReactions]] internal slot.
+ [...]
+flags: [async]
+---*/
+
+var value = {};
+var resolve;
+var p = new Promise(function(_resolve) {
+ resolve = _resolve;
+});
+
+p.then(function(x) {
+ if (x !== value) {
+ $DONE('The `onFulfilled` handler should be invoked with the promise result.');
+ return;
+ }
+ $DONE();
+}, function() {
+ $DONE('The `onRejected` handler should not be invoked.');
+});
+
+resolve(value);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-pending-rejected.js b/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-pending-rejected.js
new file mode 100644
index 0000000000..b65b5596ce
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-pending-rejected.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// Copyright (C) 2016 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: PerformPromiseThen on a pending promise that is later rejected
+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.
+ b. Append rejectReaction as the last element of the List that is the
+ value of promise's [[PromiseRejectReactions]] internal slot.
+ [...]
+flags: [async]
+---*/
+
+var value = {};
+var reject;
+var p = new Promise(function(_, _reject) {
+ reject = _reject;
+});
+
+p.then(function() {
+ $DONE('The `onFulfilled` handler should not be invoked.');
+}, function(x) {
+ if (x !== value) {
+ $DONE('The `onRejected` handler should be invoked with the promise result.');
+ return;
+ }
+ $DONE();
+});
+
+reject(value);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-rejected.js b/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-rejected.js
new file mode 100644
index 0000000000..4b74b5f3cb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/prfm-rejected.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// 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: PerformPromiseThen on a rejected promise
+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»).
+ [...]
+flags: [async]
+---*/
+
+var value = {};
+var p = new Promise(function(_, reject) {
+ reject(value);
+});
+
+p.then(function() {
+ $DONE('The `onFulfilled` handler should not be invoked.');
+}, function(x) {
+ if (x !== value) {
+ $DONE('The `onRejected` handler should be invoked with the promise result.');
+ return;
+ }
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/prop-desc.js b/js/src/tests/test262/built-ins/Promise/prototype/then/prop-desc.js
new file mode 100644
index 0000000000..75e58c3117
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/prop-desc.js
@@ -0,0 +1,19 @@
+// 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.1
+description: Promise.prototype.then property descriptor
+info: |
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(typeof Promise.prototype.then, 'function');
+
+verifyNotEnumerable(Promise.prototype, 'then');
+verifyWritable(Promise.prototype, 'then');
+verifyConfigurable(Promise.prototype, 'then');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/reject-pending-fulfilled.js b/js/src/tests/test262/built-ins/Promise/prototype/then/reject-pending-fulfilled.js
new file mode 100644
index 0000000000..7795f1bb2a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/reject-pending-fulfilled.js
@@ -0,0 +1,49 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting 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.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var resolve;
+var thenable = new Promise(function(_resolve) {
+ resolve = _resolve;
+});
+var p1 = new Promise(function(resolve) {
+ resolve();
+});
+var p2;
+
+p2 = p1.then(function() {
+ throw thenable;
+});
+
+p2.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value of the provided promise.');
+ return;
+ }
+
+ $DONE();
+});
+
+resolve();
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/reject-pending-rejected.js b/js/src/tests/test262/built-ins/Promise/prototype/then/reject-pending-rejected.js
new file mode 100644
index 0000000000..72c27c684c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/reject-pending-rejected.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting 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.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var reject;
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+var p1 = new Promise(function(_, _reject) {
+ reject = _reject;
+});
+var p2;
+
+p2 = p1.then(function() {}, function() {
+ throw thenable;
+});
+
+p2.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value of the provided promise.');
+ return;
+ }
+
+ $DONE();
+});
+
+reject();
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/reject-settled-fulfilled.js b/js/src/tests/test262/built-ins/Promise/prototype/then/reject-settled-fulfilled.js
new file mode 100644
index 0000000000..56dbd6fff3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/reject-settled-fulfilled.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting 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
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ [...]
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+var p1 = new Promise(function(resolve) {
+ resolve();
+});
+var p2;
+
+p2 = p1.then(function() {
+ throw thenable;
+});
+
+p2.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value of the provided promise.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/reject-settled-rejected.js b/js/src/tests/test262/built-ins/Promise/prototype/then/reject-settled-rejected.js
new file mode 100644
index 0000000000..0f87c6bb01
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/reject-settled-rejected.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting 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
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ [...]
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+var p1 = new Promise(function(_, reject) {
+ reject();
+});
+var p2;
+
+p2 = p1.then(function() {}, function() {
+ throw thenable;
+});
+
+p2.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value of the provided promise.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-obj.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-obj.js
new file mode 100644
index 0000000000..fd6602988b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-obj.js
@@ -0,0 +1,46 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-thenable.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-thenable.js
new file mode 100644
index 0000000000..e71b639f39
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-non-thenable.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-poisoned-then.js
new file mode 100644
index 0000000000..88c3cd57a5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-poisoned-then.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// 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]]).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-prms-cstm-then.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-prms-cstm-then.js
new file mode 100644
index 0000000000..147ce71f22
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-prms-cstm-then.js
@@ -0,0 +1,61 @@
+// |reftest| async
+// 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 resolved Promise instance whose `then` method has been overridden 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»)
+flags: [async]
+---*/
+
+var value = {};
+var resolve;
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+var p1 = new Promise(function(_resolve) {
+ resolve = _resolve;
+});
+var p2;
+
+thenable.then = function(resolve) {
+ resolve(value);
+};
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-self.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-self.js
new file mode 100644
index 0000000000..1191706a68
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-self.js
@@ -0,0 +1,53 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-thenable.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-thenable.js
new file mode 100644
index 0000000000..52ad8d2366
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-fulfilled-thenable.js
@@ -0,0 +1,57 @@
+// |reftest| async
+// 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»)
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-non-obj.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-non-obj.js
new file mode 100644
index 0000000000..1480ad1f5f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-non-obj.js
@@ -0,0 +1,47 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-non-thenable.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-non-thenable.js
new file mode 100644
index 0000000000..19764d8de7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-non-thenable.js
@@ -0,0 +1,55 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-poisoned-then.js
new file mode 100644
index 0000000000..542c6e7ead
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-poisoned-then.js
@@ -0,0 +1,55 @@
+// |reftest| async
+// 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]]).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-prms-cstm-then.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-prms-cstm-then.js
new file mode 100644
index 0000000000..4a3fbc1674
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-prms-cstm-then.js
@@ -0,0 +1,62 @@
+// |reftest| async
+// 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 resolved Promise instance whose `then` method has been overridden 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»)
+flags: [async]
+---*/
+
+var value = {};
+var reject;
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+var p1 = new Promise(function(_, _reject) {
+ reject = _reject;
+});
+var p2;
+
+thenable.then = function(resolve) {
+ resolve(value);
+};
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-self.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-self.js
new file mode 100644
index 0000000000..7a31dc46bc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-self.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-thenable.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-thenable.js
new file mode 100644
index 0000000000..775bb1f79f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-pending-rejected-thenable.js
@@ -0,0 +1,58 @@
+// |reftest| async
+// 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»)
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-obj.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-obj.js
new file mode 100644
index 0000000000..5f6494fa3a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-obj.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-thenable.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-thenable.js
new file mode 100644
index 0000000000..3ca031489f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-non-thenable.js
@@ -0,0 +1,58 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-poisoned-then.js
new file mode 100644
index 0000000000..ab5ee4a727
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-poisoned-then.js
@@ -0,0 +1,58 @@
+// |reftest| async
+// 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]]).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-prms-cstm-then.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-prms-cstm-then.js
new file mode 100644
index 0000000000..5594511e34
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-prms-cstm-then.js
@@ -0,0 +1,65 @@
+// |reftest| async
+// 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 resolved Promise instance whose `then` method has been overridden 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»)
+flags: [async]
+---*/
+
+var value = {};
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+var p1 = new Promise(function(resolve) {
+ resolve();
+});
+var p2;
+
+thenable.then = function(resolve) {
+ resolve(value);
+};
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-self.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-self.js
new file mode 100644
index 0000000000..89c4f064b8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-self.js
@@ -0,0 +1,57 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-thenable.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-thenable.js
new file mode 100644
index 0000000000..f978984c36
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-fulfilled-thenable.js
@@ -0,0 +1,61 @@
+// |reftest| async
+// 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»)
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-non-obj.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-non-obj.js
new file mode 100644
index 0000000000..1d39308386
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-non-obj.js
@@ -0,0 +1,50 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-non-thenable.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-non-thenable.js
new file mode 100644
index 0000000000..eae6797f1a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-non-thenable.js
@@ -0,0 +1,58 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-poisoned-then.js
new file mode 100644
index 0000000000..2f33c820bb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-poisoned-then.js
@@ -0,0 +1,58 @@
+// |reftest| async
+// 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]]).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-prms-cstm-then.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-prms-cstm-then.js
new file mode 100644
index 0000000000..303a5315b0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-prms-cstm-then.js
@@ -0,0 +1,65 @@
+// |reftest| async
+// 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 resolved Promise instance whose `then` method has been overridden 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»)
+flags: [async]
+---*/
+
+var value = {};
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+var p1 = new Promise(function(_, reject) {
+ reject();
+});
+var p2;
+
+thenable.then = function(resolve) {
+ resolve(value);
+};
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-self.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-self.js
new file mode 100644
index 0000000000..a585ca9b2e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-self.js
@@ -0,0 +1,57 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-thenable.js b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-thenable.js
new file mode 100644
index 0000000000..827ff855f6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/resolve-settled-rejected-thenable.js
@@ -0,0 +1,61 @@
+// |reftest| async
+// 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»)
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-invoke-nonstrict.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-invoke-nonstrict.js
new file mode 100644
index 0000000000..61fd431b65
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-invoke-nonstrict.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ [...]
+ 6. Else, let handlerResult be Call(handler, undefined, «argument»).
+es6id: S25.4.2.1_A3.1_T1
+author: Sam Mikes
+description: >
+ "fulfilled" handler invoked correctly outside of strict mode
+flags: [async, noStrict]
+---*/
+
+var expectedThis = this,
+ obj = {};
+
+var p = Promise.resolve(obj).then(function(arg) {
+ if (this !== expectedThis) {
+ $DONE("'this' must be global object, got " + this);
+ return;
+ }
+
+ if (arg !== obj) {
+ $DONE("Expected promise to be fulfilled by obj, actually " + arg);
+ return;
+ }
+
+ if (arguments.length !== 1) {
+ $DONE('Expected handler function to be called with exactly 1 argument.');
+ return;
+ }
+
+ $DONE();
+}, function() {
+ $DONE('The promise should not be rejected.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-invoke-strict-strict.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-invoke-strict-strict.js
new file mode 100644
index 0000000000..3c0ab9a54d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-invoke-strict-strict.js
@@ -0,0 +1,39 @@
+// |reftest| async
+'use strict';
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ [...]
+ 6. Else, let handlerResult be Call(handler, undefined, «argument»).
+es6id: S25.4.2.1_A3.1_T2
+author: Sam Mikes
+description: >
+ "fulfilled" handler invoked correctly in strict mode
+flags: [async, onlyStrict]
+---*/
+
+var expectedThis = undefined,
+ obj = {};
+
+var p = Promise.resolve(obj).then(function(arg) {
+ if (this !== expectedThis) {
+ $DONE("'this' must be undefined, got " + this);
+ return;
+ }
+
+ if (arg !== obj) {
+ $DONE("Expected promise to be fulfilled by obj, actually " + arg);
+ return;
+ }
+
+ if (arguments.length !== 1) {
+ $DONE('Expected handler function to be called with exactly 1 argument.');
+ return;
+ }
+
+ $DONE();
+}, function() {
+ $DONE('The promise should not be rejected.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next-abrupt.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next-abrupt.js
new file mode 100644
index 0000000000..ec9ab0172b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next-abrupt.js
@@ -0,0 +1,46 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completions should not preclude additional jobs
+es6id: 25.4.2.1
+info: |
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ b. NextJob Completion(status).
+ 8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+ «handlerResult.[[value]]»).
+ 9. NextJob Completion(status).
+flags: [async]
+---*/
+
+var promise = new Promise(function(resolve) {
+ resolve();
+});
+var fulfilledCallCount = 0;
+var rejectedCallCount = 0;
+
+promise.then(function() {
+ fulfilledCallCount += 1;
+ throw new Error();
+}, function() {
+ rejectedCallCount += 1;
+});
+
+promise.then(function() {
+ if (fulfilledCallCount !== 1) {
+ $DONE('Expected "onFulfilled" handler to be invoked exactly once.');
+ return;
+ }
+
+ if (rejectedCallCount !== 0) {
+ $DONE('Expected "onRejected" handler to not be invoked.');
+ return;
+ }
+
+ $DONE();
+}, function() {
+ $DONE('This promise should not be rejected.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next.js
new file mode 100644
index 0000000000..13fb4ca62f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-next.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: All queued jobs should be executed in series
+es6id: 25.4.2.1
+info: |
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ b. NextJob Completion(status).
+ 8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+ «handlerResult.[[value]]»).
+ 9. NextJob Completion(status).
+flags: [async]
+---*/
+
+var promise = new Promise(function(resolve) {
+ resolve();
+});
+var log = '';
+
+promise.then(function() {
+ log += 'a';
+}, function() {
+ log += 'A';
+});
+
+promise.then(function() {
+ log += 'b';
+}, function() {
+ log += 'B';
+});
+
+promise.then(function() {
+ log += 'c';
+}, function() {
+ log += 'C';
+});
+
+promise.then(function() {
+ if (log !== 'abc') {
+ $DONE(
+ 'Expected each "onFulfilled" handler to be invoked exactly once in series. ' +
+ 'Expected: abc. Actual: ' + log
+ );
+ return;
+ }
+
+ $DONE();
+}, function() {
+ $DONE('This promise should not be rejected.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-return-abrupt.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-return-abrupt.js
new file mode 100644
index 0000000000..a394847ce9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-return-abrupt.js
@@ -0,0 +1,51 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: An abrupt completion should trigger promise rejection
+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
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ b. NextJob Completion(status).
+ 8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+ «handlerResult.[[value]]»).
+ 9. NextJob Completion(status).
+flags: [async]
+---*/
+
+var value = {};
+var p1 = new Promise(function(resolve) {
+ resolve();
+});
+var p2;
+
+p2 = p1.then(function() {
+ throw value;
+}, function() {});
+
+p2.then(function() {
+ $DONE('The `onFulfilled` handler should not be invoked.');
+}, function(x) {
+ if (x !== value) {
+ $DONE('The `onRejected` handler should be invoked with the promise result.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-return-normal.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-return-normal.js
new file mode 100644
index 0000000000..5acd838f06
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-fulfilled-return-normal.js
@@ -0,0 +1,51 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: A normal completion should trigger promise fulfillment
+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
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ b. NextJob Completion(status).
+ 8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+ «handlerResult.[[value]]»).
+ 9. NextJob Completion(status).
+flags: [async]
+---*/
+
+var value = {};
+var p1 = new Promise(function(resolve) {
+ resolve();
+});
+var p2;
+
+p2 = p1.then(function() {
+ return value;
+}, function() {});
+
+p2.then(function(x) {
+ if (x !== value) {
+ $DONE('The `onFulfilled` handler should be invoked with the promise result.');
+ return;
+ }
+
+ $DONE();
+}, function() {
+ $DONE('The `onRejected` handler should not be invoked.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-identity.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-identity.js
new file mode 100644
index 0000000000..d559176177
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-identity.js
@@ -0,0 +1,25 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise reaction jobs have predictable environment
+es6id: S25.4.2.1_A1.1_T1
+author: Sam Mikes
+description: argument passes through "Identity"
+flags: [async]
+---*/
+
+var obj = {};
+
+var p = Promise.resolve(obj).then( /*Identity, Thrower*/ )
+ .then(function(arg) {
+ if (arg !== obj) {
+ $DONE("Expected promise to be fulfilled with obj, actually " + arg);
+ return;
+ }
+ $DONE();
+ }, function() {
+ $DONE('The promise should not be rejected.');
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-invoke-nonstrict.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-invoke-nonstrict.js
new file mode 100644
index 0000000000..0b548a01f5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-invoke-nonstrict.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ [...]
+ 6. Else, let handlerResult be Call(handler, undefined, «argument»).
+es6id: S25.4.2.1_A3.2_T1
+author: Sam Mikes
+description: >
+ "rejected" handler invoked correctly outside of strict mode
+flags: [async, noStrict]
+---*/
+
+var expectedThis = this,
+ obj = {};
+
+var p = Promise.reject(obj).then(function() {
+ $DONE("Unexpected fulfillment; expected rejection.");
+}, function(arg) {
+ if (this !== expectedThis) {
+ $DONE("'this' must be global object, got " + this);
+ return;
+ }
+
+ if (arg !== obj) {
+ $DONE("Expected promise to be rejected with obj, actually " + arg);
+ return;
+ }
+
+ if (arguments.length !== 1) {
+ $DONE('Expected handler function to be called with exactly 1 argument.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-invoke-strict-strict.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-invoke-strict-strict.js
new file mode 100644
index 0000000000..09f0954c0d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-invoke-strict-strict.js
@@ -0,0 +1,39 @@
+// |reftest| async
+'use strict';
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ [...]
+ 6. Else, let handlerResult be Call(handler, undefined, «argument»).
+es6id: S25.4.2.1_A3.2_T2
+author: Sam Mikes
+description: >
+ "rejected" handler invoked correctly in strict mode
+flags: [async, onlyStrict]
+---*/
+
+var expectedThis = undefined,
+ obj = {};
+
+var p = Promise.reject(obj).then(function() {
+ $DONE("Unexpected fulfillment; expected rejection.");
+}, function(arg) {
+ if (this !== expectedThis) {
+ $DONE("'this' must be undefined, got " + this);
+ return;
+ }
+
+ if (arg !== obj) {
+ $DONE("Expected promise to be rejected with obj, actually " + arg);
+ return;
+ }
+
+ if (arguments.length !== 1) {
+ $DONE('Expected handler function to be called with exactly 1 argument.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-next-abrupt.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-next-abrupt.js
new file mode 100644
index 0000000000..681f4fabc1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-next-abrupt.js
@@ -0,0 +1,46 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Abrupt completions should not preclude additional jobs
+es6id: 25.4.2.1
+info: |
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ b. NextJob Completion(status).
+ 8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+ «handlerResult.[[value]]»).
+ 9. NextJob Completion(status).
+flags: [async]
+---*/
+
+var promise = new Promise(function(_, reject) {
+ reject();
+});
+var fulfilledCallCount = 0;
+var rejectedCallCount = 0;
+
+promise.then(function() {
+ fulfilledCallCount += 1;
+}, function() {
+ rejectedCallCount += 1;
+ throw new Error();
+});
+
+promise.then(function() {
+ $DONE('This promise should not be fulfilled.');
+}, function() {
+ if (fulfilledCallCount !== 0) {
+ $DONE('Expected "onFulfilled" handler to not be invoked.');
+ return;
+ }
+
+ if (rejectedCallCount !== 1) {
+ $DONE('Expected "onRejected" handler to be invoked exactly once.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-next.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-next.js
new file mode 100644
index 0000000000..d88d3e1a48
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-next.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: All queued jobs should be executed in series
+es6id: 25.4.2.1
+info: |
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ b. NextJob Completion(status).
+ 8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+ «handlerResult.[[value]]»).
+ 9. NextJob Completion(status).
+flags: [async]
+---*/
+
+var promise = new Promise(function(_, reject) {
+ reject();
+});
+var log = '';
+
+promise.then(function() {
+ log += 'A';
+}, function() {
+ log += 'a';
+});
+
+promise.then(function() {
+ log += 'B';
+}, function() {
+ log += 'b';
+});
+
+promise.then(function() {
+ log += 'C';
+}, function() {
+ log += 'c';
+});
+
+promise.then(function() {
+ $DONE('This promise should not be fulfilled.');
+}, function() {
+ if (log !== 'abc') {
+ $DONE(
+ 'Expected each "onFulfilled" handler to be invoked exactly once in series. ' +
+ 'Expected: abc. Actual: ' + log
+ );
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-return-abrupt.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-return-abrupt.js
new file mode 100644
index 0000000000..8b89456853
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-return-abrupt.js
@@ -0,0 +1,51 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: An abrupt completion should trigger promise rejection
+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
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ b. NextJob Completion(status).
+ 8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+ «handlerResult.[[value]]»).
+ 9. NextJob Completion(status).
+flags: [async]
+---*/
+
+var value = {};
+var p1 = new Promise(function(_, reject) {
+ reject();
+});
+var p2;
+
+p2 = p1.then(function() {}, function() {
+ throw value;
+});
+
+p2.then(function() {
+ $DONE('The `onFulfilled` handler should not be invoked.');
+}, function(x) {
+ if (x !== value) {
+ $DONE('The `onRejected` handler should be invoked with the promise result.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-return-normal.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-return-normal.js
new file mode 100644
index 0000000000..d29489baa8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-rejected-return-normal.js
@@ -0,0 +1,51 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: A normal completion should trigger promise fulfillment
+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
+ [...]
+ 7. If handlerResult is an abrupt completion, then
+ a. Let status be Call(promiseCapability.[[Reject]], undefined,
+ «handlerResult.[[value]]»).
+ b. NextJob Completion(status).
+ 8. Let status be Call(promiseCapability.[[Resolve]], undefined,
+ «handlerResult.[[value]]»).
+ 9. NextJob Completion(status).
+flags: [async]
+---*/
+
+var value = {};
+var p1 = new Promise(function(_, reject) {
+ reject();
+});
+var p2;
+
+p2 = p1.then(function() {}, function() {
+ return value;
+});
+
+p2.then(function(x) {
+ if (x !== value) {
+ $DONE('The `onFulfilled` handler should be invoked with the promise result.');
+ return;
+ }
+
+ $DONE();
+}, function() {
+ $DONE('The `onRejected` handler should not be invoked.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-thrower.js b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-thrower.js
new file mode 100644
index 0000000000..6961da914e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/rxn-handler-thrower.js
@@ -0,0 +1,25 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise reaction jobs have predictable environment
+es6id: S25.4.2.1_A2.1_T1
+author: Sam Mikes
+description: argument thrown through "Thrower"
+flags: [async]
+---*/
+
+var obj = {};
+
+var p = Promise.reject(obj).then( /*Identity, Thrower*/ )
+ .then(function() {
+ $DONE("Unexpected fulfillment - promise should reject.");
+ }, function(arg) {
+ if (arg !== obj) {
+ $DONE("Expected reject reason to be obj, actually " + arg);
+ return;
+ }
+ $DONE();
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/prototype/then/shell.js b/js/src/tests/test262/built-ins/Promise/prototype/then/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/then/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A1.1_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A1.1_T1.js
new file mode 100644
index 0000000000..fadedf1e24
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A1.1_T1.js
@@ -0,0 +1,12 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.race is callable
+es6id: S25.4.4.3_A1.1_T1
+author: Sam Mikes
+description: Promise.race is callable
+---*/
+assert.sameValue(typeof Promise.race, "function", 'The value of `typeof Promise.race` is expected to be "function"');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.1_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.1_T1.js
new file mode 100644
index 0000000000..0200158ab5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.1_T1.js
@@ -0,0 +1,15 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.race returns a new promise
+es6id: S25.4.4.3_A2.1_T1
+author: Sam Mikes
+description: Promise.race returns a new promise
+---*/
+
+var p = Promise.race([]);
+
+assert(!!(p instanceof Promise), 'The value of !!(p instanceof Promise) is expected to be true');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T1.js
new file mode 100644
index 0000000000..1adfb40d63
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T1.js
@@ -0,0 +1,19 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.race rejects on non-iterable argument
+es6id: S25.4.4.3_A2.2_T1
+author: Sam Mikes
+description: Promise.race rejects if argument is not object or is non-iterable
+flags: [async]
+---*/
+
+var nonIterable = 3;
+
+Promise.race(nonIterable).then(function() {
+ throw new Test262Error('Promise unexpectedly fulfilled: Promise.race(nonIterable) should throw TypeError');
+}, function(err) {
+ assert(!!(err instanceof TypeError), 'The value of !!(err instanceof TypeError) is expected to be true');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T2.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T2.js
new file mode 100644
index 0000000000..3555d007f7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T2.js
@@ -0,0 +1,17 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: Promise.race rejects on non-iterable argument
+es6id: S25.4.4.3_A2.2_T2
+author: Sam Mikes
+description: Promise.race rejects if argument is not object or is non-iterable
+flags: [async]
+---*/
+
+Promise.race(new Error("abrupt")).then(function() {
+ throw new Test262Error('Promise unexpectedly resolved: Promise.race(abruptCompletion) should throw TypeError');
+}, function(err) {
+ assert(!!(err instanceof TypeError), 'The value of !!(err instanceof TypeError) is expected to be true');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T3.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T3.js
new file mode 100644
index 0000000000..7e8f21d0da
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A2.2_T3.js
@@ -0,0 +1,28 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.race rejects when GetIterator() returns an abrupt completion
+ 4. Let iterator be GetIterator(iterable).
+ 5. IfAbruptRejectPromise(iterator, promiseCapability)
+es6id: S25.4.4.3_A2.2_T3
+author: Sam Mikes
+description: Promise.race rejects if GetIterator throws
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+var iterThrows = {};
+Object.defineProperty(iterThrows, Symbol.iterator, {
+ get: function() {
+ throw new Error("abrupt completion");
+ }
+});
+
+Promise.race(iterThrows).then(function() {
+ throw new Test262Error('Promise unexpectedly fulfilled: Promise.race(iterThrows) should throw');
+}, function(err) {
+ assert(!!(err instanceof Error), 'The value of !!(err instanceof Error) is expected to be true');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A3.1_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A3.1_T1.js
new file mode 100644
index 0000000000..8e01562462
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A3.1_T1.js
@@ -0,0 +1,20 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.race throws on invalid 'this'
+ Note: must have at least one element in array, or else Promise.race
+ never exercises the code that throws
+es6id: S25.4.4.3_A3.1_T1
+author: Sam Mikes
+description: Promise.race throws if 'this' does not conform to Promise constructor
+---*/
+
+function ZeroArgConstructor() {}
+
+assert.throws(TypeError, function() {
+ Promise.race.call(ZeroArgConstructor, [3]);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A3.1_T2.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A3.1_T2.js
new file mode 100644
index 0000000000..ac83127e8f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A3.1_T2.js
@@ -0,0 +1,22 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.race must throw TypeError per
+ CreatePromiseCapabilityRecord step 8 when
+ promiseCapabliity.[[Resolve]] is not callable
+es6id: S25.4.4.3_A3.1_T2
+author: Sam Mikes
+description: Promise.race throws TypeError, even on empty array, when 'this' does not conform to Promise constructor
+---*/
+
+function BadPromiseConstructor(f) {
+ f(undefined, undefined);
+}
+
+assert.throws(TypeError, function() {
+ Promise.race.call(BadPromiseConstructor, []);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A4.1_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A4.1_T1.js
new file mode 100644
index 0000000000..e4602242f2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A4.1_T1.js
@@ -0,0 +1,27 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A4.1_T1
+author: Sam Mikes
+description: Promise.race rejects if IteratorStep throws
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+var iterThrows = {};
+var error = new Test262Error();
+iterThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ throw error;
+ }
+ };
+};
+
+Promise.race(iterThrows).then(function() {
+ throw new Test262Error('Promise unexpectedly fulfilled: Promise.race(iterThrows) should throw TypeError');
+}, function(reason) {
+ assert.sameValue(reason, error, 'The value of reason is expected to equal the value of error');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A4.1_T2.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A4.1_T2.js
new file mode 100644
index 0000000000..c8aeb4602f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A4.1_T2.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A4.1_T2
+author: Sam Mikes
+description: Promise.race rejects if IteratorStep throws
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+var iterThrows = {};
+Object.defineProperty(iterThrows, Symbol.iterator, {
+ get: function() {
+ return {
+ next: function() {
+ var v = {};
+ Object.defineProperty(v, 'value', {
+ get: function() {
+ throw new Error("abrupt completion");
+ }
+ });
+ return v;
+ }
+ };
+ }
+});
+
+Promise.race(iterThrows).then(function() {
+ throw new Test262Error('Promise unexpectedly fulfilled: Promise.race(iterThrows) should throw TypeError');
+}, function(err) {
+ assert(!!(err instanceof TypeError), 'The value of !!(err instanceof TypeError) is expected to be true');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A5.1_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A5.1_T1.js
new file mode 100644
index 0000000000..e8dfc87992
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A5.1_T1.js
@@ -0,0 +1,22 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A5.1_T1
+author: Sam Mikes
+description: Promise.race([]) never settles
+flags: [async]
+---*/
+
+var p = Promise.race([]);
+
+p.then(function() {
+ throw new Test262Error("Never settles.");
+}, function() {
+ throw new Test262Error("Never settles.");
+}).then($DONE, $DONE);
+
+// use three 'then's to allow above to settle
+// if this is a buggy Promise.race implementation
+Promise.resolve().then().then().then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A6.1_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A6.1_T1.js
new file mode 100644
index 0000000000..27dd872a3c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A6.1_T1.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A6.1_T1
+author: Sam Mikes
+description: Promise.race([1]) settles immediately
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var p = Promise.race([1]);
+
+sequence.push(1);
+
+p.then(function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, "This happens second");
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, "This happens first");
+}).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, "This happens third");
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A6.2_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A6.2_T1.js
new file mode 100644
index 0000000000..5be746bfab
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A6.2_T1.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A6.2_T1
+author: Sam Mikes
+description: Promise.race([p1]) settles immediately
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var p1 = Promise.reject(1),
+ p = Promise.race([p1]);
+
+sequence.push(1);
+
+p.then(function() {
+ throw new Test262Error("Should not fulfill.");
+}, function() {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4, 'The value of sequence.length is expected to be 4');
+checkSequence(sequence, "This happens second");
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3, 'The value of sequence.length is expected to be 3');
+ checkSequence(sequence, "This happens first");
+}).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5, 'The value of sequence.length is expected to be 5');
+ checkSequence(sequence, "This happens third");
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T1.js
new file mode 100644
index 0000000000..768f25c842
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T1.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A7.1_T1
+author: Sam Mikes
+description: Promise.race([p1, p2]) settles when first settles
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var p1 = Promise.resolve(1),
+ p2 = Promise.resolve(2),
+ p = Promise.race([p1, p2]);
+
+sequence.push(1);
+
+p.then(function(result) {
+ assert.sameValue(result, 1, 'The value of result is expected to be 1');
+
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4, 'The value of sequence.length is expected to be 4');
+ checkSequence(sequence, "This happens second");
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3, 'The value of sequence.length is expected to be 3');
+ checkSequence(sequence, "This happens first");
+}).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5, 'The value of sequence.length is expected to be 5');
+ checkSequence(sequence, "This happens third");
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T2.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T2.js
new file mode 100644
index 0000000000..72b7200f85
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T2.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A7.1_T2
+author: Sam Mikes
+description: Promise.race([p1, p2]) settles when first settles
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var p1 = Promise.resolve(1),
+ p2 = new Promise(function() {}),
+ p = Promise.race([p1, p2]);
+
+sequence.push(1);
+
+p.then(function(result) {
+ assert.sameValue(result, 1, 'The value of result is expected to be 1');
+
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4, 'The value of sequence.length is expected to be 4');
+ checkSequence(sequence, "This happens second");
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3, 'The value of sequence.length is expected to be 3');
+ checkSequence(sequence, "This happens first");
+}).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5, 'The value of sequence.length is expected to be 5');
+ checkSequence(sequence, "This happens third");
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T3.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T3.js
new file mode 100644
index 0000000000..ce763b023a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.1_T3.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A7.1_T3
+author: Sam Mikes
+description: Promise.race([p1, p2]) settles when first settles
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var p1 = new Promise(function() {}),
+ p2 = Promise.resolve(2),
+ p = Promise.race([p1, p2]);
+
+sequence.push(1);
+
+p.then(function(result) {
+ assert.sameValue(result, 2, 'The value of result is expected to be 2');
+
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4, 'The value of sequence.length is expected to be 4');
+ checkSequence(sequence, "This happens second");
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3, 'The value of sequence.length is expected to be 3');
+ checkSequence(sequence, "This happens first");
+}).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5, 'The value of sequence.length is expected to be 5');
+ checkSequence(sequence, "This happens third");
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.2_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.2_T1.js
new file mode 100644
index 0000000000..b38ba8eae6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.2_T1.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A7.2_T1
+author: Sam Mikes
+description: Promise.race([p1, p2]) settles when first settles
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var p1 = Promise.reject(1),
+ p2 = Promise.resolve(2),
+ p = Promise.race([p1, p2]);
+
+sequence.push(1);
+
+p.then(function() {
+ throw new Test262Error("Should not be fulfilled - expected rejection.");
+}, function(result) {
+ assert.sameValue(result, 1, 'The value of result is expected to be 1');
+
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4, 'The value of sequence.length is expected to be 4');
+ checkSequence(sequence, "This happens second");
+}).catch($DONE);
+
+Promise.resolve().then(function() {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3, 'The value of sequence.length is expected to be 3');
+ checkSequence(sequence, "This happens first");
+}).then(function() {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5, 'The value of sequence.length is expected to be 5');
+ checkSequence(sequence, "This happens third");
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.3_T1.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.3_T1.js
new file mode 100644
index 0000000000..303441a11d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.3_T1.js
@@ -0,0 +1,25 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A7.3_T1
+author: Sam Mikes
+description: Promise.race([p1, p2]) settles when first settles
+flags: [async]
+---*/
+
+var resolveP1, rejectP2,
+ p1 = new Promise(function(resolve) {
+ resolveP1 = resolve;
+ }),
+ p2 = new Promise(function(resolve, reject) {
+ rejectP2 = reject;
+ });
+
+rejectP2(new Error("Promise.race should not see this if P1 already resolved"));
+resolveP1(1);
+
+Promise.race([p1, p2]).then(function(result) {
+ assert.sameValue(result, 1, 'The value of result is expected to be 1');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.3_T2.js b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.3_T2.js
new file mode 100644
index 0000000000..7081e0b3f7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/S25.4.4.3_A7.3_T2.js
@@ -0,0 +1,27 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.3_A7.3_T2
+author: Sam Mikes
+description: Promise.race([p1, p2]) settles when first settles
+flags: [async]
+---*/
+
+var resolveP1, rejectP2,
+ p1 = new Promise(function(resolve) {
+ resolveP1 = resolve;
+ }),
+ p2 = new Promise(function(resolve, reject) {
+ rejectP2 = reject;
+ });
+
+Promise.race([p1, p2]).then(function() {
+ throw new Test262Error("Should not be fulfilled: expected rejection.");
+}, function(result) {
+ assert.sameValue(result, 2, 'The value of result is expected to be 2');
+}).then($DONE, $DONE);
+
+rejectP2(2);
+resolveP1(1);
diff --git a/js/src/tests/test262/built-ins/Promise/race/browser.js b/js/src/tests/test262/built-ins/Promise/race/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/race/capability-executor-called-twice.js b/js/src/tests/test262/built-ins/Promise/race/capability-executor-called-twice.js
new file mode 100644
index 0000000000..47dc31e96d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/capability-executor-called-twice.js
@@ -0,0 +1,101 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.3
+description: >
+ Throws a TypeError if capabilities executor already called with non-undefined values.
+info: |
+ Promise.race ( iterable )
+
+ ...
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ 7. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ 25.4.1.5.1 GetCapabilitiesExecutor Functions
+ ...
+ 3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
+ 4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
+ 5. Set promiseCapability.[[Resolve]] to resolve.
+ 6. Set promiseCapability.[[Reject]] to reject.
+ ...
+---*/
+
+var checkPoint = "";
+function fn1(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+fn1.resolve = function() {
+ throw new Test262Error();
+};
+Promise.race.call(fn1 , []);
+assert.sameValue(checkPoint, "abc", "executor initially called with no arguments");
+
+checkPoint = "";
+function fn2(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+fn2.resolve = function() {
+ throw new Test262Error();
+};
+Promise.race.call(fn2 , []);
+assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)");
+
+checkPoint = "";
+function fn3(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+Object.defineProperty(fn3, "resolve", {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.race.call(fn3 , []);
+}, "executor initially called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)");
+
+checkPoint = "";
+function fn4(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+Object.defineProperty(fn4, "resolve", {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.race.call(fn4 , []);
+}, "executor initially called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)");
+
+checkPoint = "";
+function fn5(executor) {
+ checkPoint += "a";
+ executor("invalid value", 123);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}
+Object.defineProperty(fn5, "resolve", {
+ get() { throw new Test262Error(); }
+});
+assert.throws(TypeError, function() {
+ Promise.race.call(fn5 , []);
+}, "executor initially called with (String, Number)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/capability-executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/race/capability-executor-not-callable.js
new file mode 100644
index 0000000000..d5e5bc4783
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/capability-executor-not-callable.js
@@ -0,0 +1,85 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.3
+description: >
+ Throws a TypeError if either resolve or reject capability is not callable.
+info: |
+ Promise.race ( iterable )
+
+ ...
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ 7. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ 25.4.1.5 NewPromiseCapability ( C )
+ ...
+ 4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1).
+ 5. Set the [[Capability]] internal slot of executor to promiseCapability.
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+ 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
+ 9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
+ ...
+---*/
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.race.call(function(executor) {
+ checkPoint += "a";
+ }, []);
+}, "executor not called at all");
+assert.sameValue(checkPoint, "a", "executor not called at all");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.race.call(function(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+ }, []);
+}, "executor called with no arguments");
+assert.sameValue(checkPoint, "ab", "executor called with no arguments");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.race.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+ }, []);
+}, "executor called with (undefined, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.race.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+ }, []);
+}, "executor called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, function)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.race.call(function(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+ }, []);
+}, "executor called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (function, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.race.call(function(executor) {
+ checkPoint += "a";
+ executor(123, "invalid value");
+ checkPoint += "b";
+ }, []);
+}, "executor called with (Number, String)");
+assert.sameValue(checkPoint, "ab", "executor called with (Number, String)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/ctx-ctor-throws.js b/js/src/tests/test262/built-ins/Promise/race/ctx-ctor-throws.js
new file mode 100644
index 0000000000..81988b5dea
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/ctx-ctor-throws.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.race` invoked on a constructor value that throws an error
+es6id: 25.4.4.3
+info: |
+ 1. Let C be the this value.
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ 7. ReturnIfAbrupt(promiseCapability).
+
+ 25.4.1.5 NewPromiseCapability
+ [...]
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+---*/
+
+var CustomPromise = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ Promise.race.call(CustomPromise);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/ctx-ctor.js b/js/src/tests/test262/built-ins/Promise/race/ctx-ctor.js
new file mode 100644
index 0000000000..105b3fba4c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/ctx-ctor.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.race` invoked on a constructor value
+es6id: 25.4.4.3
+info: |
+ 1. Let C be the this value.
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 10. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
+ 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+ [...]
+ 13. Return Completion(result).
+features: [class]
+---*/
+
+var executor = null;
+var callCount = 0;
+
+class SubPromise extends Promise {
+ constructor(a) {
+ super(a);
+ executor = a;
+ callCount += 1;
+ }
+}
+
+var instance = Promise.race.call(SubPromise, []);
+
+assert.sameValue(instance.constructor, SubPromise);
+assert.sameValue(instance instanceof SubPromise, true);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(typeof executor, 'function');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/ctx-non-ctor.js b/js/src/tests/test262/built-ins/Promise/race/ctx-non-ctor.js
new file mode 100644
index 0000000000..5b6b4d7af4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/ctx-non-ctor.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.race` invoked on a non-constructor value
+es6id: 25.4.4.3
+info: |
+ [...]
+ 6. Let promiseCapability be NewPromiseCapability(C).
+ 7. ReturnIfAbrupt(promiseCapability).
+
+ 25.4.1.5 NewPromiseCapability ( C )
+
+ 1. If IsConstructor(C) is false, throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.race.call(eval);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/ctx-non-object.js b/js/src/tests/test262/built-ins/Promise/race/ctx-non-object.js
new file mode 100644
index 0000000000..c2dd20aa00
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/ctx-non-object.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.race` invoked on a non-object value
+es6id: 25.4.4.3
+info: |
+ 1. Let C be the this value.
+ 2. If Type(C) is not Object, throw a TypeError exception.
+features: [Symbol]
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.race.call(undefined, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.race.call(null, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.race.call(86, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.race.call('string', []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.race.call(true, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.race.call(Symbol(), []);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-error-close.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-error-close.js
new file mode 100644
index 0000000000..a152a8b46c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-error-close.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: >
+ Explicit iterator closing in response to error from `Promise.resolve`
+esid: sec-promise.race
+info: |
+ [...]
+ 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+ 12. If result is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator,result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ h. Let nextPromise be Invoke(C, "resolve", «nextValue»).
+ i. ReturnIfAbrupt(nextPromise).
+features: [Symbol.iterator]
+---*/
+
+var iterDoneSpy = {};
+var returnCount = 0;
+iterDoneSpy[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return {
+ value: null,
+ done: false
+ };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+
+Promise.resolve = function() {
+ throw err;
+};
+
+Promise.race(iterDoneSpy);
+
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-error-reject.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-error-reject.js
new file mode 100644
index 0000000000..00a17b0568
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-error-reject.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise rejection in response to error from `Promise.resolve`
+esid: sec-promise.race
+info: |
+ [...]
+ 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+ 12. If result is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator,result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ h. Let nextPromise be Invoke(C, "resolve", «nextValue»).
+ i. ReturnIfAbrupt(nextPromise).
+flags: [async]
+---*/
+
+var err = new Test262Error();
+var CustomPromise = function(executor) {
+ return new Promise(executor);
+};
+
+CustomPromise.resolve = function() {
+ throw err;
+};
+
+Promise.race.call(CustomPromise, [1])
+ .then(function() {
+ throw new Test262Error('The promise should be rejected.');
+ }, function(reason) {
+ assert.sameValue(reason, err);
+ $DONE();
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-error-reject.js
new file mode 100644
index 0000000000..d5cb474730
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-error-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error retrieving the constructor's `resolve` method (promise rejection)
+esid: sec-promise.race
+info: |
+ 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ h. Let nextPromise be Invoke(C, "resolve", «nextValue»).
+ i. ReturnIfAbrupt(nextPromise).
+flags: [async]
+---*/
+
+var error = new Test262Error();
+Object.defineProperty(Promise, 'resolve', {
+ get: function() {
+ throw error;
+ }
+});
+
+Promise.race([new Promise(function() {})]).then(function() {
+ throw new Test262Error('The promise should be rejected');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-error.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-error.js
new file mode 100644
index 0000000000..8c0b8224f9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-error.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Promise.resolve is retrieved before GetIterator call (abrupt lookup).
+info: |
+ Promise.race ( iterable )
+
+ [...]
+ 3. Let promiseResolve be GetPromiseResolve(C).
+ 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
+
+ GetPromiseResolve ( promiseConstructor )
+
+ [...]
+ 2. Let promiseResolve be ? Get(promiseConstructor, "resolve").
+flags: [async]
+features: [Symbol.iterator]
+---*/
+
+const iter = {
+ get [Symbol.iterator]() {
+ throw new Test262Error('unreachable');
+ },
+};
+
+const resolveError = { name: 'MyError' };
+Object.defineProperty(Promise, 'resolve', {
+ get() {
+ throw resolveError;
+ },
+});
+
+Promise.race(iter).then(() => {
+ throw new Test262Error('The promise should be rejected, but it was resolved');
+}, (reason) => {
+ assert.sameValue(reason, resolveError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-once-multiple-calls.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-once-multiple-calls.js
new file mode 100644
index 0000000000..38a700ed21
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-once-multiple-calls.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Gets constructor's `resolve` method once from zero to many invocations.
+esid: sec-promise.race
+info: |
+ Runtime Semantics: PerformPromiseRace
+
+ 1. Let promiseResolve be ? Get(constructor, `"resolve"`).
+ 1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+ ...
+ 1. Repeat,
+ ...
+ 1. Let nextPromise be ? Call(promiseResolve, constructor, &laquo; nextValue &raquo;).
+---*/
+
+var p1 = Promise.resolve(1);
+var p2 = Promise.resolve(1);
+var p3 = Promise.reject(1);
+var p4 = Promise.resolve(1);
+var resolve = Promise.resolve;
+var getCount = 0;
+var callCount = 0;
+
+Object.defineProperty(Promise, 'resolve', {
+ configurable: true,
+ get() {
+ getCount += 1;
+ return function() {
+ callCount += 1;
+ return resolve.apply(Promise, arguments);
+ };
+ }
+});
+
+Promise.race([p1, p2, p3, p4]);
+
+assert.sameValue(
+ getCount, 1, 'Got `resolve` only once for each iterated value'
+);
+assert.sameValue(
+ callCount, 4, '`resolve` invoked once for each iterated value'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-once-no-calls.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-once-no-calls.js
new file mode 100644
index 0000000000..43e6718a67
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-get-once-no-calls.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Gets constructor's `resolve` method once from zero to many invocations.
+esid: sec-promise.race
+info: |
+ Runtime Semantics: PerformPromiseRace
+
+ 1. Let promiseResolve be ? Get(constructor, `"resolve"`).
+ 1. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+ ...
+ 1. Repeat,
+ ...
+ 1. Let nextPromise be ? Call(promiseResolve, constructor, &laquo; nextValue &raquo;).
+---*/
+
+var resolve = Promise.resolve;
+var getCount = 0;
+var callCount = 0;
+
+Object.defineProperty(Promise, 'resolve', {
+ configurable: true,
+ get() {
+ getCount += 1;
+ return function() {
+ callCount += 1;
+ return resolve.apply(Promise, arguments);
+ };
+ }
+});
+
+Promise.race([]);
+
+assert.sameValue(
+ getCount, 1, 'Got `resolve` only once for each iterated value'
+);
+assert.sameValue(
+ callCount, 0, '`resolve` not called for empty iterator'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-custom.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-custom.js
new file mode 100644
index 0000000000..a84e88a5fa
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-custom.js
@@ -0,0 +1,44 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with promise values
+esid: sec-promise.race
+info: |
+ Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
+
+ PerformPromiseRace
+
+ Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [class, arrow-function]
+---*/
+class Custom extends Promise {}
+
+let values = [1, 1, 1];
+let cresolveCallCount = 0;
+let presolveCallCount = 0;
+let boundCustomResolve = Custom.resolve.bind(Custom);
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Custom.resolve = function(...args) {
+ cresolveCallCount += 1;
+ return boundCustomResolve(...args);
+};
+
+Promise.resolve = function(...args) {
+ presolveCallCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.race.call(Custom, values)
+ .then(() => {
+ assert.sameValue(presolveCallCount, 0, '`Promise.resolve` is never invoked');
+ assert.sameValue(cresolveCallCount, 3, '`Custom.resolve` invoked once for every item in iterable arg');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-promise.js
new file mode 100644
index 0000000000..1f5857c182
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-promise.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with promise values
+esid: sec-promise.race
+info: |
+ Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
+
+ PerformPromiseRace
+
+ Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [arrow-function]
+---*/
+
+let values = [1, 1, 1];
+let callCount = 0;
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Promise.resolve = function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.race(values)
+ .then(() => {
+ assert.sameValue(callCount, 3, '`then` invoked once for every item in iterable arg');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-values-every-iteration-of-promise.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-values-every-iteration-of-promise.js
new file mode 100644
index 0000000000..137367bef1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-on-values-every-iteration-of-promise.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method for iterable with non-promise values
+esid: sec-promise.race
+info: |
+ Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
+
+ PerformPromiseRace
+
+ Repeat
+ ...
+ i. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+
+flags: [async]
+features: [arrow-function]
+---*/
+
+let values = [1, 2, 3];
+let callCount = 0;
+let boundPromiseResolve = Promise.resolve.bind(Promise);
+
+Promise.resolve = function(...args) {
+ callCount += 1;
+ return boundPromiseResolve(...args);
+};
+
+Promise.race(values)
+ .then(() => {
+ assert.sameValue(callCount, 3, '`Promise.resolve` invoked once for every item in iterable arg');
+ }).then($DONE, $DONE);
+
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-return.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-return.js
new file mode 100644
index 0000000000..87f3f16312
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve-return.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: Use of the value returned by the constructor's `resolve` method.
+es6id: 25.4.4.1
+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
+ [...]
+ h. Let nextPromise be Invoke(C, "resolve", «nextValue»).
+ [...]
+ j. Let result be Invoke(nextPromise, "then",
+ «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+ [...]
+---*/
+
+var originalCallCount = 0;
+var newCallCount = 0;
+var P = function(executor) {
+ executor(function() {}, function() {});
+};
+P.resolve = function() {
+ return newThenable;
+};
+
+var originalThenable = {
+ then: function() {
+ originalCallCount += 1;
+ }
+};
+var newThenable = {
+ then: function() {
+ newCallCount += 1;
+ }
+};
+
+Promise.race.call(P, [originalThenable]);
+
+assert.sameValue(originalCallCount, 0, 'original `then` method not invoked');
+assert.sameValue(newCallCount, 1, 'new `then` method invoked exactly once');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-resolve.js b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve.js
new file mode 100644
index 0000000000..8ffdf6efae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-resolve.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the constructor's `resolve` method
+es6id: 25.4.4.3
+info: |
+ 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
+
+ [...]
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ h. Let nextPromise be Invoke(C, "resolve", «nextValue»).
+---*/
+
+var p1 = new Promise(function() {});
+var p2 = new Promise(function() {});
+var p3 = new Promise(function() {});
+var resolve = Promise.resolve;
+var callCount = 0;
+var current = p1;
+var next = p2;
+var afterNext = p3;
+
+Promise.resolve = function(nextValue) {
+ assert.sameValue(
+ nextValue, current, '`resolve` invoked with next iterated value'
+ );
+ assert.sameValue(
+ arguments.length, 1, '`resolve` invoked with a single argument'
+ );
+ assert.sameValue(this, Promise, '`this` value set to the constructor');
+
+ current = next;
+ next = afterNext;
+ afterNext = null;
+
+ callCount += 1;
+
+ return resolve.apply(Promise, arguments);
+};
+
+Promise.race([p1, p2, p3]);
+
+assert.sameValue(
+ callCount, 3, '`resolve` invoked once for each iterated value'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-then-error-close.js b/js/src/tests/test262/built-ins/Promise/race/invoke-then-error-close.js
new file mode 100644
index 0000000000..b6d7e9f67c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-then-error-close.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: >
+ Error thrown when invoking the instance's `then` method (closing iterator)
+esid: sec-promise.race
+info: |
+ 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ j. Let result be Invoke(nextPromise, "then",
+ «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+ k. ReturnIfAbrupt(result).
+features: [Symbol.iterator]
+---*/
+
+var promise = new Promise(function() {});
+var iter = {};
+var returnCount = 0;
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return {
+ done: false,
+ value: promise
+ };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+promise.then = function() {
+ throw new Test262Error();
+};
+
+Promise.race(iter);
+
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-then-error-reject.js b/js/src/tests/test262/built-ins/Promise/race/invoke-then-error-reject.js
new file mode 100644
index 0000000000..2b391dd34e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-then-error-reject.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error thrown when invoking the instance's `then` method (rejecting promise)
+esid: sec-promise.race
+info: |
+ 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ j. Let result be Invoke(nextPromise, "then",
+ «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+ k. ReturnIfAbrupt(result).
+flags: [async]
+---*/
+
+var promise = new Promise(function() {});
+var error = new Test262Error();
+
+promise.then = function() {
+ throw error;
+};
+
+Promise.race([promise]).then(function() {
+ throw new Test262Error('The promise should be rejected');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-then-get-error-close.js b/js/src/tests/test262/built-ins/Promise/race/invoke-then-get-error-close.js
new file mode 100644
index 0000000000..e67faa28cd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-then-get-error-close.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: >
+ Error thrown when accessing the instance's `then` method (closing iterator)
+esid: sec-promise.race
+info: |
+ 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ j. Let result be Invoke(nextPromise, "then",
+ «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+ k. ReturnIfAbrupt(result).
+features: [Symbol.iterator]
+---*/
+
+var promise = new Promise(function() {});
+var iter = {};
+var returnCount = 0;
+iter[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return {
+ done: false,
+ value: promise
+ };
+ },
+ return: function() {
+ returnCount += 1;
+ return {};
+ }
+ };
+};
+Object.defineProperty(promise, 'then', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+Promise.race(iter);
+
+assert.sameValue(returnCount, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-then-get-error-reject.js b/js/src/tests/test262/built-ins/Promise/race/invoke-then-get-error-reject.js
new file mode 100644
index 0000000000..2c97adee85
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-then-get-error-reject.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Error thrown when accessing the instance's `then` method (rejecting promise)
+esid: sec-promise.race
+info: |
+ 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ j. Let result be Invoke(nextPromise, "then",
+ «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+ k. ReturnIfAbrupt(result).
+flags: [async]
+---*/
+
+var promise = new Promise(function() {});
+var error = new Test262Error();
+
+Object.defineProperty(promise, 'then', {
+ get: function() {
+ throw error;
+ }
+});
+
+Promise.race([promise]).then(function() {
+ throw new Test262Error('The promise should be rejected');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/invoke-then.js b/js/src/tests/test262/built-ins/Promise/race/invoke-then.js
new file mode 100644
index 0000000000..3f1ecab814
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/invoke-then.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Invocation of the instance's `then` method
+es6id: 25.4.4.3
+info: |
+ 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
+
+ [...]
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ j. Let result be Invoke(nextPromise, "then",
+ «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+ k. ReturnIfAbrupt(result).
+---*/
+
+var p1 = new Promise(function() {});
+var p2 = new Promise(function() {});
+var p3 = new Promise(function() {});
+var callCount = 0;
+var currentThis = p1;
+var nextThis = p2;
+var afterNextThis = p3;
+
+p1.then = p2.then = p3.then = function(a, b) {
+ assert.sameValue(typeof a, 'function', 'type of first argument');
+ assert.sameValue(
+ a.length,
+ 1,
+ 'ES6 25.4.1.3.2: The length property of a promise resolve function is 1.'
+ );
+ assert.sameValue(typeof b, 'function', 'type of second argument');
+ assert.sameValue(
+ b.length,
+ 1,
+ 'ES6 25.4.1.3.1: The length property of a promise reject function is 1.'
+ );
+ assert.sameValue(arguments.length, 2, '`then` invoked with two arguments');
+ assert.sameValue(this, currentThis, '`this` value');
+
+ currentThis = nextThis;
+ nextThis = afterNextThis;
+ afterNextThis = null;
+
+ callCount += 1;
+};
+
+Promise.race([p1, p2, p3]);
+
+assert.sameValue(callCount, 3, '`then` invoked once for every iterated value');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-false-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-false-reject.js
new file mode 100644
index 0000000000..666fbeead7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-false-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument is `false`
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race(false).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-null-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-null-reject.js
new file mode 100644
index 0000000000..c34066d33c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-null-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument is `null`
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race(null).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-number-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-number-reject.js
new file mode 100644
index 0000000000..9c077ee83a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-number-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument is a number
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race(1).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-string-resolve.js b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-string-resolve.js
new file mode 100644
index 0000000000..acf600e838
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-string-resolve.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Resolve when argument is a string
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race("a").then(function(v) {
+ assert.sameValue(v, "a");
+ }, function() {
+ $DONE('The promise should be resolved, but was rejected');
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be resolved, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-symbol-reject.js
new file mode 100644
index 0000000000..86dee03495
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-symbol-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument is a symbol
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race(Symbol()).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-true-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-true-reject.js
new file mode 100644
index 0000000000..1f85fed248
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-true-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument is `true`
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race(true).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-undefined-reject.js
new file mode 100644
index 0000000000..b14a91acf9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-arg-is-undefined-reject.js
@@ -0,0 +1,34 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument is `undefined`
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race(undefined).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-assigned-false-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-false-reject.js
new file mode 100644
index 0000000000..b7342a76b1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-false-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator property has the value false
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]: false
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-assigned-null-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-null-reject.js
new file mode 100644
index 0000000000..742970a8a3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-null-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator property has the value null
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]: null
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-assigned-number-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-number-reject.js
new file mode 100644
index 0000000000..4c471a6d55
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-number-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator property has the value 1
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]: 1
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-assigned-string-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-string-reject.js
new file mode 100644
index 0000000000..f35bb7abf2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-string-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator property has the value ""
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]: ""
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-assigned-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-symbol-reject.js
new file mode 100644
index 0000000000..e5bb702110
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-symbol-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator property has the value Symbol()
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]: Symbol()
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-assigned-true-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-true-reject.js
new file mode 100644
index 0000000000..d633aba403
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-true-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator property has the value true
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]: true
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-assigned-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-undefined-reject.js
new file mode 100644
index 0000000000..dbefa628a4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-assigned-undefined-reject.js
@@ -0,0 +1,36 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator property has the value undefined
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]: undefined
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-next-val-err-no-close.js b/js/src/tests/test262/built-ins/Promise/race/iter-next-val-err-no-close.js
new file mode 100644
index 0000000000..74adaa02ae
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-next-val-err-no-close.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: >
+ Error when accessing an iterator result's `value` property (not closing
+ iterator)
+esid: sec-promise.race
+info: |
+ 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ e. Let nextValue be IteratorValue(next).
+ f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ g. ReturnIfAbrupt(nextValue).
+features: [Symbol.iterator]
+---*/
+
+var iterNextValThrows = {};
+var returnCount = 0;
+var poisonedVal = {
+ done: false
+};
+var error = new Test262Error();
+Object.defineProperty(poisonedVal, 'value', {
+ get: function() {
+ throw error;
+ }
+});
+iterNextValThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedVal;
+ },
+ return: function() {
+ returnCount += 1;
+ }
+ };
+};
+
+Promise.race(iterNextValThrows);
+
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-next-val-err-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-next-val-err-reject.js
new file mode 100644
index 0000000000..866d9af062
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-next-val-err-reject.js
@@ -0,0 +1,53 @@
+// |reftest| async
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error when accessing an iterator result's `value` property (rejecting
+ promise)
+esid: sec-promise.race
+info: |
+ 11. Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
+ 12. If result is an abrupt completion,
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator, result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ [...]
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+
+ 1. Repeat
+ [...]
+ e. Let nextValue be IteratorValue(next).
+ f. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to
+ true.
+ g. ReturnIfAbrupt(nextValue).
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+var iterNextValThrows = {};
+var poisonedVal = {
+ done: false
+};
+var error = new Test262Error();
+Object.defineProperty(poisonedVal, 'value', {
+ get: function() {
+ throw error;
+ }
+});
+iterNextValThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedVal;
+ }
+ };
+};
+
+Promise.race(iterNextValThrows).then(function() {
+ $DONE('The promise should be rejected.');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-returns-false-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-returns-false-reject.js
new file mode 100644
index 0000000000..06d9baa284
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-returns-false-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator returns false
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]() {
+ return false;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-returns-null-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-returns-null-reject.js
new file mode 100644
index 0000000000..4e450e961d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-returns-null-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator returns null
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]() {
+ return null;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-returns-number-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-returns-number-reject.js
new file mode 100644
index 0000000000..2c5db3d16d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-returns-number-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator returns a number
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]() {
+ return 1;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-returns-string-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-returns-string-reject.js
new file mode 100644
index 0000000000..10e860ba82
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-returns-string-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator returns a string
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]() {
+ return "";
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-returns-symbol-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-returns-symbol-reject.js
new file mode 100644
index 0000000000..d1493510ac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-returns-symbol-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator returns a symbol
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]() {
+ return Symbol();
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-returns-true-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-returns-true-reject.js
new file mode 100644
index 0000000000..0be813db4f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-returns-true-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator returns true
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]() {
+ return true;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-returns-undefined-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-returns-undefined-reject.js
new file mode 100644
index 0000000000..1a8e034a33
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-returns-undefined-reject.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Reject when argument's Symbol.iterator returns undefined
+info: |
+ ...
+ Let iteratorRecord be GetIterator(iterable).
+ IfAbruptRejectPromise(iteratorRecord, promiseCapability).
+ ...
+
+ #sec-getiterator
+ GetIterator ( obj [ , hint [ , method ] ] )
+
+ ...
+ Let iterator be ? Call(method, obj).
+ If Type(iterator) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+try {
+ Promise.race({
+ [Symbol.iterator]() {
+ return undefined;
+ }
+ }).then(function() {
+ $DONE('The promise should be rejected, but was resolved');
+ }, function(error) {
+ assert(error instanceof TypeError);
+ }).then($DONE, $DONE);
+} catch (error) {
+ $DONE(`The promise should be rejected, but threw an exception: ${error.message}`);
+}
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-step-err-no-close.js b/js/src/tests/test262/built-ins/Promise/race/iter-step-err-no-close.js
new file mode 100644
index 0000000000..624fc107e8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-step-err-no-close.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: >
+ Error when advancing the provided iterable (not closing iterator)
+esid: sec-promise.race
+info: |
+ [...]
+ 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+ 12. If result is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator,result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+ 1. Repeat
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+features: [Symbol.iterator]
+---*/
+
+var iterStepThrows = {};
+var poisonedDone = {};
+var returnCount = 0;
+var error = new Test262Error();
+Object.defineProperty(poisonedDone, 'done', {
+ get: function() {
+ throw error;
+ }
+});
+Object.defineProperty(poisonedDone, 'value', {
+ get: function() {
+ throw new Test262Error('The `value` property should not be accessed.');
+ }
+});
+
+iterStepThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedDone;
+ },
+ return: function() {
+ returnCount += 1;
+ }
+ };
+};
+
+Promise.race(iterStepThrows);
+
+assert.sameValue(returnCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/iter-step-err-reject.js b/js/src/tests/test262/built-ins/Promise/race/iter-step-err-reject.js
new file mode 100644
index 0000000000..3b3a3e35a6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/iter-step-err-reject.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Error when advancing the provided iterable (rejecting promise)
+esid: sec-promise.race
+info: |
+ [...]
+ 11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
+ 12. If result is an abrupt completion, then
+ a. If iteratorRecord.[[done]] is false, let result be
+ IteratorClose(iterator,result).
+ b. IfAbruptRejectPromise(result, promiseCapability).
+
+ 25.4.4.3.1 Runtime Semantics: PerformPromiseRace
+ 1. Repeat
+ a. Let next be IteratorStep(iteratorRecord.[[iterator]]).
+ b. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
+ c. ReturnIfAbrupt(next).
+features: [Symbol.iterator]
+flags: [async]
+---*/
+
+var iterStepThrows = {};
+var poisonedDone = {};
+var error = new Test262Error();
+Object.defineProperty(poisonedDone, 'done', {
+ get: function() {
+ throw error;
+ }
+});
+Object.defineProperty(poisonedDone, 'value', {
+ get: function() {
+ throw new Test262Error('The `value` property should not be accessed.');
+ }
+});
+
+iterStepThrows[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return poisonedDone;
+ }
+ };
+};
+
+Promise.race(iterStepThrows).then(function() {
+ $DONE('The promise should be rejected.');
+}, function(reason) {
+ assert.sameValue(reason, error);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/length.js b/js/src/tests/test262/built-ins/Promise/race/length.js
new file mode 100644
index 0000000000..0fa1f53d8e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/length.js
@@ -0,0 +1,27 @@
+// 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.4.3
+description: Promise.race `length` property
+info: |
+ ES6 Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.race.length, 1);
+
+verifyNotEnumerable(Promise.race, 'length');
+verifyNotWritable(Promise.race, 'length');
+verifyConfigurable(Promise.race, 'length');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/name.js b/js/src/tests/test262/built-ins/Promise/race/name.js
new file mode 100644
index 0000000000..e88d3384ef
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/name.js
@@ -0,0 +1,28 @@
+// 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.4.3
+description: Promise.race `name` property
+info: |
+ ES6 Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.race.name, 'race');
+
+verifyNotEnumerable(Promise.race, 'name');
+verifyNotWritable(Promise.race, 'name');
+verifyConfigurable(Promise.race, 'name');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/race/not-a-constructor.js
new file mode 100644
index 0000000000..a6e0f33d59
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/not-a-constructor.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Promise.race does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(Promise.race), false, 'isConstructor(Promise.race) must return false');
+
+assert.throws(TypeError, () => {
+ new Promise.race([]);
+}, '`new Promise.race([])` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/prop-desc.js b/js/src/tests/test262/built-ins/Promise/race/prop-desc.js
new file mode 100644
index 0000000000..ff99905270
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/prop-desc.js
@@ -0,0 +1,21 @@
+// Copyright 2015 Jordan Harband. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: 25.4.4.3_A1.2_T1
+author: Jordan Harband
+description: Promise.race property descriptor
+info: |
+ ES6 Section 17
+
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(Promise, 'race');
+verifyWritable(Promise, 'race');
+verifyConfigurable(Promise, 'race');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/reject-deferred.js b/js/src/tests/test262/built-ins/Promise/race/reject-deferred.js
new file mode 100644
index 0000000000..4ff5cea941
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/reject-deferred.js
@@ -0,0 +1,42 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting through deferred invocation of the provided resolving function
+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.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var thenable = {
+ then: function(_, reject) {
+ new Promise(function(resolve) {
+ resolve();
+ })
+ .then(function() {
+ reject();
+ });
+ }
+};
+
+Promise.race([thenable])
+ .then(function() {
+ $DONE('The promise should not be fulfilled.');
+ }, function() {
+ $DONE();
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/race/reject-from-same-thenable.js b/js/src/tests/test262/built-ins/Promise/race/reject-from-same-thenable.js
new file mode 100644
index 0000000000..25601b9361
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/reject-from-same-thenable.js
@@ -0,0 +1,65 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiserace
+description: >
+ Promise.race does not prevent resolve from being called multiple times.
+info: |
+ PerformPromiseRace
+
+ Repeat,
+ Let next be IteratorStep(iteratorRecord).
+ If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(next).
+ If next is false, then
+ Set iteratorRecord.[[Done]] to true.
+ Return resultCapability.[[Promise]].
+ Let nextValue be IteratorValue(next).
+ If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(nextValue).
+ Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
+
+includes: [promiseHelper.js]
+---*/
+
+let callCount = 0;
+let sequence = [];
+
+function Constructor(executor) {
+ function reject(value) {
+ callCount += 1;
+ sequence.push(value);
+ }
+ executor(() => {
+ throw new Test262Error();
+ }, reject);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+let pReject;
+
+let a = {
+ then(_, rejecter) {
+ pReject = rejecter;
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to race()');
+
+Promise.race.call(Constructor, [a]);
+
+assert.sameValue(callCount, 0, 'callCount after call to race()');
+
+pReject(1);
+pReject(2);
+pReject(3);
+
+assert.sameValue(callCount, 3, 'callCount after resolving a');
+assert.sameValue(sequence.length, 3);
+checkSequence(sequence);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/reject-ignored-deferred.js b/js/src/tests/test262/built-ins/Promise/race/reject-ignored-deferred.js
new file mode 100644
index 0000000000..9c19236a74
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/reject-ignored-deferred.js
@@ -0,0 +1,57 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Resolved promises ignore rejections through deferred invocation of the
+ provided resolving function
+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.1 Promise Reject Functions
+ [...]
+ 2. Let promise be the value of F's [[Promise]] internal slot.
+ 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal
+ slot.
+ 4. If alreadyResolved.[[value]] is true, return undefined.
+flags: [async]
+---*/
+
+var fulfiller = {
+ then: function(resolve) {
+ new Promise(function(resolve) {
+ resolve();
+ })
+ .then(function() {
+ resolve();
+ });
+ }
+};
+var rejector = {
+ then: function(_, reject) {
+ new Promise(function(resolve) {
+ resolve();
+ })
+ .then(function() {
+ reject();
+ });
+ }
+};
+
+Promise.race([fulfiller, rejector])
+ .then(function() {
+ $DONE();
+ }, function() {
+ $DONE('The promise should not be rejected.');
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/race/reject-ignored-immed.js b/js/src/tests/test262/built-ins/Promise/race/reject-ignored-immed.js
new file mode 100644
index 0000000000..32404d046b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/reject-ignored-immed.js
@@ -0,0 +1,47 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Resolved promises ignore rejections through immediate invocation of the
+ provided resolving function
+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.1 Promise Reject Functions
+ [...]
+ 2. Let promise be the value of F's [[Promise]] internal slot.
+ 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal
+ slot.
+ 4. If alreadyResolved.[[value]] is true, return undefined.
+flags: [async]
+---*/
+
+var fulfiller = {
+ then: function(resolve) {
+ resolve();
+ }
+};
+var rejector = {
+ then: function(_, reject) {
+ reject();
+ }
+};
+
+Promise.race([fulfiller, rejector])
+ .then(function() {
+ $DONE();
+ }, function() {
+ $DONE('The promise should not be rejected.');
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/race/reject-immed.js b/js/src/tests/test262/built-ins/Promise/race/reject-immed.js
new file mode 100644
index 0000000000..9e079b496e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/reject-immed.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting through immediate invocation of the provided resolving function
+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.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var thenable = {
+ then: function(_, reject) {
+ reject();
+ }
+};
+
+Promise.race([thenable])
+ .then(function() {
+ $DONE('The promise should not be fulfilled.');
+ }, function() {
+ $DONE();
+ });
diff --git a/js/src/tests/test262/built-ins/Promise/race/resolve-from-same-thenable.js b/js/src/tests/test262/built-ins/Promise/race/resolve-from-same-thenable.js
new file mode 100644
index 0000000000..df4a3c4daf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-from-same-thenable.js
@@ -0,0 +1,62 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-performpromiserace
+description: >
+ Promise.race does not prevent resolve from being called multiple times.
+info: |
+ PerformPromiseRace
+
+ Repeat,
+ Let next be IteratorStep(iteratorRecord).
+ If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(next).
+ If next is false, then
+ Set iteratorRecord.[[Done]] to true.
+ Return resultCapability.[[Promise]].
+ Let nextValue be IteratorValue(next).
+ If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(nextValue).
+ Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
+
+includes: [promiseHelper.js]
+---*/
+
+let callCount = 0;
+let sequence = [];
+
+function Constructor(executor) {
+ function resolve(value) {
+ callCount += 1;
+ sequence.push(value);
+ }
+ executor(resolve, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+let pResolve;
+let a = {
+ then(resolver, rejector) {
+ pResolve = resolver;
+ }
+};
+
+assert.sameValue(callCount, 0, 'callCount before call to race()');
+
+Promise.race.call(Constructor, [a]);
+
+assert.sameValue(callCount, 0, 'callCount after call to race()');
+
+pResolve(1);
+pResolve(2);
+pResolve(3);
+
+assert.sameValue(callCount, 3, 'callCount after resolving a');
+assert.sameValue(sequence.length, 3);
+checkSequence(sequence);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/resolve-ignores-late-rejection-deferred.js b/js/src/tests/test262/built-ins/Promise/race/resolve-ignores-late-rejection-deferred.js
new file mode 100644
index 0000000000..6640930c46
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-ignores-late-rejection-deferred.js
@@ -0,0 +1,47 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through deferred invocation of the
+ provided resolving function
+esid: sec-promise.race
+info: |
+ Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
+
+ PerformPromiseRace
+
+ Repeat
+ ...
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
+
+flags: [async]
+features: [arrow-function]
+includes: [promiseHelper.js]
+---*/
+
+let sequence = [1];
+let lateRejector = {
+ then(resolve, reject) {
+ return new Promise((resolve) => {
+ sequence.push(3);
+ resolve();
+ sequence.push(4);
+ }).then(() => {
+ sequence.push(5);
+ resolve(9);
+ sequence.push(6);
+ reject();
+ sequence.push(7);
+ });
+ }
+};
+sequence.push(2);
+
+Promise.race([lateRejector])
+ .then(resolution => {
+ assert.sameValue(resolution, 9);
+ assert.sameValue(sequence.length, 7);
+ checkSequence(sequence);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/resolve-ignores-late-rejection.js b/js/src/tests/test262/built-ins/Promise/race/resolve-ignores-late-rejection.js
new file mode 100644
index 0000000000..c981b0e04e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-ignores-late-rejection.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron, 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Resolved promises ignore rejections through immediate invocation of the
+ provided resolving function
+esid: sec-promise.race
+info: |
+ Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve).
+
+ PerformPromiseRace
+
+ Repeat
+ ...
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
+
+flags: [async]
+features: [arrow-function]
+---*/
+
+let resolver = {
+ then(resolve) {
+ resolve(42);
+ }
+};
+let lateRejector = {
+ then(resolve, reject) {
+ resolve(33);
+ reject();
+ }
+};
+
+Promise.race([resolver, lateRejector])
+ .then(resolution => {
+ assert.sameValue(resolution, 42);
+ }).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/resolve-non-callable.js b/js/src/tests/test262/built-ins/Promise/race/resolve-non-callable.js
new file mode 100644
index 0000000000..b47413a78c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-non-callable.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2020 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Promise.resolve is retrieved before GetIterator call (non-callable).
+info: |
+ Promise.race ( iterable )
+
+ [...]
+ 3. Let promiseResolve be GetPromiseResolve(C).
+ 4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
+
+ GetPromiseResolve ( promiseConstructor )
+
+ [...]
+ 2. Let promiseResolve be ? Get(promiseConstructor, "resolve").
+ 3. If IsCallable(promiseResolve) is false, throw a TypeError exception.
+flags: [async]
+features: [Symbol.iterator]
+---*/
+
+const iter = { 
+ get [Symbol.iterator]() {
+ throw new Test262Error("unreachable");
+ },
+};
+
+Promise.resolve = "certainly not callable";
+
+Promise.race(iter).then(() => {
+ throw new Test262Error("The promise should be rejected, but it was resolved");
+}, (reason) => {
+ assert(reason instanceof TypeError);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/resolve-non-obj.js b/js/src/tests/test262/built-ins/Promise/race/resolve-non-obj.js
new file mode 100644
index 0000000000..1cee83de79
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-non-obj.js
@@ -0,0 +1,42 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/race/resolve-non-thenable.js b/js/src/tests/test262/built-ins/Promise/race/resolve-non-thenable.js
new file mode 100644
index 0000000000..4fd8820f2a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-non-thenable.js
@@ -0,0 +1,47 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/race/resolve-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/race/resolve-poisoned-then.js
new file mode 100644
index 0000000000..d31b42eacc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-poisoned-then.js
@@ -0,0 +1,49 @@
+// |reftest| async
+// Copyright (C) 2015 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.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]]).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/race/resolve-prms-cstm-then.js b/js/src/tests/test262/built-ins/Promise/race/resolve-prms-cstm-then.js
new file mode 100644
index 0000000000..a31f9b2133
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-prms-cstm-then.js
@@ -0,0 +1,56 @@
+// |reftest| async
+// 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 resolved Promise instance whose `then` method has been overridden
+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»)
+flags: [async]
+---*/
+
+var value = {};
+var thenableValue = {
+ then: function(resolve) {
+ resolve(value);
+ }
+};
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+
+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/js/src/tests/test262/built-ins/Promise/race/resolve-self.js b/js/src/tests/test262/built-ins/Promise/race/resolve-self.js
new file mode 100644
index 0000000000..13da6da562
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-self.js
@@ -0,0 +1,59 @@
+// |reftest| async
+// Copyright (C) 2015 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.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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/race/resolve-thenable.js b/js/src/tests/test262/built-ins/Promise/race/resolve-thenable.js
new file mode 100644
index 0000000000..72a91dc07f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolve-thenable.js
@@ -0,0 +1,54 @@
+// |reftest| async
+// 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»)
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/race/resolved-sequence-extra-ticks.js b/js/src/tests/test262/built-ins/Promise/race/resolved-sequence-extra-ticks.js
new file mode 100644
index 0000000000..6336fa8900
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolved-sequence-extra-ticks.js
@@ -0,0 +1,43 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: Resolution ticks are set in a predictable sequence with extra then calls
+info: |
+ PerformPromiseRace
+
+ Repeat,
+ Let next be IteratorStep(iteratorRecord).
+ If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(next).
+ If next is false, then
+ Set iteratorRecord.[[Done]] to true.
+ Return resultCapability.[[Promise]].
+ Let nextValue be IteratorValue(next).
+ If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(nextValue).
+ Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
+
+flags: [async]
+includes: [promiseHelper.js]
+---*/
+
+let a = new Promise(resolve => resolve({}));
+let sequence = [1];
+Promise.all([
+ Promise.race([a]).then(resolved => {
+ sequence.push(4);
+ }),
+ a.then(() => {
+ sequence.push(3);
+ }).then(() => {
+ sequence.push(5);
+ }),
+]).then(() => {
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence);
+}).then($DONE, $DONE);
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/resolved-sequence-mixed.js b/js/src/tests/test262/built-ins/Promise/race/resolved-sequence-mixed.js
new file mode 100644
index 0000000000..0c96494897
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolved-sequence-mixed.js
@@ -0,0 +1,49 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Resolution ticks are set in a predictable sequence of mixed fulfilled and rejected promises
+info: |
+ PerformPromiseRace
+
+ Repeat,
+ Let next be IteratorStep(iteratorRecord).
+ If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(next).
+ If next is false, then
+ Set iteratorRecord.[[Done]] to true.
+ Return resultCapability.[[Promise]].
+ Let nextValue be IteratorValue(next).
+ If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(nextValue).
+ Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
+
+flags: [async]
+includes: [promiseHelper.js]
+---*/
+
+let a = Promise.reject('');
+let b = new Promise(resolve => resolve(''));
+let c = new Promise((_, reject) => reject(''));
+let sequence = [1];
+Promise.all([
+ a.catch(() => {
+ sequence.push(3);
+ }),
+ Promise.race([a, b, c]).then(() => {
+ // This should not be present when the final
+ // sequence is evaluated.
+ sequence.push(5);
+ }),
+ b.then(() => {
+ sequence.push(4);
+ }),
+]).catch(() => {
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence);
+}).then($DONE, $DONE);
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/resolved-sequence-with-rejections.js b/js/src/tests/test262/built-ins/Promise/race/resolved-sequence-with-rejections.js
new file mode 100644
index 0000000000..882684d04f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolved-sequence-with-rejections.js
@@ -0,0 +1,53 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: Resolution ticks are set in a predictable sequence
+info: |
+ PerformPromiseRace
+
+ Repeat,
+ Let next be IteratorStep(iteratorRecord).
+ If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(next).
+ If next is false, then
+ Set iteratorRecord.[[Done]] to true.
+ Return resultCapability.[[Promise]].
+ Let nextValue be IteratorValue(next).
+ If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(nextValue).
+ Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
+
+flags: [async]
+includes: [compareArray.js,promiseHelper.js]
+---*/
+
+let a = new Promise((_, reject) => reject('a'));
+let b = new Promise((_, reject) => reject('b'));
+let sequence = [1];
+Promise.all([
+ a.catch(() => {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ return checkSequence(sequence, 'Expected to be called first.');
+ }),
+ Promise.race([a, b]).catch(() => {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ return checkSequence(sequence, 'Expected to be called third.');
+ }),
+ b.catch(() => {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ return checkSequence(sequence, 'Expected to be called second.');
+ })
+]).then(result => {
+ assert.compareArray(result, [true, true, true]);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence);
+}).then($DONE, $DONE);
+
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/resolved-sequence.js b/js/src/tests/test262/built-ins/Promise/race/resolved-sequence.js
new file mode 100644
index 0000000000..316db984bf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolved-sequence.js
@@ -0,0 +1,52 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: Resolution ticks are set in a predictable sequence
+info: |
+ PerformPromiseRace
+
+ Repeat,
+ Let next be IteratorStep(iteratorRecord).
+ If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(next).
+ If next is false, then
+ Set iteratorRecord.[[Done]] to true.
+ Return resultCapability.[[Promise]].
+ Let nextValue be IteratorValue(next).
+ If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(nextValue).
+ Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
+
+flags: [async]
+includes: [compareArray.js,promiseHelper.js]
+---*/
+
+let a = new Promise(resolve => resolve('a'));
+let b = new Promise(resolve => resolve('b'));
+let sequence = [1];
+Promise.all([
+ a.then(() => {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ return checkSequence(sequence, 'Expected to be called first.');
+ }),
+ Promise.race([a, b]).then(() => {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ return checkSequence(sequence, 'Expected to be called third.');
+ }),
+ b.then(() => {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ return checkSequence(sequence, 'Expected to be called second.');
+ })
+]).then(result => {
+ assert.compareArray(result, [true, true, true]);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence)
+}).then($DONE, $DONE);
+sequence.push(2);
diff --git a/js/src/tests/test262/built-ins/Promise/race/resolved-then-catch-finally.js b/js/src/tests/test262/built-ins/Promise/race/resolved-then-catch-finally.js
new file mode 100644
index 0000000000..5423f9a653
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/resolved-then-catch-finally.js
@@ -0,0 +1,40 @@
+// |reftest| async
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise.race
+description: >
+ Resolution the first resolved promise
+info: |
+ PerformPromiseRace
+
+ Repeat,
+ Let next be IteratorStep(iteratorRecord).
+ If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(next).
+ If next is false, then
+ Set iteratorRecord.[[Done]] to true.
+ Return resultCapability.[[Promise]].
+ Let nextValue be IteratorValue(next).
+ If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
+ ReturnIfAbrupt(nextValue).
+ Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
+ Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
+
+flags: [async]
+---*/
+
+let a = Promise.reject('a').catch((v) => v);
+let b = Promise.resolve('b').then((v) => { throw v });
+let c = Promise.reject('c').then((v) => { throw v; });
+let d = Promise.resolve('d').finally((v) => v);
+let e = Promise.reject('e').finally((v) => v);
+let f = Promise.resolve('f').finally((v) => { throw v; });
+let g = Promise.reject('g').finally((v) => { throw v; });
+let h = Promise.reject('h').then((v) => v, () => 'j');
+let i = Promise.resolve('i').then(v => v);
+
+Promise.race([a, b, c, d, e, f, g, h, i]).then(winner => {
+ assert.sameValue(winner, 'a');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/race/same-reject-function.js b/js/src/tests/test262/built-ins/Promise/race/same-reject-function.js
new file mode 100644
index 0000000000..a19c469ffc
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/same-reject-function.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.3.1
+description: >
+ Each Promise.race element is called with the same reject function.
+info: |
+ Runtime Semantics: PerformPromiseRace ( iteratorRecord, promiseCapability, C )
+
+ ...
+ j. Let result be Invoke(nextPromise, "then", «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+ ...
+---*/
+
+function rejectFunction() {}
+
+function Constructor(executor) {
+ executor(Test262Error.thrower, rejectFunction);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var callCount1 = 0,
+ callCount2 = 0;
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ callCount1 += 1;
+ assert.sameValue(onRejected, rejectFunction, "p1.then");
+ }
+};
+var p2 = {
+ then: function(onFulfilled, onRejected) {
+ callCount2 += 1;
+ assert.sameValue(onRejected, rejectFunction, "p2.then");
+ }
+};
+
+Promise.race.call(Constructor, [p1, p2]);
+
+assert.sameValue(callCount1, 1, "p1.then call count");
+assert.sameValue(callCount2, 1, "p2.then call count");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/same-resolve-function.js b/js/src/tests/test262/built-ins/Promise/race/same-resolve-function.js
new file mode 100644
index 0000000000..92c3cb5466
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/same-resolve-function.js
@@ -0,0 +1,46 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.3.1
+description: >
+ Each Promise.race element is called with the same resolve function.
+info: |
+ Runtime Semantics: PerformPromiseRace ( iteratorRecord, promiseCapability, C )
+
+ ...
+ j. Let result be Invoke(nextPromise, "then", «promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
+ ...
+---*/
+
+function resolveFunction() {}
+
+function Constructor(executor) {
+ executor(resolveFunction, Test262Error.thrower);
+}
+Constructor.resolve = function(v) {
+ return v;
+};
+
+var callCount1 = 0,
+ callCount2 = 0;
+
+var p1 = {
+ then: function(onFulfilled, onRejected) {
+ callCount1 += 1;
+ assert.sameValue(onFulfilled, resolveFunction, "p1.then");
+ }
+};
+var p2 = {
+ then: function(onFulfilled, onRejected) {
+ callCount2 += 1;
+ assert.sameValue(onFulfilled, resolveFunction, "p2.then");
+ }
+};
+
+Promise.race.call(Constructor, [p1, p2]);
+
+assert.sameValue(callCount1, 1, "p1.then call count");
+assert.sameValue(callCount2, 1, "p2.then call count");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/race/shell.js b/js/src/tests/test262/built-ins/Promise/race/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/race/species-get-error.js b/js/src/tests/test262/built-ins/Promise/race/species-get-error.js
new file mode 100644
index 0000000000..1198715f8b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/race/species-get-error.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Promise.race() does not retrieve `Symbol.species` property of the `this` value
+es6id: 25.4.4.3
+info: |
+ 1. Let C be the this value.
+ 2. If Type(C) is not Object, throw a TypeError exception.
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ ...
+features: [Symbol.species]
+---*/
+
+function C(executor) {
+ executor(function() {}, function() {});
+}
+Object.defineProperty(C, Symbol.species, {
+ get() {
+ throw new Test262Error("Getter for Symbol.species called");
+ }
+});
+C.resolve = function() {
+ throw new Test262Error();
+};
+
+Promise.race.call(C, []);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject-function-extensible.js b/js/src/tests/test262/built-ins/Promise/reject-function-extensible.js
new file mode 100644
index 0000000000..e53994dc0e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-function-extensible.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.3.1
+description: The [[Extensible]] slot of Promise Reject functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless specified otherwise, the [[Extensible]] internal slot
+ of a built-in object initially has the value true.
+---*/
+
+var rejectFunction;
+new Promise(function(resolve, reject) {
+ rejectFunction = reject;
+});
+
+assert(Object.isExtensible(rejectFunction));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject-function-length.js b/js/src/tests/test262/built-ins/Promise/reject-function-length.js
new file mode 100644
index 0000000000..76bcb1f5c3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-function-length.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.3.1
+description: The `length` property of Promise Reject functions
+info: |
+ The length property of a promise reject function is 1.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+var rejectFunction;
+new Promise(function(resolve, reject) {
+ rejectFunction = reject;
+});
+
+assert.sameValue(rejectFunction.length, 1);
+
+verifyNotEnumerable(rejectFunction, "length");
+verifyNotWritable(rejectFunction, "length");
+verifyConfigurable(rejectFunction, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject-function-name.js b/js/src/tests/test262/built-ins/Promise/reject-function-name.js
new file mode 100644
index 0000000000..98953b1002
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-function-name.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise-reject-functions
+description: The `name` property of Promise Reject functions
+info: |
+ A promise reject function is an anonymous built-in function.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in function object, including constructors, has a `name`
+ property whose value is a String. Functions that are identified as
+ anonymous functions use the empty string as the value of the `name`
+ property.
+ Unless otherwise specified, the `name` property of a built-in function
+ object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
+ [[Configurable]]: *true* }.
+includes: [propertyHelper.js]
+---*/
+
+var rejectFunction;
+new Promise(function(resolve, reject) {
+ rejectFunction = reject;
+});
+
+verifyProperty(rejectFunction, "name", {
+ value: "", writable: false, enumerable: false, configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject-function-nonconstructor.js b/js/src/tests/test262/built-ins/Promise/reject-function-nonconstructor.js
new file mode 100644
index 0000000000..d059d188ed
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-function-nonconstructor.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.3.1
+description: Promise Reject functions are not constructors
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified
+ in the description of a particular function.
+---*/
+
+var rejectFunction;
+new Promise(function(resolve, reject) {
+ rejectFunction = reject;
+});
+
+assert.sameValue(Object.prototype.hasOwnProperty.call(rejectFunction, "prototype"), false);
+assert.throws(TypeError, function() {
+ new rejectFunction();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject-function-property-order.js b/js/src/tests/test262/built-ins/Promise/reject-function-property-order.js
new file mode 100644
index 0000000000..7d49568d3a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-function-property-order.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createbuiltinfunction
+description: Promise reject function property order
+info: |
+ Set order: "length", "name"
+---*/
+
+var rejectFunction;
+new Promise(function(_, reject) {
+ rejectFunction = reject;
+});
+
+var propNames = Object.getOwnPropertyNames(rejectFunction);
+var lengthIndex = propNames.indexOf("length");
+var nameIndex = propNames.indexOf("name");
+
+assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1,
+ "The `length` property comes before the `name` property on built-in functions");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject-function-prototype.js b/js/src/tests/test262/built-ins/Promise/reject-function-prototype.js
new file mode 100644
index 0000000000..13dc4d919a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-function-prototype.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.3.1
+description: The [[Prototype]] of Promise Reject functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified every built-in function and every built-in
+ constructor has the Function prototype object, which is the initial
+ value of the expression Function.prototype (19.2.3), as the value of
+ its [[Prototype]] internal slot.
+---*/
+
+var rejectFunction;
+new Promise(function(resolve, reject) {
+ rejectFunction = reject;
+});
+
+assert.sameValue(Object.getPrototypeOf(rejectFunction), Function.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject-ignored-via-abrupt.js b/js/src/tests/test262/built-ins/Promise/reject-ignored-via-abrupt.js
new file mode 100644
index 0000000000..0e5a32edd1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-ignored-via-abrupt.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Resolved promises ignore rejections through an abrupt completion
+es6id: 25.4.3.1
+info: |
+ [...]
+ 9. Let completion be Call(executor, undefined,
+ «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 10. If completion is an abrupt completion, then
+ a. Let status be Call(resolvingFunctions.[[Reject]], undefined,
+ «completion.[[value]]»).
+ b. ReturnIfAbrupt(status).
+ 11. Return promise.
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal
+ slot.
+ 4. If alreadyResolved.[[value]] is true, return undefined.
+flags: [async]
+---*/
+
+var thenable = new Promise(function() {});
+var p = new Promise(function(resolve) {
+ resolve();
+ throw thenable;
+});
+
+p.then(function() {
+ $DONE();
+}, function() {
+ $DONE('The promise should not be rejected.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/reject-ignored-via-fn-deferred.js b/js/src/tests/test262/built-ins/Promise/reject-ignored-via-fn-deferred.js
new file mode 100644
index 0000000000..efe653f1db
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-ignored-via-fn-deferred.js
@@ -0,0 +1,42 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Resolved promises ignore rejections through deferred invocation of the
+ provided resolving function
+es6id: 25.4.3.1
+info: |
+ [...]
+ 9. Let completion be Call(executor, undefined,
+ «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 10. If completion is an abrupt completion, then
+ [...]
+ 11. Return promise.
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal
+ slot.
+ 4. If alreadyResolved.[[value]] is true, return undefined.
+flags: [async]
+---*/
+
+var returnValue = null;
+var thenable = new Promise(function() {});
+var resolve, reject;
+var p = new Promise(function(_resolve, _reject) {
+ resolve = _resolve;
+ reject = _reject;
+});
+
+p.then(function() {
+ $DONE();
+}, function() {
+ $DONE('The promise should not be rejected.');
+});
+
+resolve();
+returnValue = reject(thenable);
+
+assert.sameValue(returnValue, undefined, '"reject" function return value');
diff --git a/js/src/tests/test262/built-ins/Promise/reject-ignored-via-fn-immed.js b/js/src/tests/test262/built-ins/Promise/reject-ignored-via-fn-immed.js
new file mode 100644
index 0000000000..8121fc1fe8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-ignored-via-fn-immed.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Resolved promises ignore rejections through immediate invocation of the
+ provided resolving function
+es6id: 25.4.3.1
+info: |
+ [...]
+ 9. Let completion be Call(executor, undefined,
+ «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 10. If completion is an abrupt completion, then
+ [...]
+ 11. Return promise.
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal
+ slot.
+ 4. If alreadyResolved.[[value]] is true, return undefined.
+flags: [async]
+---*/
+
+var returnValue = null;
+var thenable = new Promise(function() {});
+var p = new Promise(function(resolve, reject) {
+ resolve();
+ returnValue = reject(thenable);
+});
+
+assert.sameValue(returnValue, undefined, '"reject" function return value');
+
+p.then(function() {
+ $DONE();
+}, function() {
+ $DONE('The promise should not be rejected.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/reject-via-abrupt-queue.js b/js/src/tests/test262/built-ins/Promise/reject-via-abrupt-queue.js
new file mode 100644
index 0000000000..c0a62adeb1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-via-abrupt-queue.js
@@ -0,0 +1,55 @@
+// |reftest| async
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Rejecting through an abrupt completion - captured in a queued job
+esid: sec-promise-executor
+info: |
+ 25.4.3.1 Promise ( executor )
+
+ ...
+ 9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]],
+ resolvingFunctions.[[Reject]] »).
+ 10. If completion is an abrupt completion, then
+ a. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).
+ 11. Return promise.
+
+ 25.4.1.3.1 Promise Reject Functions
+
+ ...
+ 6. Return RejectPromise(promise, reason).
+
+ 25.4.5.3.1 PerformPromiseThen ( promise, onFulfilled, onRejected, resultCapability )
+
+ ...
+ 4. If IsCallable(onRejected) is false, then
+ a. Set onRejected to undefined.
+ ...
+ 6. Let rejectReaction be the PromiseReaction { [[Capability]]: resultCapability,
+ [[Type]]: "Reject", [[Handler]]: onRejected }.
+ ...
+ 9. Else,
+ a. Assert: The value of promise.[[PromiseState]] is "rejected".
+ ...
+ d. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, « rejectReaction, reason »).
+flags: [async]
+---*/
+
+var thenable = Promise.resolve();
+var p = new Promise(function() {
+ throw thenable;
+});
+
+p.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}).then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value.');
+ return;
+ }
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/reject-via-abrupt.js b/js/src/tests/test262/built-ins/Promise/reject-via-abrupt.js
new file mode 100644
index 0000000000..49e6760849
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-via-abrupt.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting through an abrupt completion
+es6id: 25.4.3.1
+info: |
+ [...]
+ 9. Let completion be Call(executor, undefined,
+ «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 10. If completion is an abrupt completion, then
+ a. Let status be Call(resolvingFunctions.[[Reject]], undefined,
+ «completion.[[value]]»).
+ b. ReturnIfAbrupt(status).
+ 11. Return promise.
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var thenable = new Promise(function() {});
+var p = new Promise(function() {
+ throw thenable;
+});
+
+p.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/reject-via-fn-deferred-queue.js b/js/src/tests/test262/built-ins/Promise/reject-via-fn-deferred-queue.js
new file mode 100644
index 0000000000..d5e5af72ca
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-via-fn-deferred-queue.js
@@ -0,0 +1,63 @@
+// |reftest| async
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Rejecting through deferred invocation of the provided resolving function,
+ captured in a queued job.
+esid: sec-promise-executor
+info: |
+ 25.4.3.1 Promise ( executor )
+
+ ...
+ 9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]],
+ resolvingFunctions.[[Reject]] »).
+ 10. If completion is an abrupt completion, then
+ a. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).
+ 11. Return promise.
+
+ 25.4.1.3.1 Promise Reject Functions
+
+ ...
+ 6. Return RejectPromise(promise, reason).
+
+ 25.4.5.3.1 PerformPromiseThen ( promise, onFulfilled, onRejected, resultCapability )
+
+ ...
+ 4. If IsCallable(onRejected) is false, then
+ a. Set onRejected to undefined.
+ ...
+ 6. Let rejectReaction be the PromiseReaction { [[Capability]]: resultCapability,
+ [[Type]]: "Reject", [[Handler]]: onRejected }.
+ 7. If promise.[[PromiseState]] is "pending", then
+ ...
+ b. Append rejectReaction as the last element of the List that is
+ promise.[[PromiseRejectReactions]].
+ ...
+flags: [async]
+---*/
+
+var thenable = Promise.resolve();
+var returnValue = null;
+var reject;
+var p = new Promise(function(_, _reject) {
+ reject = _reject;
+});
+
+p.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}).then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value.');
+ return;
+ }
+
+ $DONE();
+});
+
+returnValue = reject(thenable);
+
+assert.sameValue(returnValue, undefined, '"reject" function return value');
diff --git a/js/src/tests/test262/built-ins/Promise/reject-via-fn-deferred.js b/js/src/tests/test262/built-ins/Promise/reject-via-fn-deferred.js
new file mode 100644
index 0000000000..a7c0caa05c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-via-fn-deferred.js
@@ -0,0 +1,41 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting through deferred invocation of the provided resolving function
+es6id: 25.4.3.1
+info: |
+ [...]
+ 9. Let completion be Call(executor, undefined,
+ «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 10. If completion is an abrupt completion, then
+ [...]
+ 11. Return promise.
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var thenable = new Promise(function() {});
+var returnValue = null;
+var reject;
+var p = new Promise(function(_, _reject) {
+ reject = _reject;
+});
+
+p.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value.');
+ return;
+ }
+
+ $DONE();
+});
+
+returnValue = reject(thenable);
+
+assert.sameValue(returnValue, undefined, '"reject" function return value');
diff --git a/js/src/tests/test262/built-ins/Promise/reject-via-fn-immed-queue.js b/js/src/tests/test262/built-ins/Promise/reject-via-fn-immed-queue.js
new file mode 100644
index 0000000000..750ba4a2f3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-via-fn-immed-queue.js
@@ -0,0 +1,60 @@
+// |reftest| async
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Rejecting through immediate invocation of the provided resolving function,
+ captured in a queued job.
+esid: sec-promise-executor
+info: |
+ 25.4.3.1 Promise ( executor )
+
+ ...
+ 9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]],
+ resolvingFunctions.[[Reject]] »).
+ 10. If completion is an abrupt completion, then
+ a. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).
+ 11. Return promise.
+
+ 25.4.1.3.1 Promise Reject Functions
+
+ ...
+ 6. Return RejectPromise(promise, reason).
+
+ 25.4.5.3.1 PerformPromiseThen ( promise, onFulfilled, onRejected, resultCapability )
+
+ ...
+ 4. If IsCallable(onRejected) is false, then
+ a. Set onRejected to undefined.
+ ...
+ 6. Let rejectReaction be the PromiseReaction { [[Capability]]: resultCapability,
+ [[Type]]: "Reject", [[Handler]]: onRejected }.
+ ...
+ 9. Else,
+ a. Assert: The value of promise.[[PromiseState]] is "rejected".
+ ...
+ d. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, « rejectReaction, reason »).
+flags: [async]
+---*/
+
+var thenable = Promise.resolve();
+var returnValue = null;
+var p = new Promise(function(_, reject) {
+ returnValue = reject(thenable);
+});
+
+assert.sameValue(returnValue, undefined, '"reject" function return value');
+
+p.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}).then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/reject-via-fn-immed.js b/js/src/tests/test262/built-ins/Promise/reject-via-fn-immed.js
new file mode 100644
index 0000000000..df9740cf3f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject-via-fn-immed.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Rejecting through immediate invocation of the provided resolving function
+es6id: 25.4.3.1
+info: |
+ [...]
+ 9. Let completion be Call(executor, undefined,
+ «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 10. If completion is an abrupt completion, then
+ [...]
+ 11. Return promise.
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+flags: [async]
+---*/
+
+var thenable = new Promise(function() {});
+var returnValue = null;
+var p = new Promise(function(_, reject) {
+ returnValue = reject(thenable);
+});
+
+assert.sameValue(returnValue, undefined, '"reject" function return value');
+
+p.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function(x) {
+ if (x !== thenable) {
+ $DONE('The promise should be rejected with the resolution value.');
+ return;
+ }
+
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A1.1_T1.js b/js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A1.1_T1.js
new file mode 100644
index 0000000000..999e0db577
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A1.1_T1.js
@@ -0,0 +1,17 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.reject
+es6id: S25.4.4.4_A1.1_T1
+author: Sam Mikes
+description: Promise.reject is a function
+---*/
+assert.sameValue(
+ typeof Promise.reject,
+ "function",
+ 'The value of `typeof Promise.reject` is expected to be "function"'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A2.1_T1.js b/js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A2.1_T1.js
new file mode 100644
index 0000000000..101f184caf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A2.1_T1.js
@@ -0,0 +1,28 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ [...]
+ 5. Let rejectResult be Call(promiseCapability.[[Reject]], undefined, «r»).
+ [...]
+
+ 25.4.1.3.1 Promise Reject Functions
+ [...]
+ 6. Return RejectPromise(promise, reason).
+es6id: 25.4.4.4
+author: Sam Mikes
+description: Promise.reject creates a new settled promise
+flags: [async]
+---*/
+
+var p = Promise.reject(3);
+
+assert(!!(p instanceof Promise), 'The value of !!(p instanceof Promise) is expected to be true');
+
+p.then(function() {
+ throw new Test262Error("Promise should not be fulfilled.");
+}, function(result) {
+ assert.sameValue(result, 3, 'The value of result is expected to be 3');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A3.1_T1.js b/js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A3.1_T1.js
new file mode 100644
index 0000000000..a3dfbbea03
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/S25.4.4.4_A3.1_T1.js
@@ -0,0 +1,18 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.reject
+es6id: S25.4.4.4_A3.1_T1
+author: Sam Mikes
+description: Promise.reject throws TypeError for bad 'this'
+---*/
+
+function ZeroArgConstructor() {}
+
+assert.throws(TypeError, function() {
+ Promise.reject.call(ZeroArgConstructor, 4);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/browser.js b/js/src/tests/test262/built-ins/Promise/reject/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/reject/capability-executor-called-twice.js b/js/src/tests/test262/built-ins/Promise/reject/capability-executor-called-twice.js
new file mode 100644
index 0000000000..17a661de34
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/capability-executor-called-twice.js
@@ -0,0 +1,81 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.4
+description: >
+ Throws a TypeError if capabilities executor already called with non-undefined values.
+info: |
+ Promise.reject ( r )
+
+ ...
+ 3. Let promiseCapability be NewPromiseCapability(C).
+ 4. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ 25.4.1.5.1 GetCapabilitiesExecutor Functions
+ ...
+ 3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
+ 4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
+ 5. Set promiseCapability.[[Resolve]] to resolve.
+ 6. Set promiseCapability.[[Reject]] to reject.
+ ...
+---*/
+
+var checkPoint = "";
+Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}, {});
+assert.sameValue(checkPoint, "abc", "executor initially called with no arguments");
+
+var checkPoint = "";
+Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}, {});
+assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+ }, {});
+}, "executor initially called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+ }, {});
+}, "executor initially called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor("invalid value", 123);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+ }, {});
+}, "executor initially called with (String, Number)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/capability-executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/reject/capability-executor-not-callable.js
new file mode 100644
index 0000000000..0002838ef8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/capability-executor-not-callable.js
@@ -0,0 +1,85 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.4
+description: >
+ Throws a TypeError if either resolve or reject capability is not callable.
+info: |
+ Promise.reject ( r )
+
+ ...
+ 3. Let promiseCapability be NewPromiseCapability(C).
+ 4. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ 25.4.1.5 NewPromiseCapability ( C )
+ ...
+ 4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1).
+ 5. Set the [[Capability]] internal slot of executor to promiseCapability.
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+ 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
+ 9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
+ ...
+---*/
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ }, {});
+}, "executor not called at all");
+assert.sameValue(checkPoint, "a", "executor not called at all");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+ }, {});
+}, "executor called with no arguments");
+assert.sameValue(checkPoint, "ab", "executor called with no arguments");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+ }, {});
+}, "executor called with (undefined, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+ }, {});
+}, "executor called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, function)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+ }, {});
+}, "executor called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (function, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.reject.call(function(executor) {
+ checkPoint += "a";
+ executor(123, "invalid value");
+ checkPoint += "b";
+ }, {});
+}, "executor called with (Number, String)");
+assert.sameValue(checkPoint, "ab", "executor called with (Number, String)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/capability-invocation-error.js b/js/src/tests/test262/built-ins/Promise/reject/capability-invocation-error.js
new file mode 100644
index 0000000000..2eaac3fac3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/capability-invocation-error.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: Abrupt completion returned by "reject" capability
+esid: sec-promise.reject
+info: |
+ 1. Let C be the this value.
+ [...]
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ 4. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
+
+ 25.4.1.5 NewPromiseCapability
+ [...]
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+---*/
+
+var P = function(executor) {
+ return new Promise(function() {
+ executor(
+ function() {},
+ function() {
+ throw new Test262Error();
+ }
+ );
+ });
+};
+
+assert.throws(Test262Error, function() {
+ Promise.reject.call(P);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/capability-invocation.js b/js/src/tests/test262/built-ins/Promise/reject/capability-invocation.js
new file mode 100644
index 0000000000..c263608cf3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/capability-invocation.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Invocation of "reject" capability
+esid: sec-promise.reject
+info: |
+ 1. Let C be the this value.
+ [...]
+ 3. Let promiseCapability be ? NewPromiseCapability(C).
+ 4. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
+ [...]
+
+ 25.4.1.5 NewPromiseCapability
+ [...]
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+---*/
+
+var expectedThis = (function() {
+ return this;
+})();
+var resolveCount = 0;
+var thisValue, args;
+var P = function(executor) {
+ return new Promise(function() {
+ executor(
+ function() {
+ resolveCount += 1;
+ },
+ function() {
+ thisValue = this;
+ args = arguments;
+ }
+ );
+ });
+};
+
+Promise.reject.call(P, 24601);
+
+assert.sameValue(resolveCount, 0);
+
+assert.sameValue(thisValue, expectedThis);
+assert.sameValue(typeof args, 'object');
+assert.sameValue(args.length, 1);
+assert.sameValue(args[0], 24601);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/ctx-ctor-throws.js b/js/src/tests/test262/built-ins/Promise/reject/ctx-ctor-throws.js
new file mode 100644
index 0000000000..85be5895f7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/ctx-ctor-throws.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.reject` invoked on a constructor value that throws an error
+es6id: 25.4.4.4
+info: |
+ 1. Let C be the this value.
+ [...]
+ 3. Let promiseCapability be NewPromiseCapability(C).
+ 4. ReturnIfAbrupt(promiseCapability).
+
+ 25.4.1.5 NewPromiseCapability
+ [...]
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+---*/
+
+var CustomPromise = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ Promise.reject.call(CustomPromise);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/ctx-ctor.js b/js/src/tests/test262/built-ins/Promise/reject/ctx-ctor.js
new file mode 100644
index 0000000000..7b18f71152
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/ctx-ctor.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.reject` invoked on a constructor value
+es6id: 25.4.4.5
+info: |
+ 1. Let C be the this value.
+ [...]
+ 3. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 7. Return promiseCapability.[[Promise]].
+features: [class]
+---*/
+
+var executor = null;
+var callCount = 0;
+
+class SubPromise extends Promise {
+ constructor(a) {
+ super(a);
+ executor = a;
+ callCount += 1;
+ }
+}
+
+var instance = Promise.reject.call(SubPromise);
+
+assert.sameValue(instance.constructor, SubPromise);
+assert.sameValue(instance instanceof SubPromise, true);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(typeof executor, 'function');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/ctx-non-ctor.js b/js/src/tests/test262/built-ins/Promise/reject/ctx-non-ctor.js
new file mode 100644
index 0000000000..7a2a41ce6b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/ctx-non-ctor.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.reject` invoked on a non-constructor value
+es6id: 25.4.4.4
+info: |
+ [...]
+ 3. Let promiseCapability be NewPromiseCapability(C).
+ 4. ReturnIfAbrupt(promiseCapability).
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.reject.call(eval);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/ctx-non-object.js b/js/src/tests/test262/built-ins/Promise/reject/ctx-non-object.js
new file mode 100644
index 0000000000..16141bbd71
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/ctx-non-object.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.resolve` invoked on a non-object value
+es6id: 25.4.4.4
+info: |
+ 1. Let C be the this value.
+ 2. If Type(C) is not Object, throw a TypeError exception.
+features: [Symbol]
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.reject.call(undefined, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.reject.call(null, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.reject.call(86, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.reject.call('string', []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.reject.call(true, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.reject.call(Symbol(), []);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/length.js b/js/src/tests/test262/built-ins/Promise/reject/length.js
new file mode 100644
index 0000000000..1773dfca57
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/length.js
@@ -0,0 +1,27 @@
+// 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.4.4
+description: Promise.reject `length` property
+info: |
+ ES6 Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.reject.length, 1);
+
+verifyNotEnumerable(Promise.reject, 'length');
+verifyNotWritable(Promise.reject, 'length');
+verifyConfigurable(Promise.reject, 'length');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/name.js b/js/src/tests/test262/built-ins/Promise/reject/name.js
new file mode 100644
index 0000000000..eb0e4c630f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/name.js
@@ -0,0 +1,28 @@
+// 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.4.4
+description: Promise.reject `name` property
+info: |
+ ES6 Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.reject.name, 'reject');
+
+verifyNotEnumerable(Promise.reject, 'name');
+verifyNotWritable(Promise.reject, 'name');
+verifyConfigurable(Promise.reject, 'name');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/reject/not-a-constructor.js
new file mode 100644
index 0000000000..1fa8864edb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/not-a-constructor.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Promise.reject does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(Promise.reject), false, 'isConstructor(Promise.reject) must return false');
+
+assert.throws(TypeError, () => {
+ new Promise.reject();
+}, '`new Promise.reject()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/prop-desc.js b/js/src/tests/test262/built-ins/Promise/reject/prop-desc.js
new file mode 100644
index 0000000000..d93864db99
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/prop-desc.js
@@ -0,0 +1,21 @@
+// Copyright 2015 Jordan Harband. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: 25.4.4.4_A1.2_T1
+author: Jordan Harband
+description: Promise.reject property descriptor
+info: |
+ ES6 Section 17
+
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(Promise, 'reject');
+verifyWritable(Promise, 'reject');
+verifyConfigurable(Promise, 'reject');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/reject/shell.js b/js/src/tests/test262/built-ins/Promise/reject/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/reject/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-function-extensible.js b/js/src/tests/test262/built-ins/Promise/resolve-function-extensible.js
new file mode 100644
index 0000000000..5014860658
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-function-extensible.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.3.2
+description: The [[Extensible]] slot of Promise Resolve functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless specified otherwise, the [[Extensible]] internal slot
+ of a built-in object initially has the value true.
+---*/
+
+var resolveFunction;
+new Promise(function(resolve, reject) {
+ resolveFunction = resolve;
+});
+
+assert(Object.isExtensible(resolveFunction));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-function-length.js b/js/src/tests/test262/built-ins/Promise/resolve-function-length.js
new file mode 100644
index 0000000000..9d6ae8ea9e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-function-length.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.3.2
+description: The `length` property of Promise Resolve functions
+info: |
+ The length property of a promise resolve function is 1.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+var resolveFunction;
+new Promise(function(resolve, reject) {
+ resolveFunction = resolve;
+});
+
+assert.sameValue(resolveFunction.length, 1);
+
+verifyNotEnumerable(resolveFunction, "length");
+verifyNotWritable(resolveFunction, "length");
+verifyConfigurable(resolveFunction, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-function-name.js b/js/src/tests/test262/built-ins/Promise/resolve-function-name.js
new file mode 100644
index 0000000000..bf3189e76b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-function-name.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-promise-resolve-functions
+description: The `name` property of Promise Resolve functions
+info: |
+ A promise resolve function is an anonymous built-in function.
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in function object, including constructors, has a `name`
+ property whose value is a String. Functions that are identified as
+ anonymous functions use the empty string as the value of the `name`
+ property.
+ Unless otherwise specified, the `name` property of a built-in function
+ object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
+ [[Configurable]]: *true* }.
+includes: [propertyHelper.js]
+---*/
+
+var resolveFunction;
+new Promise(function(resolve, reject) {
+ resolveFunction = resolve;
+});
+
+verifyProperty(resolveFunction, "name", {
+ value: "", writable: false, enumerable: false, configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-function-nonconstructor.js b/js/src/tests/test262/built-ins/Promise/resolve-function-nonconstructor.js
new file mode 100644
index 0000000000..64891fb01f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-function-nonconstructor.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.3.2
+description: Promise Resolve functions are not constructors
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified
+ in the description of a particular function.
+---*/
+
+var resolveFunction;
+new Promise(function(resolve, reject) {
+ resolveFunction = resolve;
+});
+
+assert.sameValue(Object.prototype.hasOwnProperty.call(resolveFunction, "prototype"), false);
+assert.throws(TypeError, function() {
+ new resolveFunction();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-function-property-order.js b/js/src/tests/test262/built-ins/Promise/resolve-function-property-order.js
new file mode 100644
index 0000000000..86ca8ea378
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-function-property-order.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2020 ExE Boss. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-createbuiltinfunction
+description: Promise resolve function property order
+info: |
+ Set order: "length", "name"
+---*/
+
+var resolveFunction;
+new Promise(function(resolve) {
+ resolveFunction = resolve;
+});
+
+var propNames = Object.getOwnPropertyNames(resolveFunction);
+var lengthIndex = propNames.indexOf("length");
+var nameIndex = propNames.indexOf("name");
+
+assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1,
+ "The `length` property comes before the `name` property on built-in functions");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-function-prototype.js b/js/src/tests/test262/built-ins/Promise/resolve-function-prototype.js
new file mode 100644
index 0000000000..c55ede000f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-function-prototype.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.1.3.2
+description: The [[Prototype]] of Promise Resolve functions
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+ Unless otherwise specified every built-in function and every built-in
+ constructor has the Function prototype object, which is the initial
+ value of the expression Function.prototype (19.2.3), as the value of
+ its [[Prototype]] internal slot.
+---*/
+
+var resolveFunction;
+new Promise(function(resolve, reject) {
+ resolveFunction = resolve;
+});
+
+assert.sameValue(Object.getPrototypeOf(resolveFunction), Function.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-ignored-via-fn-deferred.js b/js/src/tests/test262/built-ins/Promise/resolve-ignored-via-fn-deferred.js
new file mode 100644
index 0000000000..45b79bfb24
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-ignored-via-fn-deferred.js
@@ -0,0 +1,42 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Rejected promises ignore resolution after deferred invocation of the
+ provided reject function
+esid: sec-promise-executor
+info: |
+ [...]
+ 9. Let completion be Call(executor, undefined,
+ «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 10. If completion is an abrupt completion, then
+ [...]
+ 11. Return promise.
+
+ 25.4.1.3.2 Promise Resolve Functions
+
+ [...]
+ 3. Let alreadyResolved be F.[[AlreadyResolved]].
+ 4. If alreadyResolved.[[Value]] is true, return undefined.
+flags: [async]
+---*/
+
+var returnValue = null;
+var thenable = new Promise(function() {});
+var resolve, reject;
+var p = new Promise(function(_resolve, _reject) {
+ resolve = _resolve;
+ reject = _reject;
+});
+
+p.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function() {
+ $DONE();
+});
+
+reject(thenable);
+returnValue = resolve();
+
+assert.sameValue(returnValue, undefined, '"resolve" function return value');
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-ignored-via-fn-immed.js b/js/src/tests/test262/built-ins/Promise/resolve-ignored-via-fn-immed.js
new file mode 100644
index 0000000000..1963941120
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-ignored-via-fn-immed.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: >
+ Rejected promises ignore resolution after immediate invocation of the
+ provided reject function
+esid: sec-promise-executor
+info: |
+ [...]
+ 9. Let completion be Call(executor, undefined,
+ «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
+ 10. If completion is an abrupt completion, then
+ [...]
+ 11. Return promise.
+
+ 25.4.1.3.2 Promise Resolve Functions
+
+ [...]
+ 3. Let alreadyResolved be F.[[AlreadyResolved]].
+ 4. If alreadyResolved.[[Value]] is true, return undefined.
+flags: [async]
+---*/
+
+var returnValue = null;
+var thenable = new Promise(function() {});
+var p = new Promise(function(resolve, reject) {
+ reject(thenable);
+ returnValue = resolve();
+});
+
+assert.sameValue(returnValue, undefined, '"reject" function return value');
+
+p.then(function() {
+ $DONE('The promise should not be fulfilled.');
+}, function() {
+ $DONE();
+});
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-non-obj-deferred.js b/js/src/tests/test262/built-ins/Promise/resolve-non-obj-deferred.js
new file mode 100644
index 0000000000..4a514d378c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-non-obj-deferred.js
@@ -0,0 +1,39 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+var returnValue = null;
+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.');
+});
+
+returnValue = resolve(45);
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-non-obj-immed.js b/js/src/tests/test262/built-ins/Promise/resolve-non-obj-immed.js
new file mode 100644
index 0000000000..44e603d907
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-non-obj-immed.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+var returnValue = null;
+var promise = new Promise(function(resolve) {
+ returnValue = resolve(45);
+});
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
+
+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/js/src/tests/test262/built-ins/Promise/resolve-non-thenable-deferred.js b/js/src/tests/test262/built-ins/Promise/resolve-non-thenable-deferred.js
new file mode 100644
index 0000000000..307f3a42f7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-non-thenable-deferred.js
@@ -0,0 +1,47 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+var returnValue = null;
+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.');
+});
+
+returnValue = resolve(nonThenable);
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-non-thenable-immed.js b/js/src/tests/test262/built-ins/Promise/resolve-non-thenable-immed.js
new file mode 100644
index 0000000000..2705e00776
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-non-thenable-immed.js
@@ -0,0 +1,44 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+var returnValue = null;
+var nonThenable = {
+ then: null
+};
+var promise = new Promise(function(resolve) {
+ returnValue = resolve(nonThenable);
+});
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
+
+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/js/src/tests/test262/built-ins/Promise/resolve-poisoned-then-deferred.js b/js/src/tests/test262/built-ins/Promise/resolve-poisoned-then-deferred.js
new file mode 100644
index 0000000000..996437b636
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-poisoned-then-deferred.js
@@ -0,0 +1,46 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+var returnValue = null;
+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();
+});
+
+returnValue = resolve(poisonedThen);
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-poisoned-then-immed.js b/js/src/tests/test262/built-ins/Promise/resolve-poisoned-then-immed.js
new file mode 100644
index 0000000000..4276ec8e3f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-poisoned-then-immed.js
@@ -0,0 +1,43 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+var returnValue = null;
+var value = {};
+var poisonedThen = Object.defineProperty({}, 'then', {
+ get: function() {
+ throw value;
+ }
+});
+var promise = new Promise(function(resolve) {
+ returnValue = resolve(poisonedThen);
+});
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
+
+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/js/src/tests/test262/built-ins/Promise/resolve-prms-cstm-then-deferred.js b/js/src/tests/test262/built-ins/Promise/resolve-prms-cstm-then-deferred.js
new file mode 100644
index 0000000000..688dfb9848
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-prms-cstm-then-deferred.js
@@ -0,0 +1,55 @@
+// |reftest| async
+// 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 resolved Promise instance whose `then` method has been
+ overridden 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»)
+flags: [async]
+---*/
+
+var returnValue = null;
+var value = {};
+var resolve;
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+var promise = new Promise(function(_resolve) {
+ resolve = _resolve;
+});
+
+thenable.then = function(resolve) {
+ resolve(value);
+};
+
+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.');
+});
+
+returnValue = resolve(thenable);
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-prms-cstm-then-immed.js b/js/src/tests/test262/built-ins/Promise/resolve-prms-cstm-then-immed.js
new file mode 100644
index 0000000000..85ff117268
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-prms-cstm-then-immed.js
@@ -0,0 +1,62 @@
+// |reftest| async
+// 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 resolved Promise instance whose `then` method has been
+ overridden 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»)
+flags: [async]
+---*/
+
+var returnValue = null;
+var value = {};
+var lateCallCount = 0;
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+
+thenable.then = function(resolve) {
+ resolve(value);
+};
+
+var promise = new Promise(function(resolve) {
+ returnValue = resolve(thenable);
+});
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
+
+thenable.then = function() {
+ lateCallCount += 1;
+};
+
+promise.then(function(val) {
+ if (val !== value) {
+ $DONE('The promise should be fulfilled with the provided value.');
+ return;
+ }
+
+ if (lateCallCount > 0) {
+ $DONE('The `then` method should be executed synchronously.');
+ }
+
+ $DONE();
+}, function() {
+ $DONE('The promise should not be rejected.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-self.js b/js/src/tests/test262/built-ins/Promise/resolve-self.js
new file mode 100644
index 0000000000..072b40c44d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-self.js
@@ -0,0 +1,45 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+var returnValue = null;
+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();
+});
+
+returnValue = resolve(promise);
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-thenable-deferred.js b/js/src/tests/test262/built-ins/Promise/resolve-thenable-deferred.js
new file mode 100644
index 0000000000..ed9dd08288
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-thenable-deferred.js
@@ -0,0 +1,51 @@
+// |reftest| async
+// 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»)
+flags: [async]
+---*/
+
+var returnValue = null;
+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.');
+});
+
+returnValue = resolve(thenable);
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
diff --git a/js/src/tests/test262/built-ins/Promise/resolve-thenable-immed.js b/js/src/tests/test262/built-ins/Promise/resolve-thenable-immed.js
new file mode 100644
index 0000000000..1e50d7e080
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve-thenable-immed.js
@@ -0,0 +1,47 @@
+// |reftest| async
+// 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»)
+flags: [async]
+---*/
+
+var returnValue = null;
+var value = {};
+var thenable = new Promise(function(resolve) {
+ resolve(value);
+});
+var promise = new Promise(function(resolve) {
+ returnValue = resolve(thenable);
+});
+
+assert.sameValue(returnValue, undefined, '"resolve" return value');
+
+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/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A1.1_T1.js b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A1.1_T1.js
new file mode 100644
index 0000000000..ba9e815a66
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A1.1_T1.js
@@ -0,0 +1,17 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.resolve
+es6id: S25.4.4.5_A1.1_T1
+author: Sam Mikes
+description: Promise.resolve is a function
+---*/
+assert.sameValue(
+ typeof Promise.resolve,
+ "function",
+ 'The value of `typeof Promise.resolve` is expected to be "function"'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.1_T1.js b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.1_T1.js
new file mode 100644
index 0000000000..4277dcbbd5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.1_T1.js
@@ -0,0 +1,15 @@
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.5_A2.1_T1
+author: Sam Mikes
+description: Promise.resolve passes through a promise w/ same Constructor
+---*/
+
+var p1 = Promise.resolve(1),
+ p2 = Promise.resolve(p1);
+
+assert.sameValue(p1, p2, 'The value of p1 is expected to equal the value of p2');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.2_T1.js b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.2_T1.js
new file mode 100644
index 0000000000..1445d3a242
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.2_T1.js
@@ -0,0 +1,25 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.5_A2.2_T1
+author: Sam Mikes
+description: Promise.resolve passes through an unsettled promise w/ same Constructor
+flags: [async]
+---*/
+
+var resolveP1,
+ p1 = new Promise(function(resolve) {
+ resolveP1 = resolve;
+ }),
+ p2 = Promise.resolve(p1),
+ arg = {};
+
+assert.sameValue(p1, p2, 'The value of p1 is expected to equal the value of p2');
+
+p2.then(function(result) {
+ assert.sameValue(result, arg, 'The value of result is expected to equal the value of arg');
+}).then($DONE, $DONE);
+
+resolveP1(arg);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.3_T1.js b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.3_T1.js
new file mode 100644
index 0000000000..e028c21cba
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A2.3_T1.js
@@ -0,0 +1,27 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: S25.4.4.5_A2.3_T1
+author: Sam Mikes
+description: Promise.resolve passes through an unsettled promise w/ same Constructor
+flags: [async]
+---*/
+
+var rejectP1,
+ p1 = new Promise(function(resolve, reject) {
+ rejectP1 = reject;
+ }),
+ p2 = Promise.resolve(p1),
+ arg = {};
+
+assert.sameValue(p1, p2, 'The value of p1 is expected to equal the value of p2');
+
+p2.then(function() {
+ throw new Test262Error("Expected p2 to be rejected, not fulfilled.");
+}, function(result) {
+ assert.sameValue(result, arg, 'The value of result is expected to equal the value of arg');
+}).then($DONE, $DONE);
+
+rejectP1(arg);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A3.1_T1.js b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A3.1_T1.js
new file mode 100644
index 0000000000..78b95b93a7
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A3.1_T1.js
@@ -0,0 +1,56 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.resolve
+es6id: S25.4.4.5_A3.1_T1
+author: Sam Mikes
+description: Promise.resolve delegates to foreign thenable
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var thenable = {
+ then: function(onResolve, onReject) {
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, "thenable.then called");
+
+ assert.sameValue(this, thenable);
+
+ onResolve('resolved');
+
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, "after resolved");
+
+ throw new Error('interrupt flow');
+
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, "duplicate sequence point not pushed");
+ }
+};
+
+sequence.push(1);
+assert.sameValue(sequence.length, 1);
+checkSequence(sequence, "no async calls yet");
+
+var p1 = Promise.resolve(thenable);
+
+sequence.push(2);
+assert.sameValue(sequence.length, 2);
+checkSequence(sequence, "thenable.then queued but not yet called");
+
+p1.then(function(q) {
+ sequence.push(5);
+ assert.sameValue(sequence.length, 5);
+ checkSequence(sequence, "all done");
+
+ assert.sameValue(q, 'resolved');
+
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A4.1_T1.js b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A4.1_T1.js
new file mode 100644
index 0000000000..25b8acf3a2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/S25.4.4.5_A4.1_T1.js
@@ -0,0 +1,25 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Section 25.4.1.4.2
+es6id: S25.4.4.5_A3.1_T1
+author: Sam Mikes
+description: self-resolved Promise throws TypeError
+flags: [async]
+---*/
+
+var resolveP,
+ p = new Promise(function(resolve) {
+ resolveP = resolve;
+ });
+
+resolveP(p);
+
+p.then(function() {
+ throw new Test262Error("Should not fulfill: should reject with TypeError.");
+}, function(err) {
+ assert(!!(err instanceof TypeError), 'The value of !!(err instanceof TypeError) is expected to be true');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_1.js b/js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_1.js
new file mode 100644
index 0000000000..629b94b509
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_1.js
@@ -0,0 +1,24 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.resolve
+es6id: S25.4.4.5
+author: Sam Mikes
+description: Promise.resolve delegates to foreign thenable
+flags: [async]
+---*/
+
+var thenable = {
+ then: function(onResolve, onReject) {
+ return onResolve('resolved');
+ }
+};
+
+var p = Promise.resolve(thenable);
+
+p.then(function(r) {
+ assert.sameValue(r, 'resolved');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_2.js b/js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_2.js
new file mode 100644
index 0000000000..bc748bf8fe
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_2.js
@@ -0,0 +1,46 @@
+// |reftest| async
+// Copyright 2014 Cubane Canada, Inc. All rights reserved.
+// See LICENSE for details.
+
+/*---
+info: |
+ Promise.resolve
+es6id: S25.4.4.5
+author: Sam Mikes
+description: Promise.resolve delegates to foreign thenable
+includes: [promiseHelper.js]
+flags: [async]
+---*/
+
+var sequence = [];
+
+var thenable = {
+ then: function(onResolve, onReject) {
+
+ sequence.push(3);
+ assert.sameValue(sequence.length, 3);
+ checkSequence(sequence, "thenable.then called");
+
+ assert.sameValue(this, thenable, "thenable.then called with `thenable` as `this`");
+
+ return onResolve('resolved');
+ }
+};
+
+sequence.push(1);
+assert.sameValue(sequence.length, 1);
+checkSequence(sequence, "no async calls yet");
+
+var p = Promise.resolve(thenable);
+
+sequence.push(2);
+assert.sameValue(sequence.length, 2);
+checkSequence(sequence, "thenable.then queued but not yet called");
+
+p.then(function(r) {
+ sequence.push(4);
+ assert.sameValue(sequence.length, 4);
+ checkSequence(sequence, "all done");
+
+ assert.sameValue(r, 'resolved');
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/arg-non-thenable.js b/js/src/tests/test262/built-ins/Promise/resolve/arg-non-thenable.js
new file mode 100644
index 0000000000..1f941e050b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/arg-non-thenable.js
@@ -0,0 +1,31 @@
+// |reftest| async
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.resolve` invoked with an object whose `then` property is not callable
+es6id: 25.4.4.5
+info: |
+ 6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined,
+ «x»).
+
+ [...]
+
+ 25.4.1.3.2 Promise Resolve Functions
+
+ 11. If IsCallable(thenAction) is false, then
+ a. Return FulfillPromise(promise, resolution).
+ 12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob,
+ «promise, resolution, thenAction»)
+ 13. Return undefined.
+flags: [async]
+---*/
+
+var nonThenable = {
+ then: null
+};
+
+Promise.resolve(nonThenable).then(function(value) {
+ assert.sameValue(value, nonThenable);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/arg-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/resolve/arg-poisoned-then.js
new file mode 100644
index 0000000000..6adc9372a2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/arg-poisoned-then.js
@@ -0,0 +1,37 @@
+// |reftest| async
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.resolve` invoked 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]]).
+flags: [async]
+---*/
+
+var poisonedThen = {};
+var err = new Test262Error();
+Object.defineProperty(poisonedThen, 'then', {
+ get: function() {
+ throw err;
+ }
+});
+
+Promise.resolve(poisonedThen).then(function() {
+ throw new Test262Error(
+ 'Promise should be rejected when retrieving `then` property throws an error'
+ );
+}, function(reason) {
+ assert.sameValue(reason, err);
+}).then($DONE, $DONE);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/arg-uniq-ctor.js b/js/src/tests/test262/built-ins/Promise/resolve/arg-uniq-ctor.js
new file mode 100644
index 0000000000..d3f268f0a6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/arg-uniq-ctor.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.resolve` invoked with a Promise with a unique constructor
+es6id: 25.4.4.5
+info: |
+ 1. Let C be the this value.
+ [...]
+ 3. If IsPromise(x) is true,
+ a. Let xConstructor be Get(x, "constructor").
+ b. ReturnIfAbrupt(xConstructor).
+ c. If SameValue(xConstructor, C) is true, return x.
+ 4. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 8. Return promiseCapability.[[Promise]].
+---*/
+
+var promise1 = new Promise(function() {});
+var promise2;
+
+promise1.constructor = null;
+
+promise2 = Promise.resolve(promise1);
+
+assert.sameValue(promise1 === promise2, false);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/browser.js b/js/src/tests/test262/built-ins/Promise/resolve/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/capability-executor-called-twice.js b/js/src/tests/test262/built-ins/Promise/resolve/capability-executor-called-twice.js
new file mode 100644
index 0000000000..3a5375dd79
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/capability-executor-called-twice.js
@@ -0,0 +1,81 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.5
+description: >
+ Throws a TypeError if capabilities executor already called with non-undefined values.
+info: |
+ Promise.resolve ( x )
+
+ ...
+ 4. Let promiseCapability be NewPromiseCapability(C).
+ 5. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ 25.4.1.5.1 GetCapabilitiesExecutor Functions
+ ...
+ 3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
+ 4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
+ 5. Set promiseCapability.[[Resolve]] to resolve.
+ 6. Set promiseCapability.[[Reject]] to reject.
+ ...
+---*/
+
+var checkPoint = "";
+Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}, {});
+assert.sameValue(checkPoint, "abc", "executor initially called with no arguments");
+
+var checkPoint = "";
+Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+}, {});
+assert.sameValue(checkPoint, "abc", "executor initially called with (undefined, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+ }, {});
+}, "executor initially called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (undefined, function)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+ }, {});
+}, "executor initially called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (function, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor("invalid value", 123);
+ checkPoint += "b";
+ executor(function() {}, function() {});
+ checkPoint += "c";
+ }, {});
+}, "executor initially called with (String, Number)");
+assert.sameValue(checkPoint, "ab", "executor initially called with (String, Number)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/capability-executor-not-callable.js b/js/src/tests/test262/built-ins/Promise/resolve/capability-executor-not-callable.js
new file mode 100644
index 0000000000..09ed28476b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/capability-executor-not-callable.js
@@ -0,0 +1,85 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.5
+description: >
+ Throws a TypeError if either resolve or reject capability is not callable.
+info: |
+ Promise.resolve ( x )
+
+ ...
+ 4. Let promiseCapability be NewPromiseCapability(C).
+ 5. ReturnIfAbrupt(promiseCapability).
+ ...
+
+ 25.4.1.5 NewPromiseCapability ( C )
+ ...
+ 4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1).
+ 5. Set the [[Capability]] internal slot of executor to promiseCapability.
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+ 8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
+ 9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
+ ...
+---*/
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ }, {});
+}, "executor not called at all");
+assert.sameValue(checkPoint, "a", "executor not called at all");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor();
+ checkPoint += "b";
+ }, {});
+}, "executor called with no arguments");
+assert.sameValue(checkPoint, "ab", "executor called with no arguments");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, undefined);
+ checkPoint += "b";
+ }, {});
+}, "executor called with (undefined, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor(undefined, function() {});
+ checkPoint += "b";
+ }, {});
+}, "executor called with (undefined, function)");
+assert.sameValue(checkPoint, "ab", "executor called with (undefined, function)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor(function() {}, undefined);
+ checkPoint += "b";
+ }, {});
+}, "executor called with (function, undefined)");
+assert.sameValue(checkPoint, "ab", "executor called with (function, undefined)");
+
+var checkPoint = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call(function(executor) {
+ checkPoint += "a";
+ executor(123, "invalid value");
+ checkPoint += "b";
+ }, {});
+}, "executor called with (Number, String)");
+assert.sameValue(checkPoint, "ab", "executor called with (Number, String)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/capability-invocation-error.js b/js/src/tests/test262/built-ins/Promise/resolve/capability-invocation-error.js
new file mode 100644
index 0000000000..6302336b1c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/capability-invocation-error.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: Abrupt completion returned by "resolve" capability
+esid: sec-promise.resolve
+info: |
+ 1. Let C be the this value.
+ [...]
+ 4. Let promiseCapability be ? NewPromiseCapability(C).
+ 5. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »).
+
+ 25.4.1.5 NewPromiseCapability
+ [...]
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+---*/
+
+var P = function(executor) {
+ return new Promise(function() {
+ executor(
+ function() {
+ throw new Test262Error();
+ },
+ function() {}
+ );
+ });
+};
+
+assert.throws(Test262Error, function() {
+ Promise.resolve.call(P);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/context-non-object-with-promise.js b/js/src/tests/test262/built-ins/Promise/resolve/context-non-object-with-promise.js
new file mode 100644
index 0000000000..be4934f14e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/context-non-object-with-promise.js
@@ -0,0 +1,50 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.5
+description: >
+ Throws a TypeError if `this` is not an Object.
+info: |
+ Promise.resolve ( x )
+
+ 1. Let C be the this value.
+ 2. If Type(C) is not Object, throw a TypeError exception.
+ ...
+features: [Symbol]
+---*/
+
+var promise = new Promise(function() {});
+
+promise.constructor = undefined;
+assert.throws(TypeError, function() {
+ Promise.resolve.call(undefined, promise);
+}, "`this` value is undefined");
+
+promise.constructor = null;
+assert.throws(TypeError, function() {
+ Promise.resolve.call(null, promise);
+}, "`this` value is null");
+
+promise.constructor = true;
+assert.throws(TypeError, function() {
+ Promise.resolve.call(true, promise);
+}, "`this` value is a Boolean");
+
+promise.constructor = 1;
+assert.throws(TypeError, function() {
+ Promise.resolve.call(1, promise);
+}, "`this` value is a Number");
+
+promise.constructor = "";
+assert.throws(TypeError, function() {
+ Promise.resolve.call("", promise);
+}, "`this` value is a String");
+
+var symbol = Symbol();
+promise.constructor = symbol;
+assert.throws(TypeError, function() {
+ Promise.resolve.call(symbol, promise);
+}, "`this` value is a Symbol");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/ctx-ctor-throws.js b/js/src/tests/test262/built-ins/Promise/resolve/ctx-ctor-throws.js
new file mode 100644
index 0000000000..f73047169d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/ctx-ctor-throws.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.resolve` invoked on a constructor value that throws an error
+es6id: 25.4.4.5
+info: |
+ 1. Let C be the this value.
+ [...]
+ 4. Let promiseCapability be NewPromiseCapability(C).
+ 5. ReturnIfAbrupt(promiseCapability).
+
+ 25.4.1.5 NewPromiseCapability
+ [...]
+ 6. Let promise be Construct(C, «executor»).
+ 7. ReturnIfAbrupt(promise).
+---*/
+
+var CustomPromise = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ Promise.resolve.call(CustomPromise);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/ctx-ctor.js b/js/src/tests/test262/built-ins/Promise/resolve/ctx-ctor.js
new file mode 100644
index 0000000000..ea39cb7559
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/ctx-ctor.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.resolve` invoked on a constructor value
+es6id: 25.4.4.5
+info: |
+ 1. Let C be the this value.
+ [...]
+ 4. Let promiseCapability be NewPromiseCapability(C).
+ [...]
+ 8. Return promiseCapability.[[Promise]].
+features: [class]
+---*/
+
+var executor = null;
+var callCount = 0;
+
+class SubPromise extends Promise {
+ constructor(a) {
+ super(a);
+ executor = a;
+ callCount += 1;
+ }
+}
+
+var instance = Promise.resolve.call(SubPromise);
+
+assert.sameValue(instance.constructor, SubPromise);
+assert.sameValue(instance instanceof SubPromise, true);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(typeof executor, 'function');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/ctx-non-ctor.js b/js/src/tests/test262/built-ins/Promise/resolve/ctx-non-ctor.js
new file mode 100644
index 0000000000..03bfe89783
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/ctx-non-ctor.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.resolve` invoked on a non-constructor value
+es6id: 25.4.4.5
+info: |
+ [...]
+ 4. Let promiseCapability be NewPromiseCapability(C).
+ 5. ReturnIfAbrupt(promiseCapability).
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.resolve.call(eval);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/ctx-non-object.js b/js/src/tests/test262/built-ins/Promise/resolve/ctx-non-object.js
new file mode 100644
index 0000000000..9f7b8f9e7e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/ctx-non-object.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `Promise.resolve` invoked on a non-object value
+es6id: 25.4.4.5
+info: |
+ 1. Let C be the this value.
+ 2. If Type(C) is not Object, throw a TypeError exception.
+features: [Symbol]
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.resolve.call(undefined, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.resolve.call(null, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.resolve.call(86, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.resolve.call('string', []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.resolve.call(true, []);
+});
+
+assert.throws(TypeError, function() {
+ Promise.resolve.call(Symbol(), []);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/length.js b/js/src/tests/test262/built-ins/Promise/resolve/length.js
new file mode 100644
index 0000000000..a73283a4b2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/length.js
@@ -0,0 +1,27 @@
+// 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.4.5
+description: Promise.resolve `length` property
+info: |
+ ES6 Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.resolve.length, 1);
+
+verifyNotEnumerable(Promise.resolve, 'length');
+verifyNotWritable(Promise.resolve, 'length');
+verifyConfigurable(Promise.resolve, 'length');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/name.js b/js/src/tests/test262/built-ins/Promise/resolve/name.js
new file mode 100644
index 0000000000..b9644562b6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/name.js
@@ -0,0 +1,28 @@
+// 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.4.5
+description: Promise.resolve `name` property
+info: |
+ ES6 Section 17:
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Promise.resolve.name, 'resolve');
+
+verifyNotEnumerable(Promise.resolve, 'name');
+verifyNotWritable(Promise.resolve, 'name');
+verifyConfigurable(Promise.resolve, 'name');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/not-a-constructor.js b/js/src/tests/test262/built-ins/Promise/resolve/not-a-constructor.js
new file mode 100644
index 0000000000..e455743938
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/not-a-constructor.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Promise.resolve does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(isConstructor(Promise.resolve), false, 'isConstructor(Promise.resolve) must return false');
+
+assert.throws(TypeError, () => {
+ new Promise.resolve();
+}, '`new Promise.resolve()` throws TypeError');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/prop-desc.js b/js/src/tests/test262/built-ins/Promise/resolve/prop-desc.js
new file mode 100644
index 0000000000..ecbf48f185
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/prop-desc.js
@@ -0,0 +1,21 @@
+// Copyright 2015 Jordan Harband. All rights reserved.
+// See LICENSE for details.
+
+/*---
+es6id: 25.4.4.5_A1.2_T1
+author: Jordan Harband
+description: Promise.resolve should be non-enumerable
+info: |
+ ES6 Section 17
+
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(Promise, 'resolve');
+verifyWritable(Promise, 'resolve');
+verifyConfigurable(Promise, 'resolve');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/resolve-from-promise-capability.js b/js/src/tests/test262/built-ins/Promise/resolve/resolve-from-promise-capability.js
new file mode 100644
index 0000000000..910f3791e2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/resolve-from-promise-capability.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 25.4.4.5
+description: >
+ Resolve function is called after Promise constructor returns.
+info: |
+ Promise.resolve ( x )
+
+ ...
+ 4. Let promiseCapability be NewPromiseCapability(C).
+ 5. ReturnIfAbrupt(promiseCapability).
+ 6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined, «x»).
+ 7. ReturnIfAbrupt(resolveResult).
+ ...
+---*/
+
+var expectedThisValue = (function() {
+ return this;
+}());
+var callCount = 0;
+var object = {};
+var thisValue, args;
+
+Promise.resolve.call(function(executor) {
+ function resolve(v) {
+ callCount += 1;
+ thisValue = this;
+ args = arguments;
+ }
+ executor(resolve, Test262Error.thrower);
+ assert.sameValue(callCount, 0, "callCount before returning from constructor");
+}, object);
+
+assert.sameValue(callCount, 1, "callCount after call to resolve()");
+assert.sameValue(typeof args, "object");
+assert.sameValue(args.length, 1);
+assert.sameValue(args[0], object);
+assert.sameValue(thisValue, expectedThisValue);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/resolve-non-obj.js b/js/src/tests/test262/built-ins/Promise/resolve/resolve-non-obj.js
new file mode 100644
index 0000000000..a26ef53ca9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/resolve-non-obj.js
@@ -0,0 +1,29 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/resolve/resolve-non-thenable.js b/js/src/tests/test262/built-ins/Promise/resolve/resolve-non-thenable.js
new file mode 100644
index 0000000000..0ed1dd2541
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/resolve-non-thenable.js
@@ -0,0 +1,35 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/resolve/resolve-poisoned-then.js b/js/src/tests/test262/built-ins/Promise/resolve/resolve-poisoned-then.js
new file mode 100644
index 0000000000..330c890b42
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/resolve-poisoned-then.js
@@ -0,0 +1,38 @@
+// |reftest| async
+// 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]]).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/resolve/resolve-prms-cstm-then.js b/js/src/tests/test262/built-ins/Promise/resolve/resolve-prms-cstm-then.js
new file mode 100644
index 0000000000..fe95c71f84
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/resolve-prms-cstm-then.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 resolved Promise instance whose `then` method has been overridden
+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 rejectCallCount = 0;
+var thenable = new Promise(function(resolve) {
+ resolve();
+});
+var resolvedValue;
+
+thenable.then = function(resolve) {
+ resolve(value);
+};
+
+Promise.resolve(thenable).then(function(val) {
+ resolvedValue = val;
+}, function() {
+ rejectCallCount += 1;
+});
+
+assert.sameValue(resolvedValue, value);
+assert.sameValue(rejectCallCount, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/resolve-self.js b/js/src/tests/test262/built-ins/Promise/resolve/resolve-self.js
new file mode 100644
index 0000000000..03d14879eb
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/resolve-self.js
@@ -0,0 +1,48 @@
+// |reftest| async
+// 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).
+flags: [async]
+---*/
+
+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/js/src/tests/test262/built-ins/Promise/resolve/resolve-thenable.js b/js/src/tests/test262/built-ins/Promise/resolve/resolve-thenable.js
new file mode 100644
index 0000000000..1934ede551
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/resolve-thenable.js
@@ -0,0 +1,42 @@
+// |reftest| async
+// 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»)
+flags: [async]
+---*/
+
+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.');
+});
diff --git a/js/src/tests/test262/built-ins/Promise/resolve/shell.js b/js/src/tests/test262/built-ins/Promise/resolve/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/resolve/shell.js
diff --git a/js/src/tests/test262/built-ins/Promise/shell.js b/js/src/tests/test262/built-ins/Promise/shell.js
new file mode 100644
index 0000000000..6fbf1a63a4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/shell.js
@@ -0,0 +1,101 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
+
+// file: promiseHelper.js
+// Copyright (C) 2017 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Check that an array contains a numeric sequence starting at 1
+ and incrementing by 1 for each entry in the array. Used by
+ Promise tests to assert the order of execution in deep Promise
+ resolution pipelines.
+defines: [checkSequence, checkSettledPromises]
+---*/
+
+function checkSequence(arr, message) {
+ arr.forEach(function(e, i) {
+ if (e !== (i+1)) {
+ throw new Test262Error((message ? message : "Steps in unexpected sequence:") +
+ " '" + arr.join(',') + "'");
+ }
+ });
+
+ return true;
+}
+
+function checkSettledPromises(settleds, expected, message) {
+ const prefix = message ? `${message}: ` : '';
+
+ assert.sameValue(Array.isArray(settleds), true, `${prefix}Settled values is an array`);
+
+ assert.sameValue(
+ settleds.length,
+ expected.length,
+ `${prefix}The settled values has a different length than expected`
+ );
+
+ settleds.forEach((settled, i) => {
+ assert.sameValue(
+ Object.prototype.hasOwnProperty.call(settled, 'status'),
+ true,
+ `${prefix}The settled value has a property status`
+ );
+
+ assert.sameValue(settled.status, expected[i].status, `${prefix}status for item ${i}`);
+
+ if (settled.status === 'fulfilled') {
+ assert.sameValue(
+ Object.prototype.hasOwnProperty.call(settled, 'value'),
+ true,
+ `${prefix}The fulfilled promise has a property named value`
+ );
+
+ assert.sameValue(
+ Object.prototype.hasOwnProperty.call(settled, 'reason'),
+ false,
+ `${prefix}The fulfilled promise has no property named reason`
+ );
+
+ assert.sameValue(settled.value, expected[i].value, `${prefix}value for item ${i}`);
+ } else {
+ assert.sameValue(settled.status, 'rejected', `${prefix}Valid statuses are only fulfilled or rejected`);
+
+ assert.sameValue(
+ Object.prototype.hasOwnProperty.call(settled, 'value'),
+ false,
+ `${prefix}The fulfilled promise has no property named value`
+ );
+
+ assert.sameValue(
+ Object.prototype.hasOwnProperty.call(settled, 'reason'),
+ true,
+ `${prefix}The fulfilled promise has a property named reason`
+ );
+
+ assert.sameValue(settled.reason, expected[i].reason, `${prefix}Reason value for item ${i}`);
+ }
+ });
+}
diff --git a/js/src/tests/test262/built-ins/Promise/undefined-newtarget.js b/js/src/tests/test262/built-ins/Promise/undefined-newtarget.js
new file mode 100644
index 0000000000..e672e2a63e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/undefined-newtarget.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2019 Aleksey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-promise-executor
+description: >
+ Throws a TypeError if Promise is called without a NewTarget.
+info: |
+ 25.6.3.1 Promise ( executor )
+
+ 1. If NewTarget is undefined, throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() {
+ Promise(function() {});
+});
+
+assert.throws(TypeError, function() {
+ Promise.call(null, function() {});
+});
+
+var p = new Promise(function() {});
+assert.throws(TypeError, function() {
+ Promise.call(p, function() {});
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/withResolvers/browser.js b/js/src/tests/test262/built-ins/Promise/withResolvers/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/withResolvers/browser.js
diff --git a/js/src/tests/test262/built-ins/Promise/withResolvers/ctx-ctor.js b/js/src/tests/test262/built-ins/Promise/withResolvers/ctx-ctor.js
new file mode 100644
index 0000000000..c13c68fa9f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/withResolvers/ctx-ctor.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2023 Peter Klecha. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise.withResolvers produces instances of the receiver
+esid: sec-promise.withresolvers
+features: [promise-with-resolvers]
+---*/
+
+class SubPromise extends Promise {}
+
+var instance = Promise.withResolvers.call(SubPromise);
+
+assert.sameValue(instance.promise.constructor, SubPromise);
+assert.sameValue(instance.promise instanceof SubPromise, true);
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/withResolvers/ctx-non-ctor.js b/js/src/tests/test262/built-ins/Promise/withResolvers/ctx-non-ctor.js
new file mode 100644
index 0000000000..b5364593b8
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/withResolvers/ctx-non-ctor.js
@@ -0,0 +1,14 @@
+// Copyright (C) 2023 Peter Klecha. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise.withResolvers errors when the receiver is not a constructor
+esid: sec-promise.withresolvers
+features: [promise-with-resolvers]
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.withResolvers.call(eval);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/withResolvers/ctx-non-object.js b/js/src/tests/test262/built-ins/Promise/withResolvers/ctx-non-object.js
new file mode 100644
index 0000000000..3be318a003
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/withResolvers/ctx-non-object.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2023 Peter Klecha. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise.withResolvers errors when the receiver is not an object
+esid: sec-promise.withresolvers
+features: [promise-with-resolvers]
+---*/
+
+assert.throws(TypeError, function() {
+ Promise.withResolvers.call(undefined);
+});
+
+assert.throws(TypeError, function() {
+ Promise.withResolvers.call(null);
+});
+
+assert.throws(TypeError, function() {
+ Promise.withResolvers.call(86);
+});
+
+assert.throws(TypeError, function() {
+ Promise.withResolvers.call('string');
+});
+
+assert.throws(TypeError, function() {
+ Promise.withResolvers.call(true);
+});
+
+assert.throws(TypeError, function() {
+ Promise.withResolvers.call(Symbol());
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/withResolvers/promise.js b/js/src/tests/test262/built-ins/Promise/withResolvers/promise.js
new file mode 100644
index 0000000000..7a58ecef14
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/withResolvers/promise.js
@@ -0,0 +1,17 @@
+// Copyright (C) 2023 Peter Klecha. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise.withResolvers return value has a property called "promise" which is a Promise
+esid: sec-promise.withresolvers
+features: [promise-with-resolvers]
+---*/
+
+
+var instance = Promise.withResolvers();
+
+assert.sameValue(instance.promise.constructor, Promise);
+assert.sameValue(instance.promise instanceof Promise, true);
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/withResolvers/resolvers.js b/js/src/tests/test262/built-ins/Promise/withResolvers/resolvers.js
new file mode 100644
index 0000000000..8a0606870a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/withResolvers/resolvers.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2023 Peter Klecha. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise.withResolvers return value has properties called "resolve" and "reject" which are unary functions
+esid: sec-promise.withresolvers
+features: [promise-with-resolvers]
+---*/
+
+
+var instance = Promise.withResolvers();
+
+assert.sameValue(typeof instance.resolve, 'function', 'type of resolve property');
+assert.sameValue(instance.resolve.length, 1, 'length of resolve property');
+assert.sameValue(typeof instance.reject, 'function', 'type of reject property');
+assert.sameValue(instance.reject.length, 1, 'length of reject property');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/withResolvers/result.js b/js/src/tests/test262/built-ins/Promise/withResolvers/result.js
new file mode 100644
index 0000000000..0679dfaf31
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/withResolvers/result.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 Peter Klecha. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Promise.withResolvers result is an object with keys "promise", "reject", and "resolve"
+esid: sec-promise.withresolvers
+includes: [propertyHelper.js]
+features: [promise-with-resolvers]
+---*/
+
+
+var instance = Promise.withResolvers();
+
+assert.sameValue(typeof instance, "object");
+assert.notSameValue(instance, null);
+assert(instance instanceof Object);
+
+verifyProperty(instance, "promise", {
+ writable: true,
+ configurable: true,
+ enumerable: true,
+})
+
+verifyProperty(instance, "resolve", {
+ writable: true,
+ configurable: true,
+ enumerable: true,
+})
+
+verifyProperty(instance, "reject", {
+ writable: true,
+ configurable: true,
+ enumerable: true,
+})
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Promise/withResolvers/shell.js b/js/src/tests/test262/built-ins/Promise/withResolvers/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/withResolvers/shell.js