Skip to content

Commit

Permalink
[tests] add some Promise subclassing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Feb 24, 2016
1 parent 6aa76d7 commit 0a144de
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 6 deletions.
79 changes: 77 additions & 2 deletions tests/es.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

79 changes: 77 additions & 2 deletions tests/library.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions tests/library/es6.promise.ls
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,27 @@ if DESCRIPTORS => test 'Promise operations order' (assert)!->

test 'Promise#then' (assert)!->
assert.isFunction Promise::then
# subclassing, @@species pattern
promise = new Promise !-> it 42
promise.constructor = FakePromise1 = !-> it ->, ->
FakePromise1[Symbol?species] = FakePromise2 = !-> it ->, ->

This comment has been minimized.

Copy link
@ysmood

ysmood Feb 24, 2016

I think the FakePromise2's __proto__ should be correctly set like:

Object.setPrototypeOf FakePromise2, Promise

This comment has been minimized.

Copy link
@zloirock

zloirock Feb 24, 2016

Author Owner

Nope, we don't use prototype methods of a result instance / a fake constructor. Here tested generic behavior.

This comment has been minimized.

Copy link
@ysmood

ysmood Feb 24, 2016

If you don't set __proto__, in the line 49 when running promise.then(->), the then should throw a type error, then the assert.ok won't execute at all.

This comment has been minimized.

Copy link
@zloirock

zloirock Feb 24, 2016

Author Owner

Should not. Instantiation here should be generic. Promise methods generics in most cases, non-generic only .then and only on this (but here tested this.constructor[Symbol.species] and this.constructor). Something like that should work:

var Bluebird = require("bluebird");

var p = Promise.resolve(42);
p.constructor = {[Symbol.species]: Bluebird};
p.then(_ => _) instanceof Bluebird; // => true

Promise.all.call(Bluebird, [1, 2, 3]) instanceof Bluebird; // => true

This comment has been minimized.

Copy link
@ysmood

ysmood Feb 24, 2016

That's a bug of bluebird, its behavior is wrong. Use the latest v8 or es6-shim to test.

This comment has been minimized.

Copy link
@zloirock

zloirock Feb 24, 2016

Author Owner

It's a correct behavior by the spec, bluebird here just for example generic behavior. Latest V8 (actual build canary 50) passes this test, didn't try it on es6-shim, but I don't think it should pass - feature detection es6-shim not so correct and just ignores @@species.

This comment has been minimized.

Copy link
@ysmood

ysmood Feb 24, 2016

Nope, I tested Canary 50, it doesn't pass if you don't set the __proto__

qq20160224-0

This comment has been minimized.

Copy link
@zloirock

zloirock Feb 24, 2016

Author Owner

123

This comment has been minimized.

Copy link
@ysmood

ysmood Feb 24, 2016

Well, after more check, I think I have figured it out, I am wrong. Thank for your patience.

assert.ok promise.then(->) instanceof FakePromise2, 'subclassing, @@species pattern'
# subclassing, incorrect `this.constructor` pattern
promise = new Promise !-> it 42
promise.constructor = FakePromise1 = !-> it ->, ->
assert.ok promise.then(->) instanceof Promise, 'subclassing, incorrect `this` pattern'

test 'Promise#catch' (assert)!->
assert.isFunction Promise::catch
# subclassing, @@species pattern
promise = new Promise !-> it 42
promise.constructor = FakePromise1 = !-> it ->, ->
FakePromise1[Symbol?species] = FakePromise2 = !-> it ->, ->
assert.ok promise.catch(->) instanceof FakePromise2, 'subclassing, @@species pattern'
# subclassing, incorrect `this.constructor` pattern
promise = new Promise !-> it 42
promise.constructor = FakePromise1 = !-> it ->, ->
assert.ok promise.catch(->) instanceof Promise, 'subclassing, incorrect `this` pattern'

test 'Promise#@@toStringTag' (assert)!->
assert.ok Promise::[Symbol.toStringTag] is \Promise, 'Promise::@@toStringTag is `Promise`'
Expand Down Expand Up @@ -75,6 +93,12 @@ test 'Promise.all' (assert)!->
Promise.all(createIterable [1 2 3], return: !-> done := on)catch !->
Promise.resolve = resolve
assert.ok done, 'iteration closing'
# subclassing, `this` pattern
FakePromise1 = !-> it ->, ->
FakePromise1.all = Promise.all
FakePromise1[Symbol?species] = FakePromise2 = !-> it ->, ->
FakePromise1.resolve = FakePromise2.resolve = Promise~resolve
assert.ok FakePromise1.all([1 2 3]) instanceof FakePromise1, 'subclassing, `this` pattern'

test 'Promise.race' (assert)!->
assert.isFunction Promise.race
Expand Down Expand Up @@ -102,14 +126,30 @@ test 'Promise.race' (assert)!->
Promise.race(createIterable [1 2 3], return: !-> done := on)catch !->
Promise.resolve = resolve
assert.ok done, 'iteration closing'
# subclassing, `this` pattern
FakePromise1 = !-> it ->, ->
FakePromise1.race = Promise.race
FakePromise1[Symbol?species] = FakePromise2 = !-> it ->, ->
FakePromise1.resolve = FakePromise2.resolve = Promise~resolve
assert.ok FakePromise1.race([1 2 3]) instanceof FakePromise1, 'subclassing, `this` pattern'

test 'Promise.resolve' (assert)!->
assert.isFunction Promise.resolve
assert.throws (!-> Promise.resolve.call(null, 1).catch !->), TypeError, 'throws without context'
# subclassing, `this` pattern
FakePromise1 = !-> it ->, ->
FakePromise1[Symbol?species] = FakePromise2 = !-> it ->, ->
FakePromise1.resolve = Promise.resolve
assert.ok FakePromise1.resolve(42) instanceof FakePromise1, 'subclassing, `this` pattern'

test 'Promise.reject' (assert)!->
assert.isFunction Promise.reject
assert.throws (!-> Promise.reject.call(null, 1).catch !->), TypeError, 'throws without context'
# subclassing, `this` pattern
FakePromise1 = !-> it ->, ->
FakePromise1[Symbol?species] = FakePromise2 = !-> it ->, ->
FakePromise1.reject = Promise.reject
assert.ok FakePromise1.reject(42) instanceof FakePromise1, 'subclassing, `this` pattern'

if PROTO
test 'Promise subclassing' (assert)!->
Expand Down
Loading

0 comments on commit 0a144de

Please sign in to comment.