| OLD | NEW | 
|    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file |    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|    2 // for details. All rights reserved. Use of this source code is governed by a |    2 // for details. All rights reserved. Use of this source code is governed by a | 
|    3 // BSD-style license that can be found in the LICENSE file. |    3 // BSD-style license that can be found in the LICENSE file. | 
|    4  |    4  | 
|    5 library future_test; |    5 library future_test; | 
|    6  |    6  | 
|    7 import "package:expect/expect.dart"; |    7 import "package:expect/expect.dart"; | 
|    8 import 'dart:async'; |    8 import 'dart:async'; | 
|    9 import 'dart:isolate'; |    9 import 'dart:isolate'; | 
|   10  |   10  | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   22 testOf() { |   22 testOf() { | 
|   23   compare(func) { |   23   compare(func) { | 
|   24     // Compare the results of the following two futures. |   24     // Compare the results of the following two futures. | 
|   25     Future f1 = new Future.of(func); |   25     Future f1 = new Future.of(func); | 
|   26     Future f2 = new Future.immediate(null).then((_) => func()); |   26     Future f2 = new Future.immediate(null).then((_) => func()); | 
|   27     f2.catchError((_){});  // I'll get the error later. |   27     f2.catchError((_){});  // I'll get the error later. | 
|   28     f1.then((v1) { f2.then((v2) { Expect.equals(v1, v2); }); }, |   28     f1.then((v1) { f2.then((v2) { Expect.equals(v1, v2); }); }, | 
|   29             onError: (e1) { |   29             onError: (e1) { | 
|   30               f2.then((_) { Expect.fail("Expected error"); }, |   30               f2.then((_) { Expect.fail("Expected error"); }, | 
|   31                       onError: (e2) { |   31                       onError: (e2) { | 
|   32                          Expect.equals(e1.error, e2.error); |   32                          Expect.equals(e1, e2); | 
|   33                       }); |   33                       }); | 
|   34             }); |   34             }); | 
|   35   } |   35   } | 
|   36   Future val = new Future.immediate(42); |   36   Future val = new Future.immediate(42); | 
|   37   Future err1 = new Future.immediateError("Error")..catchError((_){}); |   37   Future err1 = new Future.immediateError("Error")..catchError((_){}); | 
|   38   Future err2 = new Future.immediateError(new AsyncError("AsyncError"))..catchEr
     ror((_){}); |   38   try { | 
 |   39     throw new List(0); | 
 |   40   } catch (e, st) { | 
 |   41     Future err2 = new Future.immediateError(e, st)..catchError((_){}); | 
 |   42   } | 
|   39   compare(() => 42); |   43   compare(() => 42); | 
|   40   compare(() => val); |   44   compare(() => val); | 
|   41   compare(() { throw "Flif"; }); |   45   compare(() { throw "Flif"; }); | 
|   42   compare(() { throw new AsyncError("AsyncFlif"); }); |  | 
|   43   compare(() => err1); |   46   compare(() => err1); | 
|   44   compare(() => err2); |  | 
|   45 } |   47 } | 
|   46  |   48  | 
|   47 testNeverComplete() { |   49 testNeverComplete() { | 
|   48   final completer = new Completer<int>(); |   50   final completer = new Completer<int>(); | 
|   49   final future = completer.future; |   51   final future = completer.future; | 
|   50   future.then((v) => Expect.fails("Value not expected")); |   52   future.then((v) => Expect.fails("Value not expected")); | 
|   51   future.catchError((e) => Expect.fails("Value not expected")); |   53   future.catchError((e) => Expect.fails("Value not expected")); | 
|   52 } |   54 } | 
|   53  |   55  | 
|   54 testComplete() { |   56 testComplete() { | 
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  120 // Tests for [catchError] |  122 // Tests for [catchError] | 
|  121  |  123  | 
|  122 testException() { |  124 testException() { | 
|  123   final completer = new Completer<int>(); |  125   final completer = new Completer<int>(); | 
|  124   final future = completer.future; |  126   final future = completer.future; | 
|  125   final ex = new Exception(); |  127   final ex = new Exception(); | 
|  126  |  128  | 
|  127   var port = new ReceivePort(); |  129   var port = new ReceivePort(); | 
|  128   future |  130   future | 
|  129       .then((v) { throw "Value not expected"; }) |  131       .then((v) { throw "Value not expected"; }) | 
|  130       .catchError((e) { |  132       .catchError((error) { | 
|  131         Expect.equals(e.error, ex); |  133         Expect.equals(error, ex); | 
|  132         port.close(); |  134         port.close(); | 
|  133       }, test: (e) => e == ex); |  135       }, test: (e) => e == ex); | 
|  134   completer.completeError(ex); |  136   completer.completeError(ex); | 
|  135 } |  137 } | 
|  136  |  138  | 
|  137 testExceptionHandler() { |  139 testExceptionHandler() { | 
|  138   final completer = new Completer<int>(); |  140   final completer = new Completer<int>(); | 
|  139   final future = completer.future; |  141   final future = completer.future; | 
|  140   final ex = new Exception(); |  142   final ex = new Exception(); | 
|  141  |  143  | 
|  142   var ex2; |  144   var ex2; | 
|  143   var done = future.catchError((e) { ex2 = e.error; }); |  145   var done = future.catchError((error) { ex2 = error; }); | 
|  144  |  146  | 
|  145   Expect.isFalse(completer.isCompleted); |  147   Expect.isFalse(completer.isCompleted); | 
|  146   completer.completeError(ex); |  148   completer.completeError(ex); | 
|  147   Expect.isTrue(completer.isCompleted); |  149   Expect.isTrue(completer.isCompleted); | 
|  148  |  150  | 
|  149   var port = new ReceivePort(); |  151   var port = new ReceivePort(); | 
|  150   done.then((_) { |  152   done.then((_) { | 
|  151     Expect.equals(ex, ex2); |  153     Expect.equals(ex, ex2); | 
|  152     port.close(); |  154     port.close(); | 
|  153   }); |  155   }); | 
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  256   var completer = new Completer(); |  258   var completer = new Completer(); | 
|  257   bool gotError = false; |  259   bool gotError = false; | 
|  258   var port = new ReceivePort(); |  260   var port = new ReceivePort(); | 
|  259   completer.future.asStream().listen( |  261   completer.future.asStream().listen( | 
|  260       (data) { |  262       (data) { | 
|  261         Expect.fail("Unexpected data"); |  263         Expect.fail("Unexpected data"); | 
|  262       }, |  264       }, | 
|  263       onError: (error) { |  265       onError: (error) { | 
|  264         Expect.isFalse(gotError); |  266         Expect.isFalse(gotError); | 
|  265         gotError = true; |  267         gotError = true; | 
|  266         Expect.equals("error", error.error); |  268         Expect.equals("error", error); | 
|  267       }, |  269       }, | 
|  268       onDone: () { |  270       onDone: () { | 
|  269         Expect.isTrue(gotError); |  271         Expect.isTrue(gotError); | 
|  270         port.close(); |  272         port.close(); | 
|  271       }); |  273       }); | 
|  272   completer.completeError("error"); |  274   completer.completeError("error"); | 
|  273 } |  275 } | 
|  274  |  276  | 
|  275 testFutureAsStreamWrapper() { |  277 testFutureAsStreamWrapper() { | 
|  276   var completer = new Completer(); |  278   var completer = new Completer(); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  309  |  311  | 
|  310 testFutureWhenCompleteError() { |  312 testFutureWhenCompleteError() { | 
|  311   var port = new ReceivePort(); |  313   var port = new ReceivePort(); | 
|  312   int counter = 2; |  314   int counter = 2; | 
|  313   countDown() { |  315   countDown() { | 
|  314     if (--counter == 0) port.close(); |  316     if (--counter == 0) port.close(); | 
|  315   } |  317   } | 
|  316   var completer = new Completer(); |  318   var completer = new Completer(); | 
|  317   Future future = completer.future; |  319   Future future = completer.future; | 
|  318   Future later = future.whenComplete(countDown); |  320   Future later = future.whenComplete(countDown); | 
|  319   later.catchError((AsyncError e) { |  321   later.catchError((error) { | 
|  320     Expect.equals("error", e.error); |  322     Expect.equals("error", error); | 
|  321     countDown(); |  323     countDown(); | 
|  322   }); |  324   }); | 
|  323   completer.completeError("error"); |  325   completer.completeError("error"); | 
|  324 } |  326 } | 
|  325  |  327  | 
|  326 testFutureWhenCompleteValueNewError() { |  328 testFutureWhenCompleteValueNewError() { | 
|  327   var port = new ReceivePort(); |  329   var port = new ReceivePort(); | 
|  328   int counter = 2; |  330   int counter = 2; | 
|  329   countDown() { |  331   countDown() { | 
|  330     if (--counter == 0) port.close(); |  332     if (--counter == 0) port.close(); | 
|  331   } |  333   } | 
|  332   var completer = new Completer(); |  334   var completer = new Completer(); | 
|  333   Future future = completer.future; |  335   Future future = completer.future; | 
|  334   Future later = future.whenComplete(() { |  336   Future later = future.whenComplete(() { | 
|  335     countDown(); |  337     countDown(); | 
|  336     throw "new error"; |  338     throw "new error"; | 
|  337   }); |  339   }); | 
|  338   later.catchError((AsyncError e) { |  340   later.catchError((error) { | 
|  339     Expect.equals("new error", e.error); |  341     Expect.equals("new error", error); | 
|  340     countDown(); |  342     countDown(); | 
|  341   }); |  343   }); | 
|  342   completer.complete(42); |  344   completer.complete(42); | 
|  343 } |  345 } | 
|  344  |  346  | 
|  345 testFutureWhenCompleteErrorNewError() { |  347 testFutureWhenCompleteErrorNewError() { | 
|  346   var port = new ReceivePort(); |  348   var port = new ReceivePort(); | 
|  347   int counter = 2; |  349   int counter = 2; | 
|  348   countDown() { |  350   countDown() { | 
|  349     if (--counter == 0) port.close(); |  351     if (--counter == 0) port.close(); | 
|  350   } |  352   } | 
|  351   var completer = new Completer(); |  353   var completer = new Completer(); | 
|  352   Future future = completer.future; |  354   Future future = completer.future; | 
|  353   Future later = future.whenComplete(() { |  355   Future later = future.whenComplete(() { | 
|  354     countDown(); |  356     countDown(); | 
|  355     throw "new error"; |  357     throw "new error"; | 
|  356   }); |  358   }); | 
|  357   later.catchError((AsyncError e) { |  359   later.catchError((error) { | 
|  358     Expect.equals("new error", e.error); |  360     Expect.equals("new error", error); | 
|  359     countDown(); |  361     countDown(); | 
|  360   }); |  362   }); | 
|  361   completer.completeError("error"); |  363   completer.completeError("error"); | 
|  362 } |  364 } | 
|  363  |  365  | 
|  364 testFutureWhenCompletePreValue() { |  366 testFutureWhenCompletePreValue() { | 
|  365   var port = new ReceivePort(); |  367   var port = new ReceivePort(); | 
|  366   int counter = 2; |  368   int counter = 2; | 
|  367   countDown() { |  369   countDown() { | 
|  368     if (--counter == 0) port.close(); |  370     if (--counter == 0) port.close(); | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  415   completer.future.whenComplete(() { |  417   completer.future.whenComplete(() { | 
|  416     countDown(3); |  418     countDown(3); | 
|  417     var completer2 = new Completer(); |  419     var completer2 = new Completer(); | 
|  418     new Timer(MS * 10, () { |  420     new Timer(MS * 10, () { | 
|  419       countDown(2); |  421       countDown(2); | 
|  420       completer2.completeError("Fail"); |  422       completer2.completeError("Fail"); | 
|  421     }); |  423     }); | 
|  422     return completer2.future; |  424     return completer2.future; | 
|  423   }).then((v) { |  425   }).then((v) { | 
|  424     Expect.fail("should fail async"); |  426     Expect.fail("should fail async"); | 
|  425   }, onError: (AsyncError e) { |  427   }, onError: (error) { | 
|  426     Expect.equals("Fail", e.error); |  428     Expect.equals("Fail", error); | 
|  427     countDown(1); |  429     countDown(1); | 
|  428   }); |  430   }); | 
|  429  |  431  | 
|  430   completer.complete(42); |  432   completer.complete(42); | 
|  431 } |  433 } | 
|  432  |  434  | 
|  433 testFutureWhenErrorFutureValue() { |  435 testFutureWhenErrorFutureValue() { | 
|  434   var port = new ReceivePort(); |  436   var port = new ReceivePort(); | 
|  435   int counter = 3; |  437   int counter = 3; | 
|  436   countDown(int expect) { |  438   countDown(int expect) { | 
|  437     Expect.equals(expect, counter); |  439     Expect.equals(expect, counter); | 
|  438     if (--counter == 0) port.close(); |  440     if (--counter == 0) port.close(); | 
|  439   } |  441   } | 
|  440   var completer = new Completer(); |  442   var completer = new Completer(); | 
|  441   completer.future.whenComplete(() { |  443   completer.future.whenComplete(() { | 
|  442     countDown(3); |  444     countDown(3); | 
|  443     var completer2 = new Completer(); |  445     var completer2 = new Completer(); | 
|  444     new Timer(MS * 10, () { |  446     new Timer(MS * 10, () { | 
|  445       countDown(2); |  447       countDown(2); | 
|  446       completer2.complete(37); |  448       completer2.complete(37); | 
|  447     }); |  449     }); | 
|  448     return completer2.future; |  450     return completer2.future; | 
|  449   }).then((v) { |  451   }).then((v) { | 
|  450     Expect.fail("should fail async"); |  452     Expect.fail("should fail async"); | 
|  451   }, onError: (AsyncError e) { |  453   }, onError: (error) { | 
|  452     Expect.equals("Error", e.error); |  454     Expect.equals("Error", error); | 
|  453     countDown(1); |  455     countDown(1); | 
|  454   }); |  456   }); | 
|  455  |  457  | 
|  456   completer.completeError("Error"); |  458   completer.completeError("Error"); | 
|  457 } |  459 } | 
|  458  |  460  | 
|  459 testFutureWhenErrorFutureError() { |  461 testFutureWhenErrorFutureError() { | 
|  460   var port = new ReceivePort(); |  462   var port = new ReceivePort(); | 
|  461   int counter = 3; |  463   int counter = 3; | 
|  462   countDown(int expect) { |  464   countDown(int expect) { | 
|  463     Expect.equals(expect, counter); |  465     Expect.equals(expect, counter); | 
|  464     if (--counter == 0) port.close(); |  466     if (--counter == 0) port.close(); | 
|  465   } |  467   } | 
|  466   var completer = new Completer(); |  468   var completer = new Completer(); | 
|  467   completer.future.whenComplete(() { |  469   completer.future.whenComplete(() { | 
|  468     countDown(3); |  470     countDown(3); | 
|  469     var completer2 = new Completer(); |  471     var completer2 = new Completer(); | 
|  470     new Timer(MS * 10, () { |  472     new Timer(MS * 10, () { | 
|  471       countDown(2); |  473       countDown(2); | 
|  472       completer2.completeError("Fail"); |  474       completer2.completeError("Fail"); | 
|  473     }); |  475     }); | 
|  474     return completer2.future; |  476     return completer2.future; | 
|  475   }).then((v) { |  477   }).then((v) { | 
|  476     Expect.fail("should fail async"); |  478     Expect.fail("should fail async"); | 
|  477   }, onError: (AsyncError e) { |  479   }, onError: (error) { | 
|  478     Expect.equals("Fail", e.error); |  480     Expect.equals("Fail", error); | 
|  479     countDown(1); |  481     countDown(1); | 
|  480   }); |  482   }); | 
|  481  |  483  | 
|  482   completer.completeError("Error"); |  484   completer.completeError("Error"); | 
|  483 } |  485 } | 
|  484  |  486  | 
|  485 testFutureThenThrowsAsync() { |  487 testFutureThenThrowsAsync() { | 
|  486   final completer = new Completer<int>(); |  488   final completer = new Completer<int>(); | 
|  487   final future = completer.future; |  489   final future = completer.future; | 
|  488   AsyncError error = new AsyncError(42, "st"); |  490   int error = 42; | 
|  489  |  491  | 
|  490   var port = new ReceivePort(); |  492   var port = new ReceivePort(); | 
|  491   future.then((v) { |  493   future.then((v) { | 
|  492     throw error; |  494     throw error; | 
|  493   }).catchError((AsyncError e) { |  495   }).catchError((e) { | 
|  494     Expect.identical(error, e); |  496     Expect.identical(error, e); | 
|  495     port.close(); |  497     port.close(); | 
|  496   }); |  498   }); | 
|  497   completer.complete(0); |  499   completer.complete(0); | 
|  498 } |  500 } | 
|  499  |  501  | 
|  500 testFutureCatchThrowsAsync() { |  502 testFutureCatchThrowsAsync() { | 
|  501   final completer = new Completer<int>(); |  503   final completer = new Completer<int>(); | 
|  502   final future = completer.future; |  504   final future = completer.future; | 
|  503   AsyncError error = new AsyncError(42, "st"); |  505   int error = 42; | 
|  504  |  506  | 
|  505   var port = new ReceivePort(); |  507   var port = new ReceivePort(); | 
|  506   future.catchError((AsyncError e) { |  508   future.catchError((e) { | 
|  507     throw error; |  509     throw error; | 
|  508   }).catchError((AsyncError e) { |  510   }).catchError((e) { | 
|  509     Expect.identical(error, e); |  511     Expect.identical(error, e); | 
|  510     port.close(); |  512     port.close(); | 
|  511   }); |  513   }); | 
|  512   completer.completeError(0); |  514   completer.completeError(0); | 
|  513 } |  515 } | 
|  514  |  516  | 
|  515 testFutureCatchRethrowsAsync() { |  517 testFutureCatchRethrowsAsync() { | 
|  516   final completer = new Completer<int>(); |  518   final completer = new Completer<int>(); | 
|  517   final future = completer.future; |  519   final future = completer.future; | 
|  518   AsyncError error; |  520   var error; | 
|  519  |  521  | 
|  520   var port = new ReceivePort(); |  522   var port = new ReceivePort(); | 
|  521   future.catchError((AsyncError e) { |  523   future.catchError((e) { | 
|  522     error = e; |  524     error = e; | 
|  523     throw e; |  525     throw e; | 
|  524   }).catchError((AsyncError e) { |  526   }).catchError((e) { | 
|  525     Expect.identical(error, e); |  527     Expect.identical(error, e); | 
|  526     port.close(); |  528     port.close(); | 
|  527   }); |  529   }); | 
|  528   completer.completeError(0); |  530   completer.completeError(0); | 
|  529 } |  531 } | 
|  530  |  532  | 
|  531 testFutureWhenThrowsAsync() { |  533 testFutureWhenThrowsAsync() { | 
|  532   final completer = new Completer<int>(); |  534   final completer = new Completer<int>(); | 
|  533   final future = completer.future; |  535   final future = completer.future; | 
|  534   AsyncError error = new AsyncError(42, "st"); |  536   var error = 42; | 
|  535  |  537  | 
|  536   var port = new ReceivePort(); |  538   var port = new ReceivePort(); | 
|  537   future.whenComplete(() { |  539   future.whenComplete(() { | 
|  538     throw error; |  540     throw error; | 
|  539   }).catchError((AsyncError e) { |  541   }).catchError((e) { | 
|  540     Expect.identical(error, e); |  542     Expect.identical(error, e); | 
|  541     port.close(); |  543     port.close(); | 
|  542   }); |  544   }); | 
|  543   completer.complete(0); |  545   completer.complete(0); | 
|  544 } |  546 } | 
|  545  |  547  | 
|  546 testCompleteWithAsyncError() { |  548 testCompleteWithError() { | 
|  547   final completer = new Completer<int>(); |  549   final completer = new Completer<int>(); | 
|  548   final future = completer.future; |  550   final future = completer.future; | 
|  549   AsyncError error = new AsyncError(42, "st"); |  551   var error = 42; | 
|  550  |  552  | 
|  551   var port = new ReceivePort(); |  553   var port = new ReceivePort(); | 
|  552   future.catchError((AsyncError e) { |  554   future.catchError((e) { | 
|  553     Expect.identical(error, e); |  555     Expect.identical(error, e); | 
|  554     port.close(); |  556     port.close(); | 
|  555   }); |  557   }); | 
|  556  |  558  | 
|  557   completer.completeError(error); |  559   completer.completeError(error); | 
|  558 } |  560 } | 
|  559  |  561  | 
|  560 testChainedFutureValue() { |  562 testChainedFutureValue() { | 
|  561   final completer = new Completer(); |  563   final completer = new Completer(); | 
|  562   final future = completer.future; |  564   final future = completer.future; | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|  592       Expect.isNull(v); |  594       Expect.isNull(v); | 
|  593       port.close(); |  595       port.close(); | 
|  594     }); |  596     }); | 
|  595 } |  597 } | 
|  596 testChainedFutureError() { |  598 testChainedFutureError() { | 
|  597   final completer = new Completer(); |  599   final completer = new Completer(); | 
|  598   final future = completer.future; |  600   final future = completer.future; | 
|  599   var port = new ReceivePort(); |  601   var port = new ReceivePort(); | 
|  600  |  602  | 
|  601   future.then((v) => new Future.immediateError("Fehler")) |  603   future.then((v) => new Future.immediateError("Fehler")) | 
|  602         .then((v) { Expect.fail("unreachable!"); }, onError: (e) { |  604         .then((v) { Expect.fail("unreachable!"); }, onError: (error) { | 
|  603           Expect.equals("Fehler", e.error); |  605           Expect.equals("Fehler", error); | 
|  604           port.close(); |  606           port.close(); | 
|  605         }); |  607         }); | 
|  606   completer.complete(21); |  608   completer.complete(21); | 
|  607 } |  609 } | 
|  608  |  610  | 
|  609 main() { |  611 main() { | 
|  610   testImmediate(); |  612   testImmediate(); | 
|  611   testOf(); |  613   testOf(); | 
|  612   testNeverComplete(); |  614   testNeverComplete(); | 
|  613  |  615  | 
|  614   testComplete(); |  616   testComplete(); | 
|  615   testCompleteWithSuccessHandlerBeforeComplete(); |  617   testCompleteWithSuccessHandlerBeforeComplete(); | 
|  616   testCompleteWithSuccessHandlerAfterComplete(); |  618   testCompleteWithSuccessHandlerAfterComplete(); | 
|  617   testCompleteManySuccessHandlers(); |  619   testCompleteManySuccessHandlers(); | 
|  618   testCompleteWithAsyncError(); |  620   testCompleteWithError(); | 
|  619  |  621  | 
|  620   testException(); |  622   testException(); | 
|  621   testExceptionHandler(); |  623   testExceptionHandler(); | 
|  622   testExceptionHandlerReturnsTrue(); |  624   testExceptionHandlerReturnsTrue(); | 
|  623   testExceptionHandlerReturnsTrue2(); |  625   testExceptionHandlerReturnsTrue2(); | 
|  624   testExceptionHandlerReturnsFalse(); |  626   testExceptionHandlerReturnsFalse(); | 
|  625  |  627  | 
|  626   testFutureAsStreamCompleteAfter(); |  628   testFutureAsStreamCompleteAfter(); | 
|  627   testFutureAsStreamCompleteBefore(); |  629   testFutureAsStreamCompleteBefore(); | 
|  628   testFutureAsStreamCompleteImmediate(); |  630   testFutureAsStreamCompleteImmediate(); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  643   testFutureCatchThrowsAsync(); |  645   testFutureCatchThrowsAsync(); | 
|  644   testFutureWhenThrowsAsync(); |  646   testFutureWhenThrowsAsync(); | 
|  645   testFutureCatchRethrowsAsync(); |  647   testFutureCatchRethrowsAsync(); | 
|  646  |  648  | 
|  647   testChainedFutureValue(); |  649   testChainedFutureValue(); | 
|  648   testChainedFutureValueDelay(); |  650   testChainedFutureValueDelay(); | 
|  649   testChainedFutureError(); |  651   testChainedFutureError(); | 
|  650 } |  652 } | 
|  651  |  653  | 
|  652  |  654  | 
| OLD | NEW |