From 08263ba71bfefa0ff8c6917481558367f7b3c058 Mon Sep 17 00:00:00 2001 From: github actions Date: Sat, 22 Feb 2025 14:48:13 +0500 Subject: [PATCH] ! F added new field to namer: useSubfolder to generate files in /approvals --- .../main.verify_combinations.approved.txt | 0 example/main.dart | 5 +- lib/src/approvals.dart | 26 +++--- lib/src/core/options.dart | 7 +- lib/src/namer/namer.dart | 86 +++++++++++-------- test/utils/helper.dart | 11 +-- 6 files changed, 75 insertions(+), 60 deletions(-) rename example/{ => approvals}/main.verify_combinations.approved.txt (100%) diff --git a/example/main.verify_combinations.approved.txt b/example/approvals/main.verify_combinations.approved.txt similarity index 100% rename from example/main.verify_combinations.approved.txt rename to example/approvals/main.verify_combinations.approved.txt diff --git a/example/main.dart b/example/main.dart index bf70a4c..b6fbbc0 100644 --- a/example/main.dart +++ b/example/main.dart @@ -6,7 +6,10 @@ void main() { test("verify combinations", () { Approvals.verifyAll( [3, 5, 15], - options: const Options( + options: Options( + namer: Namer( + useSubfolder: true, + ), reporter: DiffReporter(), ), processor: (items) => fizzBuzz(items).toString(), diff --git a/lib/src/approvals.dart b/lib/src/approvals.dart index 02983ea..5fad529 100644 --- a/lib/src/approvals.dart +++ b/lib/src/approvals.dart @@ -18,8 +18,7 @@ part of '../approval_tests.dart'; /// `Approvals` is a class that provides methods to verify the content of a response. class Approvals { - static const FilePathExtractor filePathExtractor = - FilePathExtractor(stackTraceFetcher: StackTraceFetcher()); + static const FilePathExtractor filePathExtractor = FilePathExtractor(stackTraceFetcher: StackTraceFetcher()); // Factory method to create an instance of ApprovalNamer with given file name static ApprovalNamer makeNamer( @@ -43,16 +42,18 @@ class Approvals { Options options = const Options(), }) { // Get the file path without extension or use the provided file path - final completedPath = options.namer?.filePath ?? - filePathExtractor.filePath.split('.dart').first; + final completedPath = options.namer.filePath ?? filePathExtractor.filePath.split('.dart').first; // Create namer object with given or computed file name - final namer = makeNamer( - completedPath, - description: options.namer?.description, - options: options.namer?.options, - addTestName: options.namer?.addTestName, + final namer = options.namer.copyWith( + filePath: completedPath, ); + // final namer = makeNamer( + // completedPath, + // description: options.namer?.description, + // options: options.namer?.options, + // addTestName: options.namer?.addTestName, + // ); try { // Create writer object with scrubbed response and file extension retrieved from options @@ -63,8 +64,7 @@ class Approvals { // Write the content to a file whose path is specified in namer.received writer.writeToFile(namer.received); - if (options.approveResult || - !ApprovalUtils.isFileExists(namer.approved)) { + if (options.approveResult || !ApprovalUtils.isFileExists(namer.approved)) { writer.writeToFile(namer.approved); } @@ -109,9 +109,7 @@ class Approvals { FileType.received: (ApprovalNamer n) => n.received, }; - final filePath = (namer == null) - ? Namer(filePath: filePathExtractor.filePath.split('.dart').first) - : namer; + final filePath = (namer == null) ? Namer(filePath: filePathExtractor.filePath.split('.dart').first) : namer; ApprovalUtils.deleteFile(fileToNamerMap[fileType]!(filePath)); } diff --git a/lib/src/core/options.dart b/lib/src/core/options.dart index eaf888c..556a658 100644 --- a/lib/src/core/options.dart +++ b/lib/src/core/options.dart @@ -34,7 +34,7 @@ class Options { final bool deleteReceivedFile; /// A final variable `namer` of type `Namer` used to set the name and path of the file. - final Namer? namer; + final Namer namer; /// A final bool variable `logErrors` used to determine if the errors should be logged. final bool logErrors; @@ -52,7 +52,7 @@ class Options { this.comparator = const FileComparator(), this.reporter = const CommandLineReporter(), this.deleteReceivedFile = true, - this.namer, + this.namer = const Namer(), this.logErrors = true, this.logResults = true, this.includeClassNameDuringSerialization = true, @@ -79,7 +79,6 @@ class Options { logErrors: logErrors ?? this.logErrors, logResults: logResults ?? this.logResults, includeClassNameDuringSerialization: - includeClassNameDuringSerialization ?? - this.includeClassNameDuringSerialization, + includeClassNameDuringSerialization ?? this.includeClassNameDuringSerialization, ); } diff --git a/lib/src/namer/namer.dart b/lib/src/namer/namer.dart index eba01ad..09d28c2 100644 --- a/lib/src/namer/namer.dart +++ b/lib/src/namer/namer.dart @@ -17,79 +17,68 @@ part of '../../approval_tests.dart'; /// `Namer` class is used to generate the file names for the approved and received files. + final class Namer implements ApprovalNamer { final String? filePath; final FileNamerOptions? options; final bool addTestName; final String? description; + final bool useSubfolder; const Namer({ this.filePath, this.options, this.addTestName = true, this.description, + this.useSubfolder = false, }); @override String get approved { - if (options != null) { - return options!.approved; - } + if (options != null) return options!.approved; if (description != null) { return addTestName - ? '$filePath.$currentTestName.$_updatedDescription.$approvedExtension' - : '$filePath.$_updatedDescription.$approvedExtension'; + ? '${_basePath}.$currentTestName.$_updatedDescription.$approvedExtension' + : '${_basePath}.$_updatedDescription.$approvedExtension'; } - return addTestName - ? '$filePath.$currentTestName.$approvedExtension' - : '$filePath.$approvedExtension'; + return addTestName ? '${_basePath}.$currentTestName.$approvedExtension' : '${_basePath}.$approvedExtension'; } @override String get approvedFileName { - if (options != null) { - return options!.approvedFileName; - } + if (options != null) return options!.approvedFileName; + if (description != null) { return addTestName ? '$_fileName.$currentTestName.$_updatedDescription.$approvedExtension' : '$_fileName.$_updatedDescription.$approvedExtension'; } - return addTestName - ? '$_fileName.$currentTestName.$approvedExtension' - : '$_fileName.$approvedExtension'; + return addTestName ? '$_fileName.$currentTestName.$approvedExtension' : '$_fileName.$approvedExtension'; } @override String get received { - if (options != null) { - return options!.received; - } + if (options != null) return options!.received; if (description != null) { return addTestName - ? '$filePath.$currentTestName.$_updatedDescription.$receivedExtension' - : '$filePath.$_updatedDescription.$receivedExtension'; + ? '${_basePath}.$currentTestName.$_updatedDescription.$receivedExtension' + : '${_basePath}.$_updatedDescription.$receivedExtension'; } - return addTestName - ? '$filePath.$currentTestName.$receivedExtension' - : '$filePath.$receivedExtension'; + return addTestName ? '${_basePath}.$currentTestName.$receivedExtension' : '${_basePath}.$receivedExtension'; } @override String get receivedFileName { - if (options != null) { - return options!.receivedFileName; - } + if (options != null) return options!.receivedFileName; + if (description != null) { return addTestName ? '$_fileName.$currentTestName.$_updatedDescription.$receivedExtension' : '$_fileName.$_updatedDescription.$receivedExtension'; } - return addTestName - ? '$_fileName.$currentTestName.$receivedExtension' - : '$_fileName.$receivedExtension'; + return addTestName ? '$_fileName.$currentTestName.$receivedExtension' : '$_fileName.$receivedExtension'; } @override @@ -98,17 +87,46 @@ final class Namer implements ApprovalNamer { return testName == null ? '' : testName.replaceAll(' ', '_').toLowerCase(); } - String get _updatedDescription => description == null - ? '' - : description!.replaceAll(' ', '_').toLowerCase(); + String get _updatedDescription => description == null ? '' : description!.replaceAll(' ', '_').toLowerCase(); + /// Returns the path without extension. + /// If [useSubfolder] is `true`, appends `approval_tests` to the folder path. + String get _basePath { + final separator = Platform.isWindows ? '\\' : '/'; + final idx = filePath!.lastIndexOf(separator); + final dir = idx < 0 ? '' : filePath!.substring(0, idx); + final name = filePath!.split(separator).last.split('.dart').first; + final baseDir = useSubfolder ? '$dir${separator}approvals' : dir; + return '$baseDir$separator$name'; + } + + /// Returns the file name part used in `approvedFileName` and `receivedFileName`. String get _fileName { - final path = filePath!; final separator = Platform.isWindows ? '\\' : '/'; - return path.split(separator).last.split('.dart').first; + final name = filePath!.split(separator).last.split('.dart').first; + final dirIdx = filePath!.lastIndexOf(separator); + if (dirIdx < 0) return name; + final dir = filePath!.substring(0, dirIdx); + final baseDir = useSubfolder ? '$dir${separator}approvals' : dir; + return '$baseDir$separator$name'; } static const String approvedExtension = 'approved.txt'; - static const String receivedExtension = 'received.txt'; + + Namer copyWith({ + String? filePath, + FileNamerOptions? options, + bool? addTestName, + String? description, + bool? useSubfolder, + }) { + return Namer( + filePath: filePath ?? this.filePath, + options: options ?? this.options, + addTestName: addTestName ?? this.addTestName, + description: description ?? this.description, + useSubfolder: useSubfolder ?? this.useSubfolder, + ); + } } diff --git a/test/utils/helper.dart b/test/utils/helper.dart index 443bd04..1780f3a 100644 --- a/test/utils/helper.dart +++ b/test/utils/helper.dart @@ -57,8 +57,7 @@ class ApprovalTestHelper { }) { Approvals.verifyAll( contents, - processor: (item) => item - .toString(), // Simple processor function that returns the item itself. + processor: (item) => item.toString(), // Simple processor function that returns the item itself. options: _getOptions( testName, expectException: expectException, @@ -85,8 +84,7 @@ class ApprovalTestHelper { expectException: expectException, approveResult: approveResult, deleteReceivedFile: deleteReceivedFile, - includeClassNameDuringSerialization: - includeClassNameDuringSerialization, + includeClassNameDuringSerialization: includeClassNameDuringSerialization, ), ); } @@ -167,14 +165,13 @@ class ApprovalTestHelper { description: description, ), ) - : null, + : Namer(), deleteReceivedFile: deleteReceivedFile, approveResult: approveResult, logErrors: !expectException, reporter: reporter, scrubber: scrubber, - includeClassNameDuringSerialization: - includeClassNameDuringSerialization, + includeClassNameDuringSerialization: includeClassNameDuringSerialization, ); String get fakeStackTracePath {