private static async Task Main() { var thread = new Thread(() => { Application.Run(new ClipboardNotificationWindow(cts)); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); InitializeConsole(); var options = AppOptions.Get(); Filesystem.Initialize(options.DownloadRootDirectory); await DownloadQueueObserver.ObserveAsync(options.MaxParallelDownloads, cts.Token); }
public static void TryReloadCoverage(Func <AppOptions, List <CoverageProject> > coverageProjectFactory) { var settings = AppOptions.Get(); var canReload = settings.Enabled; if (!canReload) { CoverageLines.Clear(); UpdateMarginTags?.Invoke(null); UpdateOutputWindow?.Invoke(null); } if (canReload) { var coverageProjects = coverageProjectFactory(settings); if (coverageProjects != null) { ReloadCoverage(coverageProjects); } } }
private static AppOptions GetSettings(CoverageProject project) { // get global settings var settings = AppOptions.Get(); /* * ======================================== * Process PropertyGroup settings * ======================================== * <PropertyGroup Label="FineCodeCoverage"> * ... * </PropertyGroup> */ var settingsPropertyGroup = project.ProjectFileXElement.XPathSelectElement($"/PropertyGroup[@Label='{Vsix.Code}']"); if (settingsPropertyGroup != null) { foreach (var property in settings.GetType().GetProperties()) { try { var xproperty = settingsPropertyGroup.Descendants().FirstOrDefault(x => x.Name.LocalName.Equals(property.Name, StringComparison.OrdinalIgnoreCase)); if (xproperty == null) { continue; } var strValue = xproperty.Value; if (string.IsNullOrWhiteSpace(strValue)) { continue; } var strValueArr = strValue.Split('\n', '\r').Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).ToArray(); if (!strValue.Any()) { continue; } if (TypeMatch(property.PropertyType, typeof(string))) { property.SetValue(settings, strValueArr.FirstOrDefault()); } else if (TypeMatch(property.PropertyType, typeof(string[]))) { property.SetValue(settings, strValueArr); } else if (TypeMatch(property.PropertyType, typeof(bool), typeof(bool?))) { if (bool.TryParse(strValueArr.FirstOrDefault(), out bool value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(bool[]), typeof(bool?[]))) { var arr = strValueArr.Where(x => bool.TryParse(x, out var _)).Select(x => bool.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(int), typeof(int?))) { if (int.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(int[]), typeof(int?[]))) { var arr = strValueArr.Where(x => int.TryParse(x, out var _)).Select(x => int.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(short), typeof(short?))) { if (short.TryParse(strValueArr.FirstOrDefault(), out var vaue)) { property.SetValue(settings, vaue); } } else if (TypeMatch(property.PropertyType, typeof(short[]), typeof(short?[]))) { var arr = strValueArr.Where(x => short.TryParse(x, out var _)).Select(x => short.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(long), typeof(long?))) { if (long.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(long[]), typeof(long?[]))) { var arr = strValueArr.Where(x => long.TryParse(x, out var _)).Select(x => long.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(decimal), typeof(decimal?))) { if (decimal.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(decimal[]), typeof(decimal?[]))) { var arr = strValueArr.Where(x => decimal.TryParse(x, out var _)).Select(x => decimal.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(double), typeof(double?))) { if (double.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(double[]), typeof(double?[]))) { var arr = strValueArr.Where(x => double.TryParse(x, out var _)).Select(x => double.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(float), typeof(float?))) { if (float.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(float[]), typeof(float?[]))) { var arr = strValueArr.Where(x => float.TryParse(x, out var _)).Select(x => float.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(char), typeof(char?))) { if (char.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(char[]), typeof(char?[]))) { var arr = strValueArr.Where(x => char.TryParse(x, out var _)).Select(x => char.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else { throw new Exception($"Cannot handle '{property.PropertyType.Name}' yet"); } } catch (Exception exception) { Logger.Log($"Failed to override '{property.Name}' setting", exception); } } } // return return(settings); }
private static AppOptions GetSettings(CoverageProject project) { // get global settings var settings = AppOptions.Get(); // override with test project settings XElement xproject; try { xproject = XElement.Parse(File.ReadAllText(project.ProjectFile)); } catch (Exception ex) { Logger.Log("Failed to parse project file", ex); return(settings); } var xsettings = xproject.Descendants("PropertyGroup").FirstOrDefault(x => { var label = x.Attribute("Label")?.Value?.Trim() ?? string.Empty; if (!Vsix.Code.Equals(label, StringComparison.OrdinalIgnoreCase)) { return(false); } return(true); }); if (xsettings == null) { return(settings); } foreach (var property in settings.GetType().GetProperties()) { try { var xproperty = xsettings.Descendants().FirstOrDefault(x => x.Name.LocalName.Equals(property.Name, StringComparison.OrdinalIgnoreCase)); if (xproperty == null) { continue; } var strValue = xproperty.Value; if (string.IsNullOrWhiteSpace(strValue)) { continue; } var strValueArr = strValue.Split('\n', '\r').Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).ToArray(); if (!strValue.Any()) { continue; } if (TypeMatch(property.PropertyType, typeof(string))) { property.SetValue(settings, strValueArr.FirstOrDefault()); } else if (TypeMatch(property.PropertyType, typeof(string[]))) { property.SetValue(settings, strValueArr); } else if (TypeMatch(property.PropertyType, typeof(bool), typeof(bool?))) { if (bool.TryParse(strValueArr.FirstOrDefault(), out bool value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(bool[]), typeof(bool?[]))) { var arr = strValueArr.Where(x => bool.TryParse(x, out var _)).Select(x => bool.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(int), typeof(int?))) { if (int.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(int[]), typeof(int?[]))) { var arr = strValueArr.Where(x => int.TryParse(x, out var _)).Select(x => int.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(short), typeof(short?))) { if (short.TryParse(strValueArr.FirstOrDefault(), out var vaue)) { property.SetValue(settings, vaue); } } else if (TypeMatch(property.PropertyType, typeof(short[]), typeof(short?[]))) { var arr = strValueArr.Where(x => short.TryParse(x, out var _)).Select(x => short.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(long), typeof(long?))) { if (long.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(long[]), typeof(long?[]))) { var arr = strValueArr.Where(x => long.TryParse(x, out var _)).Select(x => long.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(decimal), typeof(decimal?))) { if (decimal.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(decimal[]), typeof(decimal?[]))) { var arr = strValueArr.Where(x => decimal.TryParse(x, out var _)).Select(x => decimal.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(double), typeof(double?))) { if (double.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(double[]), typeof(double?[]))) { var arr = strValueArr.Where(x => double.TryParse(x, out var _)).Select(x => double.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(float), typeof(float?))) { if (float.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(float[]), typeof(float?[]))) { var arr = strValueArr.Where(x => float.TryParse(x, out var _)).Select(x => float.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else if (TypeMatch(property.PropertyType, typeof(char), typeof(char?))) { if (char.TryParse(strValueArr.FirstOrDefault(), out var value)) { property.SetValue(settings, value); } } else if (TypeMatch(property.PropertyType, typeof(char[]), typeof(char?[]))) { var arr = strValueArr.Where(x => char.TryParse(x, out var _)).Select(x => char.Parse(x)); if (arr.Any()) { property.SetValue(settings, arr); } } else { throw new Exception($"Cannot handle '{property.PropertyType.Name}' yet"); } } catch (Exception exception) { Logger.Log($"Failed to override '{property.Name}' setting", exception); } } // return return(settings); }
private void OperationState_StateChanged(object sender, OperationStateChangedEventArgs e) { try { if (e.State == TestOperationStates.TestExecutionStarting) { StopCoverageProcess(); // just to be sure } if (e.State == TestOperationStates.TestExecutionFinished) { var settings = AppOptions.Get(); if (!settings.Enabled) { FCCEngine.CoverageLines.Clear(); UpdateMarginTags?.Invoke(this, null); UpdateOutputWindow?.Invoke(this, null); return; } Logger.Log("================================== START =================================="); var darkMode = CurrentTheme.Equals("Dark", StringComparison.OrdinalIgnoreCase); CoverageProject[] projects = null; try { var testConfiguration = new Operation(e.Operation).Configuration; var userRunSettings = testConfiguration.UserRunSettings; var runSettingsRetriever = new RunSettingsRetriever(); var testContainers = testConfiguration.Containers; projects = testConfiguration.Containers.Select(container => { var project = new CoverageProject(); project.ProjectName = container.ProjectName; project.TestDllFile = container.Source; project.Is64Bit = container.TargetPlatform.ToString().ToLower().Equals("x64"); var containerData = container.ProjectData; project.ProjectFile = container.ProjectData.ProjectFilePath; project.RunSettingsFile = ThreadHelper.JoinableTaskFactory.Run(() => runSettingsRetriever.GetRunSettingsFileAsync(userRunSettings, containerData)); return(project); }).ToArray(); }catch (Exception exc) { throw new Exception("Error test container discoverer reflection", exc); } _reloadCoverageThread = new Thread(() => { try { // compute coverage FCCEngine.ReloadCoverage(projects, darkMode); // update margins { UpdateMarginTagsEventArgs updateMarginTagsEventArgs = null; try { updateMarginTagsEventArgs = new UpdateMarginTagsEventArgs { }; } catch { // ignore } finally { UpdateMarginTags?.Invoke(this, updateMarginTagsEventArgs); } } // update output window { UpdateOutputWindowEventArgs updateOutputWindowEventArgs = null; try { updateOutputWindowEventArgs = new UpdateOutputWindowEventArgs { HtmlContent = File.ReadAllText(FCCEngine.HtmlFilePath) }; } catch { // ignore } finally { UpdateOutputWindow?.Invoke(this, updateOutputWindowEventArgs); } } // log Logger.Log("================================== DONE ==================================="); } catch (Exception exception) { if (!(exception is ThreadAbortException) && _reloadCoverageThread != null) { Logger.Log("Error", exception); Logger.Log("================================== ERROR =================================="); } } }); _reloadCoverageThread.Start(); } } catch (Exception exception) { Logger.Log("Error processing unit test events", exception); } }
private void OperationState_StateChanged(object sender, OperationStateChangedEventArgs e) { try { if (e.State == TestOperationStates.TestExecutionStarting) { try { _reloadCoverageThread?.Abort(); } catch { // ignore } finally { _reloadCoverageThread = null; FCCEngine.ClearProcesses(); } } if (e.State == TestOperationStates.TestExecutionFinished) { var settings = AppOptions.Get(); if (!settings.Enabled) { FCCEngine.CoverageLines.Clear(); UpdateMarginTags?.Invoke(this, null); UpdateOutputWindow?.Invoke(this, null); return; } Logger.Log("================================== START =================================="); var operationType = e.Operation.GetType(); var darkMode = CurrentTheme.Equals("Dark", StringComparison.OrdinalIgnoreCase); var testConfiguration = (operationType.GetProperty("Configuration") ?? operationType.GetProperty("Configuration", BindingFlags.Instance | BindingFlags.NonPublic)).GetValue(e.Operation); var testContainers = ((IEnumerable <object>)testConfiguration.GetType().GetProperty("Containers").GetValue(testConfiguration)).ToArray(); var projects = new List <CoverageProject>(); foreach (var container in testContainers) { var project = new CoverageProject(); var containerType = container.GetType(); var containerData = containerType.GetProperty("ProjectData").GetValue(container); var containerDataType = containerData.GetType(); project.ProjectGuid = containerType.GetProperty("ProjectGuid").GetValue(container).ToString(); project.ProjectName = containerType.GetProperty("ProjectName").GetValue(container).ToString(); project.TestDllFileInOutputFolder = containerType.GetProperty("Source").GetValue(container).ToString(); project.TestDllCompilationMode = AssemblyUtil.GetCompilationMode(project.TestDllFileInOutputFolder); project.ProjectFile = containerDataType.GetProperty("ProjectFilePath", BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic).GetValue(containerData).ToString(); var defaultOutputFolder = Path.GetDirectoryName(containerDataType.GetProperty("DefaultOutputPath", BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic).GetValue(containerData).ToString()); project.WorkFolder = Path.Combine(Path.GetDirectoryName(defaultOutputFolder), "fine-code-coverage"); projects.Add(project); } _reloadCoverageThread = new Thread(() => { try { // compute coverage FCCEngine.ReloadCoverage(projects.ToArray(), darkMode); // update margins { UpdateMarginTagsEventArgs updateMarginTagsEventArgs = null; try { updateMarginTagsEventArgs = new UpdateMarginTagsEventArgs { }; } catch { // ignore } finally { UpdateMarginTags?.Invoke(this, updateMarginTagsEventArgs); } } // update output window { UpdateOutputWindowEventArgs updateOutputWindowEventArgs = null; try { updateOutputWindowEventArgs = new UpdateOutputWindowEventArgs { HtmlContent = File.ReadAllText(FCCEngine.HtmlFilePath) }; } catch { // ignore } finally { UpdateOutputWindow?.Invoke(this, updateOutputWindowEventArgs); } } // log Logger.Log("================================== DONE ==================================="); } catch (Exception exception) { if (!(exception is ThreadAbortException) && _reloadCoverageThread != null) { Logger.Log("Error", exception); Logger.Log("================================== ERROR =================================="); } } }); _reloadCoverageThread.Start(); } } catch (Exception exception) { Logger.Log("Error processing unit test events", exception); } }