Logger: Add a test

Fixes stack parsing bug
This commit is contained in:
Vishesh Handa
2021-05-17 14:35:50 +02:00
parent c7007ab98a
commit 862c594034
2 changed files with 120 additions and 26 deletions

View File

@ -9,6 +9,7 @@ import 'package:path_provider/path_provider.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:time/time.dart';
// FIXME: Only catch Exception? type. Something else needs to be done with Errors
class Log {
static late String logFolderPath;
static RandomAccessFile? logFile;
@ -35,10 +36,6 @@ class Log {
StackTrace? stacktrace,
Map<String, dynamic>? props,
}) {
assert(
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
);
if (stacktrace != null) {
stacktrace = Trace.from(stacktrace).terse;
}
@ -56,10 +53,6 @@ class Log {
StackTrace? stacktrace,
Map<String, dynamic>? props,
}) {
assert(
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
);
if (stacktrace != null) {
stacktrace = Trace.from(stacktrace).terse;
}
@ -77,10 +70,6 @@ class Log {
StackTrace? stacktrace,
Map<String, dynamic>? props,
}) {
assert(
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
);
if (stacktrace != null) {
stacktrace = Trace.from(stacktrace).terse;
}
@ -101,10 +90,6 @@ class Log {
StackTrace? stacktrace,
Map<String, dynamic>? props,
}) {
assert(
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
);
if (stacktrace != null) {
stacktrace = Trace.from(stacktrace).terse;
}
@ -122,10 +107,6 @@ class Log {
StackTrace? stacktrace,
Map<String, dynamic>? props,
}) {
assert(
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
);
if (stacktrace != null) {
stacktrace = Trace.from(stacktrace).terse;
}
@ -144,10 +125,6 @@ class Log {
StackTrace? stackTrace,
Map<String, dynamic>? props,
) {
assert(
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
);
if (logFile == null) {
return;
}
@ -197,7 +174,8 @@ class Log {
static Iterable<LogMessage> fetchLogsForDate(DateTime date) sync* {
var file = File(filePathForDate(date));
if (!file.existsSync()) {
Log.i("No log file for $date");
var dateOnly = date.toIso8601String().substring(0, 10);
Log.i("No log file for $dateOnly");
return;
}
@ -260,16 +238,29 @@ class LogMessage {
};
}
// todo: Make sure type conversion doesn't fuck up anything
LogMessage.fromMap(Map<String, dynamic> map) {
t = map['t'];
l = map['l'];
msg = map['msg'];
ex = _checkForStringNull(map['ex']);
stack = _checkForStringNull(map['stack']);
stack = _parseJson(map['stack']);
props = _checkForStringNull(map['p']);
}
}
List<Map<String, dynamic>>? _parseJson(List<dynamic>? l) {
if (l == null) {
return null;
}
var list = <Map<String, dynamic>>[];
for (var i in l) {
list.add(i);
}
return list;
}
dynamic _checkForStringNull(dynamic e) {
if (e == null) return e;
if (e.runtimeType == String && e.toString().trim() == 'null') {

103
test/utils/logger_test.dart Normal file
View File

@ -0,0 +1,103 @@
import 'dart:io';
import 'package:flutter_test/flutter_test.dart' as ft;
import 'package:path/path.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:test/fake.dart';
import 'package:test/test.dart';
import 'package:gitjournal/utils/logger.dart';
void main() {
setUp(() async {
ft.TestWidgetsFlutterBinding.ensureInitialized();
var provider = await FakePathProviderPlatform.init();
PathProviderPlatform.instance = provider;
await Log.init();
});
test('Logger', () async {
Log.e("Hello");
try {
throw Exception("Boo");
} catch (e, st) {
Log.e("Caught", ex: e, stacktrace: st);
}
var logs = Log.fetchLogsForDate(DateTime.now()).toList();
expect(logs.length, 2);
expect(logs[0].msg, "Hello");
expect(logs[1].msg, "Caught");
});
}
// todo: Make this async
// todo: Make sure all exceptions are being caught
// from path_provider_test
const String kTemporaryPath = 'temporaryPath';
const String kApplicationSupportPath = 'applicationSupportPath';
const String kDownloadsPath = 'downloadsPath';
const String kLibraryPath = 'libraryPath';
const String kApplicationDocumentsPath = 'applicationDocumentsPath';
const String kExternalCachePath = 'externalCachePath';
const String kExternalStoragePath = 'externalStoragePath';
class FakePathProviderPlatform extends Fake
with MockPlatformInterfaceMixin
implements PathProviderPlatform {
final Directory dir;
FakePathProviderPlatform(this.dir);
static Future<FakePathProviderPlatform> init() async {
var dir = await Directory.systemTemp.createTemp();
await Directory(join(dir.path, kTemporaryPath)).create();
return FakePathProviderPlatform(dir);
}
@override
Future<String?> getTemporaryPath() async {
return join(dir.path, kTemporaryPath);
}
@override
Future<String?> getApplicationSupportPath() async {
return kApplicationSupportPath;
}
@override
Future<String?> getLibraryPath() async {
return kLibraryPath;
}
@override
Future<String?> getApplicationDocumentsPath() async {
return kApplicationDocumentsPath;
}
@override
Future<String?> getExternalStoragePath() async {
return kExternalStoragePath;
}
@override
Future<List<String>?> getExternalCachePaths() async {
return <String>[kExternalCachePath];
}
@override
Future<List<String>?> getExternalStoragePaths({
StorageDirectory? type,
}) async {
return <String>[kExternalStoragePath];
}
@override
Future<String?> getDownloadsPath() async {
return kDownloadsPath;
}
}