blob: 1400afd3e1c0522f32dfdc83393944ebaca02b53 [file] [edit]
// Copyright (c) 2017, 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.
// This tests if the modification of a status file is done correctly, by
// checking that all entries in the original status file are to be found in the
// new status file. The check therefore allows the merging of section headers if
// they are equal, alphabetizing sections and entries, removing line columns and
// normalizing section conditions.
import 'dart:io';
import 'package:status_file/canonical_status_file.dart';
import 'package:status_file/src/expression.dart';
import 'package:status_file/status_file_normalizer.dart';
final Uri statusFilePath = Platform.script.resolve("data/");
void main() {
sanityCheck();
normalizeCheck();
}
void normalizeCheck() {
var files = getStatusFiles();
for (var file in files) {
print("------- ${file.path} -------");
var statusFile = StatusFile.read(file.path);
var statusFileOther = normalizeStatusFile(
StatusFile.read(file.path),
deleteNonExisting: false,
);
checkSemanticallyEqual(
statusFile,
statusFileOther,
warnOnDuplicateHeader: true,
);
checkFileHeaderIntact(statusFile, statusFileOther);
print("------- ${file.path} -------");
}
}
void sanityCheck() {
var files = getStatusFiles();
for (var file in files) {
print("------- ${file.path} -------");
var statusFile = StatusFile.read(file.path);
var statusFileOther = StatusFile.read(file.path);
checkSemanticallyEqual(
statusFile,
statusFileOther,
warnOnDuplicateHeader: true,
);
checkFileHeaderIntact(statusFile, statusFileOther);
print("------- ${file.path} -------");
}
}
List<FileSystemEntity> getStatusFiles() {
var statusFiles = <FileSystemEntity>[];
for (var entry in Directory.fromUri(
statusFilePath,
).listSync(recursive: true)) {
statusFiles.add(entry);
}
return statusFiles;
}
void checkSemanticallyEqual(
StatusFile original,
StatusFile normalized, {
bool warnOnDuplicateHeader = false,
}) {
var entriesInOriginal = countEntries(original);
var entriesInNormalized = countEntries(normalized);
if (entriesInOriginal != entriesInNormalized) {
print(original);
print("==================");
print(normalized);
throw Exception(
"The count of entries in original is "
"$entriesInOriginal and the count of entries in normalized is "
"$entriesInNormalized. Those two numbers are not the same.",
);
}
for (var section in original.sections) {
section.entries.whereType<StatusEntry>().forEach(
(entry) => findInStatusFile(
normalized,
entry,
section.condition.normalize(),
warnOnDuplicateHeader: warnOnDuplicateHeader,
),
);
}
}
int countEntries(StatusFile statusFile) {
return statusFile.sections
.map((section) => section.entries.whereType<StatusEntry>().length)
.fold(0, (count, sum) => count + sum);
}
void findInStatusFile(
StatusFile statusFile,
StatusEntry entryToFind,
Expression condition, {
bool warnOnDuplicateHeader = false,
}) {
int foundEntryPosition = -1;
for (var section in statusFile.sections) {
if (section.condition.normalize().compareTo(condition) != 0) {
continue;
}
var matchingEntries = section.entries
.where(
(entry) =>
entry is StatusEntry &&
entry.path.compareTo(entryToFind.path) == 0 &&
listEqual(entry.expectations, entryToFind.expectations),
)
.toList();
if (matchingEntries.isEmpty) {
var message =
"Could not find the entry even though the section "
"header matched on line number ${section.lineNumber}. Sections "
"should be unique.";
if (warnOnDuplicateHeader) {
print(message);
} else {
throw Exception(message);
}
} else if (matchingEntries.length == 1 && foundEntryPosition >= 0) {
throw Exception(
"The entry '$entryToFind' on line "
"${entryToFind.lineNumber} in section ${section.condition} was "
"already found in a previous section on line $foundEntryPosition.",
);
} else if (matchingEntries.length == 1) {
foundEntryPosition = matchingEntries[0].lineNumber;
} else {
throw Exception(
"The entry '$entryToFind' on line "
"${entryToFind.lineNumber} in section ${section.condition} on line "
"${section.lineNumber} had multiple matches in section.",
);
}
}
if (foundEntryPosition < 0) {
throw Exception(
"Could not find entry '$entryToFind' under the "
"condition $condition in the status file.",
);
}
}
void checkFileHeaderIntact(StatusFile original, StatusFile normalized) {
var originalHeader = original.sections.first.sectionHeaderComments.toString();
var normalizedHeader = normalized.sections.first.sectionHeaderComments
.toString();
if (originalHeader != normalizedHeader) {
throw Exception(
"File headers changed.\nExpected:\n$originalHeader\n\nActual:\n$normalizedHeader",
);
}
}
bool listEqual<T>(List<T> first, List<T> second) {
if (first.length != second.length) {
return false;
}
for (int i = 0; i < first.length; i++) {
if (first[i] != second[i]) {
return false;
}
}
return true;
}