<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Text.RegularExpressions;

namespace MarkdownSharpTests
{
    class Program
    {

        static void Main(string[] args)
        {

            //UnitTests();

            //
            // this is the closest thing to a set of Markdown reference tests I could find
            //
            // see http://six.pairlist.net/pipermail/markdown-discuss/2009-February/001526.html
            // and http://michelf.com/docs/projets/mdtest-1.1.zip
            // and http://git.michelf.com/mdtest/
            //
            GenerateTestOutput(@"mdtest-1.1");

            //
            // same as mdtest-1.1, but:
            //
            // * remove any non-significant whitespace or extra paragraph differences
            //   (there are only two as I recall; not sure why, but frankly who cares)
            // * comment out any edge conditions we aren't dealing with yet; search for
            //   the string "omitted:" to see what those are
            //
            GenerateTestOutput(@"mdtest-1.1-alt");

            //
            // a few additional random "Hello World" type tests
            //
            GenerateTestOutput(@"test-input");

            Benchmark();

            //AdHocTest();
            
            Console.ReadKey();
        }

        /// <summary>
        /// mini test harness for one-liner Markdown bug repros 
        /// for anything larger, I recommend using the folder based approach and GenerateTestOutput()
        /// </summary>
        private static void AdHocTest()
        {
            var m = new MarkdownSharp.Markdown();

            string input = "mail me at <<EMAIL>> please";
            string output = m.Transform(input);

            Console.WriteLine("input:");
            Console.WriteLine(input);
            Console.WriteLine("output:");
            Console.WriteLine(output);
        }

        /// <summary>
        /// iterates through all the test files in a given folder and generates file-based output 
        /// this is essentially the same as running the unit tests, but with diff-able results
        /// </summary>
        /// <remarks>
        /// two files should be present for each test:
        /// 
        /// test_name.text         -- input (raw markdown)
        /// test_name.html         -- output (expected cooked html output from reference markdown engine)
        /// 
        /// this file will be generated if, and ONLY IF, the expected output does not match the actual output:
        /// 
        /// test_name.xxxx.actual.html  -- actual output (actual cooked html output from our markdown c# engine)
        ///                             -- xxxx is the 16-bit CRC checksum of the file contents; this is included
        ///                                so you can tell if the contents of a failing test have changed
        /// </remarks>
        static void GenerateTestOutput(string testfolder)
        {
            var m = new MarkdownSharp.Markdown();

            Console.WriteLine();
            Console.WriteLine(@"MarkdownSharp v" + m.Version + @" test run on " + Path.DirectorySeparatorChar + testfolder);
            Console.WriteLine();

            string path = Path.Combine(ExecutingAssemblyPath, testfolder);
            string output;
            string expected;
            string actual;

            int ok = 0;
            int err = 0;
            int errnew = 0;
            int total = 0;            

            foreach (var file in Directory.GetFiles(path, "*.text"))
            {

                expected = FileContents(Path.ChangeExtension(file, "html"));
                output = m.Transform(FileContents(file));
                
                total++;

                Console.Write(String.Format("{0:000} {1,-55}", total, Path.GetFileNameWithoutExtension(file)));

                if (output == expected)
                {
                    ok++;
                    Console.WriteLine("OK");
                }
                else
                {

                    actual = Path.ChangeExtension(file, GetCrc16(output) + ".actual.html");

                    err++;
                    if (File.Exists(actual))
                    {
                        Console.WriteLine("Mismatch");
                    }
                    else
                    {
                        errnew++;
                        Console.WriteLine("Mismatch *NEW*");                        
                        File.WriteAllText(actual, output);
                    }
                }
            }

            Console.WriteLine();
            Console.WriteLine("Tests        : " + total);
            Console.WriteLine("OK           : " + ok);
            Console.Write("Mismatch     : " + err);
            if (errnew > 0)
                Console.WriteLine(" (" + errnew + " *NEW*)");
            else
                Console.WriteLine();

            if (errnew > 0)
            {
                Console.WriteLine();
                Console.WriteLine("for each mismatch, an *.actual.html file was generated in");
                Console.WriteLine(path);
                Console.WriteLine("to troubleshoot mismatches, use a diff tool on *.html and *.actual.html");
            }

        }

        /// <summary>
        /// returns CRC-16 of string as 4 hex characters
        /// </summary>
        private static string GetCrc16(string s)
        {            
            if (String.IsNullOrEmpty(s)) return "";
            byte[] b = new Crc16().ComputeChecksumBytes(Encoding.UTF8.GetBytes(s));
            return b[0].ToString("x2") + b[1].ToString("x2");
        }


        /// <summary>
        /// returns the contents of the specified file as a string  
        /// assumes the file is relative to the root of the project
        /// </summary>
        static string FileContents(string filename)<commit_msg>enhance Test() to fallback to comparing input/output with whitespace removed; this eliminates 2 false "Mismatches" in mdtest-1.1 files<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Text.RegularExpressions;

namespace MarkdownSharpTests
{
    class Program
    {

        static void Main(string[] args)
        {

            //UnitTests();

            //
            // this is the closest thing to a set of Markdown reference tests I could find
            //
            // see http://six.pairlist.net/pipermail/markdown-discuss/2009-February/001526.html
            // and http://michelf.com/docs/projets/mdtest-1.1.zip
            // and http://git.michelf.com/mdtest/
            //
            Test(@"mdtest-1.1");

            //
            // same as mdtest-1.1, but:
            //
            // * remove any non-significant whitespace or extra paragraph differences
            //   (there are only two as I recall; not sure why, but frankly who cares)
            // * comment out any edge conditions we aren't dealing with yet; search for
            //   the string "omitted:" to see what those are
            //
            Test(@"mdtest-1.1-alt");

            //
            // a few additional random "Hello World" type tests
            //
            Test(@"test-input");

            Benchmark();

            //AdHocTest();
            
            Console.ReadKey();
        }

        /// <summary>
        /// mini test harness for one-liner Markdown bug repros 
        /// for anything larger, I recommend using the folder based approach and Test()
        /// </summary>
        private static void AdHocTest()
        {
            var m = new MarkdownSharp.Markdown();

            string input = "mail me at <<EMAIL>> please";
            string output = m.Transform(input);

            Console.WriteLine("input:");
            Console.WriteLine(input);
            Console.WriteLine("output:");
            Console.WriteLine(output);
        }

        /// <summary>
        /// iterates through all the test files in a given folder and generates file-based output 
        /// this is essentially the same as running the unit tests, but with diff-able results
        /// </summary>
        /// <remarks>
        /// two files should be present for each test:
        /// 
        /// test_name.text         -- input (raw markdown)
        /// test_name.html         -- output (expected cooked html output from reference markdown engine)
        /// 
        /// this file will be generated if, and ONLY IF, the expected output does not match the actual output:
        /// 
        /// test_name.xxxx.actual.html  -- actual output (actual cooked html output from our markdown c# engine)
        ///                             -- xxxx is the 16-bit CRC checksum of the file contents; this is included
        ///                                so you can tell if the contents of a failing test have changed
        /// </remarks>
        static void Test(string testfolder)
        {
            var m = new MarkdownSharp.Markdown();

            Console.WriteLine();
            Console.WriteLine(@"MarkdownSharp v" + m.Version + @" test run on " + Path.DirectorySeparatorChar + testfolder);
            Console.WriteLine();

            string path = Path.Combine(ExecutingAssemblyPath, testfolder);
            string output;
            string expected;
            string actualpath;

            int ok = 0;
            int okalt = 0;
            int err = 0;
            int errnew = 0;
            int total = 0;            

            foreach (var file in Directory.GetFiles(path, "*.text"))
            {

                expected = FileContents(Path.ChangeExtension(file, "html"));                
                output = m.Transform(FileContents(file));

                actualpath = Path.ChangeExtension(file, GetCrc16(output) + ".actual.html");
                
                total++;

                Console.Write(String.Format("{0:000} {1,-55}", total, Path.GetFileNameWithoutExtension(file)));

                if (output == expected)
                {
                    ok++;
                    Console.WriteLine("OK");
                }
                else if (RemoveWhitespace(output) == RemoveWhitespace(expected))
                {
                    ok++;
                    okalt++;
                    Console.WriteLine("OK^");
                    File.WriteAllText(actualpath, output);
                }
                else
                {                    
                    err++;
                    if (File.Exists(actualpath))
                    {
                        Console.WriteLine("Mismatch");
                    }
                    else
                    {
                        errnew++;
                        Console.WriteLine("Mismatch *NEW*");
                        File.WriteAllText(actualpath, output);
                    }
                }
            }

            Console.WriteLine();
            Console.WriteLine("Tests        : " + total);
            if (okalt > 0)
                Console.WriteLine("OK           : " + ok + " (^ " + okalt + " whitespace differences)");
            else
                Console.WriteLine("OK           : " + ok);
            Console.Write("Mismatch     : " + err);
            if (errnew > 0)
                Console.WriteLine(" (" + errnew + " *NEW*)");
            else
                Console.WriteLine();

            if (errnew > 0)
            {
                Console.WriteLine();
                Console.WriteLine("for each mismatch, an *.actual.html file was generated in");
                Console.WriteLine(path);
                Console.WriteLine("to troubleshoot mismatches, use a diff tool on *.html and *.actual.html");
            }

        }

        /// <summary>
        /// removes any empty newlines and any leading spaces at the start of lines
        /// </summary>
        private static string RemoveWhitespace(string s)
        {
            return Regex.Replace(s, @"^\n|^\s+", "", RegexOptions.Multiline);
        }


        /// <summary>
        /// returns CRC-16 of string as 4 hex characters
        /// </summary>
        private static string GetCrc16(string s)
        {            
            if (String.IsNullOrEmpty(s)) return "";
            byte[] b = new Crc16().ComputeChecksumBytes(Encoding.UTF8.GetBytes(s));
            return b[0].ToString("x2") + b[1].ToString("x2");
        }


        /// <summary>
        /// returns the contents of the specified file as a string  
        /// assumes the file is relative to the root of the project
        /// </summary>
        static string FileContents(string filename)
{'fraction_non_alphanumeric': 0.10526315789473684, 'fraction_numerical': 0.007673823734594218, 'mean_word_length': 1.3360492485967772, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3924265', 'n_tokens_mistral': 3242, 'n_tokens_neox': 3003, 'n_words': 917}