context: using System.Linq;
  using Microsoft.Vbe.Interop;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using Moq;
  using Rubberduck.Inspections;
  using Rubberduck.Parsing.VBA;
  using Rubberduck.VBEditor.Extensions;
  using Rubberduck.VBEditor.VBEHost;
  using RubberduckTests.Mocks;
  using Rubberduck.Settings;
  using Rubberduck.Inspections.Rubberduck.Inspections;
  using System.Threading;
  using Rubberduck.Parsing;
  
  namespace RubberduckTests.Inspections
  {
      [TestClass]
      public class EmptyStringLiteralInspectionTests
      {
          [TestMethod]
          [TestCategory("Inspections")]
          public void EmptyStringLiteral_ReturnsResult_PassToProcedure()
          {
              const string inputCode =
  @"Public Sub Bar()
      Foo """"
  End Sub
  
  Public Sub Foo(ByRef arg1 As String)
  End Sub";
  
              //Arrange
              var settings = new Mock<IGeneralConfigService>();
              var config = GetTestConfig();
              settings.Setup(x => x.LoadConfiguration()).Returns(config);
  
              var builder = new MockVbeBuilder();
              VBComponent component;
              var vbe = builder.BuildFromSingleStandardModule(inputCode, out component);
              var mockHost = new Mock<IHostApplication>();
              mockHost.SetupAllProperties();
              var parser = MockParser.Create(vbe.Object, new RubberduckParserState(new Mock<ISinks>().Object));
  
              parser.Parse(new CancellationTokenSource());
              if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
  
              var inspection = new EmptyStringLiteralInspection(parser.State);
              var inspector = new Inspector(settings.Object, new IInspection[] { inspection });
  
              var inspectionResults = inspector.FindIssuesAsync(parser.State, CancellationToken.None).Result;
  
              Assert.AreEqual(1, inspectionResults.Count());
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void EmptyStringLiteral_ReturnsResult_Assignment()
          {
              const string inputCode =
  @"Public Sub Foo(ByRef arg1 As String)
      arg1 = """"
  End Sub";
  
              //Arrange
              var settings = new Mock<IGeneralConfigService>();
              var config = GetTestConfig();
              settings.Setup(x => x.LoadConfiguration()).Returns(config);
  
              var builder = new MockVbeBuilder();
              VBComponent component;
              var vbe = builder.BuildFromSingleStandardModule(inputCode, out component);
              var mockHost = new Mock<IHostApplication>();
              mockHost.SetupAllProperties();
              var parser = MockParser.Create(vbe.Object, new RubberduckParserState(new Mock<ISinks>().Object));
  
              parser.Parse(new CancellationTokenSource());
              if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
  
              var inspection = new EmptyStringLiteralInspection(parser.State);
              var inspector = new Inspector(settings.Object, new IInspection[] { inspection });
  
              var inspectionResults = inspector.FindIssuesAsync(parser.State, CancellationToken.None).Result;
  
              Assert.AreEqual(1, inspectionResults.Count());
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void NotEmptyStringLiteral_DoesNotReturnResult()
          {
              const string inputCode =
  @"Public Sub Foo(ByRef arg1 As String)
      arg1 = ""test""
  End Sub";
  
              //Arrange
              var settings = new Mock<IGeneralConfigService>();
              var config = GetTestConfig();
              settings.Setup(x => x.LoadConfiguration()).Returns(config);
  
              var builder = new MockVbeBuilder();
              VBComponent component;
              var vbe = builder.BuildFromSingleStandardModule(inputCode, out component);
              var mockHost = new Mock<IHostApplication>();
              mockHost.SetupAllProperties();
              var parser = MockParser.Create(vbe.Object, new RubberduckParserState(new Mock<ISinks>().Object));
  
              parser.Parse(new CancellationTokenSource());
              if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
  
              var inspection = new EmptyStringLiteralInspection(parser.State);
              var inspector = new Inspector(settings.Object, new IInspection[] { inspection });
  
              var inspectionResults = inspector.FindIssuesAsync(parser.State, CancellationToken.None).Result;
  
              Assert.AreEqual(0, inspectionResults.Count());
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void EmptyStringLiteral_Ignored_DoesNotReturnResult()
          {
              const string inputCode =
  @"Public Sub Foo(ByRef arg1 As String)
      '@Ignore EmptyStringLiteral
      arg1 = """"
  End Sub";
  
              //Arrange
              var settings = new Mock<IGeneralConfigService>();
              var config = GetTestConfig();
              settings.Setup(x => x.LoadConfiguration()).Returns(config);
  
              var builder = new MockVbeBuilder();
              VBComponent component;
              var vbe = builder.BuildFromSingleStandardModule(inputCode, out component);
              var mockHost = new Mock<IHostApplication>();
              mockHost.SetupAllProperties();
              var parser = MockParser.Create(vbe.Object, new RubberduckParserState(new Mock<ISinks>().Object));
  
              parser.Parse(new CancellationTokenSource());
              if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
  
              var inspection = new EmptyStringLiteralInspection(parser.State);
              var inspector = new Inspector(settings.Object, new IInspection[] { inspection });
  
              var inspectionResults = inspector.FindIssuesAsync(parser.State, CancellationToken.None).Result;
  
              Assert.AreEqual(0, inspectionResults.Count());
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void EmptyStringLiteral_QuickFixWorks()
          {
              const string inputCode =
  @"Public Sub Foo(ByRef arg1 As String)
      arg1 = """"
  End Sub";
  
              const string expectedCode =
  @"Public Sub Foo(ByRef arg1 As String)
      arg1 = vbNullString
  End Sub";
  
              //Arrange
              var settings = new Mock<IGeneralConfigService>();
              var config = GetTestConfig();
              settings.Setup(x => x.LoadConfiguration()).Returns(config);
  
              var builder = new MockVbeBuilder();
              VBComponent component;
              var vbe = builder.BuildFromSingleStandardModule(inputCode, out component);
              var project = vbe.Object.VBProjects.Item(0);
              var module = project.VBComponents.Item(0).CodeModule;
              var mockHost = new Mock<IHostApplication>();
              mockHost.SetupAllProperties();
              var parser = MockParser.Create(vbe.Object, new RubberduckParserState(new Mock<ISinks>().Object));
  
              parser.Parse(new CancellationTokenSource());
              if (parser.State.Status >= ParserState.Error) { Assert.Inconclusive("Parser Error"); }
  
              var inspection = new EmptyStringLiteralInspection(parser.State);
              var inspector = new Inspector(settings.Object, new IInspection[] { inspection });
  
              var inspectionResults = inspector.FindIssuesAsync(parser.State, CancellationToken.None).Result;
  
              inspectionResults.First().QuickFixes.First().Fix();
  
              Assert.AreEqual(expectedCode, module.Lines());
          }
  
          [TestMethod]
          [TestCategory("Inspections")]
          public void EmptyStringLiteral_IgnoreQuickFixWorks()
          {
              const string inputCode =
  @"Public Sub Foo(ByRef arg1 As String)
      arg1 = """"
  End Sub";
  
              const string expectedCode =
  @"Public Sub Foo(ByRef arg1 As String)
  '@Ignore EmptyStringLiteral
      arg1 = """"
  End Sub";
  
              //Arrange
  
gt:             var settings = new Mock<IGeneralConfigService>();