public void DefaultPropertyEditTest() { var root = Path.Combine(Environment.CurrentDirectory, "Apps", "MyWeather.msapp"); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); Assert.IsFalse(errors.HasErrors); MergeTester( msapp, (branchADoc) => { // Nothing }, (branchBDoc) => { branchBDoc._screens.TryGetValue("Screen1", out var control); var label = control.Children.First(child => child.Name.Identifier == "Label1"); label.Properties.Add(new PropertyNode() { Identifier = "Fill", Expression = new ExpressionNode() { Expression = "Color.Blue" } }); }, (resultDoc) => { resultDoc._screens.TryGetValue("Screen1", out var control); var label = control.Children.First(child => child.Name.Identifier == "Label1"); var fillProp = label.Properties.First(prop => prop.Identifier == "Fill"); Assert.AreEqual("Color.Blue", fillProp.Expression.Expression); }); }
public void PropertyEditCollisonTest() { var root = Path.Combine(Environment.CurrentDirectory, "Apps", "MyWeather.msapp"); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); Assert.IsFalse(errors.HasErrors); MergeTester(msapp, (branchADoc) => { branchADoc._screens.TryGetValue("Screen1", out var control); var label = control.Children.First(child => child.Name.Identifier == "Label1"); var textProp = label.Properties.First(prop => prop.Identifier == "Text"); textProp.Expression.Expression = "UpdatedBranchA"; }, (branchBDoc) => { branchBDoc._screens.TryGetValue("Screen1", out var control); var label = control.Children.First(child => child.Name.Identifier == "Label1"); var textProp = label.Properties.First(prop => prop.Identifier == "Text"); textProp.Expression.Expression = "UpdatedBranchB"; }, (resultDoc) => { resultDoc._screens.TryGetValue("Screen1", out var control); var label = control.Children.First(child => child.Name.Identifier == "Label1"); var textProp = label.Properties.First(prop => prop.Identifier == "Text"); Assert.AreEqual("UpdatedBranchA", textProp.Expression.Expression); }); }
public void TestPackWhenEditorStateIsDeleted(string appName) { var root = Path.Combine(Environment.CurrentDirectory, "Apps", appName); Assert.IsTrue(File.Exists(root)); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); errors.ThrowOnErrors(); using (var tempDir = new TempDir()) { string outSrcDir = tempDir.Dir; // Save to sources msapp.SaveToSources(outSrcDir); // Delete Entropy directory var editorStatePath = Path.Combine(outSrcDir, "Src", "EditorState"); if (Directory.Exists(editorStatePath)) { Directory.Delete(editorStatePath, true); } // Load app from the sources after deleting the entropy var app = SourceSerializer.LoadFromSource(outSrcDir, new ErrorContainer()); using (var tempFile = new TempFile()) { // Repack the app MsAppSerializer.SaveAsMsApp(app, tempFile.FullPath, new ErrorContainer()); } } }
public void PropertyRemoveDefaultTest() { var root = Path.Combine(Environment.CurrentDirectory, "Apps", "MyWeather.msapp"); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); Assert.IsFalse(errors.HasErrors); MergeTester(msapp, (branchADoc) => { // Nothing }, (branchBDoc) => { branchBDoc._screens.TryGetValue("Screen1", out var control); var label = control.Children.First(child => child.Name.Identifier == "Label1"); var textProp = label.Properties.First(prop => prop.Identifier == "Text"); label.Properties.Remove(textProp); }, (resultDoc) => { resultDoc._screens.TryGetValue("Screen1", out var control); var label = control.Children.First(child => child.Name.Identifier == "Label1"); var textProp = label.Properties.FirstOrDefault(prop => prop.Identifier == "Text"); Assert.AreEqual(default, textProp);
public void TestTopParentSerialization(string appName, string topParentName) { var root = Path.Combine(Environment.CurrentDirectory, "Apps", appName); Assert.IsTrue(File.Exists(root)); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); errors.ThrowOnErrors(); using (var tempDir = new TempDir()) { string outSrcDir = tempDir.Dir; // Save to sources msapp.SaveToSources(outSrcDir); // Go find the source file for the editor state string filename = $"{topParentName}{EditorStateFileExtension}"; string fullFilePath = Path.Combine(outSrcDir, "Src", "EditorState", filename); if (File.Exists(fullFilePath)) { // Get the file for the specific control we're looking for DirectoryReader.Entry file = new DirectoryReader.Entry(fullFilePath); ControlTreeState editorState = file.ToObject <ControlTreeState>(); // Check that the IsTopParent was set correctly Assert.AreEqual(topParentName, editorState.TopParentName); } else { Assert.Fail($"Could not find expected file {fullFilePath}."); } } }
public void TestTableDefinitionsAreLastEntriesWhenEntropyDeleted(string appName) { var root = Path.Combine(Environment.CurrentDirectory, "Apps", appName); Assert.IsTrue(File.Exists(root)); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); errors.ThrowOnErrors(); using (var tempDir = new TempDir()) { string outSrcDir = tempDir.Dir; // Save to sources msapp.SaveToSources(outSrcDir); // Delete Entropy directory var entropyPath = Path.Combine(outSrcDir, "Entropy"); if (Directory.Exists(entropyPath)) { Directory.Delete(entropyPath, true); } // Load app from the sources after deleting the entropy var app = SourceSerializer.LoadFromSource(outSrcDir, new ErrorContainer()); using (var tempFile = new TempFile()) { // Repack the app MsAppSerializer.SaveAsMsApp(app, tempFile.FullPath, new ErrorContainer()); using (var stream = new FileStream(tempFile.FullPath, FileMode.Open)) { // Read the msapp file ZipArchive zipOpen = new ZipArchive(stream, ZipArchiveMode.Read); foreach (var entry in zipOpen.Entries) { var kind = FileEntry.TriageKind(FilePath.FromMsAppPath(entry.FullName)); switch (kind) { // Validate that the last entry in the DataSources.json is TableDefinition entry. case FileKind.DataSources: { var dataSourcesFromMsapp = ToObject <DataSourcesJson>(entry); var last = dataSourcesFromMsapp.DataSources.LastOrDefault(); Assert.AreEqual(last.TableDefinition != null, true); return; } default: break; } } } } } }
public void Test() { // Empty stream is invalid document, should generate a Read error. MemoryStream ms = new MemoryStream(); (var doc, var errors) = CanvasDocument.LoadFromMsapp(ms); Assert.IsTrue(errors.HasErrors); Assert.IsNull(doc); }
public void TestTopParentNameFallback(string appName, string topParentName) { var root = Path.Combine(Environment.CurrentDirectory, "Apps", appName); Assert.IsTrue(File.Exists(root)); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); errors.ThrowOnErrors(); using (var tempDir = new TempDir()) { string outSrcDir = tempDir.Dir; // Save to sources msapp.SaveToSources(outSrcDir); // Go find the source file for the editor state string filename = $"{topParentName}.editorstate.json"; string fullFilePath = Path.Combine(outSrcDir, "Src", "EditorState", filename); if (File.Exists(fullFilePath)) { // Get the file for the specific control we're looking for DirectoryReader.Entry file = new DirectoryReader.Entry(fullFilePath); ControlTreeState editorState = file.ToObject <ControlTreeState>(); // Rename the file so we know that the file name itself is used. string newFileName = Guid.NewGuid().ToString(); string newFilePath = Path.Combine(outSrcDir, "Src", "EditorState"); // Write out only the dictionary to the file, which is the older format. DirectoryWriter dir = new DirectoryWriter(newFilePath); dir.WriteAllJson(newFilePath, $"{newFileName}{EditorStateFileExtension}", editorState.ControlStates); // Remove the old file, we only want the re-written and re-named file File.Delete(fullFilePath); // Load app from the source folder var app = SourceSerializer.LoadFromSource(outSrcDir, new ErrorContainer()); // Find the relevant controls and check their top parent name foreach (var control in editorState.ControlStates) { app._editorStateStore.TryGetControlState(control.Value.Name, out ControlState state); Assert.AreEqual(newFileName, state.TopParentName); } } else { Assert.Fail($"Could not find expected file {fullFilePath}."); } } }
public void TestEditorStateRename(string appName) { var root = Path.Combine(Environment.CurrentDirectory, "Apps", appName); Assert.IsTrue(File.Exists(root)); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); errors.ThrowOnErrors(); using (var tempDir = new TempDir()) { string outSrcDir = tempDir.Dir; // Create a list of expected controles with an EditorState file List <string> expectedControlsWithEditorState = new List <string>(); expectedControlsWithEditorState.AddRange(msapp._screens.Keys); expectedControlsWithEditorState.AddRange(msapp._components.Keys); // Save to sources msapp.SaveToSources(outSrcDir); // Look for the expected controls in the EditorState files string srcPath = Path.Combine(outSrcDir, "Src", "EditorState"); foreach (string editorStateFile in Directory.GetFiles(srcPath, "*.editorstate.json", SearchOption.TopDirectoryOnly)) { string fileName = Path.GetFileName(editorStateFile).Replace(".editorstate.json", string.Empty); // Check for an exact match between the control and the file. if (expectedControlsWithEditorState.Contains(fileName)) { expectedControlsWithEditorState.Remove(fileName); continue; } // Replace any appended suffixes on Windows to see if there was a file collision. fileName = Regex.Replace(fileName, "(?:_\\d+)?$", string.Empty); // Check if the new file name without a suffix matches, otherwise fail the test if (expectedControlsWithEditorState.Contains(fileName)) { expectedControlsWithEditorState.Remove(fileName); } else { Assert.Fail($"Unexpected file {editorStateFile} in EditorState folder."); } } // There should be no expected files that were not found Assert.AreEqual <int>(expectedControlsWithEditorState.Count, 0, $"{expectedControlsWithEditorState.Count} editor state files not found in EditorState directory."); } }
public void TestScreenRename(string appName) { var root = Path.Combine(Environment.CurrentDirectory, "Apps", appName); Assert.IsTrue(File.Exists(root)); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); errors.ThrowOnErrors(); using (var tempDir = new TempDir()) { string outSrcDir = tempDir.Dir; // Create a list of screens expected to be seen in the output List <string> expectedScreens = msapp._screens.Keys.ToList(); // Save to sources msapp.SaveToSources(outSrcDir); // Look for the expected screens in the YAML files string srcPath = Path.Combine(outSrcDir, "Src"); foreach (string yamlFile in Directory.GetFiles(srcPath, "*.fx.yaml", SearchOption.TopDirectoryOnly)) { string fileName = Path.GetFileName(yamlFile).Replace(".fx.yaml", string.Empty); // Check for an exact match between the screen name and the file. if (expectedScreens.Contains(fileName)) { expectedScreens.Remove(fileName); continue; } // Replace any appended suffixes on Windows to see if there was a file collision. fileName = Regex.Replace(fileName, "(?:_\\d+)?$", string.Empty); // Check if the new file name without a suffix matches, otherwise fail the test if (expectedScreens.Contains(fileName)) { expectedScreens.Remove(fileName); } else { Assert.Fail($"Unexpected file {yamlFile} in Src folder."); } } // There should be no expected files that were not found Assert.AreEqual <int>(expectedScreens.Count, 0, $"{expectedScreens.Count} screens not found in Src directory."); } }
public void TestConnectionInstanceIDHandling(string appName) { var pathToMsApp = Path.Combine(Environment.CurrentDirectory, "Apps", appName); Assert.IsTrue(File.Exists(pathToMsApp)); var(msApp, errors) = CanvasDocument.LoadFromMsapp(pathToMsApp); errors.ThrowOnErrors(); // Testing if conn instance id is added to entropy Assert.IsNotNull(msApp._entropy.LocalConnectionIDReferences); using var sourcesTempDir = new TempDir(); var sourcesTempDirPath = sourcesTempDir.Dir; ErrorContainer errorsCaptured = msApp.SaveToSources(sourcesTempDirPath, pathToMsApp); errorsCaptured.ThrowOnErrors(); }
public void TestNoLocalDatabaseRefsWhenLocalDatabaseReferencesPropertyWasEmptyJson(string appName) { var pathToMsApp = Path.Combine(Environment.CurrentDirectory, "Apps", appName); Assert.IsTrue(File.Exists(pathToMsApp)); var(msApp, errors) = CanvasDocument.LoadFromMsapp(pathToMsApp); errors.ThrowOnErrors(); using var sourcesTempDir = new TempDir(); var sourcesTempDirPath = sourcesTempDir.Dir; msApp.SaveToSources(sourcesTempDirPath); var loadedMsApp = SourceSerializer.LoadFromSource(sourcesTempDirPath, new ErrorContainer()); Assert.IsTrue(loadedMsApp._entropy.WasLocalDatabaseReferencesEmpty.Value); Assert.IsFalse(loadedMsApp._entropy.LocalDatabaseReferencesAsEmpty); Assert.IsTrue(loadedMsApp._dataSourceReferences.Count == 0); }
public void NoOpMergeTest() { var root = Path.Combine(Environment.CurrentDirectory, "Apps", "MyWeather.msapp"); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); Assert.IsFalse(errors.HasErrors); MergeTester(msapp, (branchADoc) => { // Nothing }, (branchBDoc) => { // Nothing }, (resultDoc) => { Assert.AreEqual(4, resultDoc._editorStateStore.Contents.Count()); }); }
public void ScreenDeletionTest() { var root = Path.Combine(Environment.CurrentDirectory, "Apps", "Chess_for_Power_Apps_v1.03.msapp"); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); Assert.IsFalse(errors.HasErrors); MergeTester( msapp, (branchADoc) => { // Nothing }, (branchBDoc) => { branchBDoc._screens.Remove("Home Screen", out var control); }, (resultDoc) => { Assert.IsFalse(resultDoc._screens.ContainsKey("Home Screen")); }); }
public void TestGroupControlRecreation() { // Pull both the msapp and the baseline from our embedded resources. var root = Path.Combine(Environment.CurrentDirectory, "Apps", "GroupControlTest.msapp"); Assert.IsTrue(File.Exists(root)); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); errors.ThrowOnErrors(); msapp._editorStateStore.Remove("Group1"); msapp.ApplyBeforeMsAppWriteTransforms(errors); errors.ThrowOnErrors(); Assert.IsTrue(msapp._screens.TryGetValue("Screen1", out var screen)); var sourceFile = IRStateHelpers.CombineIRAndState(screen, errors, msapp._editorStateStore, msapp._templateStore, new UniqueIdRestorer(msapp._entropy), msapp._entropy); Assert.AreEqual("Screen1", sourceFile.ControlName); // Check that the group control was still moved to the end of the children list Assert.AreEqual("Group1", sourceFile.Value.TopParent.Children.Last().Name); }
public void TestScreenBaselines(string appName, string sourceFileName, string screenBaselineName) { // Pull both the msapp and the baseline from our embedded resources. var root = Path.Combine(Environment.CurrentDirectory, "Apps", appName); Assert.IsTrue(File.Exists(root)); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); errors.ThrowOnErrors(); // validate the source using (var tempDir = new TempDir()) { string outSrcDir = tempDir.Dir; msapp.SaveToSources(outSrcDir); var pathActual = Path.Combine(outSrcDir, "Src", sourceFileName); var pathExpected = Path.Combine(Environment.CurrentDirectory, "SrcBaseline", screenBaselineName); // TODO - as the format stabalizes, we can compare more aggressively. AssertFilesEqual(pathExpected, pathActual); } }
public void OpenMissingMsApp() { (var doc, var errors) = CanvasDocument.LoadFromMsapp(PathMissingMsapp); Assert.IsTrue(errors.HasErrors); Assert.IsNull(doc); }
public void SimpleControlAddTest() { var root = Path.Combine(Environment.CurrentDirectory, "Apps", "MyWeather.msapp"); (var msapp, var errors) = CanvasDocument.LoadFromMsapp(root); Assert.IsFalse(errors.HasErrors); MergeTester(msapp, (branchADoc) => { branchADoc._screens.TryGetValue("Screen1", out var control); control.Children.Add(new BlockNode() { Name = new TypedNameNode() { Identifier = "Foo", Kind = new TypeNode() { TypeName = "label" } }, Properties = new List <PropertyNode>() { new PropertyNode { Identifier = "SomeProp", Expression = new ExpressionNode() { Expression = "Expr" } } } }); }, (branchBDoc) => { branchBDoc._screens.TryGetValue("Screen1", out var control); control.Children.Add(new BlockNode() { Name = new TypedNameNode() { Identifier = "Bar", Kind = new TypeNode() { TypeName = "label" } }, Properties = new List <PropertyNode>() { new PropertyNode { Identifier = "SomeOtherProp", Expression = new ExpressionNode() { Expression = "Expr" } } } }); }, (resultDoc) => { resultDoc._screens.TryGetValue("Screen1", out var control); Assert.IsTrue(control.Children.Any(item => item.Name.Identifier == "Foo")); Assert.IsTrue(control.Children.Any(item => item.Name.Identifier == "Bar")); }); }
static void Main(string[] args) { Console.WriteLine($"MsApp/Source converter. Version: {SourceSerializer.CurrentSourceVersion}"); var mode = args.Length > 0 ? args[0]?.ToLower() : null; if (mode == "-test") { if (args.Length < 2) { Usage(); return; } string msAppPath = args[1]; Console.WriteLine("Test roundtripping: " + msAppPath); // Test round-tripping MsAppTest.StressTest(msAppPath); return; } if (mode == "-testall") { if (args.Length < 2) { Usage(); return; } // Roundtrip all .msapps in a folder. string msAppPathDir = args[1]; int countTotal = 0; int countPass = 0; Console.WriteLine("Test roundtripping all .msapps in : " + msAppPathDir); foreach (var msAppPath in Directory.EnumerateFiles(msAppPathDir, "*.msapp", SearchOption.TopDirectoryOnly)) { Stopwatch sw = Stopwatch.StartNew(); bool ok = MsAppTest.StressTest(msAppPath); var str = ok ? "Pass" : "FAIL"; countTotal++; if (ok) { countPass++; } sw.Stop(); Console.WriteLine($"Test: {Path.GetFileName(msAppPath)}: {str} ({sw.ElapsedMilliseconds/1000}s)"); } Console.WriteLine($"{countPass}/{countTotal} ({countPass * 100 / countTotal}% passed"); } else if (mode == "-unpack") { if (args.Length < 2) { Usage(); return; } string msAppPath = args[1]; msAppPath = Path.GetFullPath(msAppPath); if (!msAppPath.EndsWith(".msapp", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("must be path to .msapp file"); } string outDir; if (args.Length == 2) { outDir = msAppPath.Substring(0, msAppPath.Length - 6) + "_src"; // chop off ".msapp"; } else { outDir = args[2]; } Console.WriteLine($"Unpack: {msAppPath} --> {outDir} "); (CanvasDocument msApp, ErrorContainer errors) = CanvasDocument.LoadFromMsapp(msAppPath); errors.Write(Console.Error); if (errors.HasErrors) { return; } errors = msApp.SaveToSources(outDir); errors.Write(Console.Error); if (errors.HasErrors) { return; } // Test that we can repack { (CanvasDocument msApp2, ErrorContainer errors2) = CanvasDocument.LoadFromSources(outDir); errors2.Write(Console.Error); if (errors2.HasErrors) { return; } using (var temp = new TempFile()) { errors2 = msApp2.SaveToMsApp(temp.FullPath); errors2.Write(Console.Error); if (errors2.HasErrors) { return; } bool ok = MsAppTest.Compare(msAppPath, temp.FullPath, TextWriter.Null); } } } else if (mode == "-pack") { if (args.Length < 3) { Usage(); return; } string msAppPath = Path.GetFullPath(args[1]); string inputDir = Path.GetFullPath(args[2]); Console.WriteLine($"Pack: {inputDir} --> {msAppPath} "); (CanvasDocument msApp, ErrorContainer errors) = CanvasDocument.LoadFromSources(inputDir); errors.Write(Console.Error); if (errors.HasErrors) { return; } errors = msApp.SaveToMsApp(msAppPath); errors.Write(Console.Error); if (errors.HasErrors) { return; } } else if (mode == "-make") { if (args.Length < 4) { Usage(); return; } string msAppPath = Path.GetFullPath(args[1]); string pkgsPath = Path.GetFullPath(args[2]); string inputPA = Path.GetFullPath(args[3]); Console.WriteLine($"Make: {inputPA} --> {msAppPath} "); var appName = Path.GetFileName(msAppPath); (var app, var errors) = CanvasDocument.MakeFromSources(appName, pkgsPath, new List <string>() { inputPA }); errors.Write(Console.Error); if (errors.HasErrors) { return; } errors = app.SaveToMsApp(msAppPath); errors.Write(Console.Error); if (errors.HasErrors) { return; } } else { Usage(); } }
static void Main(string[] args) { Console.WriteLine($"MsApp/Source converter. Version: {SourceSerializer.CurrentSourceVersion}"); var mode = args.Length > 0 ? args[0]?.ToLower() : null; if (mode == "-test") { if (args.Length < 2) { Usage(); return; } string msAppPath = args[1]; Console.WriteLine("Test roundtripping: " + msAppPath); // Test round-tripping MsAppTest.StressTest(msAppPath); return; } if (mode == "-testall") { if (args.Length < 2) { Usage(); return; } // Roundtrip all .msapps in a folder. string msAppPathDir = args[1]; int countTotal = 0; int countPass = 0; Console.WriteLine("Test roundtripping all .msapps in : " + msAppPathDir); foreach (var msAppPath in Directory.EnumerateFiles(msAppPathDir, "*.msapp", SearchOption.TopDirectoryOnly)) { Stopwatch sw = Stopwatch.StartNew(); bool ok = MsAppTest.StressTest(msAppPath); var str = ok ? "Pass" : "FAIL"; countTotal++; if (ok) { countPass++; } sw.Stop(); Console.WriteLine($"Test: {Path.GetFileName(msAppPath)}: {str} ({sw.ElapsedMilliseconds / 1000}s)"); } Console.WriteLine($"{countPass}/{countTotal} ({countPass * 100 / countTotal}% passed"); } else if (mode == "-unpack") { if (args.Length < 2) { Usage(); return; } string msAppPath = args[1]; msAppPath = Path.GetFullPath(msAppPath); if (!msAppPath.EndsWith(".msapp", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("must be path to .msapp file"); } string outDir; if (args.Length == 2) { outDir = msAppPath.Substring(0, msAppPath.Length - 6) + "_src"; // chop off ".msapp"; } else { outDir = args[2]; } Console.WriteLine($"Unpack: {msAppPath} --> {outDir} "); (CanvasDocument msApp, ErrorContainer errors) = TryOperation(() => CanvasDocument.LoadFromMsapp(msAppPath)); errors.Write(Console.Error); if (errors.HasErrors) { return; } errors = TryOperation(() => msApp.SaveToSources(outDir, verifyOriginalPath: msAppPath)); errors.Write(Console.Error); if (errors.HasErrors) { return; } } else if (mode == "-pack") { if (args.Length < 3) { Usage(); return; } string msAppPath = Path.GetFullPath(args[1]); string inputDir = Path.GetFullPath(args[2]); Console.WriteLine($"Pack: {inputDir} --> {msAppPath} "); (CanvasDocument msApp, ErrorContainer errors) = TryOperation(() => CanvasDocument.LoadFromSources(inputDir)); errors.Write(Console.Error); if (errors.HasErrors) { return; } errors = TryOperation(() => msApp.SaveToMsApp(msAppPath)); errors.Write(Console.Error); if (errors.HasErrors) { return; } } else if (mode == "-make") { if (args.Length < 4) { Usage(); return; } string msAppPath = Path.GetFullPath(args[1]); string pkgsPath = Path.GetFullPath(args[2]); string inputPA = Path.GetFullPath(args[3]); Console.WriteLine($"Make: {inputPA} --> {msAppPath} "); var appName = Path.GetFileName(msAppPath); (var app, var errors) = TryOperation(() => CanvasDocument.MakeFromSources(appName, pkgsPath, new List <string>() { inputPA })); errors.Write(Console.Error); if (errors.HasErrors) { return; } errors = TryOperation(() => app.SaveToMsApp(msAppPath)); errors.Write(Console.Error); if (errors.HasErrors) { return; } } else if (mode == "-merge") { if (args.Length < 5) { Usage(); return; } string path1 = args[1]; string path2 = args[2]; string parent = args[3]; string pathresult = args[4]; Console.WriteLine($"Merge is very experimental right now, do not rely on this behavior"); Console.WriteLine($"Merge: {path1}, {path2} --> {pathresult} "); (var app1, var errors1) = TryOperation(() => CanvasDocument.LoadFromSources(path1)); errors1.Write(Console.Error); if (errors1.HasErrors) { return; } (var app2, var errors2) = TryOperation(() => CanvasDocument.LoadFromSources(path2)); errors2.Write(Console.Error); if (errors2.HasErrors) { return; } (var parentApp, var errors3) = TryOperation(() => CanvasDocument.LoadFromSources(parent)); errors3.Write(Console.Error); if (errors3.HasErrors) { return; } var result = CanvasMerger.Merge(app1, app2, parentApp); var errors = result.SaveToSources(pathresult); errors.Write(Console.Error); if (errors.HasErrors) { return; } } else { Usage(); } }
public void Test() { (var doc, var errors) = CanvasDocument.LoadFromMsapp(@"c:\missing"); Assert.IsTrue(errors.HasErrors); Assert.IsNull(doc); }