| // 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; |
| } |