|
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
' These tests specifically cover late binding scenarios
Option Strict Off
Imports System.Dynamic
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.VisualStudio.Debugger.Clr
Imports Microsoft.VisualStudio.Debugger.Evaluation
Imports Roslyn.Test.Utilities
Imports Xunit
Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.UnitTests
Public Class DynamicViewTests : Inherits VisualBasicResultProviderTestBase
<Fact>
Public Sub MultipleMembers()
Dim expression = "o"
Dim o As Object = New ExpandoObject()
o.Philosophers = New Object() {"Pythagoras", "Lucretius", "Zeno"}
o.WhatsForDinner = "Crab Cakes"
o.NumForks = 2
Dim type = New DkmClrType(CType(o.GetType(), TypeImpl))
Dim value = CreateDkmClrValue(o, type)
Dim result = FormatResult(expression, value)
Verify(result,
EvalResult(expression, "{System.Dynamic.ExpandoObject}", "System.Dynamic.ExpandoObject", expression, DkmEvaluationResultFlags.Expandable))
Dim dynamicView = GetChildren(result).Last()
Verify(dynamicView,
EvalResult(Resources.DynamicView, Resources.DynamicViewValueWarning, "", "o, dynamic", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
Verify(GetChildren(dynamicView),
EvalResult("NumForks", "2", "System.Int32", "New Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView(o).Items(0)", DkmEvaluationResultFlags.ReadOnly),
EvalResult("Philosophers", "{Length=3}", "System.Object[]", "New Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView(o).Items(1)", DkmEvaluationResultFlags.ReadOnly),
EvalResult("WhatsForDinner", """Crab Cakes""", "System.String", "New Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView(o).Items(2)", DkmEvaluationResultFlags.ReadOnly))
End Sub
<Fact>
Public Sub MultipleExpansions()
Dim expression = "o"
Dim o As Object = New ExpandoObject()
o.Answer = 42
Dim type = New DkmClrType(CType(o.GetType(), TypeImpl))
Dim value = CreateDkmClrValue(o, type)
' Dynamic View should appear after all other expansions.
Dim result = FormatResult(expression, value)
Verify(result,
EvalResult(expression, "{System.Dynamic.ExpandoObject}", "System.Dynamic.ExpandoObject", expression, DkmEvaluationResultFlags.Expandable))
Verify(GetChildren(result),
EvalResult("[Class]", "{System.Dynamic.ExpandoClass}", "System.Dynamic.ExpandoClass", "o.[Class]", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly Or DkmEvaluationResultFlags.CanFavorite, DkmEvaluationResultCategory.Property, DkmEvaluationResultAccessType.Internal),
EvalResult("LockObject", "{Object}", "Object", "o.LockObject", DkmEvaluationResultFlags.ReadOnly Or DkmEvaluationResultFlags.CanFavorite, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.Internal),
EvalResult("System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Object)).Count", "1", "Integer", "DirectCast(o, System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Object))).Count", DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Property, DkmEvaluationResultAccessType.Private),
EvalResult("System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Object)).IsReadOnly", "False", "Boolean", "DirectCast(o, System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of String, Object))).IsReadOnly", DkmEvaluationResultFlags.Boolean Or DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Property, DkmEvaluationResultAccessType.Private),
EvalResult("System.Collections.Generic.IDictionary(Of String, Object).Keys", "Count = 1", "System.Collections.Generic.ICollection(Of String) {System.Dynamic.ExpandoObject.KeyCollection}", "DirectCast(o, System.Collections.Generic.IDictionary(Of String, Object)).Keys", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Property, DkmEvaluationResultAccessType.Private),
EvalResult("System.Collections.Generic.IDictionary(Of String, Object).Values", "Count = 1", "System.Collections.Generic.ICollection(Of Object) {System.Dynamic.ExpandoObject.ValueCollection}", "DirectCast(o, System.Collections.Generic.IDictionary(Of String, Object)).Values", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Property, DkmEvaluationResultAccessType.Private),
EvalResult("_count", "1", "Integer", "o._count", DkmEvaluationResultFlags.CanFavorite, category:=DkmEvaluationResultCategory.Data, access:=DkmEvaluationResultAccessType.Private),
EvalResult("_data", "{System.Dynamic.ExpandoObject.ExpandoData}", "System.Dynamic.ExpandoObject.ExpandoData", "o._data", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.CanFavorite, DkmEvaluationResultCategory.Data, DkmEvaluationResultAccessType.Private),
EvalResult("_propertyChanged", "Nothing", "System.ComponentModel.PropertyChangedEventHandler", "o._propertyChanged", DkmEvaluationResultFlags.CanFavorite, category:=DkmEvaluationResultCategory.Data, access:=DkmEvaluationResultAccessType.Private),
EvalResult(Resources.SharedMembers, Nothing, "", "System.Dynamic.ExpandoObject", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Class),
EvalResult(Resources.DynamicView, Resources.DynamicViewValueWarning, "", "o, dynamic", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
End Sub
<Fact>
Public Sub ExceptionTypeMember()
Dim expression = "o"
Dim o As Object = New ExpandoObject()
Dim exception = New NotImplementedException()
o.Member = exception
Dim type = New DkmClrType(CType(o.GetType(), TypeImpl))
Dim value = CreateDkmClrValue(o, type)
Dim result = FormatResult(expression, value)
Verify(result,
EvalResult(expression, "{System.Dynamic.ExpandoObject}", "System.Dynamic.ExpandoObject", expression, DkmEvaluationResultFlags.Expandable))
Dim dynamicView = GetChildren(result).Last()
Verify(dynamicView,
EvalResult(Resources.DynamicView, Resources.DynamicViewValueWarning, "", "o, dynamic", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
Verify(GetChildren(dynamicView),
EvalResult("Member", $"{{{exception.ToString()}}}", "System.NotImplementedException", "New Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView(o).Items(0)", DkmEvaluationResultFlags.ReadOnly))
End Sub
<Fact>
Public Sub DynamicTypeMember()
Dim expression = "o"
Dim o As Object = New ExpandoObject()
o.Pi = Math.PI
o.OnAndOn = o
Dim type = New DkmClrType(CType(o.GetType(), TypeImpl))
Dim value = CreateDkmClrValue(o, type)
Dim result = FormatResult(expression, value)
Verify(result,
EvalResult(expression, "{System.Dynamic.ExpandoObject}", "System.Dynamic.ExpandoObject", expression, DkmEvaluationResultFlags.Expandable))
Dim members = GetChildren(result)
Dim fullNameOnAndOn = "o"
Dim fullNamePi = "o"
' Expand 3 levels...
For i = 1 To 3
Dim dynamicView = members.Last()
Verify(dynamicView,
EvalResult(Resources.DynamicView, Resources.DynamicViewValueWarning, "", $"{fullNameOnAndOn}, dynamic", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
members = GetChildren(dynamicView)
fullNamePi = $"New Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView({fullNameOnAndOn}).Items(1)"
fullNameOnAndOn = $"New Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView({fullNameOnAndOn}).Items(0)"
Verify(members,
EvalResult("OnAndOn", "{System.Dynamic.ExpandoObject}", "System.Dynamic.ExpandoObject", fullNameOnAndOn, DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly),
EvalResult("Pi", "3.1415926535897931", "System.Double", fullNamePi, DkmEvaluationResultFlags.ReadOnly))
members = GetChildren(members(0))
Next
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/5667")>
Public Sub NoMembers()
Using New EnsureEnglishUICulture()
Dim expression = "o"
Dim o As Object = New ExpandoObject()
Dim type = New DkmClrType(CType(o.GetType(), TypeImpl))
Dim value = CreateDkmClrValue(o, type)
Dim result = FormatResult(expression, value)
Verify(result,
EvalResult(expression, "{System.Dynamic.ExpandoObject}", "System.Dynamic.ExpandoObject", expression, DkmEvaluationResultFlags.Expandable))
Dim dynamicView = GetChildren(result).Last()
Verify(dynamicView,
EvalResult(Resources.DynamicView, Resources.DynamicViewValueWarning, "", "o, dynamic", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
Verify(GetChildren(dynamicView),
EvalFailedResult(Resources.ErrorName, GetDynamicDebugViewEmptyMessage()))
End Using
End Sub
<Fact>
Public Sub NullComObject()
Dim comObjectTypeName = "System.__ComObject"
Dim expression = $"DirectCast(Nothing, {comObjectTypeName})"
Dim type = New DkmClrType(CType(GetType(Object).Assembly.GetType(comObjectTypeName), TypeImpl))
Dim value = CreateDkmClrValue(Nothing, type)
Dim result = FormatResult(expression, value)
Verify(result,
EvalResult(expression, "Nothing", comObjectTypeName, expression))
result = FormatResult(expression, expression + ",dynamic", value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalFailedResult(expression, Resources.DynamicViewNotDynamic))
End Sub
<Fact>
Public Sub NullIDynamicMetaObjectProvider()
Dim expression = "o"
Dim type = New DkmClrType(CType(GetType(IDynamicMetaObjectProvider), TypeImpl))
Dim value = CreateDkmClrValue(Nothing, type)
Dim result = FormatResult(expression, value)
Verify(result,
EvalResult(expression, "Nothing", "System.Dynamic.IDynamicMetaObjectProvider", expression))
result = FormatResult(expression, expression + ",dynamic", value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalFailedResult(expression, Resources.DynamicViewNotDynamic))
End Sub
<Fact>
Public Sub NullDynamicObject()
Dim expression = "o"
Dim type = New DkmClrType(CType(GetType(ExpandoObject), TypeImpl))
Dim value = CreateDkmClrValue(Nothing, type)
Dim result = FormatResult(expression, value)
Verify(result,
EvalResult(expression, "Nothing", "System.Dynamic.ExpandoObject", expression, DkmEvaluationResultFlags.Expandable))
Verify(GetChildren(result),
EvalResult(Resources.SharedMembers, Nothing, "", "System.Dynamic.ExpandoObject", DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly, DkmEvaluationResultCategory.Class))
result = FormatResult(expression, expression + ",dynamic", value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalFailedResult(expression, Resources.DynamicViewNotDynamic))
End Sub
<Fact>
Public Sub DynamicTypeError()
Dim expression = "o"
Dim obj = New ExpandoObject()
' Verify that things *work* in this scenario if there was no error in member access.
Dim value = CreateDkmClrValue(obj)
Dim fullName = expression + ", dynamic"
Dim result = FormatResult(expression, fullName, value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalResult(expression, Resources.DynamicViewValueWarning, "", fullName, DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
' Verify no Dynamic View if member access is changed to result in an error.
Dim runtime = New DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlibAndSystemCore())
value = CreateErrorValue(runtime.GetType(obj.GetType()), "Function evaluation timed out")
result = FormatResult(expression, fullName, value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalFailedResult(expression, Resources.DynamicViewNotDynamic))
End Sub
<Fact>
Public Sub DynamicMetaObjectProviderDebugViewItemsError()
Dim expression = "o"
Dim o As Object = New ExpandoObject()
o.Answer = 42
Dim runtime As DkmClrRuntimeInstance = Nothing
runtime = New DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlib(),
getMemberValue:=Function(v, m) If(m = "Items", CreateErrorValue(runtime.GetType(GetType(Array)), "Function evaluation timed out"), Nothing))
Dim type = New DkmClrType(runtime, CType(o.GetType(), TypeImpl))
Dim value = CreateDkmClrValue(o, type)
Dim fullName = expression + ", dynamic"
Dim result = FormatResult(expression, fullName, value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalResult(expression, Resources.DynamicViewValueWarning, "", fullName, DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
Verify(GetChildren(result),
EvalFailedResult(Resources.ErrorName, "Function evaluation timed out"))
End Sub
<Fact>
Public Sub DynamicMetaObjectProviderDebugViewItemsException()
Dim expression = "o"
Dim fullName = expression + ", dynamic"
Dim o As Object = New ExpandoObject()
o.Answer = 42
Dim runtime As DkmClrRuntimeInstance = Nothing
Dim getExceptionValue = Function() CreateDkmClrValue(New NotImplementedException(), evalFlags:=DkmEvaluationResultFlags.ExceptionThrown)
runtime = New DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlib(), getMemberValue:=Function(v, m) If(m = "Items", getExceptionValue(), Nothing))
Dim type = New DkmClrType(runtime, CType(o.GetType(), TypeImpl))
Dim value = CreateDkmClrValue(o, type)
Dim result = FormatResult(expression, fullName, value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalResult(expression, Resources.DynamicViewValueWarning, "", fullName, DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
Dim members = GetChildren(result)
Assert.Equal(32, members.Length)
Verify(members(1),
EvalResult("HResult", "-2147467263", "Integer", Nothing, category:=DkmEvaluationResultCategory.Property, access:=DkmEvaluationResultAccessType.Public))
getExceptionValue = Function() CreateDkmClrValue(New NotImplementedException())
result = FormatResult(expression, fullName, value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalResult(expression, Resources.DynamicViewValueWarning, "", fullName, DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
members = GetChildren(result)
Assert.Equal(32, members.Length)
Verify(members(1),
EvalResult("HResult", "-2147467263", "Integer", "DirectCast(New Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView(o).Items, System.Exception).HResult", category:=DkmEvaluationResultCategory.Property, access:=DkmEvaluationResultAccessType.Public))
End Sub
<Fact>
Public Sub DynamicFormatSpecifier()
Dim expression = "o"
Dim o As Object = New ExpandoObject()
o.Answer = 42
Dim type = New DkmClrType(CType(o.GetType(), TypeImpl))
Dim value = CreateDkmClrValue(o, type)
Dim fullName = expression + ", dynamic"
Dim result = FormatResult(expression, fullName, value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalResult(expression, Resources.DynamicViewValueWarning, "", fullName, DkmEvaluationResultFlags.Expandable Or DkmEvaluationResultFlags.ReadOnly))
Verify(GetChildren(result),
EvalResult("Answer", "42", "System.Int32", "New Microsoft.CSharp.RuntimeBinder.DynamicMetaObjectProviderDebugView(o).Items(0)", DkmEvaluationResultFlags.ReadOnly))
End Sub
<Fact>
Public Sub DynamicFormatSpecifierError()
Dim expression = "o"
Dim o = New Object()
Dim type = New DkmClrType(CType(o.GetType(), TypeImpl))
Dim value = CreateDkmClrValue(o, type)
Dim result = FormatResult(expression, expression + ",dynamic", value, inspectionContext:=CreateDkmInspectionContext(DkmEvaluationFlags.DynamicView))
Verify(result,
EvalFailedResult(expression, Resources.DynamicViewNotDynamic))
End Sub
End Class
End Namespace
|