mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-29 02:07:39 +08:00
Logger: Add a test
Fixes stack parsing bug
This commit is contained in:
@ -9,6 +9,7 @@ import 'package:path_provider/path_provider.dart';
|
|||||||
import 'package:stack_trace/stack_trace.dart';
|
import 'package:stack_trace/stack_trace.dart';
|
||||||
import 'package:time/time.dart';
|
import 'package:time/time.dart';
|
||||||
|
|
||||||
|
// FIXME: Only catch Exception? type. Something else needs to be done with Errors
|
||||||
class Log {
|
class Log {
|
||||||
static late String logFolderPath;
|
static late String logFolderPath;
|
||||||
static RandomAccessFile? logFile;
|
static RandomAccessFile? logFile;
|
||||||
@ -35,10 +36,6 @@ class Log {
|
|||||||
StackTrace? stacktrace,
|
StackTrace? stacktrace,
|
||||||
Map<String, dynamic>? props,
|
Map<String, dynamic>? props,
|
||||||
}) {
|
}) {
|
||||||
assert(
|
|
||||||
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (stacktrace != null) {
|
if (stacktrace != null) {
|
||||||
stacktrace = Trace.from(stacktrace).terse;
|
stacktrace = Trace.from(stacktrace).terse;
|
||||||
}
|
}
|
||||||
@ -56,10 +53,6 @@ class Log {
|
|||||||
StackTrace? stacktrace,
|
StackTrace? stacktrace,
|
||||||
Map<String, dynamic>? props,
|
Map<String, dynamic>? props,
|
||||||
}) {
|
}) {
|
||||||
assert(
|
|
||||||
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (stacktrace != null) {
|
if (stacktrace != null) {
|
||||||
stacktrace = Trace.from(stacktrace).terse;
|
stacktrace = Trace.from(stacktrace).terse;
|
||||||
}
|
}
|
||||||
@ -77,10 +70,6 @@ class Log {
|
|||||||
StackTrace? stacktrace,
|
StackTrace? stacktrace,
|
||||||
Map<String, dynamic>? props,
|
Map<String, dynamic>? props,
|
||||||
}) {
|
}) {
|
||||||
assert(
|
|
||||||
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (stacktrace != null) {
|
if (stacktrace != null) {
|
||||||
stacktrace = Trace.from(stacktrace).terse;
|
stacktrace = Trace.from(stacktrace).terse;
|
||||||
}
|
}
|
||||||
@ -101,10 +90,6 @@ class Log {
|
|||||||
StackTrace? stacktrace,
|
StackTrace? stacktrace,
|
||||||
Map<String, dynamic>? props,
|
Map<String, dynamic>? props,
|
||||||
}) {
|
}) {
|
||||||
assert(
|
|
||||||
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (stacktrace != null) {
|
if (stacktrace != null) {
|
||||||
stacktrace = Trace.from(stacktrace).terse;
|
stacktrace = Trace.from(stacktrace).terse;
|
||||||
}
|
}
|
||||||
@ -122,10 +107,6 @@ class Log {
|
|||||||
StackTrace? stacktrace,
|
StackTrace? stacktrace,
|
||||||
Map<String, dynamic>? props,
|
Map<String, dynamic>? props,
|
||||||
}) {
|
}) {
|
||||||
assert(
|
|
||||||
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (stacktrace != null) {
|
if (stacktrace != null) {
|
||||||
stacktrace = Trace.from(stacktrace).terse;
|
stacktrace = Trace.from(stacktrace).terse;
|
||||||
}
|
}
|
||||||
@ -144,10 +125,6 @@ class Log {
|
|||||||
StackTrace? stackTrace,
|
StackTrace? stackTrace,
|
||||||
Map<String, dynamic>? props,
|
Map<String, dynamic>? props,
|
||||||
) {
|
) {
|
||||||
assert(
|
|
||||||
ex == null || ex.runtimeType == Error || ex.runtimeType == Exception,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (logFile == null) {
|
if (logFile == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -197,7 +174,8 @@ class Log {
|
|||||||
static Iterable<LogMessage> fetchLogsForDate(DateTime date) sync* {
|
static Iterable<LogMessage> fetchLogsForDate(DateTime date) sync* {
|
||||||
var file = File(filePathForDate(date));
|
var file = File(filePathForDate(date));
|
||||||
if (!file.existsSync()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,16 +238,29 @@ class LogMessage {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: Make sure type conversion doesn't fuck up anything
|
||||||
LogMessage.fromMap(Map<String, dynamic> map) {
|
LogMessage.fromMap(Map<String, dynamic> map) {
|
||||||
t = map['t'];
|
t = map['t'];
|
||||||
l = map['l'];
|
l = map['l'];
|
||||||
msg = map['msg'];
|
msg = map['msg'];
|
||||||
ex = _checkForStringNull(map['ex']);
|
ex = _checkForStringNull(map['ex']);
|
||||||
stack = _checkForStringNull(map['stack']);
|
stack = _parseJson(map['stack']);
|
||||||
props = _checkForStringNull(map['p']);
|
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) {
|
dynamic _checkForStringNull(dynamic e) {
|
||||||
if (e == null) return e;
|
if (e == null) return e;
|
||||||
if (e.runtimeType == String && e.toString().trim() == 'null') {
|
if (e.runtimeType == String && e.toString().trim() == 'null') {
|
||||||
|
103
test/utils/logger_test.dart
Normal file
103
test/utils/logger_test.dart
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user