Compare commits
1
Commits
main
...
issue-150-fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab2363fd2b |
@@ -15,6 +15,8 @@ class CrashScreen extends StatelessWidget {
|
|||||||
final Object exception;
|
final Object exception;
|
||||||
final StackTrace? stackTrace;
|
final StackTrace? stackTrace;
|
||||||
|
|
||||||
|
static const _gitHash = String.fromEnvironment('GIT_HASH');
|
||||||
|
|
||||||
Future<String> _buildReport() async {
|
Future<String> _buildReport() async {
|
||||||
String version = 'unknown';
|
String version = 'unknown';
|
||||||
try {
|
try {
|
||||||
@@ -23,7 +25,11 @@ class CrashScreen extends StatelessWidget {
|
|||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
final platform =
|
final platform =
|
||||||
'${Platform.operatingSystem} ${Platform.operatingSystemVersion}';
|
'${Platform.operatingSystem} ${Platform.operatingSystemVersion}';
|
||||||
|
final gitLine = _gitHash.isNotEmpty
|
||||||
|
? 'Git Commit: [$_gitHash](https://codeberg.org/guettli/sharedinbox/commit/$_gitHash)\n'
|
||||||
|
: '';
|
||||||
return 'App Version: $version\n'
|
return 'App Version: $version\n'
|
||||||
|
'$gitLine'
|
||||||
'Platform: $platform\n\n'
|
'Platform: $platform\n\n'
|
||||||
'Error:\n```\n$exception\n```\n\n'
|
'Error:\n```\n$exception\n```\n\n'
|
||||||
'Stack Trace:\n```\n$stackTrace\n```';
|
'Stack Trace:\n```\n$stackTrace\n```';
|
||||||
@@ -92,6 +98,32 @@ class CrashScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
if (_gitHash.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
const Text(
|
||||||
|
'Git Commit:',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
final url = Uri.parse(
|
||||||
|
'https://codeberg.org/guettli/sharedinbox/commit/$_gitHash',
|
||||||
|
);
|
||||||
|
await launchUrl(
|
||||||
|
url,
|
||||||
|
mode: LaunchMode.externalApplication,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text(
|
||||||
|
_gitHash,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.blue,
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
@@ -76,6 +77,52 @@ void main() {
|
|||||||
expect(mock.launchedUrl, isNot(contains('Stack%20Trace')));
|
expect(mock.launchedUrl, isNot(contains('Stack%20Trace')));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'CrashScreen copy-to-clipboard includes version and platform info',
|
||||||
|
(tester) async {
|
||||||
|
tester.view.physicalSize = const Size(800, 1200);
|
||||||
|
tester.view.devicePixelRatio = 1.0;
|
||||||
|
addTearDown(() => tester.view.resetPhysicalSize());
|
||||||
|
|
||||||
|
String? clipboardText;
|
||||||
|
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(
|
||||||
|
SystemChannels.platform,
|
||||||
|
(MethodCall call) async {
|
||||||
|
if (call.method == 'Clipboard.setData') {
|
||||||
|
clipboardText =
|
||||||
|
(call.arguments as Map<dynamic, dynamic>)['text'] as String?;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
addTearDown(
|
||||||
|
() => tester.binding.defaultBinaryMessenger
|
||||||
|
.setMockMethodCallHandler(SystemChannels.platform, null),
|
||||||
|
);
|
||||||
|
|
||||||
|
const exception = 'TestException: clipboard test';
|
||||||
|
final stackTrace = StackTrace.current;
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: CrashScreen(exception: exception, stackTrace: stackTrace),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.tap(find.text('Copy to Clipboard'));
|
||||||
|
await tester.pump();
|
||||||
|
await tester.pump();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(clipboardText, isNotNull);
|
||||||
|
expect(clipboardText, contains('App Version: 1.0.0+42'));
|
||||||
|
expect(clipboardText, contains('Platform:'));
|
||||||
|
expect(clipboardText, contains('TestException: clipboard test'));
|
||||||
|
// GIT_HASH is empty in test builds — no Git Commit line expected
|
||||||
|
expect(clipboardText, isNot(contains('Git Commit:')));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'CrashScreen used as root widget — buttons work without ScaffoldMessenger crash',
|
'CrashScreen used as root widget — buttons work without ScaffoldMessenger crash',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
|
|||||||
Reference in New Issue
Block a user