Skip to content

Commit

Permalink
Fix SpecFlow extension compatibility (#25)
Browse files Browse the repository at this point in the history
* remove duplicate classification names

* Make a separate interface for IFileSystem

* Make a separate interface for IContextInitializer

* Update CHANGELOG.md
  • Loading branch information
gasparnagy authored Jun 14, 2024
1 parent 0c08f15 commit a7869f0
Show file tree
Hide file tree
Showing 26 changed files with 79 additions and 58 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

## Improvements:

* Find Unused Step Definitions Command: Improved handling of Step Definitions decorated with the 'StepDefinition' attribute. If a Step Definition is used in any Given/Then/When step in a Feature file, the step will no longer show in the 'Find Unused Step Definitions' context menu.
* Find Unused Step Definitions Command: Improved handling of Step Definitions decorated with the 'StepDefinition' attribute. If a Step Definition is used in any Given/Then/When step in a Feature file, the step will no longer show in the 'Find Unused Step Definitions' context menu. (#24)

*Contributors of this release (in alphabetical order):* @UL-ChrisGlew
## Bug fixes:

* Fix: Using the extension side-by-side with the SpecFlow for Visual Studio extension causes CompositionFailedException (#25)

*Contributors of this release (in alphabetical order):* @gasparnagy, @UL-ChrisGlew

# v2024.2.93 - 2024-06-05

Expand Down
4 changes: 2 additions & 2 deletions Reqnroll.VisualStudio.Package/ProjectSystem/NullVsIdeScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public NullVsIdeScope(IDeveroomLogger logger, IServiceProvider serviceProvider,
MonitoringService = monitoringService;
ServiceProvider = serviceProvider;
WindowManager = new DeveroomWindowManager(serviceProvider, monitoringService);
FileSystem = new FileSystem();
FileSystem = new FileSystemForVs();
Actions = new NullIdeActions(this);
Dte = null;
DeveroomOutputPaneServices = null;
Expand All @@ -26,7 +26,7 @@ public NullVsIdeScope(IDeveroomLogger logger, IServiceProvider serviceProvider,
public IMonitoringService MonitoringService { get; }
public IIdeActions Actions { get; }
public IDeveroomWindowManager WindowManager { get; }
public IFileSystem FileSystem { get; }
public IFileSystemForVs FileSystem { get; }

public event EventHandler<EventArgs> WeakProjectsBuilt
{
Expand Down
4 changes: 2 additions & 2 deletions Reqnroll.VisualStudio.Package/ProjectSystem/VsIdeScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ private readonly ConcurrentDictionary<string, VsProjectScope>
[ImportingConstructor]
public VsIdeScope([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider,
IVsSolutionEventListener solutionEventListener, IMonitoringService monitoringService,
IDeveroomWindowManager windowManager, IFileSystem fileSystem, DeveroomCompositeLogger compositeLogger)
IDeveroomWindowManager windowManager, IFileSystemForVs fileSystem, DeveroomCompositeLogger compositeLogger)
{
Logger = compositeLogger;
ServiceProvider = serviceProvider;
Expand Down Expand Up @@ -65,7 +65,7 @@ public VsIdeScope([Import(typeof(SVsServiceProvider))] IServiceProvider serviceP
public IMonitoringService MonitoringService { get; }
public IIdeActions Actions { get; }
public IDeveroomWindowManager WindowManager { get; }
public IFileSystem FileSystem { get; }
public IFileSystemForVs FileSystem { get; }
public IDeveroomOutputPaneServices DeveroomOutputPaneServices { get; }
public IDeveroomErrorListServices DeveroomErrorListServices { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ private static IDeveroomLogger GetSafeLogger(IServiceProvider serviceProvider)
{
try
{
var fileSystem = VsUtils.ResolveMefDependency<IFileSystem>(serviceProvider);
var fileSystem = VsUtils.ResolveMefDependency<IFileSystemForVs>(serviceProvider);
var asyncLogger = AsynchronousFileLogger.CreateInstance(fileSystem);
var compositeLogger = VsUtils.ResolveMefDependency<DeveroomCompositeLogger>(serviceProvider);
compositeLogger.Add(asyncLogger);
Expand Down Expand Up @@ -114,7 +114,7 @@ private void MonitorLoadProjectSystem()

public IDeveroomWindowManager WindowManager => VsIdeScope.WindowManager;

public IFileSystem FileSystem => VsIdeScope.FileSystem;
public IFileSystemForVs FileSystem => VsIdeScope.FileSystem;

public event EventHandler<EventArgs> WeakProjectsBuilt
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ namespace Reqnroll.VisualStudio.Analytics;
[Export(typeof(ITelemetryConfigurationHolder))]
public class ApplicationInsightsConfigurationHolder : ITelemetryConfigurationHolder
{
private readonly IContextInitializer _contextInitializer;
private readonly IReqnrollContextInitializer _contextInitializer;

[ImportingConstructor]
public ApplicationInsightsConfigurationHolder(IContextInitializer contextInitializer)
public ApplicationInsightsConfigurationHolder(IReqnrollContextInitializer contextInitializer)
{
_contextInitializer = contextInitializer;
}
Expand Down
4 changes: 2 additions & 2 deletions Reqnroll.VisualStudio/Analytics/IUserUniqueIdStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ public interface IUserUniqueIdStore
public class FileUserIdStore : IUserUniqueIdStore
{
public static readonly string UserIdFilePath = Environment.ExpandEnvironmentVariables(@"%APPDATA%\Reqnroll\userid");
private readonly IFileSystem _fileSystem;
private readonly IFileSystemForVs _fileSystem;

private readonly Lazy<string> _lazyUniqueUserId;

[ImportingConstructor]
public FileUserIdStore(IFileSystem fileSystem)
public FileUserIdStore(IFileSystemForVs fileSystem)
{
_fileSystem = fileSystem;
_lazyUniqueUserId = new Lazy<string>(FetchAndPersistUserId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
namespace Reqnroll.VisualStudio.Analytics;

[System.Composition.Export(typeof(IContextInitializer))]
public class ReqnrollTelemetryContextInitializer : IContextInitializer
// We cannot directly use IContextInitializer as dependency (with MEF), because there might be other extensions (e.g. SpecFlow)
// that also export an implementation of IContextInitializer. We need to have a separate contract for "our" context initializer.
public interface IReqnrollContextInitializer : IContextInitializer
{
}

[System.Composition.Export(typeof(IReqnrollContextInitializer))]
public class ReqnrollTelemetryContextInitializer : IReqnrollContextInitializer
{
private readonly IUserUniqueIdStore _userUniqueIdStore;
private readonly IVersionProvider _versionProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ namespace Reqnroll.VisualStudio.Configuration;
public class DeveroomConfigurationLoader
{
private readonly IConfigDeserializer<DeveroomConfiguration> _configDeserializer;
private readonly IFileSystem _fileSystem;
private readonly IFileSystemForVs _fileSystem;

private DeveroomConfigurationLoader(
IConfigDeserializer<DeveroomConfiguration> configDeserializer,
IFileSystem fileSystem)
IFileSystemForVs fileSystem)
{
_configDeserializer = configDeserializer;
_fileSystem = fileSystem;
}

public static DeveroomConfigurationLoader CreateReqnrollJsonConfigurationLoader(IFileSystem fileSystem) =>
public static DeveroomConfigurationLoader CreateReqnrollJsonConfigurationLoader(IFileSystemForVs fileSystem) =>
new(new ReqnrollConfigDeserializer(), fileSystem);

public static DeveroomConfigurationLoader CreateDeveroomJsonConfigurationLoader(IFileSystem fileSystem) =>
public static DeveroomConfigurationLoader CreateDeveroomJsonConfigurationLoader(IFileSystemForVs fileSystem) =>
new(new JsonNetConfigDeserializer<DeveroomConfiguration>(), fileSystem);

public DeveroomConfiguration Load(string configFilePath)
Expand Down
6 changes: 3 additions & 3 deletions Reqnroll.VisualStudio/Diagnostics/AsynchronousFileLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ namespace Reqnroll.VisualStudio.Diagnostics;
public class AsynchronousFileLogger : IDeveroomLogger, IDisposable
{
private readonly Channel<LogMessage> _channel;
private readonly IFileSystem _fileSystem;
private readonly IFileSystemForVs _fileSystem;
private readonly CancellationTokenSource _stopTokenSource;

protected AsynchronousFileLogger(IFileSystem fileSystem, TraceLevel level)
protected AsynchronousFileLogger(IFileSystemForVs fileSystem, TraceLevel level)
{
_fileSystem = fileSystem;
Level = level;
Expand Down Expand Up @@ -41,7 +41,7 @@ internal static string GetLogFile()
#endif
}

public static AsynchronousFileLogger CreateInstance(IFileSystem fileSystem)
public static AsynchronousFileLogger CreateInstance(IFileSystemForVs fileSystem)
{
var fileLogger = new AsynchronousFileLogger(fileSystem, TraceLevel.Verbose);
Task.Factory.StartNew(
Expand Down
2 changes: 1 addition & 1 deletion Reqnroll.VisualStudio/Diagnostics/SynchronousFileLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace Reqnroll.VisualStudio.Diagnostics;
public class SynchronousFileLogger : AsynchronousFileLogger
{
public SynchronousFileLogger()
: base(new FileSystem(), TraceLevel.Verbose)
: base(new FileSystemForVs(), TraceLevel.Verbose)
{
EnsureLogFolder();
}
Expand Down
2 changes: 1 addition & 1 deletion Reqnroll.VisualStudio/Discovery/DiscoveryInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal class DiscoveryInvoker
{
private readonly IDiscoveryResultProvider _discoveryResultProvider;
private readonly IDeveroomErrorListServices _errorListServices;
private readonly IFileSystem _fileSystem;
private readonly IFileSystemForVs _fileSystem;
private readonly IDeveroomLogger _logger;
private readonly IMonitoringService _monitoringService;
private readonly IProjectScope _projectScope;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ namespace Reqnroll.VisualStudio.Editor.Classification;

internal static class DeveroomClassifications
{
public const string Keyword = "deveroom.keyword";
public const string Tag = "deveroom.tag";
public const string Description = "deveroom.description";
public const string Comment = "deveroom.comment";
public const string DocString = "deveroom.doc_string";
public const string DataTable = "deveroom.data_table";
public const string DataTableHeader = "deveroom.data_table_header";

public const string UndefinedStep = "deveroom.undefined_step";
public const string StepParameter = "deveroom.step_parameter";
public const string ScenarioOutlinePlaceholder = "deveroom.scenario_outline_placeholder";
public const string Keyword = "reqnroll.keyword";
public const string Tag = "reqnroll.tag";
public const string Description = "reqnroll.description";
public const string Comment = "reqnroll.comment";
public const string DocString = "reqnroll.doc_string";
public const string DataTable = "reqnroll.data_table";
public const string DataTableHeader = "reqnroll.data_table_header";

public const string UndefinedStep = "reqnroll.undefined_step";
public const string StepParameter = "reqnroll.step_parameter";
public const string ScenarioOutlinePlaceholder = "reqnroll.scenario_outline_placeholder";

// This disables "The field is never used" compiler's warning. Justification: the field is used by MEF.
#pragma warning disable 169
Expand Down Expand Up @@ -203,7 +203,7 @@ public GherkinScenarioOutlinePlaceholderClassificationFormat()


#if DEBUG
public const string DebugMarker = "deveroom.debug_marker";
public const string DebugMarker = "reqnroll.debug_marker";

[Export] [Name(DebugMarker)] private static ClassificationTypeDefinition _debugEditorClassificationTypeDefinition;

Expand Down
2 changes: 1 addition & 1 deletion Reqnroll.VisualStudio/FileSystemExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Reqnroll.VisualStudio;

public static class FileSystemExtensions
{
public static string GetFilePathIfExists(this IFileSystem fileSystem, string filePath)
public static string GetFilePathIfExists(this IFileSystemForVs fileSystem, string filePath)
{
if (fileSystem.File.Exists(filePath))
return filePath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@

namespace Reqnroll.VisualStudio;

[Export(typeof(IFileSystem))]
public class FileSystemWrapper : IFileSystem
// We cannot directly use IFileSystem as dependency (with MEF), because there might be other extensions (e.g. SpecFlow)
// that also export an implementation of IFileSystem. We need to have a separate contract for "our" file system.
public interface IFileSystemForVs : IFileSystem
{
private readonly IFileSystem _fileSystem = new FileSystem();

}

[Export(typeof(IFileSystemForVs))]
public class FileSystemForVs : IFileSystemForVs
{
private readonly FileSystem _fileSystem = new();

public IFile File => _fileSystem.File;
public IDirectory Directory => _fileSystem.Directory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public record ConfigSource(string FilePath, DateTimeOffset LastChangeTime, strin
{
public bool IsValid => !string.IsNullOrEmpty(FilePath);

public static ConfigSource TryGetConfigSource(string filePath, IFileSystem fileSystem, IDeveroomLogger logger)
public static ConfigSource TryGetConfigSource(string filePath, IFileSystemForVs fileSystem, IDeveroomLogger logger)
{
if (string.IsNullOrEmpty(filePath))
return CreateInvalid("Test assembly path could not be detected, therefore some Reqnroll Visual Studio Extension features are disabled. Try to rebuild the project or restart Visual Studio.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public ProjectScopeDeveroomConfigurationProvider([NotNull] IProjectScope project

private IDeveroomLogger Logger => _projectScope.IdeScope.Logger;
private IMonitoringService MonitoringService => _projectScope.IdeScope.MonitoringService;
private IFileSystem FileSystem => _projectScope.IdeScope.FileSystem;
private IFileSystemForVs FileSystem => _projectScope.IdeScope.FileSystem;

public event EventHandler<EventArgs> WeakConfigurationChanged
{
Expand Down
2 changes: 1 addition & 1 deletion Reqnroll.VisualStudio/ProjectSystem/IIdeScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public interface IIdeScope
IDeveroomWindowManager WindowManager { get; }
IDeveroomOutputPaneServices DeveroomOutputPaneServices { get; }
IDeveroomErrorListServices DeveroomErrorListServices { get; }
IFileSystem FileSystem { get; }
IFileSystemForVs FileSystem { get; }
IProjectScope? GetProject(ITextBuffer textBuffer);
event EventHandler<EventArgs> WeakProjectsBuilt;
event EventHandler<EventArgs> WeakProjectOutputsUpdated;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ internal class ReqnrollPackageDetector
new(SpecSyncPackageRe)
};

private readonly IFileSystem _fileSystem;
private readonly IFileSystemForVs _fileSystem;

public ReqnrollPackageDetector(IFileSystem fileSystem)
public ReqnrollPackageDetector(IFileSystemForVs fileSystem)
{
_fileSystem = fileSystem;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ internal class SpecFlowPackageDetector
new(SpecSyncPackageRe)
};

private readonly IFileSystem _fileSystem;
private readonly IFileSystemForVs _fileSystem;

public SpecFlowPackageDetector(IFileSystem fileSystem)
public SpecFlowPackageDetector(IFileSystemForVs fileSystem)
{
_fileSystem = fileSystem;
}
Expand Down
4 changes: 2 additions & 2 deletions Reqnroll.VisualStudio/ProjectSystem/WelcomeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public interface IWelcomeService
public class WelcomeService : IWelcomeService
{
private static DispatcherTimer _welcomeMessageTimer;
private readonly IFileSystem _fileSystem;
private readonly IFileSystemForVs _fileSystem;
private readonly IGuidanceConfiguration _guidanceConfiguration;
private readonly IRegistryManager _registryManager;
private readonly IServiceProvider _serviceProvider;
Expand All @@ -22,7 +22,7 @@ public class WelcomeService : IWelcomeService
[ImportingConstructor]
public WelcomeService([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider,
IRegistryManager registryManager, IVersionProvider versionProvider,
IGuidanceConfiguration guidanceConfiguration, IFileSystem fileSystem)
IGuidanceConfiguration guidanceConfiguration, IFileSystemForVs fileSystem)
{
_serviceProvider = serviceProvider;
_registryManager = registryManager;
Expand Down
4 changes: 2 additions & 2 deletions Reqnroll.VisualStudio/WindowsFileAssociationDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ public class WindowsFileAssociationDetector
private const string ProgId = "Reqnroll.GherkinFile";
private const string FriendlyTypeName = "Gherkin Specification File for Reqnroll";

private readonly IFileSystem _fileSystem;
private readonly IFileSystemForVs _fileSystem;
private readonly IIdeScope _ideScope;

public WindowsFileAssociationDetector(IFileSystem fileSystem, IIdeScope ideScope)
public WindowsFileAssociationDetector(IFileSystemForVs fileSystem, IIdeScope ideScope)
{
_fileSystem = fileSystem;
_ideScope = ideScope;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Reqnroll.VisualStudio.Tests.Analytics;
public class FileUserIdStoreTests
{
private const string UserId = "491ed5c0-9f25-4c27-941a-19b17cc81c87";
private Mock<IFileSystem> fileSystemStub;
private Mock<IFileSystemForVs> fileSystemStub;

[Fact]
public void Should_GetUserIdFromFile_WhenFileExists()
Expand Down Expand Up @@ -36,7 +36,7 @@ public void Should_PersistNewlyGeneratedUserId_WhenNoUserIdExists()

public FileUserIdStore CreateSut()
{
fileSystemStub = new Mock<IFileSystem>();
fileSystemStub = new Mock<IFileSystemForVs>();
return new FileUserIdStore(fileSystemStub.Object);
}

Expand Down
6 changes: 3 additions & 3 deletions Tests/Reqnroll.VisualStudio.Tests/Diagnostics/LoggingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class LoggingTests
public void MessageIsLogged(TraceLevel logLevel)
{
//arrange
var fileSystem = new MockFileSystem();
var fileSystem = new MockFileSystemForVs();
var logger = AsynchronousFileLogger.CreateInstance(fileSystem);
Warmup(logger, fileSystem);

Expand All @@ -29,7 +29,7 @@ public void MessageIsLogged(TraceLevel logLevel)
$"{message.TimeStamp:yyyy-MM-ddTHH\\:mm\\:ss.fffzzz}, {message.Level}@{message.ManagedThreadId}, {message.CallerMethod}: {message.Message}");
}

private void Warmup(AsynchronousFileLogger logger, IFileSystem fileSystem)
private void Warmup(AsynchronousFileLogger logger, IFileSystemForVs fileSystem)
{
var message = new LogMessage(TraceLevel.Error, "warmup", nameof(MessageIsLogged));
logger.Log(message);
Expand All @@ -43,7 +43,7 @@ private void Warmup(AsynchronousFileLogger logger, IFileSystem fileSystem)
public void DisposeStopsLogging()
{
//arrange
var fileSystem = new MockFileSystem();
var fileSystem = new MockFileSystemForVs();
var logger = AsynchronousFileLogger.CreateInstance(fileSystem);
Warmup(logger, fileSystem);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class ReqnrollPackageDetectorTests
@"C:\MyProject\packages\SpecSync.AzureDevOps.Reqnroll.2-4.2.0.0";

private const string SpecFlow240PackagePathSolutionPackages = @"C:\MyProject\packages\Reqnroll.2.4.0";
private readonly MockFileSystem _mockFileSystem = new();
private readonly MockFileSystemForVs _mockFileSystem = new();

public ReqnrollPackageDetectorTests()
{
Expand Down
4 changes: 4 additions & 0 deletions Tests/Reqnroll.VisualStudio.VsxStubs/MockFileSystemForVs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace Reqnroll.VisualStudio.VsxStubs;
public class MockFileSystemForVs : MockFileSystem, IFileSystemForVs
{
}
Loading

0 comments on commit a7869f0

Please sign in to comment.