OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 library dart_style.example.format; |
| 6 |
| 7 import 'dart:io'; |
| 8 import 'dart:mirrors'; |
| 9 |
| 10 import 'package:path/path.dart' as p; |
| 11 |
| 12 import 'package:dart_style/dart_style.dart'; |
| 13 import 'package:dart_style/src/debug.dart' as debug; |
| 14 |
| 15 void main(List<String> args) { |
| 16 // Enable debugging so you can see some of the formatter's internal state. |
| 17 // Normal users do not do this. |
| 18 debug.traceChunkBuilder = true; |
| 19 debug.traceLineWriter = true; |
| 20 debug.traceSplitter = true; |
| 21 debug.useAnsiColors = true; |
| 22 |
| 23 runTest("regression/0000/0068.stmt", 14); |
| 24 |
| 25 formatStmt("hello(world);"); |
| 26 } |
| 27 |
| 28 void formatStmt(String source, [int pageWidth = 80]) { |
| 29 runFormatter(source, pageWidth, isCompilationUnit: false); |
| 30 } |
| 31 |
| 32 void formatUnit(String source, [int pageWidth = 80]) { |
| 33 runFormatter(source, pageWidth, isCompilationUnit: true); |
| 34 } |
| 35 |
| 36 void runFormatter(String source, int pageWidth, {bool isCompilationUnit}) { |
| 37 try { |
| 38 var formatter = new DartFormatter(pageWidth: pageWidth); |
| 39 |
| 40 var result; |
| 41 if (isCompilationUnit) { |
| 42 result = formatter.format(source); |
| 43 } else { |
| 44 result = formatter.formatStatement(source); |
| 45 } |
| 46 |
| 47 if (debug.useAnsiColors) { |
| 48 result = result.replaceAll(" ", debug.gray(debug.unicodeMidDot)); |
| 49 } |
| 50 |
| 51 drawRuler("before", pageWidth); |
| 52 print(source); |
| 53 drawRuler("after", pageWidth); |
| 54 print(result); |
| 55 } on FormatterException catch (error) { |
| 56 print(error.message()); |
| 57 } |
| 58 } |
| 59 |
| 60 void drawRuler(String label, int width) { |
| 61 var padding = " " * (width - label.length - 1); |
| 62 print("$label:$padding|"); |
| 63 } |
| 64 |
| 65 /// Runs the formatter test starting on [line] at [path] inside the "test" |
| 66 /// directory. |
| 67 void runTest(String path, int line) { |
| 68 var indentPattern = new RegExp(r"^\(indent (\d+)\)\s*"); |
| 69 |
| 70 // Locate the "test" directory. Use mirrors so that this works with the test |
| 71 // package, which loads this suite into an isolate. |
| 72 var testDir = p.join( |
| 73 p.dirname(currentMirrorSystem() |
| 74 .findLibrary(#dart_style.example.format) |
| 75 .uri |
| 76 .path), |
| 77 "../test"); |
| 78 |
| 79 var lines = new File(p.join(testDir, path)).readAsLinesSync(); |
| 80 |
| 81 // The first line may have a "|" to indicate the page width. |
| 82 var pageWidth = 80; |
| 83 if (lines[0].endsWith("|")) { |
| 84 pageWidth = lines[0].indexOf("|"); |
| 85 lines = lines.skip(1).toList(); |
| 86 } |
| 87 |
| 88 var i = 0; |
| 89 while (i < lines.length) { |
| 90 var description = lines[i++].replaceAll(">>>", "").trim(); |
| 91 |
| 92 // Let the test specify a leading indentation. This is handy for |
| 93 // regression tests which often come from a chunk of nested code. |
| 94 var leadingIndent = 0; |
| 95 var indentMatch = indentPattern.firstMatch(description); |
| 96 if (indentMatch != null) { |
| 97 leadingIndent = int.parse(indentMatch[1]); |
| 98 description = description.substring(indentMatch.end); |
| 99 } |
| 100 |
| 101 if (description == "") { |
| 102 description = "line ${i + 1}"; |
| 103 } else { |
| 104 description = "line ${i + 1}: $description"; |
| 105 } |
| 106 var startLine = i + 1; |
| 107 |
| 108 var input = ""; |
| 109 while (!lines[i].startsWith("<<<")) { |
| 110 input += lines[i++] + "\n"; |
| 111 } |
| 112 |
| 113 var expectedOutput = ""; |
| 114 while (++i < lines.length && !lines[i].startsWith(">>>")) { |
| 115 expectedOutput += lines[i] + "\n"; |
| 116 } |
| 117 |
| 118 if (line != startLine) continue; |
| 119 |
| 120 var isCompilationUnit = p.extension(path) == ".unit"; |
| 121 |
| 122 var inputCode = |
| 123 _extractSelection(input, isCompilationUnit: isCompilationUnit); |
| 124 |
| 125 var expected = |
| 126 _extractSelection(expectedOutput, isCompilationUnit: isCompilationUnit); |
| 127 |
| 128 var formatter = |
| 129 new DartFormatter(pageWidth: pageWidth, indent: leadingIndent); |
| 130 |
| 131 var actual = formatter.formatSource(inputCode); |
| 132 |
| 133 // The test files always put a newline at the end of the expectation. |
| 134 // Statements from the formatter (correctly) don't have that, so add |
| 135 // one to line up with the expected result. |
| 136 var actualText = actual.text; |
| 137 if (!isCompilationUnit) actualText += "\n"; |
| 138 |
| 139 print("$path $description"); |
| 140 drawRuler("before", pageWidth); |
| 141 print(input); |
| 142 if (actualText == expected.text) { |
| 143 drawRuler("result", pageWidth); |
| 144 print(actualText); |
| 145 } else { |
| 146 print("FAIL"); |
| 147 drawRuler("expected", pageWidth); |
| 148 print(expected.text); |
| 149 drawRuler("actual", pageWidth); |
| 150 print(actualText); |
| 151 } |
| 152 } |
| 153 } |
| 154 |
| 155 /// Given a source string that contains ‹ and › to indicate a selection, returns |
| 156 /// a [SourceCode] with the text (with the selection markers removed) and the |
| 157 /// correct selection range. |
| 158 SourceCode _extractSelection(String source, {bool isCompilationUnit: false}) { |
| 159 var start = source.indexOf("‹"); |
| 160 source = source.replaceAll("‹", ""); |
| 161 |
| 162 var end = source.indexOf("›"); |
| 163 source = source.replaceAll("›", ""); |
| 164 |
| 165 return new SourceCode(source, |
| 166 isCompilationUnit: isCompilationUnit, |
| 167 selectionStart: start == -1 ? null : start, |
| 168 selectionLength: end == -1 ? null : end - start); |
| 169 } |
OLD | NEW |