<commit_before>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace NUnit3TestReport
{
    public class Program
    {
        public static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                PrintUsage();
                Environment.Exit(1);
            }

            var files = GetFiles(args[0]);

            var testResults = new List<TestResultData>();
            foreach (var file in files)
            {
                testResults.Add(GetTestResultData(Path.GetFileName(file), File.ReadAllText(file)));
            }

            var tableRowsHtml = new StringBuilder();
            foreach (var testResult in testResults)
            {
                tableRowsHtml.AppendLine(testResult.ToHtml());
            }

            var template = GetEmbeddedResource("NUnit3TestReport.Template.html");
            var output = template.Replace("##TestResults##", tableRowsHtml.ToString());
            output = output.Replace("##FileCount##", files.Length.ToString());
            File.WriteAllText(args[1], output);
        }

        private static void PrintUsage()
        {
            var info = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);

            Console.WriteLine($@"{info.InternalName}
Version {info.ProductVersion}
{info.LegalCopyright}

{info.Comments}

Usage:
    {info.InternalName} [input-path-with-wildcards] [output-path]
Examples:
    Single input file: {info.InternalName} TestResults.xml TestResult.html
    Folder:            {info.InternalName} C:\Folder\* TestResult.html
    File pattern:      {info.InternalName} C:\Folder\*.xml TestResult.html");
        }

        public static string[] GetFiles(string filePattern)
        {
            var folder = Path.GetDirectoryName(filePattern);
            var searchPattern = Path.GetFileName(filePattern);
            return Directory.GetFiles(folder, searchPattern);
        }

        public static string GetEmbeddedResource(string fullyQualifiedName)
        {
            using (var reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(fullyQualifiedName)))
            {
                return reader.ReadToEnd();
            }
        }

        public static TestResultData GetTestResultData(string filename, string fileContents)
        {
            try
            {
                var xElement = XElement.Parse(fileContents);
                return new TestResultData
                {
                    IsValid = true,
                    FileName = filename,
                    Result = xElement.Element("test-suite").Attribute("result").Value,
                    Total = int.Parse(xElement.Attribute("total").Value),
                    Passed = int.Parse(xElement.Attribute("passed").Value),
                    Failed = int.Parse(xElement.Attribute("failed").Value),
                    Inconclusive = int.Parse(xElement.Attribute("inconclusive").Value),
                    Skipped = int.Parse(xElement.Attribute("skipped").Value),
                    Duration = double.Parse(xElement.Attribute("duration").Value)
                };
            }
            catch
            {
                return new TestResultData() {IsValid = false, FileName = filename };
            }
        }
    }

    public class TestResultData
    {
        public bool IsValid { get; set; }
        public string FileName { get; set; }
        public string Result { get; set; }
        public int Total { get; set; }
        public int Passed { get; set; }
        public int Failed { get; set; }
        public int Inconclusive { get; set; }
        public int Skipped { get; set; }
        public double Duration { get; set; }<commit_msg>fixed minor issue in xml parse<commit_after>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace NUnit3TestReport
{
    public class Program
    {
        public static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                PrintUsage();
                Environment.Exit(1);
            }

            var files = GetFiles(args[0]);

            var testResults = new List<TestResultData>();
            foreach (var file in files)
            {
                testResults.Add(GetTestResultData(Path.GetFileName(file), File.ReadAllText(file)));
            }

            var tableRowsHtml = new StringBuilder();
            foreach (var testResult in testResults)
            {
                tableRowsHtml.AppendLine(testResult.ToHtml());
            }

            var template = GetEmbeddedResource("NUnit3TestReport.Template.html");
            var output = template.Replace("##TestResults##", tableRowsHtml.ToString());
            output = output.Replace("##FileCount##", files.Length.ToString());
            File.WriteAllText(args[1], output);
        }

        private static void PrintUsage()
        {
            var info = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);

            Console.WriteLine($@"{info.InternalName}
Version {info.ProductVersion}
{info.LegalCopyright}

{info.Comments}

Usage:
    {info.InternalName} [input-path-with-wildcards] [output-path]
Examples:
    Single input file: {info.InternalName} TestResults.xml TestResult.html
    Folder:            {info.InternalName} C:\Folder\* TestResult.html
    File pattern:      {info.InternalName} C:\Folder\*.xml TestResult.html");
        }

        public static string[] GetFiles(string filePattern)
        {
            var folder = Path.GetDirectoryName(filePattern);
            var searchPattern = Path.GetFileName(filePattern);
            return Directory.GetFiles(folder, searchPattern);
        }

        public static string GetEmbeddedResource(string fullyQualifiedName)
        {
            using (var reader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(fullyQualifiedName)))
            {
                return reader.ReadToEnd();
            }
        }

        public static TestResultData GetTestResultData(string filename, string fileContents)
        {
            try
            {
                var xElement = XElement.Parse(fileContents);
                return new TestResultData
                {
                    IsValid = true,
                    FileName = filename,
                    Result = xElement.Attribute("result").Value,
                    Total = int.Parse(xElement.Attribute("total").Value),
                    Passed = int.Parse(xElement.Attribute("passed").Value),
                    Failed = int.Parse(xElement.Attribute("failed").Value),
                    Inconclusive = int.Parse(xElement.Attribute("inconclusive").Value),
                    Skipped = int.Parse(xElement.Attribute("skipped").Value),
                    Duration = double.Parse(xElement.Attribute("duration").Value)
                };
            }
            catch
            {
                return new TestResultData() {IsValid = false, FileName = filename };
            }
        }
    }

    public class TestResultData
    {
        public bool IsValid { get; set; }
        public string FileName { get; set; }
        public string Result { get; set; }
        public int Total { get; set; }
        public int Passed { get; set; }
        public int Failed { get; set; }
        public int Inconclusive { get; set; }
        public int Skipped { get; set; }
        public double Duration { get; set; }
{'fraction_non_alphanumeric': 0.10047785096215937, 'fraction_numerical': 0.0015497869043006587, 'mean_word_length': 1.9355572403335861, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 5}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '664321', 'n_tokens_mistral': 1972, 'n_tokens_neox': 1889, 'n_words': 431}