| Index: example/format.dart | 
| diff --git a/example/format.dart b/example/format.dart | 
| index f41327f1879dde264855b0218871b44ab9d6f536..4eec856e6d1528540f1c9cc48a1625acc52f2074 100644 | 
| --- a/example/format.dart | 
| +++ b/example/format.dart | 
| @@ -2,34 +2,34 @@ | 
| // 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. | 
|  | 
| -import 'package:dart_style/dart_style.dart'; | 
| +library dart_style.example.format; | 
| + | 
| +import 'dart:io'; | 
| +import 'dart:mirrors'; | 
| + | 
| +import 'package:path/path.dart' as p; | 
|  | 
| +import 'package:dart_style/dart_style.dart'; | 
| import 'package:dart_style/src/debug.dart' as debug; | 
|  | 
| void main(List<String> args) { | 
| // Enable debugging so you can see some of the formatter's internal state. | 
| // Normal users do not do this. | 
| debug.traceChunkBuilder = true; | 
| -  //debug.traceLineWriter = true; | 
| -  //debug.traceSplitter = true; | 
| +  debug.traceLineWriter = true; | 
| +  debug.traceSplitter = true; | 
| debug.useAnsiColors = true; | 
|  | 
| -  formatStmt(""" | 
| -  init({@Option( | 
| -      help: 'The git Uri containing the jefe.yaml.', | 
| -      abbr: 'g') String gitUri, @Option( | 
| -      help: 'The directory to install into', | 
| -      abbr: 'd') String installDirectory: '.', @Flag( | 
| -      help: 'Skips the checkout of the develop branch', | 
| -      abbr: 's') bool skipCheckout: false}) async {} | 
| -""", 80); | 
| +  runTest("regression/0000/0068.stmt", 14); | 
| + | 
| +  formatStmt("hello(world);"); | 
| } | 
|  | 
| -void formatStmt(String source, [int pageWidth = 40]) { | 
| +void formatStmt(String source, [int pageWidth = 80]) { | 
| runFormatter(source, pageWidth, isCompilationUnit: false); | 
| } | 
|  | 
| -void formatUnit(String source, [int pageWidth = 40]) { | 
| +void formatUnit(String source, [int pageWidth = 80]) { | 
| runFormatter(source, pageWidth, isCompilationUnit: true); | 
| } | 
|  | 
| @@ -61,3 +61,109 @@ void drawRuler(String label, int width) { | 
| var padding = " " * (width - label.length - 1); | 
| print("$label:$padding|"); | 
| } | 
| + | 
| +/// Runs the formatter test starting on [line] at [path] inside the "test" | 
| +/// directory. | 
| +void runTest(String path, int line) { | 
| +  var indentPattern = new RegExp(r"^\(indent (\d+)\)\s*"); | 
| + | 
| +  // Locate the "test" directory. Use mirrors so that this works with the test | 
| +  // package, which loads this suite into an isolate. | 
| +  var testDir = p.join( | 
| +      p.dirname(currentMirrorSystem() | 
| +          .findLibrary(#dart_style.example.format) | 
| +          .uri | 
| +          .path), | 
| +      "../test"); | 
| + | 
| +  var lines = new File(p.join(testDir, path)).readAsLinesSync(); | 
| + | 
| +  // The first line may have a "|" to indicate the page width. | 
| +  var pageWidth = 80; | 
| +  if (lines[0].endsWith("|")) { | 
| +    pageWidth = lines[0].indexOf("|"); | 
| +    lines = lines.skip(1).toList(); | 
| +  } | 
| + | 
| +  var i = 0; | 
| +  while (i < lines.length) { | 
| +    var description = lines[i++].replaceAll(">>>", "").trim(); | 
| + | 
| +    // Let the test specify a leading indentation. This is handy for | 
| +    // regression tests which often come from a chunk of nested code. | 
| +    var leadingIndent = 0; | 
| +    var indentMatch = indentPattern.firstMatch(description); | 
| +    if (indentMatch != null) { | 
| +      leadingIndent = int.parse(indentMatch[1]); | 
| +      description = description.substring(indentMatch.end); | 
| +    } | 
| + | 
| +    if (description == "") { | 
| +      description = "line ${i + 1}"; | 
| +    } else { | 
| +      description = "line ${i + 1}: $description"; | 
| +    } | 
| +    var startLine = i + 1; | 
| + | 
| +    var input = ""; | 
| +    while (!lines[i].startsWith("<<<")) { | 
| +      input += lines[i++] + "\n"; | 
| +    } | 
| + | 
| +    var expectedOutput = ""; | 
| +    while (++i < lines.length && !lines[i].startsWith(">>>")) { | 
| +      expectedOutput += lines[i] + "\n"; | 
| +    } | 
| + | 
| +    if (line != startLine) continue; | 
| + | 
| +    var isCompilationUnit = p.extension(path) == ".unit"; | 
| + | 
| +    var inputCode = | 
| +        _extractSelection(input, isCompilationUnit: isCompilationUnit); | 
| + | 
| +    var expected = | 
| +        _extractSelection(expectedOutput, isCompilationUnit: isCompilationUnit); | 
| + | 
| +    var formatter = | 
| +        new DartFormatter(pageWidth: pageWidth, indent: leadingIndent); | 
| + | 
| +    var actual = formatter.formatSource(inputCode); | 
| + | 
| +    // The test files always put a newline at the end of the expectation. | 
| +    // Statements from the formatter (correctly) don't have that, so add | 
| +    // one to line up with the expected result. | 
| +    var actualText = actual.text; | 
| +    if (!isCompilationUnit) actualText += "\n"; | 
| + | 
| +    print("$path $description"); | 
| +    drawRuler("before", pageWidth); | 
| +    print(input); | 
| +    if (actualText == expected.text) { | 
| +      drawRuler("result", pageWidth); | 
| +      print(actualText); | 
| +    } else { | 
| +      print("FAIL"); | 
| +      drawRuler("expected", pageWidth); | 
| +      print(expected.text); | 
| +      drawRuler("actual", pageWidth); | 
| +      print(actualText); | 
| +    } | 
| +  } | 
| +} | 
| + | 
| +/// Given a source string that contains ‹ and › to indicate a selection, returns | 
| +/// a [SourceCode] with the text (with the selection markers removed) and the | 
| +/// correct selection range. | 
| +SourceCode _extractSelection(String source, {bool isCompilationUnit: false}) { | 
| +  var start = source.indexOf("‹"); | 
| +  source = source.replaceAll("‹", ""); | 
| + | 
| +  var end = source.indexOf("›"); | 
| +  source = source.replaceAll("›", ""); | 
| + | 
| +  return new SourceCode(source, | 
| +      isCompilationUnit: isCompilationUnit, | 
| +      selectionStart: start == -1 ? null : start, | 
| +      selectionLength: end == -1 ? null : end - start); | 
| +} | 
|  |