-
Notifications
You must be signed in to change notification settings - Fork 579
Expand file tree
/
Copy pathExceptionTest.cs
More file actions
82 lines (69 loc) · 2.87 KB
/
Copy pathExceptionTest.cs
File metadata and controls
82 lines (69 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using Android.App;
using Android.Content;
using Android.Runtime;
using NUnit.Framework;
namespace Xamarin.Android.RuntimeTests {
[TestFixture]
public class ExceptionTest {
static Java.Lang.Throwable CreateJavaProxyThrowable (Exception e)
{
var JavaProxyThrowable_type = typeof (Java.Lang.Object)
.Assembly
.GetType ("Android.Runtime.JavaProxyThrowable");
MethodInfo? create = JavaProxyThrowable_type.GetMethod (
"Create",
BindingFlags.Static | BindingFlags.Public,
new Type[] { typeof (Exception) }
);
Assert.AreNotEqual (null, create, "Unable to find the Android.Runtime.JavaProxyThrowable.Create(Exception) method");
return (Java.Lang.Throwable)create.Invoke (null, new object[] { e }); // Don't append Java stack trace
}
[Test]
public void InnerExceptionIsSet ()
{
Exception ex;
try {
throw new InvalidOperationException ("boo!");
} catch (Exception e) {
ex = e;
}
using Java.Lang.Throwable proxy = CreateJavaProxyThrowable (ex);
using var source = new Java.Lang.Throwable ("detailMessage", proxy);
using var alias = new Java.Lang.Throwable (source.Handle, JniHandleOwnership.DoNotTransfer);
CompareStackTraces (ex, proxy);
Assert.AreEqual ("detailMessage", alias.Message);
Assert.AreSame (ex, alias.InnerException);
}
void CompareStackTraces (Exception ex, Java.Lang.Throwable throwable)
{
var managedTrace = new StackTrace (ex);
StackFrame[] managedFrames = managedTrace.GetFrames ();
Java.Lang.StackTraceElement[] javaFrames = throwable.GetStackTrace ();
// Java
Assert.IsTrue (javaFrames.Length >= managedFrames.Length,
$"Java should have at least as many frames as .NET does; java({javaFrames.Length}) < managed({managedFrames.Length})");
for (int i = 0; i < managedFrames.Length; i++) {
var mf = managedFrames[i];
var jf = javaFrames[i];
// Unknown line locations are -1 on the Java side if they're managed, -2 if they're native
int managedLine = mf.GetFileLineNumber ();
if (managedLine == 0) {
managedLine = mf.HasNativeImage () ? -2 : -1;
}
if (managedLine > 0) {
Assert.AreEqual (mf.GetMethod ()?.Name, jf.MethodName, $"Frame {i}: method names differ");
} else {
string managedMethodName = mf.GetMethod ()?.Name ?? String.Empty;
Assert.IsTrue (jf.MethodName.StartsWith ($"{managedMethodName} + 0x"), $"Frame {i}: method name should start with: '{managedMethodName} + 0x'");
}
Assert.AreEqual (mf.GetMethod ()?.DeclaringType.FullName, jf.ClassName, $"Frame {i}: class names differ");
Assert.AreEqual (mf.GetFileName (), jf.FileName, $"Frame {i}: file names differ");
Assert.AreEqual (managedLine, jf.LineNumber, $"Frame {i}: line numbers differ");
}
}
}
}