public void FA001_DocumentsWithRevTracking(string testId, string src) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Load the source document DirectoryInfo sourceDir = new DirectoryInfo("../../../../TestFiles/"); FileInfo sourceDocxFi = new FileInfo(Path.Combine(sourceDir.FullName, src)); WmlDocument wmlSourceDocument = new WmlDocument(sourceDocxFi.FullName); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Create the dir for the test var rootTempDir = TestUtil.TempDir; var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId)); if (thisTestTempDir.Exists) { Assert.True(false, "Duplicate test id: " + testId); } else { thisTestTempDir.Create(); } var tempDirFullName = thisTestTempDir.FullName; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Copy src DOCX to temp directory, for ease of review var sourceDocxCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, sourceDocxFi.Name)); if (!sourceDocxCopiedToDestFileName.Exists) { wmlSourceDocument.SaveAs(sourceDocxCopiedToDestFileName.FullName); } var sourceDocxAcceptedCopiedToDestFileName = new FileInfo(Path.Combine(tempDirFullName, sourceDocxFi.Name.ToLower().Replace(".docx", "-accepted.docx"))); var wmlSourceAccepted = RevisionProcessor.AcceptRevisions(wmlSourceDocument); wmlSourceAccepted.SaveAs(sourceDocxAcceptedCopiedToDestFileName.FullName); var outFi = new FileInfo(Path.Combine(tempDirFullName, "Output.docx")); FormattingAssemblerSettings settings = new FormattingAssemblerSettings(); var assembledWml = FormattingAssembler.AssembleFormatting(wmlSourceDocument, settings); assembledWml.SaveAs(outFi.FullName); var outAcceptedFi = new FileInfo(Path.Combine(tempDirFullName, "Output-accepted.docx")); var assembledAcceptedWml = RevisionProcessor.AcceptRevisions(assembledWml); assembledAcceptedWml.SaveAs(outAcceptedFi.FullName); Validate(outFi); }
public static bool HasTrackedRevisions(WordprocessingDocument doc) { return(RevisionProcessor.HasTrackedRevisions(doc)); }
public static bool HasTrackedRevisions(WmlDocument document) { return(RevisionProcessor.HasTrackedRevisions(document)); }
public static bool PartHasTrackedRevisions(OpenXmlPart part) { return(RevisionProcessor.PartHasTrackedRevisions(part)); }
public static void AcceptRevisions(WordprocessingDocument doc) { RevisionProcessor.AcceptRevisions(doc); }
public void DoTest(string name) { var sourceFi = new FileInfo(Path.Combine(TestUtil.SourceDir.FullName, name)); var baselineAcceptedFi = new FileInfo(Path.Combine(TestUtil.SourceDir.FullName, name.Replace(".docx", "-Accepted.docx"))); var baselineRejectedFi = new FileInfo(Path.Combine(TestUtil.SourceDir.FullName, name.Replace(".docx", "-Rejected.docx"))); WmlDocument sourceWml = new WmlDocument(sourceFi.FullName); WmlDocument afterRejectingWml = RevisionProcessor.RejectRevisions(sourceWml); WmlDocument afterAcceptingWml = RevisionProcessor.AcceptRevisions(sourceWml); var processedAcceptedFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceFi.Name.Replace(".docx", "-Accepted.docx"))); afterAcceptingWml.SaveAs(processedAcceptedFi.FullName); var processedRejectedFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceFi.Name.Replace(".docx", "-Rejected.docx"))); afterRejectingWml.SaveAs(processedRejectedFi.FullName); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Copy source files to temp dir if (m_CopySourceFilesToTempDir) { while (true) { try { ////////// CODE TO REPEAT UNTIL SUCCESS ////////// var sourceDocxCopiedToDestFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceFi.Name)); if (!sourceDocxCopiedToDestFi.Exists) { sourceWml.SaveAs(sourceDocxCopiedToDestFi.FullName); } ////////////////////////////////////////////////// break; } catch (IOException) { System.Threading.Thread.Sleep(50); } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // create batch file to copy properly processed documents to the TestFiles directory. while (true) { try { ////////// CODE TO REPEAT UNTIL SUCCESS ////////// var batchFileName = "Copy-Gen-Files-To-TestFiles.bat"; var batchFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, batchFileName)); var batch = ""; batch += "copy " + processedAcceptedFi.FullName + " " + baselineAcceptedFi.FullName + Environment.NewLine; batch += "copy " + processedRejectedFi.FullName + " " + baselineRejectedFi.FullName + Environment.NewLine; if (batchFi.Exists) { File.AppendAllText(batchFi.FullName, batch); } else { File.WriteAllText(batchFi.FullName, batch); } ////////////////////////////////////////////////// break; } catch (IOException) { System.Threading.Thread.Sleep(50); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Open Windows Explorer if (m_OpenTempDirInExplorer) { while (true) { try { ////////// CODE TO REPEAT UNTIL SUCCESS ////////// var semaphorFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, "z_ExplorerOpenedSemaphore.txt")); if (!semaphorFi.Exists) { File.WriteAllText(semaphorFi.FullName, ""); TestUtil.Explorer(TestUtil.TempDir); } ////////////////////////////////////////////////// break; } catch (IOException) { System.Threading.Thread.Sleep(50); } } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Use WmlComparer to see if accepted baseline is same as processed if (baselineAcceptedFi.Exists) { var baselineAcceptedWml = new WmlDocument(baselineAcceptedFi.FullName); WmlComparerSettings wmlComparerSettings = new WmlComparerSettings(); WmlDocument result = WmlComparer.Compare(baselineAcceptedWml, afterAcceptingWml, wmlComparerSettings); var revisions = WmlComparer.GetRevisions(result, wmlComparerSettings); if (revisions.Any()) { Assert.True(false, "Regression Error: Accepted baseline document did not match processed document"); } } else { Assert.True(false, "No Accepted baseline document"); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Use WmlComparer to see if rejected baseline is same as processed if (baselineRejectedFi.Exists) { var baselineRejectedWml = new WmlDocument(baselineRejectedFi.FullName); WmlComparerSettings wmlComparerSettings = new WmlComparerSettings(); WmlDocument result = WmlComparer.Compare(baselineRejectedWml, afterRejectingWml, wmlComparerSettings); var revisions = WmlComparer.GetRevisions(result, wmlComparerSettings); if (revisions.Any()) { Assert.True(false, "Regression Error: Rejected baseline document did not match processed document"); } } else { Assert.True(false, "No Rejected baseline document"); } }
public void WC003_Compare(string testId, string name1, string name2, int revisionCount) { var sourceDir = new DirectoryInfo("../../../../TestFiles/"); var source1Docx = new FileInfo(Path.Combine(sourceDir.FullName, name1)); var source2Docx = new FileInfo(Path.Combine(sourceDir.FullName, name2)); var rootTempDir = TestUtil.TempDir; var thisTestTempDir = new DirectoryInfo(Path.Combine(rootTempDir.FullName, testId)); if (thisTestTempDir.Exists) { Assert.True(false, "Duplicate test id???"); } else { thisTestTempDir.Create(); } var source1CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source1Docx.Name)); var source2CopiedToDestDocx = new FileInfo(Path.Combine(thisTestTempDir.FullName, source2Docx.Name)); File.Copy(source1Docx.FullName, source1CopiedToDestDocx.FullName); File.Copy(source2Docx.FullName, source2CopiedToDestDocx.FullName); var before = source1CopiedToDestDocx.Name.Replace(".docx", ""); var after = source2CopiedToDestDocx.Name.Replace(".docx", ""); var docxWithRevisionsFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, before + "-COMPARE-" + after + ".docx")); var source1Wml = new WmlDocument(source1CopiedToDestDocx.FullName); var source2Wml = new WmlDocument(source2CopiedToDestDocx.FullName); var settings = new WmlComparerSettings { DebugTempFileDi = thisTestTempDir }; var comparedWml = OpenXmlPowerTools.WmlComparer.WmlComparer.Compare(source1Wml, source2Wml, settings); comparedWml.SaveAs(docxWithRevisionsFi.FullName); // validate generated document var validationErrors = ""; using (var ms = new MemoryStream()) { ms.Write(comparedWml.DocumentByteArray, 0, comparedWml.DocumentByteArray.Length); using var wDoc = WordprocessingDocument.Open(ms, true); var validator = new OpenXmlValidator(); var errors = validator.Validate(wDoc).Where(e => !ExpectedErrors.Contains(e.Description)); if (errors.Any()) { var ind = " "; var sb = new StringBuilder(); foreach (var err in errors) { sb.Append("Error" + Environment.NewLine); sb.Append(ind + "ErrorType: " + err.ErrorType.ToString() + Environment.NewLine); sb.Append(ind + "Description: " + err.Description + Environment.NewLine); sb.Append(ind + "Part: " + err.Part.Uri.ToString() + Environment.NewLine); sb.Append(ind + "XPath: " + err.Path.XPath + Environment.NewLine); } validationErrors = sb.ToString(); } } if (!string.IsNullOrEmpty(validationErrors)) { Assert.True(false, validationErrors); } var settings2 = new WmlComparerSettings(); var revisionWml = new WmlDocument(docxWithRevisionsFi.FullName); var revisions = OpenXmlPowerTools.WmlComparer.WmlComparer.GetRevisions(revisionWml, settings); Assert.Equal(revisionCount, revisions.Count); var afterRejectingWml = RevisionProcessor.RejectRevisions(revisionWml); var WRITE_TEMP_FILES = true; if (WRITE_TEMP_FILES) { var afterRejectingFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, "AfterRejecting.docx")); afterRejectingWml.SaveAs(afterRejectingFi.FullName); } var afterRejectingComparedWml = OpenXmlPowerTools.WmlComparer.WmlComparer.Compare(source1Wml, afterRejectingWml, settings); var sanityCheck1 = OpenXmlPowerTools.WmlComparer.WmlComparer.GetRevisions(afterRejectingComparedWml, settings); if (WRITE_TEMP_FILES) { var afterRejectingComparedFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, "AfterRejectingCompared.docx")); afterRejectingComparedWml.SaveAs(afterRejectingComparedFi.FullName); } var afterAcceptingWml = RevisionProcessor.AcceptRevisions(revisionWml); if (WRITE_TEMP_FILES) { var afterAcceptingFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, "AfterAccepting.docx")); afterAcceptingWml.SaveAs(afterAcceptingFi.FullName); } var afterAcceptingComparedWml = OpenXmlPowerTools.WmlComparer.WmlComparer.Compare(source2Wml, afterAcceptingWml, settings); var sanityCheck2 = OpenXmlPowerTools.WmlComparer.WmlComparer.GetRevisions(afterAcceptingComparedWml, settings); if (WRITE_TEMP_FILES) { var afterAcceptingComparedFi = new FileInfo(Path.Combine(thisTestTempDir.FullName, "AfterAcceptingCompared.docx")); afterAcceptingComparedWml.SaveAs(afterAcceptingComparedFi.FullName); } if (sanityCheck1.Count != 0) { Assert.True(false, "Sanity Check #1 failed"); } if (sanityCheck2.Count != 0) { Assert.True(false, "Sanity Check #2 failed"); } }
private static WmlDocument CompareInternal( WmlDocument source1, WmlDocument source2, WmlComparerSettings settings, bool preProcessMarkupInOriginal) { if (preProcessMarkupInOriginal) { source1 = PreProcessMarkup(source1, settings.StartingIdForFootnotesEndnotes + 1000); } source2 = PreProcessMarkup(source2, settings.StartingIdForFootnotesEndnotes + 2000); SaveDocumentIfDesired(source1, "Source1-Step1-PreProcess.docx", settings); SaveDocumentIfDesired(source2, "Source2-Step1-PreProcess.docx", settings); // at this point, both source1 and source2 have unid on every element. These are the values that will // enable reassembly of the XML tree. But we need other values. // In source1: // - accept tracked revisions // - determine hash code for every block-level element // - save as attribute on every element // - accept tracked revisions and reject tracked revisions leave the unids alone, where possible. // - after accepting and calculating the hash, then can use the unids to find the right block-level // element in the unmodified source1, and install the hash // In source2: // - reject tracked revisions // - determine hash code for every block-level element // - save as an attribute on every element // - after rejecting and calculating the hash, then can use the unids to find the right block-level element // in the unmodified source2, and install the hash // - sometimes after accepting or rejecting tracked revisions, several paragraphs will get coalesced into a // single paragraph due to paragraph marks being inserted / deleted. // - in this case, some paragraphs will not get a hash injected onto them. // - if a paragraph doesn't have a hash, then it will never correspond to another paragraph, and such // issues will need to be resolved in the normal execution of the LCS algorithm. // - note that when we do propagate the unid through for the first paragraph. // Establish correlation between the two. // Find the longest common sequence of block-level elements where hash codes are the same. // this sometimes will be every block level element in the document. Or sometimes will be just a fair // number of them. // at the start of doing the LCS algorithm, we will match up content, and put them in corresponding unknown // correlated comparison units. Those paragraphs will only ever be matched to their corresponding paragraph. // then the algorithm can proceed as usual. // need to call ChangeFootnoteEndnoteReferencesToUniqueRange before creating the wmlResult document, so that // the same GUID ids are used for footnote and endnote references in both the 'after' document, and in the // result document. WmlDocument source1AfterAccepting = RevisionProcessor.AcceptRevisions(source1); WmlDocument source2AfterRejecting = RevisionProcessor.RejectRevisions(source2); SaveDocumentIfDesired(source1AfterAccepting, "Source1-Step2-AfterAccepting.docx", settings); SaveDocumentIfDesired(source2AfterRejecting, "Source2-Step2-AfterRejecting.docx", settings); // this creates the correlated hash codes that enable us to match up ranges of paragraphs based on // accepting in source1, rejecting in source2 source1 = HashBlockLevelContent(source1, source1AfterAccepting, settings); source2 = HashBlockLevelContent(source2, source2AfterRejecting, settings); SaveDocumentIfDesired(source1, "Source1-Step3-AfterHashing.docx", settings); SaveDocumentIfDesired(source2, "Source2-Step3-AfterHashing.docx", settings); // Accept revisions in before, and after source1 = RevisionProcessor.AcceptRevisions(source1); source2 = RevisionProcessor.AcceptRevisions(source2); SaveDocumentIfDesired(source1, "Source1-Step4-AfterAccepting.docx", settings); SaveDocumentIfDesired(source2, "Source2-Step4-AfterAccepting.docx", settings); // after accepting revisions, some unids may have been removed by revision accepter, along with the // correlatedSHA1Hash codes, this is as it should be. // but need to go back in and add guids to paragraphs that have had them removed. using (var ms = new MemoryStream()) { ms.Write(source2.DocumentByteArray, 0, source2.DocumentByteArray.Length); using (WordprocessingDocument wDoc = WordprocessingDocument.Open(ms, true)) { AddUnidsToMarkupInContentParts(wDoc); } } var wmlResult = new WmlDocument(source1); using (var ms1 = new MemoryStream()) using (var ms2 = new MemoryStream()) { ms1.Write(source1.DocumentByteArray, 0, source1.DocumentByteArray.Length); ms2.Write(source2.DocumentByteArray, 0, source2.DocumentByteArray.Length); WmlDocument producedDocument; using (WordprocessingDocument wDoc1 = WordprocessingDocument.Open(ms1, true)) using (WordprocessingDocument wDoc2 = WordprocessingDocument.Open(ms2, true)) { producedDocument = ProduceDocumentWithTrackedRevisions(settings, wmlResult, wDoc1, wDoc2); } SaveDocumentsAfterProducingDocument(ms1, ms2, settings); SaveCleanedDocuments(source1, producedDocument, settings); return(producedDocument); } }
public void RP001(string name) { var sourceDir = new DirectoryInfo("../../../../TestFiles/"); var sourceFi = new FileInfo(Path.Combine(sourceDir.FullName, name)); var baselineAcceptedFi = new FileInfo(Path.Combine(sourceDir.FullName, name.Replace(".docx", "-Accepted.docx"))); var baselineRejectedFi = new FileInfo(Path.Combine(sourceDir.FullName, name.Replace(".docx", "-Rejected.docx"))); var sourceWml = new WmlDocument(sourceFi.FullName); var afterRejectingWml = RevisionProcessor.RejectRevisions(sourceWml); var afterAcceptingWml = RevisionProcessor.AcceptRevisions(sourceWml); var processedAcceptedFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceFi.Name.Replace(".docx", "-Accepted.docx"))); afterAcceptingWml.SaveAs(processedAcceptedFi.FullName); var processedRejectedFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, sourceFi.Name.Replace(".docx", "-Rejected.docx"))); afterRejectingWml.SaveAs(processedRejectedFi.FullName); // create batch file to copy properly processed documents to the TestFiles directory. while (true) { try { var batchFileName = "Copy-Gen-Files-To-TestFiles.bat"; var batchFi = new FileInfo(Path.Combine(TestUtil.TempDir.FullName, batchFileName)); var batch = ""; batch += "copy " + processedAcceptedFi.FullName + " " + baselineAcceptedFi.FullName + Environment.NewLine; batch += "copy " + processedRejectedFi.FullName + " " + baselineRejectedFi.FullName + Environment.NewLine; if (batchFi.Exists) { File.AppendAllText(batchFi.FullName, batch); } else { File.WriteAllText(batchFi.FullName, batch); } break; } catch (IOException) { System.Threading.Thread.Sleep(50); } } // Use WmlComparer to see if accepted baseline is same as processed if (baselineAcceptedFi.Exists) { var baselineAcceptedWml = new WmlDocument(baselineAcceptedFi.FullName); var wmlComparerSettings = new WmlComparerSettings(); var result = OpenXmlPowerTools.WmlComparer.WmlComparer.Compare(baselineAcceptedWml, afterAcceptingWml, wmlComparerSettings); var revisions = OpenXmlPowerTools.WmlComparer.WmlComparer.GetRevisions(result, wmlComparerSettings); if (revisions.Any()) { Assert.True(false, "Regression Error: Accepted baseline document did not match processed document"); } } else { Assert.True(false, "No Accepted baseline document"); } // Use WmlComparer to see if rejected baseline is same as processed if (baselineRejectedFi.Exists) { var baselineRejectedWml = new WmlDocument(baselineRejectedFi.FullName); var wmlComparerSettings = new WmlComparerSettings(); var result = OpenXmlPowerTools.WmlComparer.WmlComparer.Compare(baselineRejectedWml, afterRejectingWml, wmlComparerSettings); var revisions = OpenXmlPowerTools.WmlComparer.WmlComparer.GetRevisions(result, wmlComparerSettings); if (revisions.Any()) { Assert.True(false, "Regression Error: Rejected baseline document did not match processed document"); } } else { Assert.True(false, "No Rejected baseline document"); } }