|  | // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | // Test that closures have a useful string that identifies the function by name | 
|  | // in error messages. | 
|  |  | 
|  | import "package:expect/expect.dart"; | 
|  |  | 
|  | @pragma('dart2js:noInline') | 
|  | @pragma('dart2js:assumeDynamic') | 
|  | confuse(x) => x; | 
|  |  | 
|  | class CCCC { | 
|  | instanceMethod([a, b]) => '[$a, $b]'; | 
|  | static staticMethod() => 'hi'; | 
|  | // Default `toString` method returns "Instance of 'CCCC'" or similar with a | 
|  | // shorter name if minified. | 
|  | } | 
|  |  | 
|  | main() { | 
|  | var c = confuse(new CCCC()); | 
|  |  | 
|  | var instanceString = confuse(c).toString(); | 
|  | bool isMinified = | 
|  | instanceString.contains(new RegExp("Instance of '..?.?'")) || | 
|  | instanceString.contains('minified:'); | 
|  | if (!isMinified) { | 
|  | Expect.equals("Instance of 'CCCC'", instanceString); | 
|  | } | 
|  |  | 
|  | checkContains(String message, String tag) { | 
|  | if (!message.contains(tag)) { | 
|  | if (!isMinified) { | 
|  | Expect.fail('"$message" should contain "$tag"'); | 
|  | } | 
|  | // When minified we will accept quoted names up to 3 characters. | 
|  | Expect.isTrue( | 
|  | message.contains(new RegExp("'..?.?'")) || | 
|  | message.contains("'minified:"), | 
|  | '"$message" should contain minified name'); | 
|  | } | 
|  | } | 
|  |  | 
|  | // We use ArgumentError.value since it prints the value using | 
|  | // Error.safeToString. | 
|  | var e1 = new ArgumentError.value(c); | 
|  | var s1 = '$e1'; | 
|  | Expect.isTrue(s1.contains(instanceString), | 
|  | 'Error message "$s1" should contain "$instanceString"'); | 
|  |  | 
|  | // Instance method tear-off. | 
|  | var e2 = new ArgumentError.value(confuse(c).instanceMethod); | 
|  | var s2 = '$e2'; | 
|  | // Instance method tear-off should contain instance string. | 
|  | Expect.isTrue(s2.contains(instanceString), | 
|  | 'Error message "$s2" should contain "$instanceString"'); | 
|  | // Instance method tear-off should also name the method. | 
|  | checkContains(s2.replaceAll(instanceString, '*'), "instanceMethod"); | 
|  |  | 
|  | // Top level tear-off. | 
|  | var e3 = new ArgumentError.value(confuse); | 
|  | var s3 = '$e3'; | 
|  | checkContains(s3, "confuse"); | 
|  | checkContains('$confuse', "confuse"); | 
|  |  | 
|  | // Static method tear-off. | 
|  | var e4 = new ArgumentError.value(CCCC.staticMethod); | 
|  | var s4 = '$e4'; | 
|  | checkContains(s4, "staticMethod"); | 
|  | checkContains('${CCCC.staticMethod}', "staticMethod"); | 
|  |  | 
|  | // Local anonymous closure. | 
|  | var anon = () => c; | 
|  | var e5 = new ArgumentError.value(anon); | 
|  | var s5 = '$e5'; | 
|  | checkContains(s5, "main_closure"); | 
|  | checkContains('$anon', "main_closure"); | 
|  |  | 
|  | // Local named closure. | 
|  | localFunction() => c; | 
|  | var e6 = new ArgumentError.value(localFunction); | 
|  | var s6 = '$e6'; | 
|  | checkContains(s6, "localFunction"); | 
|  | checkContains('$localFunction', "localFunction"); | 
|  | } |