diff --git a/README.md b/README.md
index 9c93a8b..791a844 100644
--- a/README.md
+++ b/README.md
@@ -47,8 +47,10 @@ ApprovalTests is designed for two level: Dart and Flutter.
## 📋 How it works
-- If the changed results match the approved file perfectly, the test passes.
-- If there's a difference, a reporter tool will highlight the mismatch and the test fails.
+- The first run of the test automatically creates an `approved` file if there is no such file.
+- If the changed results match the `approved` file perfectly, the test passes.
+- If there's a difference, a `reporter` tool will highlight the mismatch and the test fails.
+- If the test is passed, the `received` file is deleted automatically. You can change this by changing the `deleteReceivedFile` value in `options`. If the test fails, the received file remains for analysis.
## 📦 Installation
@@ -57,7 +59,7 @@ Add the following to your `pubspec.yaml` file:
```yaml
dependencies:
approval_tests: ^1.1.0
- approval_tests_flutter: ^1.1.0 # if you need
+ approval_tests_flutter: ^1.1.0 # If you need. This package is needed for widget and integration tests.
```
## 👀 Getting Started
@@ -75,13 +77,13 @@ It comes ready with:
## 📚 How to use
-In order to use Approval Tests, the user needs to:
+In order to use `Approval Tests`, the user needs to:
1. Set up a test: This involves importing the Approval Tests library into your own code.
-2. Optionally, set up a reporter: Reporters are tools that highlight differences between approved and received files when a test fails. Although not necessary, they make it significantly easier to see what changes have caused a test to fail. The default reporter is the `CommandLineReporter`. You can also use the `DiffReporter` to compare the files in your IDE.
+2. Optionally, set up a reporter: Reporters are tools that highlight differences between approved and received files when a test fails. Although not necessary, they make it significantly easier to see what changes have caused a test to fail. The default reporter is the `CommandLineReporter`. You can also use the `DiffReporter` to compare the files in your IDE, and the `GitReporter` to see the differences in the `Git GUI`.
-3. Manage the "approved" file: When the test is run for the first time, an approved file is created automatically. This file will represent the expected outcome. Once the test results in a favorable outcome, the approved file should be updated to reflect these changes. A little bit below I wrote how to do it.
+3. Manage the `approved` file: When the test is run for the first time, an approved file is created automatically. This file will represent the expected outcome. Once the test results in a favorable outcome, the approved file should be updated to reflect these changes. A little bit below I wrote how to do it.
This setup is useful because it shortens feedback loops, saving developers time by only highlighting what has been altered rather than requiring them to parse through their entire output to see what effect their changes had.
@@ -95,6 +97,16 @@ We’ll provide more explanation in due course, but, briefly, here are the most
Most diff tools have the ability to move text from left to right, and save the result.
How to use diff tools is just below, there is a `Comparator` class for that.
+#### • Via CLI command
+You can run the command in a terminal to review your files:
+```bash
+dart run approval_tests:review
+```
+After running the command, the files will be analyzed and you will be asked to choose one of the options:
+- `y` - Approve the received file.
+- `n` - Reject the received file.
+- `v`iew - View the differences between the received and approved files. After selecting `v` you will be asked which IDE you want to use to view the differences.
+
#### • Via approveResult property
If you want the result to be automatically saved after running the test, you need to use the `approveResult` property in `Options`:
@@ -177,6 +189,7 @@ You can study it to understand how to use the package to test complex code.
And the `verify_methods` folder has small examples of using different `ApprovalTests` methods for different cases.
### JSON example
+With `verifyAsJson`, if you pass data models as `JsonItem`, with nested other models as `AnotherItem` and `SubItem`, then you need to add an `toJson` method to each model for the serialization to succeed.
diff --git a/examples/dart_example/test/dart_example_test.dart b/examples/dart_example/test/dart_example_test.dart
index ef89d04..310a697 100644
--- a/examples/dart_example/test/dart_example_test.dart
+++ b/examples/dart_example/test/dart_example_test.dart
@@ -9,7 +9,7 @@ void main() {
[3, 5, 15],
options: const Options(
reporter: DiffReporter(),
- deleteReceivedFile: false,
+ deleteApprovedFile: true,
),
processor: (items) => fizzBuzz(items).toString(),
);
diff --git a/examples/dart_example/test/dart_example_test.verify_combinations.approved.txt b/examples/dart_example/test/dart_example_test.verify_combinations.approved.txt
deleted file mode 100644
index 10e3275..0000000
--- a/examples/dart_example/test/dart_example_test.verify_combinations.approved.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-[1, 2, Fizz]
-[1, 2, Fizz, 4, Buzz]
-[1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz]
\ No newline at end of file
diff --git a/packages/approval_tests/bin/review.dart b/packages/approval_tests/bin/review.dart
index 2237ef0..903e8bb 100644
--- a/packages/approval_tests/bin/review.dart
+++ b/packages/approval_tests/bin/review.dart
@@ -37,9 +37,10 @@ Future processFile(File approvedFile, FileSystemEntity reviewFile) async {
ComparatorIDE comparatorIDE = ComparatorIDE.vsCode;
if (resultString.isNotEmpty || resultString.isNotEmpty) {
- final String fileNameWithoutExtension =
- approvedFile.path.split('/').last.split('.').first;
- GitReporter.printGitDiffs(fileNameWithoutExtension, resultString);
+ // final String fileNameWithoutExtension =
+ // approvedFile.path.split('/').last.split('.').first;
+ // GitReporter.printGitDiffs(fileNameWithoutExtension, resultString);
+ const CommandLineReporter().report(approvedFile.path, reviewFile.path);
String? firstCharacter;
diff --git a/packages/approval_tests/example/main.dart b/packages/approval_tests/example/main.dart
index 26b50ee..bf70a4c 100644
--- a/packages/approval_tests/example/main.dart
+++ b/packages/approval_tests/example/main.dart
@@ -8,7 +8,6 @@ void main() {
[3, 5, 15],
options: const Options(
reporter: DiffReporter(),
- deleteReceivedFile: true,
),
processor: (items) => fizzBuzz(items).toString(),
);
diff --git a/packages/approval_tests/example/verify_methods/verify/verify_test.dart b/packages/approval_tests/example/verify_methods/verify/verify_test.dart
index a69ed12..b05f0d6 100644
--- a/packages/approval_tests/example/verify_methods/verify/verify_test.dart
+++ b/packages/approval_tests/example/verify_methods/verify/verify_test.dart
@@ -8,7 +8,6 @@ void main() {
Approvals.verify(
response,
- options: const Options(deleteReceivedFile: true),
);
});
}
diff --git a/packages/approval_tests/example/verify_methods/verify_all/verify_all_test.dart b/packages/approval_tests/example/verify_methods/verify_all/verify_all_test.dart
index 4832904..3927b13 100644
--- a/packages/approval_tests/example/verify_methods/verify_all/verify_all_test.dart
+++ b/packages/approval_tests/example/verify_methods/verify_all/verify_all_test.dart
@@ -8,7 +8,6 @@ void main() {
Approvals.verifyAll(
items,
processor: (item) => 'Item: $item',
- options: const Options(deleteReceivedFile: true),
);
});
}
diff --git a/packages/approval_tests/example/verify_methods/verify_all_combinations/verify_all_combinations_test.dart b/packages/approval_tests/example/verify_methods/verify_all_combinations/verify_all_combinations_test.dart
index e08a11f..ca4a9a9 100644
--- a/packages/approval_tests/example/verify_methods/verify_all_combinations/verify_all_combinations_test.dart
+++ b/packages/approval_tests/example/verify_methods/verify_all_combinations/verify_all_combinations_test.dart
@@ -11,7 +11,6 @@ void main() {
Approvals.verifyAllCombinations(
inputs,
processor: (combination) => 'Combination: ${combination.join(", ")}',
- options: const Options(deleteReceivedFile: true),
);
});
}
diff --git a/packages/approval_tests/example/verify_methods/verify_as_json/json_test.dart b/packages/approval_tests/example/verify_methods/verify_as_json/json_test.dart
index 080299c..0f7529a 100644
--- a/packages/approval_tests/example/verify_methods/verify_as_json/json_test.dart
+++ b/packages/approval_tests/example/verify_methods/verify_as_json/json_test.dart
@@ -11,7 +11,6 @@ void main() {
};
Approvals.verifyAsJson(
complexObject,
- options: const Options(deleteReceivedFile: true),
);
});
});
diff --git a/packages/approval_tests/example/verify_methods/verify_as_json/verify_as_json_test.dart b/packages/approval_tests/example/verify_methods/verify_as_json/verify_as_json_test.dart
index c49c398..bcd1ce5 100644
--- a/packages/approval_tests/example/verify_methods/verify_as_json/verify_as_json_test.dart
+++ b/packages/approval_tests/example/verify_methods/verify_as_json/verify_as_json_test.dart
@@ -23,8 +23,6 @@ void main() {
Approvals.verifyAsJson(
jsonItem,
options: const Options(
- deleteReceivedFile:
- true, // Automatically delete the received file after the test.
approveResult:
true, // Approve the result automatically. You can remove this property after the approved file is created.
),
diff --git a/packages/approval_tests/example/verify_methods/verify_query/verify_db_query_test.dart b/packages/approval_tests/example/verify_methods/verify_query/verify_db_query_test.dart
index 83f990a..7f1452d 100644
--- a/packages/approval_tests/example/verify_methods/verify_query/verify_db_query_test.dart
+++ b/packages/approval_tests/example/verify_methods/verify_query/verify_db_query_test.dart
@@ -8,7 +8,6 @@ void main() async {
test('verify db query', () async {
await Approvals.verifyQuery(
dbQuery,
- options: const Options(deleteReceivedFile: true),
);
});
}
diff --git a/packages/approval_tests/example/verify_methods/verify_query/verify_network_query_test.dart b/packages/approval_tests/example/verify_methods/verify_query/verify_network_query_test.dart
index c02180d..ebe1e2a 100644
--- a/packages/approval_tests/example/verify_methods/verify_query/verify_network_query_test.dart
+++ b/packages/approval_tests/example/verify_methods/verify_query/verify_network_query_test.dart
@@ -10,7 +10,6 @@ void main() async {
test('verify network query', () async {
await Approvals.verifyQuery(
query,
- options: const Options(deleteReceivedFile: true),
);
});
}
diff --git a/packages/approval_tests/example/verify_methods/verify_sequence/verify_sequence_test.dart b/packages/approval_tests/example/verify_methods/verify_sequence/verify_sequence_test.dart
index 9850547..abd8a3b 100644
--- a/packages/approval_tests/example/verify_methods/verify_sequence/verify_sequence_test.dart
+++ b/packages/approval_tests/example/verify_methods/verify_sequence/verify_sequence_test.dart
@@ -7,7 +7,6 @@ void main() {
Approvals.verifySequence(
sequence,
- options: const Options(deleteReceivedFile: true),
);
});
}
diff --git a/packages/approval_tests/lib/approval_tests.dart b/packages/approval_tests/lib/approval_tests.dart
index c8cac6b..9b5f2d7 100644
--- a/packages/approval_tests/lib/approval_tests.dart
+++ b/packages/approval_tests/lib/approval_tests.dart
@@ -4,6 +4,7 @@ import 'dart:convert';
import 'dart:io';
import 'dart:math';
+import 'package:approval_tests/src/core/enums/file_type.dart';
import 'package:diff_match_patch2/diff_match_patch.dart';
import 'package:talker/talker.dart';
import 'package:test_api/src/backend/invoker.dart' show Invoker;
diff --git a/packages/approval_tests/lib/src/approvals.dart b/packages/approval_tests/lib/src/approvals.dart
index ee8a284..ceee29b 100644
--- a/packages/approval_tests/lib/src/approvals.dart
+++ b/packages/approval_tests/lib/src/approvals.dart
@@ -70,33 +70,37 @@ class Approvals {
ApprovalLogger.success(
'Test passed: [${namer.approvedFileName}] matches [${namer.receivedFileName}]\n\n- Approved file path: ${namer.approved}\n\n- Received file path: ${namer.received}',
);
+ if (options.deleteReceivedFile) {
+ _deleteFileAfterTest(namer: namer, fileType: FileType.received);
+ }
+ if (options.deleteApprovedFile) {
+ _deleteFileAfterTest(namer: namer, fileType: FileType.approved);
+ }
}
}
} catch (e, st) {
if (options.logErrors) {
ApprovalLogger.exception(e, stackTrace: st);
}
- if (options.deleteReceivedFile) {
- _deleteFileAfterTest(namer);
- }
rethrow;
- } finally {
- if (options.deleteReceivedFile) {
- _deleteFileAfterTest(namer);
- }
}
}
/// `_deleteFileAfterTest` method to delete the received file after the test.
- static void _deleteFileAfterTest(ApprovalNamer? namer) {
- if (namer != null) {
- ApprovalUtils.deleteFile(namer.received);
- } else {
- ApprovalUtils.deleteFile(
- Namer(filePath: filePathExtractor.filePath.split('.dart').first)
- .received,
- );
- }
+ static void _deleteFileAfterTest({
+ required ApprovalNamer? namer,
+ required FileType fileType,
+ }) {
+ final fileToNamerMap = {
+ FileType.approved: (ApprovalNamer n) => n.approved,
+ FileType.received: (ApprovalNamer n) => n.received,
+ };
+
+ final filePath = (namer == null)
+ ? Namer(filePath: filePathExtractor.filePath.split('.dart').first)
+ : namer;
+
+ ApprovalUtils.deleteFile(fileToNamerMap[fileType]!(filePath));
}
/// Verifies all combinations of inputs for a provided function.
@@ -127,7 +131,7 @@ class Approvals {
// Encode the object into JSON format
final jsonContent = ApprovalConverter.encodeReflectively(
encodable,
- includeClassName: true,
+ includeClassName: options.includeClassNameDuringSerialization,
);
final prettyJson = ApprovalConverter.convert(jsonContent);
diff --git a/packages/approval_tests/lib/src/core/enums/file_type.dart b/packages/approval_tests/lib/src/core/enums/file_type.dart
new file mode 100644
index 0000000..96994d1
--- /dev/null
+++ b/packages/approval_tests/lib/src/core/enums/file_type.dart
@@ -0,0 +1,4 @@
+enum FileType {
+ approved,
+ received,
+}
diff --git a/packages/approval_tests/lib/src/core/options.dart b/packages/approval_tests/lib/src/core/options.dart
index 6ca78be..c522e51 100644
--- a/packages/approval_tests/lib/src/core/options.dart
+++ b/packages/approval_tests/lib/src/core/options.dart
@@ -29,17 +29,21 @@ class Options {
/// A final bool variable `logResults` used to determine if the results should be logged.
final bool logResults;
+ /// A final bool variable `includeClassNameDuringSerialization` used to determine if the class name should be included during serialization.
+ final bool includeClassNameDuringSerialization;
+
// A constructor for the class Options which initializes `isScrub` and `fileExtensionWithoutDot`.
const Options({
this.scrubber = const ScrubNothing(),
this.approveResult = false,
this.comparator = const FileComparator(),
this.reporter = const CommandLineReporter(),
- this.deleteReceivedFile = false,
+ this.deleteReceivedFile = true,
this.deleteApprovedFile = false,
this.namer,
this.logErrors = true,
this.logResults = true,
+ this.includeClassNameDuringSerialization = true,
});
Options copyWith({
@@ -52,6 +56,7 @@ class Options {
Namer? namer,
bool? logErrors,
bool? logResults,
+ bool? includeClassNameDuringSerialization,
}) =>
Options(
scrubber: scrubber ?? this.scrubber,
@@ -63,5 +68,8 @@ class Options {
namer: namer ?? this.namer,
logErrors: logErrors ?? this.logErrors,
logResults: logResults ?? this.logResults,
+ includeClassNameDuringSerialization:
+ includeClassNameDuringSerialization ??
+ this.includeClassNameDuringSerialization,
);
}
diff --git a/packages/approval_tests/lib/src/namer/file_namer_options.dart b/packages/approval_tests/lib/src/namer/file_namer_options.dart
index 9fd3ca1..dc5dd3e 100644
--- a/packages/approval_tests/lib/src/namer/file_namer_options.dart
+++ b/packages/approval_tests/lib/src/namer/file_namer_options.dart
@@ -4,18 +4,33 @@ final class FileNamerOptions {
final String folderPath;
final String fileName;
final String testName;
+ final String? description;
const FileNamerOptions({
required this.folderPath,
required this.fileName,
required this.testName,
+ required this.description,
});
String get approved => '$folderPath/$approvedFileName';
String get received => '$folderPath/$receivedFileName';
- String get approvedFileName => '$fileName.$testName.approved.txt';
+ String get approvedFileName {
+ if (description != null) {
+ return '$fileName.$testName.$_updatedDescription.approved.txt';
+ }
+ return '$fileName.$testName.approved.txt';
+ }
- String get receivedFileName => '$fileName.$testName.received.txt';
+ String get receivedFileName {
+ if (description != null) {
+ return '$fileName.$testName.$_updatedDescription.received.txt';
+ }
+ return '$fileName.$testName.received.txt';
+ }
+
+ String get _updatedDescription =>
+ description == null ? '' : description!.replaceAll(' ', '_');
}
diff --git a/packages/approval_tests/lib/src/namer/namer.dart b/packages/approval_tests/lib/src/namer/namer.dart
index e916aaa..df7e867 100644
--- a/packages/approval_tests/lib/src/namer/namer.dart
+++ b/packages/approval_tests/lib/src/namer/namer.dart
@@ -79,11 +79,12 @@ final class Namer implements ApprovalNamer {
@override
String get currentTestName {
final testName = Invoker.current?.liveTest.individualName;
- return testName == null ? '' : testName.replaceAll(' ', '_');
+ return testName == null ? '' : testName.replaceAll(' ', '_').toLowerCase();
}
- String get _updatedDescription =>
- description == null ? '' : description!.replaceAll(' ', '_');
+ String get _updatedDescription => description == null
+ ? ''
+ : description!.replaceAll(' ', '_').toLowerCase();
String get _fileName {
final path = filePath!;
diff --git a/packages/approval_tests/lib/src/reporters/git.dart b/packages/approval_tests/lib/src/reporters/git.dart
index 7380a37..99e5b94 100644
--- a/packages/approval_tests/lib/src/reporters/git.dart
+++ b/packages/approval_tests/lib/src/reporters/git.dart
@@ -2,12 +2,15 @@ part of '../../approval_tests.dart';
/// `GitReporter` is a class for reporting the comparison results using the git.
class GitReporter implements Reporter {
- const GitReporter();
+ final DiffInfo? customDiffInfo;
+ const GitReporter({
+ this.customDiffInfo,
+ });
@override
Future report(String approvedPath, String receivedPath) async {
- const DiffInfo diffInfo =
- DiffInfo(name: "Git", command: 'git', arg: 'diff --no-index');
+ final DiffInfo diffInfo = customDiffInfo ??
+ const DiffInfo(name: "Git", command: 'git', arg: 'diff --no-index');
try {
await Future.wait([
@@ -74,10 +77,10 @@ class GitReporter implements Reporter {
return result;
}
- static void printGitDiffs(String testDescription, String differences) {
- ApprovalLogger.log(
- "Results of git diff during approvalTest('$testDescription'):",
- );
- ApprovalLogger.log(differences.trim());
- }
+ // static void printGitDiffs(String testDescription, String differences) {
+ // ApprovalLogger.log(
+ // "Results of git diff during approvalTest('$testDescription'):",
+ // );
+ // ApprovalLogger.log(differences.trim());
+ // }
}
diff --git a/packages/approval_tests/test/groups/minor_tests.verify_without_namer.approved.txt b/packages/approval_tests/test/approved_files/approval_test.description_with_filenamer.test_description.approved.txt
similarity index 100%
rename from packages/approval_tests/test/groups/minor_tests.verify_without_namer.approved.txt
rename to packages/approval_tests/test/approved_files/approval_test.description_with_filenamer.test_description.approved.txt
diff --git a/packages/approval_tests/test/approved_files/approval_test.verify_without_class_name.approved.txt b/packages/approval_tests/test/approved_files/approval_test.verify_without_class_name.approved.txt
new file mode 100644
index 0000000..64a376b
--- /dev/null
+++ b/packages/approval_tests/test/approved_files/approval_test.verify_without_class_name.approved.txt
@@ -0,0 +1,22 @@
+{
+ "id": 1,
+ "name": "JsonItem",
+ "subItem": {
+ "id": 1,
+ "name": "SubItem",
+ "anotherItems": [
+ {
+ "id": 1,
+ "name": "AnotherItem 1"
+ },
+ {
+ "id": 2,
+ "name": "AnotherItem 2"
+ }
+ ]
+ },
+ "anotherItem": {
+ "id": 1,
+ "name": "AnotherItem"
+ }
+}
\ No newline at end of file
diff --git a/packages/approval_tests/test/groups/diff_tools_tests.dart b/packages/approval_tests/test/groups/diff_tools_tests.dart
index 65a126c..344dd52 100644
--- a/packages/approval_tests/test/groups/diff_tools_tests.dart
+++ b/packages/approval_tests/test/groups/diff_tools_tests.dart
@@ -8,6 +8,7 @@ import '../approval_test.dart';
void main() {
final isWindows = Platform.isWindows;
final isLinux = Platform.isLinux;
+ const gitReporter = GitReporter();
group('Approvals: test for Diff Tools', () {
setUpAll(() {
@@ -68,6 +69,23 @@ void main() {
);
});
+ test('verify reporter availability on Linux', () {
+ const reporter = DiffReporter(
+ ide: ComparatorIDE.studio,
+ platformWrapper: LinuxPlatformWrapper(),
+ );
+
+ // Expect an exception to be thrown
+ expect(
+ reporter.isReporterAvailable,
+ isLinux ? returnsNormally : false,
+ );
+
+ ApprovalLogger.success(
+ "Test Passed: Successfully handled availability: ${isLinux ? 'normal' : 'false'} for Android Studio DiffReporter on Linux.",
+ );
+ });
+
test('verify string with NoPlatformWrapper', () {
const reporter = DiffReporter(
ide: ComparatorIDE.studio,
@@ -93,5 +111,68 @@ void main() {
"Test Passed: Successfully handled NoDiffToolException.",
);
});
+
+ test('verify string with Git reporter', () {
+ // Setup: paths to existent files
+ const existentApprovedPath =
+ 'test/approved_files/approval_test.verify.approved.txt';
+ const existentReceivedPath =
+ 'test/approved_files/approval_test.verify.received.txt';
+
+ // Expect an exception to be thrown
+ expect(
+ () => gitReporter.report(
+ existentApprovedPath,
+ existentReceivedPath,
+ ),
+ returnsNormally,
+ );
+
+ ApprovalLogger.success(
+ "Test Passed: Successfully handled 'normal' for Git reporter.",
+ );
+ });
+
+ test('Should throw PathNotFoundException when file does not exist', () {
+ const String approvedPath = "/path/to/nonexisting/approved/file";
+ const String receivedPath = "/path/to/nonexisting/received/file";
+
+ expect(
+ () async => gitReporter.report(approvedPath, receivedPath),
+ throwsA(isA()),
+ );
+ });
+
+ test(
+ 'gitDiffFiles should return an empty string if no differences for valid files',
+ () {
+ final File path0 = File('/path/to/existing/file0');
+ final FileSystemEntity path1 = File('/path/to/existing/file1');
+
+ final diffResult = GitReporter.gitDiffFiles(path0, path1);
+
+ expect(diffResult, equals(''));
+ });
+
+ test('GitReporter with not correct custom diff info', () {
+ const DiffInfo customDiffInfo =
+ DiffInfo(name: "G1t", command: 'g1t', arg: 'diff --no-index');
+
+ const gitReporter = GitReporter(customDiffInfo: customDiffInfo);
+
+ const existentApprovedPath =
+ 'test/approved_files/approval_test.verify.approved.txt';
+ const existentReceivedPath =
+ 'test/approved_files/approval_test.verify.received.txt';
+
+ // Expect an exception to be thrown
+ expect(
+ () => gitReporter.report(
+ existentApprovedPath,
+ existentReceivedPath,
+ ),
+ throwsA(isA()),
+ );
+ });
});
}
diff --git a/packages/approval_tests/test/groups/exception_tests.dart b/packages/approval_tests/test/groups/exception_tests.dart
index 4eb8954..a50dc30 100644
--- a/packages/approval_tests/test/groups/exception_tests.dart
+++ b/packages/approval_tests/test/groups/exception_tests.dart
@@ -2,6 +2,7 @@ import 'package:approval_tests/approval_tests.dart';
import 'package:test/test.dart';
import '../approval_test.dart';
+import '../models/item.dart';
void main() {
group('Approvals: test for exceptions |', () {
@@ -17,6 +18,7 @@ void main() {
'Hello W0rld',
'verify',
expectException: true,
+ deleteReceivedFile: false,
),
throwsA(isA()),
);
@@ -39,5 +41,17 @@ void main() {
"Test Passed: Successfully handled a log mismatch. Method «verify» correctly throws DoesntMatchException as expected.",
);
});
+
+ test('Verify model (not map). Must throw UnsupportedError exception.', () {
+ expect(
+ () => Approvals.verifyAsJson(
+ const ErrorItem(
+ id: 1,
+ name: "JsonItem",
+ ),
+ ),
+ throwsA(isA()),
+ );
+ });
});
}
diff --git a/packages/approval_tests/test/groups/minor_tests.dart b/packages/approval_tests/test/groups/minor_tests.dart
index a9739e3..449dd25 100644
--- a/packages/approval_tests/test/groups/minor_tests.dart
+++ b/packages/approval_tests/test/groups/minor_tests.dart
@@ -183,7 +183,67 @@ void main() {
Approvals.verify(
'Hello World',
options: const Options(
- deleteReceivedFile: true,
+ deleteApprovedFile: true,
+ ),
+ );
+ });
+
+ test('Verify model without class name', () {
+ helper.verifyAsJson(
+ ApprovalTestHelper.jsonItem,
+ 'verify_without_class_name',
+ includeClassNameDuringSerialization: false,
+ );
+ });
+
+ test('Should return correct directory path on linux/macOS/Windows', () {
+ final fakeStackTraceFetcher = FakeStackTraceFetcher(
+ helper.fakeStackTracePath,
+ );
+
+ final filePathExtractor =
+ FilePathExtractor(stackTraceFetcher: fakeStackTraceFetcher);
+ final directoryPath = filePathExtractor.directoryPath;
+
+ expect(directoryPath, helper.testDirectoryPath);
+ ApprovalLogger.success(
+ "Test Passed: Successfully extracted the directory path from the stack trace.",
+ );
+ });
+
+ test('Should throw FileNotFoundException when no match found', () {
+ const fakeStackTraceFetcher = FakeStackTraceFetcher(
+ 'no file path in this stack trace\nother stack trace lines...',
+ );
+
+ const filePathExtractor =
+ FilePathExtractor(stackTraceFetcher: fakeStackTraceFetcher);
+
+ expect(
+ () => filePathExtractor.directoryPath,
+ throwsA(isA()),
+ );
+
+ ApprovalLogger.success(
+ "Test Passed: Successfully handled a file not found error during getting directory path.",
+ );
+ });
+
+ test('Verify with description: with FileNamer', () {
+ helper.verify(
+ 'Hello World',
+ 'description_with_filenamer',
+ description: 'test description',
+ );
+ });
+
+ test('description with Namer', () {
+ Approvals.verify(
+ 'Hello World',
+ options: const Options(
+ namer: Namer(
+ description: 'test description',
+ ),
),
);
});
diff --git a/packages/approval_tests/test/groups/minor_tests.description_with_namer.test_description.approved.txt b/packages/approval_tests/test/groups/minor_tests.description_with_namer.test_description.approved.txt
new file mode 100644
index 0000000..5e1c309
--- /dev/null
+++ b/packages/approval_tests/test/groups/minor_tests.description_with_namer.test_description.approved.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file
diff --git a/packages/approval_tests/test/models/item.dart b/packages/approval_tests/test/models/item.dart
index fc3f4ad..87b3d6f 100644
--- a/packages/approval_tests/test/models/item.dart
+++ b/packages/approval_tests/test/models/item.dart
@@ -51,3 +51,11 @@ class AnotherItem {
'name': name,
};
}
+
+/// Item without `toJson` method
+class ErrorItem {
+ final int id;
+ final String name;
+
+ const ErrorItem({required this.id, required this.name});
+}
diff --git a/packages/approval_tests/test/utils/helper.dart b/packages/approval_tests/test/utils/helper.dart
index 0d9b94e..443bd04 100644
--- a/packages/approval_tests/test/utils/helper.dart
+++ b/packages/approval_tests/test/utils/helper.dart
@@ -27,6 +27,7 @@ class ApprovalTestHelper {
bool approveResult = false,
bool deleteReceivedFile = true,
bool useDefaultPath = true,
+ String? description,
ApprovalScrubber scrubber = const ScrubNothing(),
Reporter reporter = const CommandLineReporter(),
}) {
@@ -40,6 +41,7 @@ class ApprovalTestHelper {
useDefaultPath: useDefaultPath,
reporter: reporter,
scrubber: scrubber,
+ description: description,
),
);
}
@@ -74,6 +76,7 @@ class ApprovalTestHelper {
bool expectException = false,
bool approveResult = false,
bool deleteReceivedFile = true,
+ bool includeClassNameDuringSerialization = true,
}) {
Approvals.verifyAsJson(
encodable,
@@ -82,6 +85,8 @@ class ApprovalTestHelper {
expectException: expectException,
approveResult: approveResult,
deleteReceivedFile: deleteReceivedFile,
+ includeClassNameDuringSerialization:
+ includeClassNameDuringSerialization,
),
);
}
@@ -146,7 +151,9 @@ class ApprovalTestHelper {
required bool expectException,
required bool approveResult,
required bool deleteReceivedFile,
+ bool includeClassNameDuringSerialization = true,
bool useDefaultPath = true,
+ String? description,
ApprovalScrubber scrubber = const ScrubNothing(),
Reporter reporter = const CommandLineReporter(),
}) =>
@@ -157,6 +164,7 @@ class ApprovalTestHelper {
folderPath: basePath,
testName: testName,
fileName: 'approval_test',
+ description: description,
),
)
: null,
@@ -165,6 +173,8 @@ class ApprovalTestHelper {
logErrors: !expectException,
reporter: reporter,
scrubber: scrubber,
+ includeClassNameDuringSerialization:
+ includeClassNameDuringSerialization,
);
String get fakeStackTracePath {
@@ -182,4 +192,12 @@ class ApprovalTestHelper {
return '/path/to/file.dart';
}
}
+
+ String get testDirectoryPath {
+ if (Platform.isWindows) {
+ return 'C:\\path\\to';
+ } else {
+ return '/path/to';
+ }
+ }
}
diff --git a/packages/approval_tests_flutter/lib/src/src.dart b/packages/approval_tests_flutter/lib/src/src.dart
index f7a562c..b1d57e2 100644
--- a/packages/approval_tests_flutter/lib/src/src.dart
+++ b/packages/approval_tests_flutter/lib/src/src.dart
@@ -50,6 +50,8 @@ Future Function(String?, String, Options?) _globalApprovalTest =
),
logErrors: options.logErrors,
logResults: options.logResults,
+ includeClassNameDuringSerialization:
+ options.includeClassNameDuringSerialization,
)
: Options(
namer: Namer(