Skip to content

Commit cca55a3

Browse files
authored
Update test running code in example script. (#1299)
The example script in example/format.dart has long been my sandbox script for debugging the formatter. One thing it has is a little helper function to run one of the format tests. That helper code was copy/pasted from an ancient version of the test running code. Cleaned it up here to actually use the TestFile class now that there is some abstraction for running tests. Also added support to example/format.dart to handle selections in tests. (I'm starting to work on handling selections in the new formatter.)
1 parent c96a7a4 commit cca55a3

File tree

2 files changed

+48
-107
lines changed

2 files changed

+48
-107
lines changed

example/format.dart

Lines changed: 37 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
4-
library dart_style.example.format;
5-
6-
import 'dart:io';
7-
import 'dart:mirrors';
8-
94
import 'package:dart_style/dart_style.dart';
105
import 'package:dart_style/src/constants.dart';
116
import 'package:dart_style/src/debug.dart' as debug;
12-
import 'package:path/path.dart' as p;
7+
import 'package:dart_style/src/testing/test_file.dart';
138

149
void main(List<String> args) {
1510
// Enable debugging so you can see some of the formatter's internal state.
@@ -21,7 +16,7 @@ void main(List<String> args) {
2116
debug.tracePieceBuilder = true;
2217
debug.traceSolver = true;
2318

24-
formatUnit("import 'a.dart';", tall: true);
19+
runTest('selection/selection.stmt', 2);
2520
}
2621

2722
void formatStmt(String source, {required bool tall, int pageWidth = 80}) {
@@ -62,105 +57,40 @@ void drawRuler(String label, int width) {
6257

6358
/// Runs the formatter test starting on [line] at [path] inside the "test"
6459
/// directory.
65-
void runTest(String path, int line) {
66-
var indentPattern = RegExp(r'^\(indent (\d+)\)\s*');
67-
68-
// Locate the "test" directory. Use mirrors so that this works with the test
69-
// package, which loads this suite into an isolate.
70-
var testDir = p.join(
71-
p.dirname(currentMirrorSystem()
72-
.findLibrary(#dart_style.example.format)
73-
.uri
74-
.path),
75-
'../test');
76-
77-
var lines = File(p.join(testDir, path)).readAsLinesSync();
78-
79-
// The first line may have a "|" to indicate the page width.
80-
var pageWidth = 80;
81-
if (lines[0].endsWith('|')) {
82-
pageWidth = lines[0].indexOf('|');
83-
lines = lines.skip(1).toList();
60+
Future<void> runTest(String path, int line,
61+
{int pageWidth = 40, bool tall = true}) async {
62+
var testFile = await TestFile.read(path);
63+
var formatTest = testFile.tests.firstWhere((test) => test.line == line);
64+
65+
var formatter = DartFormatter(
66+
pageWidth: testFile.pageWidth,
67+
indent: formatTest.leadingIndent,
68+
fixes: formatTest.fixes,
69+
experimentFlags: tall
70+
? const ['inline-class', tallStyleExperimentFlag]
71+
: const ['inline-class']);
72+
73+
var actual = formatter.formatSource(formatTest.input);
74+
75+
// The test files always put a newline at the end of the expectation.
76+
// Statements from the formatter (correctly) don't have that, so add
77+
// one to line up with the expected result.
78+
var actualText = actual.textWithSelectionMarkers;
79+
if (!testFile.isCompilationUnit) actualText += '\n';
80+
81+
var expectedText = formatTest.output.textWithSelectionMarkers;
82+
83+
print('$path ${formatTest.description}');
84+
drawRuler('before', pageWidth);
85+
print(formatTest.input.textWithSelectionMarkers);
86+
if (actualText == expectedText) {
87+
drawRuler('result', pageWidth);
88+
print(actualText);
89+
} else {
90+
print('FAIL');
91+
drawRuler('expected', pageWidth);
92+
print(expectedText);
93+
drawRuler('actual', pageWidth);
94+
print(actualText);
8495
}
85-
86-
var i = 0;
87-
while (i < lines.length) {
88-
var description = lines[i++].replaceAll('>>>', '').trim();
89-
90-
// Let the test specify a leading indentation. This is handy for
91-
// regression tests which often come from a chunk of nested code.
92-
var leadingIndent = 0;
93-
var indentMatch = indentPattern.firstMatch(description);
94-
if (indentMatch != null) {
95-
leadingIndent = int.parse(indentMatch[1]!);
96-
description = description.substring(indentMatch.end);
97-
}
98-
99-
if (description == '') {
100-
description = 'line ${i + 1}';
101-
} else {
102-
description = 'line ${i + 1}: $description';
103-
}
104-
var startLine = i + 1;
105-
106-
var input = '';
107-
while (!lines[i].startsWith('<<<')) {
108-
input += '${lines[i++]}\n';
109-
}
110-
111-
var expectedOutput = '';
112-
while (++i < lines.length && !lines[i].startsWith('>>>')) {
113-
expectedOutput += '${lines[i]}\n';
114-
}
115-
116-
if (line != startLine) continue;
117-
118-
var isCompilationUnit = p.extension(path) == '.unit';
119-
120-
var inputCode =
121-
_extractSelection(input, isCompilationUnit: isCompilationUnit);
122-
123-
var expected =
124-
_extractSelection(expectedOutput, isCompilationUnit: isCompilationUnit);
125-
126-
var formatter = DartFormatter(pageWidth: pageWidth, indent: leadingIndent);
127-
128-
var actual = formatter.formatSource(inputCode);
129-
130-
// The test files always put a newline at the end of the expectation.
131-
// Statements from the formatter (correctly) don't have that, so add
132-
// one to line up with the expected result.
133-
var actualText = actual.text;
134-
if (!isCompilationUnit) actualText += '\n';
135-
136-
print('$path $description');
137-
drawRuler('before', pageWidth);
138-
print(input);
139-
if (actualText == expected.text) {
140-
drawRuler('result', pageWidth);
141-
print(actualText);
142-
} else {
143-
print('FAIL');
144-
drawRuler('expected', pageWidth);
145-
print(expected.text);
146-
drawRuler('actual', pageWidth);
147-
print(actualText);
148-
}
149-
}
150-
}
151-
152-
/// Given a source string that contains ‹ and › to indicate a selection, returns
153-
/// a [SourceCode] with the text (with the selection markers removed) and the
154-
/// correct selection range.
155-
SourceCode _extractSelection(String source, {bool isCompilationUnit = false}) {
156-
var start = source.indexOf('‹');
157-
source = source.replaceAll('‹', '');
158-
159-
var end = source.indexOf('›');
160-
source = source.replaceAll('›', '');
161-
162-
return SourceCode(source,
163-
isCompilationUnit: isCompilationUnit,
164-
selectionStart: start == -1 ? null : start,
165-
selectionLength: end == -1 ? null : end - start);
16696
}

lib/src/testing/test_file.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,17 @@ class FormatTest {
169169
}
170170
}
171171

172+
extension SourceCodeExtensions on SourceCode {
173+
/// If the source code has a selection, returns its text with `‹` and `›`
174+
/// inserted at the selection begin and end points.
175+
///
176+
/// Otherwise, returns the code as-is.
177+
String get textWithSelectionMarkers {
178+
if (selectionStart == null) return text;
179+
return '$textBeforeSelection‹$selectedText›$textAfterSelection';
180+
}
181+
}
182+
172183
/// Given a source string that contains ‹ and › to indicate a selection, returns
173184
/// a [SourceCode] with the text (with the selection markers removed) and the
174185
/// correct selection range.

0 commit comments

Comments
 (0)