Skip to content

Commit 4110e71

Browse files
committed
refactor MsCodeCoverageRunSettingsService - tests to change in next commit
1 parent 4eeb9e5 commit 4110e71

File tree

1 file changed

+163
-138
lines changed

1 file changed

+163
-138
lines changed

SharedProject/Core/MsTestPlatform/MsCodeCoverageRunSettingsService.cs

Lines changed: 163 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,17 @@ public void Copy(List<ICoverageProject> coverageProjects)
186186
private const string msCodeCoverageMessage = "Ms code coverage";
187187
internal Dictionary<string, UserRunSettingsProjectDetails> userRunSettingsProjectDetailsLookup;
188188
private ShimCopier shimCopier;
189-
private ProjectRunSettingsGenerator projectRunSettingsGenerator;
189+
private readonly IProjectRunSettingsGenerator projectRunSettingsGenerator;
190+
private readonly IUserRunSettingsService userRunSettingsService;
190191

191192
[ImportingConstructor]
192193
public MsCodeCoverageRunSettingsService(
193194
IToolFolder toolFolder,
194195
IToolZipProvider toolZipProvider,
195-
[Import(typeof(SVsServiceProvider))]
196-
IServiceProvider serviceProvider,
197196
IAppOptionsProvider appOptionsProvider,
198197
ICoverageToolOutputManager coverageOutputManager,
198+
IProjectRunSettingsGenerator projectRunSettingsGenerator,
199+
IUserRunSettingsService userRunSettingsService,
199200
IBuiltInRunSettingsTemplate builtInRunSettingsTemplate,
200201
ICustomRunSettingsTemplateProvider customRunSettingsTemplateProvider,
201202
ILogger logger,
@@ -211,7 +212,8 @@ IReportGeneratorUtil reportGeneratorUtil
211212
this.logger = logger;
212213
this.reportGeneratorUtil = reportGeneratorUtil;
213214
builtInRunSettingsTemplateString = builtInRunSettingsTemplate.Template;
214-
this.projectRunSettingsGenerator = new ProjectRunSettingsGenerator(serviceProvider);
215+
this.projectRunSettingsGenerator = projectRunSettingsGenerator;
216+
this.userRunSettingsService = userRunSettingsService;
215217
}
216218

217219
public void Initialize(string appDataFolder, IFCCEngine fccEngine, CancellationToken cancellationToken)
@@ -234,7 +236,7 @@ public MsCodeCoverageCollectionStatus IsCollecting(ITestOperation testOperation)
234236
var coverageProjects = await testOperation.GetCoverageProjectsAsync();
235237
var coverageProjectsWithRunSettings = coverageProjects.Where(coverageProject => coverageProject.RunSettingsFile != null).ToList();
236238

237-
var (suitable,specifiedMsCodeCoverage) = CheckUserRunSettingsSuitability(
239+
var (suitable,specifiedMsCodeCoverage) = userRunSettingsService.CheckUserRunSettingsSuitability(
238240
coverageProjectsWithRunSettings.Select(cp => cp.RunSettingsFile),useMsCodeCoverage
239241
);
240242

@@ -275,69 +277,6 @@ await CombinedLogAsync(() =>
275277
return collectionStatus;
276278
}
277279

278-
#region user runsettings suitability
279-
private static (bool Suitable, bool SpecifiedMsCodeCoverage) CheckUserRunSettingsSuitability(IEnumerable<string> userRunSettingsFiles, bool useMsCodeCoverage)
280-
{
281-
var specifiedMsCodeCoverage = false;
282-
foreach (var userRunSettingsFile in userRunSettingsFiles)
283-
{
284-
var (suitable, projectSpecifiedMsCodeCoverage) = ValidateUserRunSettings(File.ReadAllText(userRunSettingsFile), useMsCodeCoverage);
285-
if (!suitable)
286-
{
287-
return (false, false);
288-
}
289-
if (projectSpecifiedMsCodeCoverage)
290-
{
291-
specifiedMsCodeCoverage = true;
292-
}
293-
}
294-
295-
return (true, specifiedMsCodeCoverage);
296-
}
297-
298-
internal static (bool Suitable, bool SpecifiedMsCodeCoverage) ValidateUserRunSettings(string runSettings, bool useMsCodeCoverage)
299-
{
300-
try
301-
{
302-
var runSettingsDoc = XDocument.Parse(runSettings);
303-
var dataCollectorsElement = runSettingsDoc.GetStrictDescendant("RunSettings/DataCollectionRunSettings/DataCollectors");
304-
if (dataCollectorsElement == null)
305-
{
306-
return (useMsCodeCoverage, false);
307-
}
308-
309-
var msDataCollectorElement = RunSettingsHelper.FindMsDataCollector(dataCollectorsElement);
310-
311-
if (msDataCollectorElement == null)
312-
{
313-
return (useMsCodeCoverage, false);
314-
}
315-
316-
if (HasCoberturaFormat(msDataCollectorElement))
317-
{
318-
return (true, true);
319-
}
320-
321-
return (useMsCodeCoverage, true);
322-
}
323-
catch
324-
{
325-
return (false, false);
326-
}
327-
}
328-
329-
private static bool HasCoberturaFormat(XElement msDataCollectorElement)
330-
{
331-
var formatElement = msDataCollectorElement.GetStrictDescendant("Configuration/Format");
332-
if (formatElement == null)
333-
{
334-
return false;
335-
}
336-
return formatElement.Value == "Cobertura";
337-
}
338-
339-
#endregion
340-
341280
private async Task PrepareCoverageProjectsAsync(List<ICoverageProject> coverageProjects)
342281
{
343282
userRunSettingsProjectDetailsLookup = new Dictionary<string, UserRunSettingsProjectDetails>();
@@ -457,27 +396,21 @@ public IXPathNavigable AddRunSettings(IXPathNavigable inputRunSettingDocument, I
457396
{
458397
if (configurationInfo.RequestState == RunSettingConfigurationInfoState.Execution && NotFCCGenerated(inputRunSettingDocument))
459398
{
460-
return AddFCCSettings(inputRunSettingDocument, configurationInfo);
399+
var replacements = CreateReplacements(configurationInfo.TestContainers);
400+
return userRunSettingsService.AddFCCRunSettings(replacements, inputRunSettingDocument);
461401
}
462402
return null;
463403
}
464404

465-
internal IXPathNavigable AddFCCSettings(IXPathNavigable inputRunSettingDocument, IRunSettingsConfigurationInfo configurationInfo)
405+
private bool NotFCCGenerated(IXPathNavigable inputRunSettingDocument)
466406
{
467407
var navigator = inputRunSettingDocument.CreateNavigator();
468-
navigator.MoveToFirstChild();
469-
var clonedNavigator = navigator.Clone();
470-
IRunSettingsTemplateReplacements runSettingsTemplateReplacements = CreateReplacements(configurationInfo);
471-
ConfigureRunConfiguration(navigator, runSettingsTemplateReplacements);
472-
EnsureMsDataCollector(clonedNavigator, runSettingsTemplateReplacements);
473-
474-
return inputRunSettingDocument;
408+
return navigator.SelectSingleNode($"//{builtInRunSettingsTemplate.FCCMarkerElementName}") == null;
475409
}
476410

477-
private IRunSettingsTemplateReplacements CreateReplacements(IRunSettingsConfigurationInfo configurationInfo)
411+
private IRunSettingsTemplateReplacements CreateReplacements(IEnumerable<ITestContainer> testContainers)
478412
{
479-
var allProjectDetails = configurationInfo.TestContainers.Select(tc => userRunSettingsProjectDetailsLookup[tc.Source]).ToList();
480-
// might have an issue with &resultsdirectory& as there is a ResultsDirectory property ?
413+
var allProjectDetails = testContainers.Select(tc => userRunSettingsProjectDetailsLookup[tc.Source]).ToList();
481414
var resultsDirectory = allProjectDetails[0].OutputFolder;
482415
var allSettings = allProjectDetails.Select(pd => pd.Settings);
483416
var mergedSettings = new MergedIncludesExcludesOptions(allSettings);
@@ -501,6 +434,142 @@ private IRunSettingsTemplateReplacements CreateReplacements(IRunSettingsConfigur
501434
return new RunSettingsTemplateReplacements(mergedSettings, resultsDirectory, "true", modulePathsInclude, modulePathsExclude, MsCodeCoveragePath);
502435
}
503436

437+
#endregion
438+
439+
public void Collect(IOperation operation, ITestOperation testOperation)
440+
{
441+
var resultsUris = operation.GetRunSettingsMsDataCollectorResultUri();
442+
var coberturaFiles = new string[0];
443+
if (resultsUris != null)
444+
{
445+
coberturaFiles = resultsUris.Select(uri => uri.LocalPath).Where(f => f.EndsWith(".cobertura.xml")).ToArray();
446+
}
447+
448+
if (coberturaFiles.Length == 0)
449+
{
450+
ThreadHelper.JoinableTaskFactory.Run(async () =>
451+
{
452+
await CombinedLogAsync("No cobertura files for ms code coverage.");
453+
});
454+
}
455+
456+
fccEngine.RunAndProcessReport(coberturaFiles,() =>
457+
{
458+
ThreadHelper.JoinableTaskFactory.Run(async () =>
459+
{
460+
List<ICoverageProject> coverageProjects = await testOperation.GetCoverageProjectsAsync();
461+
await projectRunSettingsGenerator.RemoveGeneratedProjectSettingsAsync(coverageProjects);
462+
});
463+
});
464+
}
465+
466+
public void StopCoverage()
467+
{
468+
fccEngine.StopCoverage();
469+
}
470+
471+
#region Logging
472+
private async Task CombinedLogAsync(string message)
473+
{
474+
await CombinedLogAsync(() =>
475+
{
476+
logger.Log(message);
477+
reportGeneratorUtil.LogCoverageProcess(message);
478+
});
479+
}
480+
481+
private async Task CombinedLogAsync(Action action)
482+
{
483+
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
484+
action();
485+
}
486+
#endregion
487+
488+
}
489+
490+
internal interface IUserRunSettingsService
491+
{
492+
IXPathNavigable AddFCCRunSettings(IBuiltInRunSettingsTemplate builtInRunSettingsTemplate, IRunSettingsTemplateReplacements replacements, IXPathNavigable inputRunSettingDocument);
493+
(bool Suitable, bool SpecifiedMsCodeCoverage) CheckUserRunSettingsSuitability(IEnumerable<string> userRunSettingsFiles, bool useMsCodeCoverage);
494+
}
495+
496+
[Export(typeof(IUserRunSettingsService))]
497+
internal class UserRunSettingsService : IUserRunSettingsService
498+
{
499+
private IBuiltInRunSettingsTemplate builtInRunSettingsTemplate;
500+
501+
public (bool Suitable, bool SpecifiedMsCodeCoverage) CheckUserRunSettingsSuitability(IEnumerable<string> userRunSettingsFiles, bool useMsCodeCoverage)
502+
{
503+
var specifiedMsCodeCoverage = false;
504+
foreach (var userRunSettingsFile in userRunSettingsFiles)
505+
{
506+
var (suitable, projectSpecifiedMsCodeCoverage) = ValidateUserRunSettings(File.ReadAllText(userRunSettingsFile), useMsCodeCoverage);
507+
if (!suitable)
508+
{
509+
return (false, false);
510+
}
511+
if (projectSpecifiedMsCodeCoverage)
512+
{
513+
specifiedMsCodeCoverage = true;
514+
}
515+
}
516+
517+
return (true, specifiedMsCodeCoverage);
518+
}
519+
520+
private static (bool Suitable, bool SpecifiedMsCodeCoverage) ValidateUserRunSettings(string runSettings, bool useMsCodeCoverage)
521+
{
522+
try
523+
{
524+
var runSettingsDoc = XDocument.Parse(runSettings);
525+
var dataCollectorsElement = runSettingsDoc.GetStrictDescendant("RunSettings/DataCollectionRunSettings/DataCollectors");
526+
if (dataCollectorsElement == null)
527+
{
528+
return (useMsCodeCoverage, false);
529+
}
530+
531+
var msDataCollectorElement = RunSettingsHelper.FindMsDataCollector(dataCollectorsElement);
532+
533+
if (msDataCollectorElement == null)
534+
{
535+
return (useMsCodeCoverage, false);
536+
}
537+
538+
if (HasCoberturaFormat(msDataCollectorElement))
539+
{
540+
return (true, true);
541+
}
542+
543+
return (useMsCodeCoverage, true);
544+
}
545+
catch
546+
{
547+
return (false, false);
548+
}
549+
}
550+
551+
private static bool HasCoberturaFormat(XElement msDataCollectorElement)
552+
{
553+
var formatElement = msDataCollectorElement.GetStrictDescendant("Configuration/Format");
554+
if (formatElement == null)
555+
{
556+
return false;
557+
}
558+
return formatElement.Value == "Cobertura";
559+
}
560+
561+
public IXPathNavigable AddFCCRunSettings(IBuiltInRunSettingsTemplate builtInRunSettingsTemplate, IRunSettingsTemplateReplacements replacements, IXPathNavigable inputRunSettingDocument)
562+
{
563+
this.builtInRunSettingsTemplate = builtInRunSettingsTemplate;
564+
var navigator = inputRunSettingDocument.CreateNavigator();
565+
navigator.MoveToFirstChild();
566+
var clonedNavigator = navigator.Clone();
567+
ConfigureRunConfiguration(navigator, replacements);
568+
EnsureMsDataCollector(clonedNavigator, replacements);
569+
return navigator;
570+
}
571+
572+
504573
private void ConfigureRunConfiguration(XPathNavigator xpathNavigator, IRunSettingsTemplateReplacements replacements)
505574
{
506575
var movedToRunConfiguration = xpathNavigator.MoveToChild("RunConfiguration", "");
@@ -630,71 +699,27 @@ private void EnsureCorrectCoberturaFormat(XPathNavigator navigator)
630699
navigator.AppendChild("<Configuration><Format>Cobertura</Format></Configuration>");
631700
}
632701
}
702+
}
633703

634-
private bool NotFCCGenerated(IXPathNavigable inputRunSettingDocument)
635-
{
636-
var navigator = inputRunSettingDocument.CreateNavigator();
637-
return navigator.SelectSingleNode($"//{builtInRunSettingsTemplate.FCCMarkerElementName}") == null;
638-
}
639-
#endregion
640-
641-
public void Collect(IOperation operation, ITestOperation testOperation)
642-
{
643-
var resultsUris = operation.GetRunSettingsMsDataCollectorResultUri();
644-
var coberturaFiles = new string[0];
645-
if (resultsUris != null)
646-
{
647-
coberturaFiles = resultsUris.Select(uri => uri.LocalPath).Where(f => f.EndsWith(".cobertura.xml")).ToArray();
648-
}
649-
650-
if (coberturaFiles.Length == 0)
651-
{
652-
ThreadHelper.JoinableTaskFactory.Run(async () =>
653-
{
654-
await CombinedLogAsync("No cobertura files for ms code coverage.");
655-
});
656-
}
657-
658-
fccEngine.RunAndProcessReport(coberturaFiles,() =>
659-
{
660-
ThreadHelper.JoinableTaskFactory.Run(async () =>
661-
{
662-
List<ICoverageProject> coverageProjects = await testOperation.GetCoverageProjectsAsync();
663-
await projectRunSettingsGenerator.RemoveGeneratedProjectSettingsAsync(coverageProjects);
664-
});
665-
});
666-
}
667-
668-
public void StopCoverage()
669-
{
670-
fccEngine.StopCoverage();
671-
}
672-
673-
#region Logging
674-
private async Task CombinedLogAsync(string message)
675-
{
676-
await CombinedLogAsync(() =>
677-
{
678-
logger.Log(message);
679-
reportGeneratorUtil.LogCoverageProcess(message);
680-
});
681-
}
682-
683-
private async Task CombinedLogAsync(Action action)
684-
{
685-
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
686-
action();
687-
}
688-
#endregion
689-
704+
internal interface IProjectRunSettingsGenerator
705+
{
706+
string GeneratedProjectRunSettingsFilePath(ICoverageProject coverageProject);
707+
Task RemoveGeneratedProjectSettingsAsync(IEnumerable<ICoverageProject> coverageProjects);
708+
Task<List<string>> WriteProjectsRunSettingsAsync(List<(string projectRunSettings, string projectRunSettingsFilePath, Guid projectGuid, string customTemplatePath)> projectsRunSettingsWriteDetails);
690709
}
691710

692-
internal class ProjectRunSettingsGenerator
711+
[Export(typeof(IProjectRunSettingsGenerator))]
712+
internal class ProjectRunSettingsGenerator : IProjectRunSettingsGenerator
693713
{
694714
private readonly IServiceProvider serviceProvider;
695715
private const string fccGeneratedRunSettingsSuffix = "fcc-mscodecoverage-generated";
696716

697-
public ProjectRunSettingsGenerator(IServiceProvider serviceProvider)
717+
718+
[ImportingConstructor]
719+
public ProjectRunSettingsGenerator(
720+
[Import(typeof(SVsServiceProvider))]
721+
IServiceProvider serviceProvider
722+
)
698723
{
699724
this.serviceProvider = serviceProvider;
700725
}

0 commit comments

Comments
 (0)