Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
                }
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
            }
        }