blob: 889196336b2f9b54d4a1d0f99798938f581ef1cf [file] [log] [blame]
// Copyright (c) 2022, 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.
import 'dart:io' as io;
import 'package:analyzer/source/line_info.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
class NodeTextExpectationsCollector {
static const updatingIsEnabled = false;
static const assertMethods = {
'ContextResolutionTest.assertDriverStateString',
'FileResolutionTest.assertStateString',
'ResolutionTest.assertResolvedNodeText',
};
static final Map<String, _File> _files = {};
static void add(String actual) {
if (!updatingIsEnabled) {
return;
}
var traceLines = '${StackTrace.current}'.split('\n');
for (var traceIndex = 0; traceIndex < traceLines.length; traceIndex++) {
var traceLine = traceLines[traceIndex];
for (var assertMethod in assertMethods) {
if (traceLine.contains(' $assertMethod ')) {
var invocationLine = traceLines[traceIndex + 1];
var locationMatch = RegExp(
r'file://(.+_test.dart):(\d+):',
).firstMatch(invocationLine);
if (locationMatch == null) {
fail('Cannot parse: $invocationLine');
}
var path = locationMatch.group(1)!;
var line = int.parse(locationMatch.group(2)!);
var file = _getFile(path);
var invocationOffset = file.lineInfo.getOffsetOfLine(line - 1);
const String rawStringPrefix = "r'''";
var expectationOffset = file.content.indexOf(
rawStringPrefix,
invocationOffset,
);
expectationOffset += rawStringPrefix.length;
var expectationEnd = file.content.indexOf("'''", expectationOffset);
file.replacements.add(
_Replacement(
expectationOffset,
expectationEnd,
'\n$actual',
),
);
}
}
}
}
static void _apply() {
for (var file in _files.values) {
file.applyReplacements();
}
_files.clear();
}
static _File _getFile(String path) {
return _files[path] ??= _File(path);
}
}
@reflectiveTest
class UpdateNodeTextExpectations {
test_applyReplacements() {
NodeTextExpectationsCollector._apply();
}
}
class _File {
final String path;
final String content;
final LineInfo lineInfo;
final List<_Replacement> replacements = [];
factory _File(String path) {
var content = io.File(path).readAsStringSync();
return _File._(
path: path,
content: content,
lineInfo: LineInfo.fromContent(content),
);
}
_File._({
required this.path,
required this.content,
required this.lineInfo,
});
void applyReplacements() {
replacements.sort((a, b) => b.offset - a.offset);
var newCode = content;
for (var replacement in replacements) {
newCode = newCode.substring(0, replacement.offset) +
replacement.text +
newCode.substring(replacement.end);
}
io.File(path).writeAsStringSync(newCode);
}
}
class _Replacement {
final int offset;
final int end;
final String text;
_Replacement(this.offset, this.end, this.text);
}