Skip to content

Commit

Permalink
. t coverage code 97% by tests, need to add tests for diff tool: wind…
Browse files Browse the repository at this point in the history
…ows and linux, android studio for mac
  • Loading branch information
yelmuratoff committed May 18, 2024
1 parent 14c3d8f commit aec417e
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 50 deletions.
6 changes: 4 additions & 2 deletions lib/approval_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ part 'src/core/scrubber.dart';
part 'src/core/utils/converter.dart';
part 'src/core/utils/executable_query.dart';
part 'src/core/utils/utils.dart';
part 'src/exceptions/command_line_comparator_exception.dart';
part 'src/exceptions/doesnt_match_exception.dart';
part 'src/exceptions/ide_comparator_exception.dart';
part 'src/namer/file_namer_options.dart';
part 'src/namer/namer.dart';
part 'src/reporters/command_line/command_line_reporter.dart';
Expand All @@ -35,3 +33,7 @@ part 'src/scrubbers/date_scrubber.dart';
part 'src/scrubbers/nothing_scrubber.dart';
part 'src/scrubbers/reg_exp_scrubber.dart';
part 'src/writers/approval_text_writer.dart';
part 'src/core/stack_trace_fetcher/stack_trace_fetcher.dart';
part 'src/core/file_path_extractor.dart';
part 'src/exceptions/file_not_found_exception.dart';
part 'src/core/stack_trace_fetcher/fetcher.dart';
6 changes: 4 additions & 2 deletions lib/src/approvals.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ 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());

// Factory method to create an instance of ApprovalNamer with given file name
static ApprovalNamer makeNamer(String filePath) => Namer(filePath: filePath);

Expand All @@ -14,7 +16,7 @@ class Approvals {
}) {
try {
// Get the file path without extension or use the provided file path
final completedPath = options.namer?.filePath ?? ApprovalUtils.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 = options.namer ?? makeNamer(completedPath);
Expand Down Expand Up @@ -69,7 +71,7 @@ class Approvals {
ApprovalUtils.deleteFile(options.namer!.received);
} else {
ApprovalUtils.deleteFile(
Namer(filePath: ApprovalUtils.filePath.split('.dart').first).received,
Namer(filePath: filePathExtractor.filePath.split('.dart').first).received,
);
}
}
Expand Down
30 changes: 30 additions & 0 deletions lib/src/core/file_path_extractor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
part of '../../approval_tests.dart';

class FilePathExtractor {
final IStackTraceFetcher _stackTraceFetcher;

const FilePathExtractor({
IStackTraceFetcher? stackTraceFetcher,
}) : _stackTraceFetcher = stackTraceFetcher ?? const StackTraceFetcher();

String get filePath {
try {
final stackTraceString = _stackTraceFetcher.currentStackTrace;
final uriRegExp = RegExp(r'file:\/\/\/([^\s:]+)');

final match = uriRegExp.firstMatch(stackTraceString);

if (match != null) {
final filePath = Uri.tryParse('file:///${match.group(1)!}');
return filePath!.toFilePath();
} else {
throw FileNotFoundException(
message: 'File not found in stack trace',
stackTrace: StackTrace.current,
);
}
} catch (e) {
rethrow;
}
}
}
4 changes: 4 additions & 0 deletions lib/src/core/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class Options {
/// A final bool variable `deleteReceivedFile` used to determine if the received file should be deleted after passed test.
final bool deleteReceivedFile;

/// A final bool variable `deleteApprovedFile` used to determine if the approved file should be deleted after passed test.
final bool deleteApprovedFile;

/// A final variable `namer` of type `Namer` used to set the name and path of the file.
final Namer? namer;

Expand All @@ -33,6 +36,7 @@ class Options {
this.comparator = const FileComparator(),
this.reporter = const CommandLineReporter(),
this.deleteReceivedFile = false,
this.deleteApprovedFile = false,
this.namer,
this.logErrors = true,
this.logResults = true,
Expand Down
6 changes: 6 additions & 0 deletions lib/src/core/stack_trace_fetcher/fetcher.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
part of '../../../approval_tests.dart';

/// Interface for fetching the current stack trace.
abstract interface class IStackTraceFetcher {
String get currentStackTrace;
}
9 changes: 9 additions & 0 deletions lib/src/core/stack_trace_fetcher/stack_trace_fetcher.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
part of '../../../approval_tests.dart';

/// A class that provides the current stack trace.
final class StackTraceFetcher implements IStackTraceFetcher {
const StackTraceFetcher();

@override
String get currentStackTrace => StackTrace.current.toString();
}
18 changes: 1 addition & 17 deletions lib/src/core/utils/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ final class ApprovalUtils {
final int green = int.parse(hex.substring(2, 4), radix: 16);
final int blue = int.parse(hex.substring(4, 6), radix: 16);

final AnsiPen pen = AnsiPen()
..rgb(r: red / 255, g: green / 255, b: blue / 255);
final AnsiPen pen = AnsiPen()..rgb(r: red / 255, g: green / 255, b: blue / 255);
return pen;
}

Expand All @@ -25,21 +24,6 @@ final class ApprovalUtils {
}
}

// Property that gets the file path of the current file.
static String get filePath {
final stackTraceString = StackTrace.current.toString();
final uriRegExp = RegExp(r'file:\/\/\/([^:]*):');

final match = uriRegExp.firstMatch(stackTraceString);

if (match != null) {
final filePath = Uri.tryParse(match.group(0)!);
return filePath!.toFilePath();
} else {
throw Exception('Could not find file path');
}
}

static String readFile({
required String path,
}) {
Expand Down
14 changes: 0 additions & 14 deletions lib/src/exceptions/command_line_comparator_exception.dart

This file was deleted.

12 changes: 12 additions & 0 deletions lib/src/exceptions/file_not_found_exception.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
part of '../../approval_tests.dart';

class FileNotFoundException implements Exception {
final String message;

final StackTrace? stackTrace;

FileNotFoundException({
required this.message,
this.stackTrace,
});
}
14 changes: 0 additions & 14 deletions lib/src/exceptions/ide_comparator_exception.dart

This file was deleted.

37 changes: 36 additions & 1 deletion test/approval_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'queries/db_request_query.dart';

part 'utils/helper.dart';
part 'constants/lines.dart';
part 'utils/testable_file_path_extractor.dart';

void main() {
/// ================== Init fields ==================
Expand Down Expand Up @@ -38,6 +39,7 @@ void main() {
helper.verify(
'Hello World',
'verify',
approveResult: true,
);
});

Expand Down Expand Up @@ -116,7 +118,7 @@ void main() {
ApprovalLogger.log("$lines25 Group: Minor cases are starting $lines25");
});

test('Simulate file not found error during comparison. Must throw CommandLineComparatorException.', () async {
test('Simulate file not found error during comparison. Must throw PathNotFoundException.', () async {
const comparator = FileComparator();

// Setup: paths to non-existent files
Expand Down Expand Up @@ -226,6 +228,39 @@ void main() {
deleteReceivedFile: false,
);
});

test('returns correct file path', () {
const fakeStackTraceFetcher = FakeStackTraceFetcher('file:///path/to/file.dart:10:11\nother stack trace lines...');

const filePathExtractor = FilePathExtractor(stackTraceFetcher: fakeStackTraceFetcher);
final filePath = filePathExtractor.filePath;

expect(filePath, '/path/to/file.dart');
ApprovalLogger.success(
"Test Passed: Successfully extracted the file path from the stack trace.",
);
});

test('throws FileNotFoundException when no file path in stack trace', () {
const fakeStackTraceFetcher = FakeStackTraceFetcher('no file path in this stack trace\nother stack trace lines...');

const filePathExtractor = FilePathExtractor(stackTraceFetcher: fakeStackTraceFetcher);

expect(() => filePathExtractor.filePath, throwsA(isA<FileNotFoundException>()));

ApprovalLogger.success(
"Test Passed: Successfully handled a file not found error during comparison.",
);
});

test('verify without namer', () {
Approvals.verify(
'Hello World',
options: const Options(
deleteReceivedFile: true,
),
);
});
});

/// ================== Tear down ==================
Expand Down
1 change: 1 addition & 0 deletions test/approval_test.verify_without_namer.approved.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello World
11 changes: 11 additions & 0 deletions test/utils/testable_file_path_extractor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
part of '../approval_test.dart';

/// `FakeStackTraceFetcher` is a fake implementation of [IStackTraceFetcher] that needs to be used in tests.
class FakeStackTraceFetcher implements IStackTraceFetcher {
final String stackTrace;

const FakeStackTraceFetcher(this.stackTrace);

@override
String get currentStackTrace => stackTrace;
}

0 comments on commit aec417e

Please sign in to comment.