Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions FineCodeCoverage/FineCodeCoverage.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
<Compile Include="Options\IAppOptions.cs" />
<Compile Include="Options\IAppOptionsProvider.cs" />
<Compile Include="Options\IAppOptionsStorageProvider.cs" />
<Compile Include="Output\ClearUICommand.cs" />
<Compile Include="Output\IProcess.cs" />
<Compile Include="Output\OutputToolWindow.cs" />
<Compile Include="Output\OutputToolWindowCommand.cs" />
Expand Down Expand Up @@ -228,6 +229,7 @@
<Link>Resources\LICENSE</Link>
<IncludeInVSIX>true</IncludeInVSIX>
</Content>
<Content Include="Output\Resources\ClearUICommand.png" />
<Content Include="Output\Resources\OutputToolWindowCommand.png" />
<Content Include="ZippedTools\coverlet.console.3.0.3.zip">
<IncludeInVSIX>true</IncludeInVSIX>
Expand Down
83 changes: 83 additions & 0 deletions FineCodeCoverage/Output/ClearUICommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.ComponentModel.Design;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using FineCodeCoverage.Engine;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;

namespace FineCodeCoverage.Output
{
/// <summary>
/// Command handler
/// </summary>
internal sealed class ClearUICommand
{
/// <summary>
/// Command ID.
/// </summary>
public const int CommandId = 256;

/// <summary>
/// Command menu group (command set GUID).
/// </summary>
public static readonly Guid CommandSet = new Guid("d58a999f-4a1b-42df-839a-cb31a0a4fed7");

private readonly IFCCEngine fccEngine;

/// <summary>
/// Initializes a new instance of the <see cref="ClearUICommand"/> class.
/// Adds our command handlers for menu (commands must exist in the command table file)
/// </summary>
/// <param name="package">Owner package, not null.</param>
/// <param name="commandService">Command service to add command to, not null.</param>
private ClearUICommand(OleMenuCommandService commandService, IFCCEngine fccEngine)
{
this.fccEngine = fccEngine;
commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));

var menuCommandID = new CommandID(CommandSet, CommandId);
var menuItem = new MenuCommand(this.Execute, menuCommandID);
commandService.AddCommand(menuItem);
}

/// <summary>
/// Gets the instance of the command.
/// </summary>
public static ClearUICommand Instance
{
get;
private set;
}

/// <summary>
/// Initializes the singleton instance of the command.
/// </summary>
/// <param name="package">Owner package, not null.</param>
public static async Task InitializeAsync(AsyncPackage package, IFCCEngine fccEngine)
{
// Switch to the main thread - the call to AddCommand in ClearUICommand's constructor requires
// the UI thread.
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);

OleMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService;
Instance = new ClearUICommand(commandService, fccEngine);
}

/// <summary>
/// This function is the callback used to execute the command when the menu item is clicked.
/// See the constructor to see how the menu item is associated with this function using
/// OleMenuCommandService service and MenuCommand class.
/// </summary>
/// <param name="sender">Event sender.</param>
/// <param name="e">Event args.</param>
private void Execute(object sender, EventArgs e)
{
ThreadHelper.ThrowIfNotOnUIThread();
fccEngine.ClearUI();
}

}
}
1 change: 1 addition & 0 deletions FineCodeCoverage/Output/OutputToolWindowPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke
componentModel = sp.GetService(typeof(Microsoft.VisualStudio.ComponentModelHost.SComponentModel)) as Microsoft.VisualStudio.ComponentModelHost.IComponentModel;
Assumes.Present(componentModel);
await OutputToolWindowCommand.InitializeAsync(this);
await ClearUICommand.InitializeAsync(this, componentModel.GetService<IFCCEngine>());
}

protected override System.Threading.Tasks.Task<object> InitializeToolWindowAsync(Type toolWindowType, int id, CancellationToken cancellationToken)
Expand Down
32 changes: 27 additions & 5 deletions FineCodeCoverage/Output/OutputToolWindowPackage.vsct
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
defining some of the constants that we will use inside the file. -->

<!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->
<Extern href="stdidcmd.h"/>
<Extern href="stdidcmd.h" />

<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<Extern href="vsshlids.h" />

<!--The Commands section is where commands, menus, and menu groups are defined.
This section uses a Guid to identify the package that provides the command defined inside it. -->
Expand All @@ -43,12 +43,19 @@
<CommandFlag>DynamicVisibility</CommandFlag>
If you do not want an image next to your command, remove the Icon node /> -->
<Button guid="guidOutputToolWindowPackageCmdSet" id="OutputToolWindowCommandId" priority="0x0100" type="Button">
<Parent guid="guidSHLMainMenu" id="IDG_VS_WNDO_OTRWNDWS1"/>
<Parent guid="guidSHLMainMenu" id="IDG_VS_WNDO_OTRWNDWS1" />
<Icon guid="guidImages" id="bmpPic1" />
<Strings>
<ButtonText>Fine Code Coverage</ButtonText>
</Strings>
</Button>
<Button guid="guidOutputToolWindowPackageCmdSet1" id="cmdidClearUICommand" priority="0x0100" type="Button">
<Parent guid="guidOutputToolWindowPackageCmdSet1" id="MyMenuGroup" />
<Icon guid="guidImages1" id="bmpPic1" />
<Strings>
<ButtonText>FCC Clear UI</ButtonText>
</Strings>
</Button>
</Buttons>

<!--The bitmaps section is used to define the bitmaps that are used for the commands.-->
Expand All @@ -58,8 +65,14 @@
bitmap strip containing the bitmaps and then there are the numeric ids of the elements used
inside a button definition. An important aspect of this declaration is that the element id
must be the actual index (1-based) of the bitmap inside the bitmap strip. -->
<Bitmap guid="guidImages" href="Resources\OutputToolWindowCommand.png" usedList="bmpPic1"/>
<Bitmap guid="guidImages" href="Resources\OutputToolWindowCommand.png" usedList="bmpPic1" />
<Bitmap guid="guidImages1" href="Resources\ClearUICommand.png" usedList="bmpPic1" />
</Bitmaps>
<Groups>
<Group guid="guidOutputToolWindowPackageCmdSet1" id="MyMenuGroup" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS" />
</Group>
</Groups>
</Commands>

<Symbols>
Expand All @@ -71,7 +84,16 @@
<IDSymbol name="OutputToolWindowCommandId" value="0x0100" />
</GuidSymbol>

<GuidSymbol name="guidImages" value="{297e101c-4afa-47b1-b382-087cfb4618b0}" >
<GuidSymbol name="guidImages" value="{297e101c-4afa-47b1-b382-087cfb4618b0}">
<IDSymbol name="bmpPic1" value="1" />
</GuidSymbol>

<GuidSymbol value="{d58a999f-4a1b-42df-839a-cb31a0a4fed7}" name="guidOutputToolWindowPackageCmdSet1">
<IDSymbol value="4128" name="MyMenuGroup" />
<IDSymbol value="256" name="cmdidClearUICommand" />
</GuidSymbol>

<GuidSymbol value="{8252a6d7-bcf3-4518-ae22-ad20ef8d4b63}" name="guidImages1">
<IDSymbol name="bmpPic1" value="1" />
</GuidSymbol>
</Symbols>
Expand Down
8 changes: 8 additions & 0 deletions FineCodeCoverage/Output/OutputToolWindowPackage1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ internal sealed partial class PackageGuids

public const string guidImagesString = "297e101c-4afa-47b1-b382-087cfb4618b0";
public static Guid guidImages = new Guid(guidImagesString);

public const string guidOutputToolWindowPackageCmdSet1String = "d58a999f-4a1b-42df-839a-cb31a0a4fed7";
public static Guid guidOutputToolWindowPackageCmdSet1 = new Guid(guidOutputToolWindowPackageCmdSet1String);

public const string guidImages1String = "8252a6d7-bcf3-4518-ae22-ad20ef8d4b63";
public static Guid guidImages1 = new Guid(guidImages1String);
}
/// <summary>
/// Helper class that encapsulates all CommandIDs uses across VS Package.
Expand All @@ -28,5 +34,7 @@ internal sealed partial class PackageIds
{
public const int OutputToolWindowCommandId = 0x0100;
public const int bmpPic1 = 0x0001;
public const int MyMenuGroup = 0x1020;
public const int cmdidClearUICommand = 0x0100;
}
}
Binary file added FineCodeCoverage/Output/Resources/ClearUICommand.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Introduction

Fine Code Coverage works by reacting to the visual studio test explorer, providing coverage from each test project containing tests that you have selected
to run. This coverage is presented as a single unified report as well as coloured margins alongside your code.
This coverage is not dynamic and represents the coverage obtained from the last time you executed tests.
When the coverage becomes outdated, you can click the 'FCC Clear UI' button in Tools or run coverage again.

The coverage is provided by either [OpenCover](https://github.com/OpenCover/opencover) for old style projects and [Coverlet](https://github.com/coverlet-coverage/coverlet)
for new style sdk projects. FCC provides an abstraction over both so that it is possible to ignore the differences between the two but there are circumstances where
it is important to be aware of cover tool that will be run. This is most apparent when Coverlet is used, please read on for the specifics.
Expand Down