32
32
*/
33
33
34
34
describe ( 'q' , function ( ) {
35
- var q , defer , deferred , promise , log ;
35
+ var q , defer , deferred , promise , log , exceptionHandlerCalls ;
36
36
37
37
// The following private functions are used to help with logging for testing invocation of the
38
38
// promise callbacks.
@@ -181,12 +181,23 @@ describe('q', function() {
181
181
} ;
182
182
183
183
184
+ function exceptionHandler ( reason ) {
185
+ exceptionHandlerCalls . push ( reason ) ;
186
+ }
187
+
188
+
189
+ function exceptionHandlerStr ( ) {
190
+ return exceptionHandlerCalls . join ( '; ' ) ;
191
+ }
192
+
193
+
184
194
beforeEach ( function ( ) {
185
- q = qFactory ( mockNextTick . nextTick , noop ) ,
195
+ q = qFactory ( mockNextTick . nextTick , exceptionHandler ) ,
186
196
defer = q . defer ;
187
197
deferred = defer ( ) ;
188
198
promise = deferred . promise ;
189
199
log = [ ] ;
200
+ exceptionHandlerCalls = [ ] ;
190
201
mockNextTick . queue = [ ] ;
191
202
} ) ;
192
203
@@ -1586,6 +1597,8 @@ describe('q', function() {
1586
1597
var rejectedPromise = q . reject ( 'rejected' ) ;
1587
1598
expect ( rejectedPromise [ 'finally' ] ) . not . toBeUndefined ( ) ;
1588
1599
expect ( rejectedPromise [ 'catch' ] ) . not . toBeUndefined ( ) ;
1600
+ rejectedPromise . then ( noop , noop ) ;
1601
+ mockNextTick . flush ( ) ;
1589
1602
} ) ;
1590
1603
} ) ;
1591
1604
@@ -1995,15 +2008,15 @@ describe('q', function() {
1995
2008
it ( 'should log exceptions thrown in a success callback and reject the derived promise' ,
1996
2009
function ( ) {
1997
2010
var success1 = success ( 1 , 'oops' , true ) ;
1998
- promise . then ( success1 ) . then ( success ( 2 ) , error ( 2 ) ) ;
2011
+ promise . then ( success1 ) . then ( success ( 2 ) , error ( 2 ) ) . then ( noop , noop ) ;
1999
2012
syncResolve ( deferred , 'done' ) ;
2000
2013
expect ( logStr ( ) ) . toBe ( 'success1(done)->throw(oops); error2(oops)->reject(oops)' ) ;
2001
2014
expect ( mockExceptionLogger . log ) . toEqual ( [ 'oops' ] ) ;
2002
2015
} ) ;
2003
2016
2004
2017
2005
2018
it ( 'should NOT log exceptions when a success callback returns rejected promise' , function ( ) {
2006
- promise . then ( success ( 1 , q . reject ( 'rejected' ) ) ) . then ( success ( 2 ) , error ( 2 ) ) ;
2019
+ promise . then ( success ( 1 , q . reject ( 'rejected' ) ) ) . then ( success ( 2 ) , error ( 2 ) ) . then ( noop , noop ) ;
2007
2020
syncResolve ( deferred , 'done' ) ;
2008
2021
expect ( logStr ( ) ) . toBe ( 'success1(done)->{}; error2(rejected)->reject(rejected)' ) ;
2009
2022
expect ( mockExceptionLogger . log ) . toEqual ( [ ] ) ;
@@ -2012,15 +2025,15 @@ describe('q', function() {
2012
2025
2013
2026
it ( 'should log exceptions thrown in a errback and reject the derived promise' , function ( ) {
2014
2027
var error1 = error ( 1 , 'oops' , true ) ;
2015
- promise . then ( null , error1 ) . then ( success ( 2 ) , error ( 2 ) ) ;
2028
+ promise . then ( null , error1 ) . then ( success ( 2 ) , error ( 2 ) ) . then ( noop , noop ) ;
2016
2029
syncReject ( deferred , 'nope' ) ;
2017
2030
expect ( logStr ( ) ) . toBe ( 'error1(nope)->throw(oops); error2(oops)->reject(oops)' ) ;
2018
2031
expect ( mockExceptionLogger . log ) . toEqual ( [ 'oops' ] ) ;
2019
2032
} ) ;
2020
2033
2021
2034
2022
2035
it ( 'should NOT log exceptions when an errback returns a rejected promise' , function ( ) {
2023
- promise . then ( null , error ( 1 , q . reject ( 'rejected' ) ) ) . then ( success ( 2 ) , error ( 2 ) ) ;
2036
+ promise . then ( null , error ( 1 , q . reject ( 'rejected' ) ) ) . then ( success ( 2 ) , error ( 2 ) ) . then ( noop , noop ) ;
2024
2037
syncReject ( deferred , 'nope' ) ;
2025
2038
expect ( logStr ( ) ) . toBe ( 'error1(nope)->{}; error2(rejected)->reject(rejected)' ) ;
2026
2039
expect ( mockExceptionLogger . log ) . toEqual ( [ ] ) ;
@@ -2029,7 +2042,7 @@ describe('q', function() {
2029
2042
2030
2043
it ( 'should log exceptions throw in a progressack and stop propagation, but shoud NOT reject ' +
2031
2044
'the promise' , function ( ) {
2032
- promise . then ( success ( ) , error ( ) , progress ( 1 , 'failed' , true ) ) . then ( null , error ( 1 ) , progress ( 2 ) ) ;
2045
+ promise . then ( success ( ) , error ( ) , progress ( 1 , 'failed' , true ) ) . then ( null , error ( 1 ) , progress ( 2 ) ) . then ( noop , noop ) ;
2033
2046
syncNotify ( deferred , '10%' ) ;
2034
2047
expect ( logStr ( ) ) . toBe ( 'progress1(10%)->throw(failed)' ) ;
2035
2048
expect ( mockExceptionLogger . log ) . toEqual ( [ 'failed' ] ) ;
@@ -2045,15 +2058,15 @@ describe('q', function() {
2045
2058
it ( 'should log exceptions thrown in a success callback and reject the derived promise' ,
2046
2059
function ( ) {
2047
2060
var success1 = success ( 1 , 'oops' , true ) ;
2048
- q . when ( 'hi' , success1 , error ( ) ) . then ( success ( ) , error ( 2 ) ) ;
2061
+ q . when ( 'hi' , success1 , error ( ) ) . then ( success ( ) , error ( 2 ) ) . then ( noop , noop ) ;
2049
2062
mockNextTick . flush ( ) ;
2050
2063
expect ( logStr ( ) ) . toBe ( 'success1(hi)->throw(oops); error2(oops)->reject(oops)' ) ;
2051
2064
expect ( mockExceptionLogger . log ) . toEqual ( [ 'oops' ] ) ;
2052
2065
} ) ;
2053
2066
2054
2067
2055
2068
it ( 'should NOT log exceptions when a success callback returns rejected promise' , function ( ) {
2056
- q . when ( 'hi' , success ( 1 , q . reject ( 'rejected' ) ) ) . then ( success ( 2 ) , error ( 2 ) ) ;
2069
+ q . when ( 'hi' , success ( 1 , q . reject ( 'rejected' ) ) ) . then ( success ( 2 ) , error ( 2 ) ) . then ( noop , noop ) ;
2057
2070
mockNextTick . flush ( ) ;
2058
2071
expect ( logStr ( ) ) . toBe ( 'success1(hi)->{}; error2(rejected)->reject(rejected)' ) ;
2059
2072
expect ( mockExceptionLogger . log ) . toEqual ( [ ] ) ;
@@ -2062,7 +2075,7 @@ describe('q', function() {
2062
2075
2063
2076
it ( 'should log exceptions thrown in a errback and reject the derived promise' , function ( ) {
2064
2077
var error1 = error ( 1 , 'oops' , true ) ;
2065
- q . when ( q . reject ( 'sorry' ) , success ( ) , error1 ) . then ( success ( ) , error ( 2 ) ) ;
2078
+ q . when ( q . reject ( 'sorry' ) , success ( ) , error1 ) . then ( success ( ) , error ( 2 ) ) . then ( noop , noop ) ;
2066
2079
mockNextTick . flush ( ) ;
2067
2080
expect ( logStr ( ) ) . toBe ( 'error1(sorry)->throw(oops); error2(oops)->reject(oops)' ) ;
2068
2081
expect ( mockExceptionLogger . log ) . toEqual ( [ 'oops' ] ) ;
@@ -2071,7 +2084,7 @@ describe('q', function() {
2071
2084
2072
2085
it ( 'should NOT log exceptions when an errback returns a rejected promise' , function ( ) {
2073
2086
q . when ( q . reject ( 'sorry' ) , success ( ) , error ( 1 , q . reject ( 'rejected' ) ) ) .
2074
- then ( success ( 2 ) , error ( 2 ) ) ;
2087
+ then ( success ( 2 ) , error ( 2 ) ) . then ( noop , noop ) ;
2075
2088
mockNextTick . flush ( ) ;
2076
2089
expect ( logStr ( ) ) . toBe ( 'error1(sorry)->{}; error2(rejected)->reject(rejected)' ) ;
2077
2090
expect ( mockExceptionLogger . log ) . toEqual ( [ ] ) ;
@@ -2080,6 +2093,43 @@ describe('q', function() {
2080
2093
} ) ;
2081
2094
2082
2095
2096
+ describe ( 'when exceptionHandler is called' , function ( ) {
2097
+ it ( 'should log an unhandled rejected promise' , function ( ) {
2098
+ var defer = q . defer ( ) ;
2099
+ defer . reject ( 'foo' ) ;
2100
+ mockNextTick . flush ( ) ;
2101
+ expect ( exceptionHandlerStr ( ) ) . toBe ( 'Possibly unhandled rejection: "foo"' ) ;
2102
+ } ) ;
2103
+
2104
+
2105
+ it ( 'should log a handled rejected promise on a promise without rejection callbacks' , function ( ) {
2106
+ var defer = q . defer ( ) ;
2107
+ defer . promise . then ( noop ) ;
2108
+ defer . reject ( 'foo' ) ;
2109
+ mockNextTick . flush ( ) ;
2110
+ expect ( exceptionHandlerStr ( ) ) . toBe ( 'Possibly unhandled rejection: "foo"' ) ;
2111
+ } ) ;
2112
+
2113
+
2114
+ it ( 'should not log a handled rejected promise' , function ( ) {
2115
+ var defer = q . defer ( ) ;
2116
+ defer . promise . then ( noop , noop ) ;
2117
+ defer . reject ( 'foo' ) ;
2118
+ mockNextTick . flush ( ) ;
2119
+ expect ( exceptionHandlerStr ( ) ) . toBe ( '' ) ;
2120
+ } ) ;
2121
+
2122
+
2123
+ it ( 'should not log a handled rejected promise that is handled in a future tick' , function ( ) {
2124
+ var defer = q . defer ( ) ;
2125
+ defer . promise . then ( noop , noop ) ;
2126
+ defer . resolve ( q . reject ( 'foo' ) ) ;
2127
+ mockNextTick . flush ( ) ;
2128
+ expect ( exceptionHandlerStr ( ) ) . toBe ( '' ) ;
2129
+ } ) ;
2130
+ } ) ;
2131
+
2132
+
2083
2133
describe ( 'when exceptionHandler rethrows exceptions, ' , function ( ) {
2084
2134
var originalLogExceptions , deferred , errorSpy , exceptionExceptionSpy ;
2085
2135
0 commit comments