context: using System.Linq;
  using System.Threading;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using Rubberduck.Inspections.Concrete;
  using Rubberduck.Parsing.VBA;
  using Rubberduck.VBEditor.SafeComWrappers;
  using RubberduckTests.Mocks;
  
  namespace RubberduckTests.Inspections
  {
      [TestClass]
      public class ObjectVariableNotSetInspectionTests
      {
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_OnlyAssignedToNothing_ReturnsResult()
          {
              var expectResultCount = 1;
              var input =
                  @"
  Private Sub DoSomething()
      Dim target As Object
      target.DoSomething ' error 91
      Set target = Nothing
  End Sub
  ";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_AlsoAssignedToNothing_ReturnsNoResult()
          {
              var expectResultCount = 0;
              var input =
                  @"
  Private Sub DoSomething()
      Dim target As Object
      Set target = New Object
      target.DoSomething
      Set target = Nothing
  End Sub
  ";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenIndexerObjectAccess_ReturnsNoResult()
          {
              var expectResultCount = 0;
              var input =
  @"
  Private Sub DoSomething()
      Dim target As Object
      Set target = CreateObject(""Scripting.Dictionary"")
      target(""foo"") = 42
  End Sub
  ";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenPropertyLet_ReturnsNoResult()
          {
              var expectResultCount = 0;
              var input =
                  @"
  Public Property Let Foo(rhs As String)
  End Property
  
  Private Sub DoSomething()
      Foo = 42
  End Sub
  ";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenPropertySet_WithoutSet_ReturnsResult()
          {
              var expectResultCount = 1;
              var input =
                  @"
  Public Property Set Foo(rhs As Object)
  End Property
  
  Private Sub DoSomething()
      Foo = New Object
  End Sub
  ";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenPropertySet_WithSet_ReturnsNoResult()
          {
              var expectResultCount = 0;
              var input =
                  @"
  Public Property Set Foo(rhs As Object)
  End Property
  
  Private Sub DoSomething()
      Set Foo = New Object
  End Sub
  ";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenIndexerObjectAccess_ReturnsResult()
          {
              var expectResultCount = 1;
              var input =
  @"
  Private Sub DoSomething()
      Dim target As Object
      target = CreateObject(""Scripting.Dictionary"")
      target(""foo"") = 42
  End Sub
  ";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenStringVariable_ReturnsNoResult()
          {
              var expectResultCount = 0;
              var input =
  @"
  Private Sub Workbook_Open()
      
      Dim target As String
      target = Range(""A1"")
      
      target.Value = ""all good""
  
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenVariantVariableAssignedObject_ReturnsResult()
          {
              var expectResultCount = 1;
              var input =
  @"
  Private Sub TestSub(ByRef testParam As Variant)
  'whoCares is a LExprContext and is a known interesting declaration
      Dim target As Collection
      Set target = new Collection
      testParam = target             
      testParam.Add 100
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenVariantVariableAssignedNewObject_ReturnsResult()
          {
              var expectResultCount = 1;
              var input =
  @"
  Private Sub TestSub(ByRef testParam As Variant)
  'is a NewExprContext
      testParam = new Collection     
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenVariantVariableAssignedRange_ReturnsResult()
          {
              var expectResultCount = 0;
              var input =
  @"
  Private Sub TestSub(ByRef testParam As Variant)
  'Range(""A1:C1"") is a LExprContext but is not a known interesting declaration
      testParam = Range(""A1:C1"")    
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenVariantVariableAssignedDeclaredRange_ReturnsResult()
          {
              var expectResultCount = 1;
              var input =
  @"
  Private Sub TestSub(ByRef testParam As Variant, target As Range)
  'target is a LExprContext and is a known interesting declaration
      testParam = target
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenVariantVariableAssignedDeclaredVariant_ReturnsNoResult()
          {
              var expectResultCount = 1;
              var input =
  @"
  Private Sub TestSub(ByRef testParam As Variant, target As Range)
  'target is a LExprContext and is a known interesting declaration
      testParam = target
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenVariantVariableAssignedBaseType_ReturnsNoResult()
          {
              var expectResultCount = 0;
              var input =
  @"
  Private Sub Workbook_Open()
      Dim target As Variant
      target = ""A1""     'is a LiteralExprContext
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenObjectVariableNotSet_ReturnsResult()
          {
              var expectResultCount = 1;
              var input =
  @"
  Private Sub Workbook_Open()
      
      Dim target As Range
      target = Range(""A1"")
      
      target.Value = ""forgot something?""
  
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenObjectVariableNotSet_Ignored_DoesNotReturnResult()
          {
              var expectResultCount = 0;
              var input =
  @"
  Private Sub Workbook_Open()
      
      Dim target As Range
  '@Ignore ObjectVariableNotSet
      target = Range(""A1"")
      
      target.Value = ""forgot something?""
  
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_GivenSetObjectVariable_ReturnsNoResult()
          {
              var expectResultCount = 0;
              var input =
  @"
  Private Sub Workbook_Open()
      
      Dim target As Range
      Set target = Range(""A1"")
      
      target.Value = ""All good""
  
  End Sub";
              AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount);
          }
  
          //https://github.com/rubberduck-vba/Rubberduck/issues/2266
          [TestMethod]
          [DeploymentItem(@"Testfiles\")]
          [TestCategory("Inspections")]
          public void ObjectVariableNotSet_FunctionReturnsArrayOfType_ReturnsNoResult()
          {
              var expectedResultCount = 0;
              var input =
  @"
  Private Function GetSomeDictionaries() As Dictionary()
      Dim temp(0 To 1) As Worksheet
      Set temp(0) = New Dictionary
      Set temp(1) = New Dictionary
      GetSomeDictionaries = temp
  End Function";
  
  
gt:             var builder = new MockVbeBuilder();