/// <summary> /// Parse an file using a NodeListener and IReport instance and compare the resulting report. /// </summary> /// <typeparam name="TCtx"></typeparam> /// <param name="fileName">The file name to parse</param> /// <param name="reportFileName">The file that contains the expected report</param> /// <param name="reportType">The Type of the IReport instance to be instantiated.</param> public static void ParseWithNodeListenerReportCompare <TCtx>(string fileName, string reportFileName, System.Type reportType) where TCtx : class { Assert.IsTrue(Tools.Reflection.IsTypeOf(reportType, typeof(IReport))); IReport report = null;//Variable to receive the created report instance. TypeCobol.Compiler.Parser.NodeListenerFactory <TCtx> factory = () => { object obj = System.Activator.CreateInstance(reportType); Assert.IsTrue(obj is NodeListener <TCtx>); TypeCobol.Compiler.Parser.NodeListener <TCtx> nodeListener = (TypeCobol.Compiler.Parser.NodeListener <TCtx>)obj; Assert.IsNotNull(nodeListener); report = (IReport)nodeListener; return(nodeListener); }; //Register the Node Listener Factory TypeCobol.Compiler.Parser.NodeDispatcher <TCtx> .RegisterStaticNodeListenerFactory(factory); try { string input = Path.Combine(ROOT_INPUT, fileName); string output = Path.Combine(ROOT_OUTPUT, reportFileName); DocumentFormat format = DocumentFormat.RDZReferenceFormat; var parser = new TypeCobol.Parser(); var typeCobolOption = new TypeCobolOptions { ExecToStep = ExecutionStep.CrossCheck }; #if EUROINFO_RULES bool autoRemarks = false; typeCobolOption.AutoRemarksEnable = autoRemarks; #endif String copyFolder = Path.Combine(Directory.GetCurrentDirectory(), ROOT_COPY); parser.Init(input, typeCobolOption, format, new List <string>() { copyFolder }); parser.Parse(input); var allDiags = parser.Results.AllDiagnostics(); if (allDiags.Count == 0) { if (report != null) { using (System.IO.StringWriter sw = new StringWriter()) { report.Report(sw); // compare with expected result string result = sw.ToString(); string expected = File.ReadAllText(output, format.Encoding); TypeCobol.Test.TestUtils.compareLines(input, result, expected); } } } } finally { TypeCobol.Compiler.Parser.NodeDispatcher <TCtx> .RemoveStaticNodeListenerFactory(factory); } }
public static void CheckTests(string rootFolder, string resultFolder, string timedResultFile, string regex, string[] include, string[] exclude, string[] copiesFolder, string skelPath, int stopAfterAsManyErrors, bool autoRemarks, string expectedResultFile) { string[] files = Directory.GetFiles(rootFolder, regex, SearchOption.AllDirectories); bool codegen = true; var format = TypeCobol.Compiler.DocumentFormat.RDZReferenceFormat; string resultFile = "GeneratedResultFile.txt"; //Initialize both files File.WriteAllText(timedResultFile, ""); if (expectedResultFile != null) { File.WriteAllText(resultFile, ""); } int tested = 0, nbFilesInError = 0, ignores = 0; TimeSpan parsingSumDuration = new TimeSpan(0); TimeSpan codeGenSumDuration = new TimeSpan(0); int parseErrors = 0; int codegenErrors = 0; int codegenDiff = 0; foreach (var file in files) { string filename = Path.GetFileName(file); AppendTextToFiles((filename + ':'), timedResultFile, resultFile); bool ignore = include.Length > 0 && !include.Contains(filename); if (!ignore) { ignore = exclude.Contains(filename); } if (ignore) { ignores++; File.AppendAllText(timedResultFile, " ignored.\n"); continue; } string path = Path.Combine(rootFolder, filename); Stopwatch watch = new Stopwatch(); watch.Start(); var document = new TypeCobol.Parser(); var options = new TypeCobolOptions { ExecToStep = ExecutionStep.CrossCheck, #if EUROINFO_RULES AutoRemarksEnable = autoRemarks #endif }; document.Init(path, options, format, copiesFolder); document.Parse(path); watch.Stop(); //TestJSONSerializer.DumpAsJSON(unit.CodeElementsDocumentSnapshot.CodeElements, filename); TimeSpan elapsed = watch.Elapsed; parsingSumDuration += elapsed; string formatted = String.Format("{0:00}m{1:00}s{2:000}ms", elapsed.Minutes, elapsed.Seconds, elapsed.Milliseconds); AppendTextToFiles(" parsed in " + formatted + "\n", timedResultFile); AppendTextToFiles("- " + document.Results.PerfStatsForText.FirstCompilationTime + " ms : text update\n", timedResultFile); AppendTextToFiles("- " + document.Results.PerfStatsForScanner.FirstCompilationTime + " ms : scanner\n", timedResultFile); AppendTextToFiles("- " + document.Results.PerfStatsForPreprocessor.FirstCompilationTime + " ms : preprocessor\n", timedResultFile); AppendTextToFiles("- " + document.Results.PerfStatsForCodeElementsParser.FirstCompilationTime + " ms : code elements parser\n", timedResultFile); AppendTextToFiles("- " + document.Results.PerfStatsForTemporarySemantic.FirstCompilationTime + " ms : temporary semantic class parser\n", timedResultFile); AppendTextToFiles("- " + document.Results.PerfStatsForProgramCrossCheck.FirstCompilationTime + " ms : cross check class parser\n", timedResultFile); tested++; Console.WriteLine(filename); bool okay = true; var diagnostics = document.Results.AllDiagnostics(); if (diagnostics.Count > 0) { okay = false; parseErrors += diagnostics.Count; } displayAndWriteErrorsToGrammarResult(diagnostics, timedResultFile, resultFile); if (!okay) { nbFilesInError++; if (nbFilesInError >= stopAfterAsManyErrors) { break; } } if (codegen && okay) { watch.Reset(); watch.Start(); var writer = new StringWriter(); //Retrieve skeletons var skeletons = !string.IsNullOrEmpty(skelPath) ? Config.Parse(skelPath) : null; var generator = new TypeCobol.Codegen.Generators.DefaultGenerator(document.Results, writer, skeletons, null); var columns = document.Results.ProgramClassDocumentSnapshot.TextSourceInfo.ColumnsLayout; generator.Generate(document.Results, columns); writer.Close(); //Write duration to GrammarResultFile watch.Stop(); elapsed = watch.Elapsed; codeGenSumDuration += elapsed; formatted = String.Format("{0:00}m{1:00}s{2:000}ms", elapsed.Minutes, elapsed.Seconds, elapsed.Milliseconds); AppendTextToFiles(" generated in " + formatted + "\n", timedResultFile); //Error during generation, no need to check the content of generated Cobol if (generator.Diagnostics != null && generator.Diagnostics.Count > 0) { codegenErrors += generator.Diagnostics.Count; displayAndWriteErrorsToGrammarResult(generator.Diagnostics, timedResultFile, resultFile); nbFilesInError++; if (nbFilesInError >= stopAfterAsManyErrors) { break; } } else { //Compare generated Cobol with expected var expected = AsLines(File.ReadAllText(path, format.Encoding)); var actual = AsLines(writer.ToString()); Directory.CreateDirectory(resultFolder); var linesKO = new List <int>(); for (int i = 0; i < Math.Min(expected.Count, actual.Count); i++) { if (!expected[i].Equals(actual[i])) { linesKO.Add(i); } } var errors = new System.Text.StringBuilder(); string fmt = Lines2FormatString(Math.Max(expected.Count, actual.Count)); if (linesKO.Count > 0 || expected.Count != actual.Count) { errors.AppendLine("--- Lines mismatch ---"); File.WriteAllLines( resultFolder + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(file) + "-Expected" + Path.GetExtension(file), expected); File.WriteAllLines( resultFolder + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(file) + "-Actual" + Path.GetExtension(file), actual); } int start = -1; for (int i = 0; i < linesKO.Count; i++) { int currentline = linesKO[i]; bool follows = i > 0 && linesKO[i - 1] == currentline - 1; if (!follows) { start = currentline; before(errors, expected, currentline, 3, fmt); } bool preceeds = i + 1 < linesKO.Count && linesKO[i + 1] == currentline + 1; if (!preceeds) { diff(errors, expected, actual, start, currentline, fmt); after(errors, expected, currentline, 3, fmt); start = -1; } } for (int i = actual.Count; i < expected.Count; i++) { errors.AppendLine(String.Format("-{0:" + fmt + "} {1}", i, expected[i])); } for (int i = expected.Count; i < actual.Count; i++) { errors.AppendLine(String.Format("+{0:" + fmt + "} {1}", i, actual[i])); } if (errors.Length > 0) { codegenDiff += linesKO.Count + Math.Abs(actual.Count - expected.Count); AppendTextToFiles(errors.ToString(), timedResultFile, resultFile); if (okay) { nbFilesInError++; } } } } else { AppendTextToFiles("\n", timedResultFile, resultFile); } } TimeSpan totalTestDuration = parsingSumDuration + codeGenSumDuration; string parsingTotalDurationFormatted = String.Format("{0:00}m{1:00}s{2:000}ms", parsingSumDuration.Minutes, parsingSumDuration.Seconds, parsingSumDuration.Milliseconds); string message = "Files tested=" + tested + "/" + files.Length + ", files in error=" + nbFilesInError + ", ignored=" + ignores + "\n"; AppendTextToFiles(message, resultFile); if (parseErrors > 0) { message += "Parsing errors: " + parseErrors + '\n'; } if (codegenErrors > 0) { message += "Codegen errors: " + codegenErrors + '\n'; } if (codegenDiff > 0) { message += "Codegen Diff: " + codegenDiff + '\n'; } message += "Parsing time: " + parsingTotalDurationFormatted; if (codegen) { string codeGenTotalDurationFormatted = string.Format("{0:00}m{1:00}s{2:000}ms", codeGenSumDuration.Minutes, codeGenSumDuration.Seconds, codeGenSumDuration.Milliseconds); string totalDurationFormatted = String.Format("{0:00}m{1:00}s{2:000}ms", totalTestDuration.Minutes, totalTestDuration.Seconds, totalTestDuration.Milliseconds); message += " + Codegen time: " + codeGenTotalDurationFormatted + " => Total time: " + totalDurationFormatted; } AppendTextToFiles(message, timedResultFile); if (nbFilesInError > 0 && expectedResultFile == null) { Assert.Fail('\n' + message); //If no expectedFile to compare throw assert if error } else if (expectedResultFile != null) //If expectedFileResult exists compare the DefaultGeneratedFile with expectedFile { StreamReader expectedResultReader = new StreamReader(new FileStream(expectedResultFile, FileMode.Open)); StreamReader actualResultReader = new StreamReader(new FileStream(resultFile, FileMode.Open)); TestUtils.compareLines("GrammarTestCompareFiles", expectedResultReader.ReadToEnd(), actualResultReader.ReadToEnd()); //The test will fail if result files are different expectedResultReader.Close(); actualResultReader.Close(); } }
public void FullParsingAndGenerationTest() { string[] copiesFolder = new string[] { }; string pwd = Directory.GetCurrentDirectory(); var format = TypeCobol.Compiler.DocumentFormat.RDZReferenceFormat; string rootFolder = Directory.GetParent(pwd)?.Parent?.FullName + "\\TypeCobol.Test\\Parser\\Samples"; string textName = "BigBatch"; string filename = Path.GetFileName(textName); string path = Path.Combine(rootFolder, filename); TestUtils.CompilationStats stats = new TestUtils.CompilationStats(); stats.IterationNumber = 20; //Warmup before measurement var documentWarmup = new TypeCobol.Parser(); var optionsWarmup = new TypeCobolOptions { ExecToStep = ExecutionStep.CrossCheck, #if EUROINFO_RULES AutoRemarksEnable = true #endif }; for (int i = 0; i < stats.IterationNumber; i++) { documentWarmup = new TypeCobol.Parser(); documentWarmup.Init(path, optionsWarmup, format, copiesFolder); documentWarmup.Parse(path); var document = new TypeCobol.Parser(); var options = new TypeCobolOptions { ExecToStep = ExecutionStep.CrossCheck, #if EUROINFO_RULES AutoRemarksEnable = true #endif }; document.Init(path, options, format, copiesFolder); document.Parse(path); stats.AverageTextUpdateTime += document.Results.PerfStatsForText.FirstCompilationTime; stats.AverageScannerTime += document.Results.PerfStatsForScanner.FirstCompilationTime; stats.AveragePreprocessorTime += document.Results.PerfStatsForPreprocessor.FirstCompilationTime; stats.AverageCodeElementParserTime += document.Results.PerfStatsForCodeElementsParser.FirstCompilationTime; stats.AverateTemporarySemanticsParserTime += document.Results.PerfStatsForTemporarySemantic.FirstCompilationTime; stats.AverageCrossCheckerParserTime += document.Results.PerfStatsForProgramCrossCheck.FirstCompilationTime; } //Compute average time needed for each phase stats.AverageTextUpdateTime = (int)stats.AverageTextUpdateTime / stats.IterationNumber; stats.AverageScannerTime = (int)stats.AverageScannerTime / stats.IterationNumber; stats.AveragePreprocessorTime = (int)stats.AveragePreprocessorTime / stats.IterationNumber; stats.AverageCodeElementParserTime = (int)stats.AverageCodeElementParserTime / stats.IterationNumber; stats.AverateTemporarySemanticsParserTime = (int)stats.AverateTemporarySemanticsParserTime / stats.IterationNumber; stats.AverageCrossCheckerParserTime = (int)stats.AverageCrossCheckerParserTime / stats.IterationNumber; stats.AverageTotalProcessingTime = stats.AverageCodeElementParserTime + stats.AverageCrossCheckerParserTime + stats.AveragePreprocessorTime + stats.AverageScannerTime + stats.AverageTextUpdateTime + stats.AverateTemporarySemanticsParserTime; stats.Line = documentWarmup.Results.CobolTextLines.Count; stats.TotalCodeElements = documentWarmup.Results.CodeElementsDocumentSnapshot.CodeElements.Count(); TestUtils.CreateRunReport(TestUtils.GetReportDirectoryPath(), filename + "-FullParsing", stats, null); }