From 173cb70a5a4512bc47c546e53613663c429603b8 Mon Sep 17 00:00:00 2001 From: "Trachsel Markus, BKW (ext.)" Date: Wed, 3 Sep 2025 17:47:03 +0200 Subject: [PATCH 1/6] Extract header files Add functionality to check if only the time changed --- Constants/FileHeaderConstants.cs | 73 +++++++++++++ LCG-UDG/Generation/Extensions.cs | 98 ++++++++++++++--- LCG-UDG/LCG-UDG-Common.csproj | 1 + LCGTests/DatePreservationTests.cs | 168 ++++++++++++++++++++++++++++++ 4 files changed, 325 insertions(+), 15 deletions(-) create mode 100644 Constants/FileHeaderConstants.cs create mode 100644 LCGTests/DatePreservationTests.cs diff --git a/Constants/FileHeaderConstants.cs b/Constants/FileHeaderConstants.cs new file mode 100644 index 0000000..a312f34 --- /dev/null +++ b/Constants/FileHeaderConstants.cs @@ -0,0 +1,73 @@ +namespace Rappen.XTB.LCG +{ + /// + /// Constants used for file header generation and template placeholders + /// + public static class FileHeaderConstants + { + /// + /// Template placeholder for tool name + /// + public const string ToolName = "{toolname}"; + + /// + /// Template placeholder for version + /// + public const string Version = "{version}"; + + /// + /// Template placeholder for organization URL + /// + public const string Organization = "{organization}"; + + /// + /// Template placeholder for filename + /// + public const string Filename = "{filename}"; + + /// + /// Template placeholder for creation date + /// + public const string CreateDate = "{createdate}"; + + /// + /// Template placeholder for legend + /// + public const string Legend = "{legend}"; + + /// + /// Template placeholder for namespace + /// + public const string Namespace = "{namespace}"; + + /// + /// Template placeholder for theme + /// + public const string Theme = "{theme}"; + + /// + /// Template placeholder for padding size + /// + public const string PaddingSize = "{paddingsize}"; + + /// + /// Template placeholder for data content + /// + public const string Data = "{data}"; + + /// + /// Label used for the "Created" line in file headers + /// + public const string CreatedLabel = "Created"; + + /// + /// Double line ending used in file headers + /// + public const string LineEnding = "\r\n\r\n"; + + /// + /// Single line ending used in file headers + /// + public const string SingleLineEnding = "\r\n"; + } +} diff --git a/LCG-UDG/Generation/Extensions.cs b/LCG-UDG/Generation/Extensions.cs index 7ab3a47..29f8d51 100644 --- a/LCG-UDG/Generation/Extensions.cs +++ b/LCG-UDG/Generation/Extensions.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using System.Windows.Forms; using McTools.Xrm.Connection; using Microsoft.Xrm.Sdk.Metadata; @@ -12,6 +13,9 @@ namespace Rappen.XTB.LCG { public static class Extensions { + private const string DatePattern = @"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}"; + private const string DateFormat = "yyyy-MM-dd HH:mm:ss"; + public static AttributeMetadata GetAttribute(this Dictionary entities, string entity, string attribute) { if (entities == null @@ -31,13 +35,20 @@ public static bool WriteFile(this string data, string filename, string orgurl, S var content = GetDataContent(data, settings, version); content = header + "\r\n\r\n" + content; content = content.BeautifyContent(settings.TemplateSettings.Template.IndentStr); + if (settings.SaveConfigurationInCommonFile) { string selection = GetInlineConfiguration(settings); content += "\r\n\r\n" + selection; } + try { + if (File.Exists(filename)) + { + content = PreserveOriginalDateIfContentUnchanged(filename, content); + } + File.WriteAllText(filename, content); return true; } @@ -48,6 +59,63 @@ public static bool WriteFile(this string data, string filename, string orgurl, S } } + private static string RemoveDateFromContent(string content) + { + var lines = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); + var result = new List(); + + foreach (var line in lines) + { + if (line.Contains(FileHeaderConstants.CreatedLabel) && line.Contains(":") && + Regex.IsMatch(line, DatePattern)) + { + continue; + } + result.Add(line); + } + + return string.Join("\r\n", result); + } + + private static string ExtractDateFromContent(string content) + { + var lines = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); + + foreach (var line in lines) + { + if (line.Contains(FileHeaderConstants.CreatedLabel) && line.Contains(":")) + { + + var match = Regex.Match(line, DatePattern); + if (match.Success) + { + return match.Value; + } + } + } + + return null; + } + + private static string PreserveOriginalDateIfContentUnchanged(string filename, string content) + { + var existingContent = File.ReadAllText(filename); + var contentWithoutDate = RemoveDateFromContent(content); + var existingContentWithoutDate = RemoveDateFromContent(existingContent); + + if (contentWithoutDate.Equals(existingContentWithoutDate, StringComparison.Ordinal)) + { + var originalDate = ExtractDateFromContent(existingContent); + + if (!string.IsNullOrEmpty(originalDate)) + { + content = content.Replace(DateTime.Now.ToString(DateFormat), originalDate); + } + } + + return content; + } + private static string GetInlineConfiguration(Settings settings) { var inlineconfig = Settings.GetBlankSettings(settings.TemplateFormat); @@ -63,27 +131,27 @@ private static string GetInlineConfiguration(Settings settings) private static string GetFileHeader(string filename, string orgurl, Settings settings, string version) { var header = settings.TemplateSettings.Template.FileHeader - .Replace("{toolname}", settings.TemplateSettings.ToolName) - .Replace("{version}", version) - .Replace("{organization}", orgurl) - .Replace("{filename}", filename) - .Replace("{createdate}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")) - .Replace("{legend}", settings.Legend ? settings.TemplateSettings.Template.Legend : string.Empty) - .Replace("{namespace}", settings.NameSpace) - .Replace("\r\n\r\n", "\r\n"); + .Replace(FileHeaderConstants.ToolName, settings.TemplateSettings.ToolName) + .Replace(FileHeaderConstants.Version, version) + .Replace(FileHeaderConstants.Organization, orgurl) + .Replace(FileHeaderConstants.Filename, filename) + .Replace(FileHeaderConstants.CreateDate, DateTime.Now.ToString(DateFormat)) + .Replace(FileHeaderConstants.Legend, settings.Legend ? settings.TemplateSettings.Template.Legend : string.Empty) + .Replace(FileHeaderConstants.Namespace, settings.NameSpace) + .Replace(FileHeaderConstants.LineEnding, FileHeaderConstants.SingleLineEnding); return header; } private static string GetDataContent(string data, Settings settings, string version) { return settings.TemplateSettings.Template.DataContainer - .Replace("{toolname}", settings.TemplateSettings.ToolName) - .Replace("{version}", version) - .Replace("{namespace}", settings.NameSpace) - .Replace("{theme}", string.IsNullOrEmpty(settings.Theme) ? settings.TemplateSettings.Template.DefaultTheme : settings.GetTheme()) - .Replace("{legend}", settings.Legend ? settings.TemplateSettings.Template.Legend : string.Empty) - .Replace("{paddingsize}", settings.TableSize.ToString()) - .Replace("{data}", data); + .Replace(FileHeaderConstants.ToolName, settings.TemplateSettings.ToolName) + .Replace(FileHeaderConstants.Version, version) + .Replace(FileHeaderConstants.Namespace, settings.NameSpace) + .Replace(FileHeaderConstants.Theme, string.IsNullOrEmpty(settings.Theme) ? settings.TemplateSettings.Template.DefaultTheme : settings.GetTheme()) + .Replace(FileHeaderConstants.Legend, settings.Legend ? settings.TemplateSettings.Template.Legend : string.Empty) + .Replace(FileHeaderConstants.PaddingSize, settings.TableSize.ToString()) + .Replace(FileHeaderConstants.Data, data); } private static string BeautifyContent(this string content, string indentstr) diff --git a/LCG-UDG/LCG-UDG-Common.csproj b/LCG-UDG/LCG-UDG-Common.csproj index 0d47522..6c06366 100644 --- a/LCG-UDG/LCG-UDG-Common.csproj +++ b/LCG-UDG/LCG-UDG-Common.csproj @@ -267,6 +267,7 @@ + UserControl diff --git a/LCGTests/DatePreservationTests.cs b/LCGTests/DatePreservationTests.cs new file mode 100644 index 0000000..d33983b --- /dev/null +++ b/LCGTests/DatePreservationTests.cs @@ -0,0 +1,168 @@ +using System; +using System.IO; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Rappen.XTB.LCG; + +namespace LateboundConstantGeneratorTests +{ + [TestClass] + public class DatePreservationTests + { + private string _testFilePath; + + [TestInitialize] + public void Setup() + { + _testFilePath = Path.GetTempFileName(); + } + + [TestCleanup] + public void Cleanup() + { + if (File.Exists(_testFilePath)) + { + File.Delete(_testFilePath); + } + } + + [TestMethod] + public void WriteFile_WhenContentUnchanged_ShouldPreserveOriginalDate() + { + // Arrange + var settings = new Settings(); + var originalDate = "2023-01-15 10:30:45"; + var originalContent = $@"// ********************************************************************* +// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox +// Tool Author: Jonas Rapp https://jonasr.app/ +// GitHub : https://github.com/rappen/LCG-UDG/ +// Source Org : https://test.crm.dynamics.com +// Filename : {Path.GetFileName(_testFilePath)} +// Created : {originalDate} +// ********************************************************************* + +namespace TestNamespace +{{ + public class TestClass + {{ + public const string EntityName = ""test_entity""; + }} +}}"; + + // Write original file + File.WriteAllText(_testFilePath, originalContent); + + // Act - Write the same content again + var newContent = $@"// ********************************************************************* +// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox +// Tool Author: Jonas Rapp https://jonasr.app/ +// GitHub : https://github.com/rappen/LCG-UDG/ +// Source Org : https://test.crm.dynamics.com +// Filename : {Path.GetFileName(_testFilePath)} +// Created : {DateTime.Now:yyyy-MM-dd HH:mm:ss} +// ********************************************************************* + +namespace TestNamespace +{{ + public class TestClass + {{ + public const string EntityName = ""test_entity""; + }} +}}"; + + var result = newContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); + + // Assert + Assert.IsTrue(result); + var finalContent = File.ReadAllText(_testFilePath); + Assert.IsTrue(finalContent.Contains(originalDate), "Original date should be preserved"); + Assert.IsFalse(finalContent.Contains(DateTime.Now.ToString("yyyy-MM-dd")), "Current date should not be used"); + } + + [TestMethod] + public void WriteFile_WhenContentChanged_ShouldUpdateDate() + { + // Arrange + var settings = new Settings(); + var originalDate = "2023-01-15 10:30:45"; + var originalContent = $@"// ********************************************************************* +// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox +// Tool Author: Jonas Rapp https://jonasr.app/ +// GitHub : https://github.com/rappen/LCG-UDG/ +// Source Org : https://test.crm.dynamics.com +// Filename : {Path.GetFileName(_testFilePath)} +// Created : {originalDate} +// ********************************************************************* + +namespace TestNamespace +{{ + public class TestClass + {{ + public const string EntityName = ""test_entity""; + }} +}}"; + + // Write original file + File.WriteAllText(_testFilePath, originalContent); + + // Act - Write different content + var newContent = $@"// ********************************************************************* +// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox +// Tool Author: Jonas Rapp https://jonasr.app/ +// GitHub : https://github.com/rappen/LCG-UDG/ +// Source Org : https://test.crm.dynamics.com +// Filename : {Path.GetFileName(_testFilePath)} +// Created : {DateTime.Now:yyyy-MM-dd HH:mm:ss} +// ********************************************************************* + +namespace TestNamespace +{{ + public class TestClass + {{ + public const string EntityName = ""modified_entity""; + public const string NewProperty = ""new_value""; + }} +}}"; + + var result = newContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); + + // Assert + Assert.IsTrue(result); + var finalContent = File.ReadAllText(_testFilePath); + Assert.IsFalse(finalContent.Contains(originalDate), "Original date should not be preserved when content changes"); + Assert.IsTrue(finalContent.Contains(DateTime.Now.ToString("yyyy-MM-dd")), "Current date should be used when content changes"); + Assert.IsTrue(finalContent.Contains("modified_entity"), "Modified content should be present"); + } + + [TestMethod] + public void WriteFile_WhenFileDoesNotExist_ShouldUseCurrentDate() + { + // Arrange + var settings = new Settings(); + var newContent = $@"// ********************************************************************* +// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox +// Tool Author: Jonas Rapp https://jonasr.app/ +// GitHub : https://github.com/rappen/LCG-UDG/ +// Source Org : https://test.crm.dynamics.com +// Filename : {Path.GetFileName(_testFilePath)} +// Created : {DateTime.Now:yyyy-MM-dd HH:mm:ss} +// ********************************************************************* + +namespace TestNamespace +{{ + public class TestClass + {{ + public const string EntityName = ""new_entity""; + }} +}}"; + + // Act - Write to new file + var result = newContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); + + // Assert + Assert.IsTrue(result); + var finalContent = File.ReadAllText(_testFilePath); + Assert.IsTrue(finalContent.Contains(DateTime.Now.ToString("yyyy-MM-dd")), "Current date should be used for new files"); + Assert.IsTrue(finalContent.Contains("new_entity"), "New content should be present"); + } + } +} From 64c2eb5ca0537e3b32ba932315d25f3f9ebaa715 Mon Sep 17 00:00:00 2001 From: "Trachsel Markus, BKW (ext.)" Date: Wed, 3 Sep 2025 18:00:01 +0200 Subject: [PATCH 2/6] Added Filename check as well --- Constants/FileHeaderConstants.cs | 5 + .../Constants/FileHeaderConstants.cs | 73 +++++++++ LCG-UDG/Generation/Extensions.cs | 141 +++++++++++------- LCG-UDG/LCG-UDG-Common.csproj | 2 +- LCG-UDG/constants/FileHeaderConstants.cs | 78 ++++++++++ LCGTests/DatePreservationTests.cs | 55 +++++++ 6 files changed, 298 insertions(+), 56 deletions(-) create mode 100644 LCG-UDG/Generation/Constants/FileHeaderConstants.cs create mode 100644 LCG-UDG/constants/FileHeaderConstants.cs diff --git a/Constants/FileHeaderConstants.cs b/Constants/FileHeaderConstants.cs index a312f34..acf6b92 100644 --- a/Constants/FileHeaderConstants.cs +++ b/Constants/FileHeaderConstants.cs @@ -60,6 +60,11 @@ public static class FileHeaderConstants /// public const string CreatedLabel = "Created"; + /// + /// Label used for the "Filename" line in file headers + /// + public const string FilenameLabel = "Filename"; + /// /// Double line ending used in file headers /// diff --git a/LCG-UDG/Generation/Constants/FileHeaderConstants.cs b/LCG-UDG/Generation/Constants/FileHeaderConstants.cs new file mode 100644 index 0000000..fa48ab3 --- /dev/null +++ b/LCG-UDG/Generation/Constants/FileHeaderConstants.cs @@ -0,0 +1,73 @@ +namespace Rappen.XTB.LCG +{ + /// + /// Constants used for file header generation and template placeholders + /// + public static class FileHeaderConstants + { + /// + /// Template placeholder for tool name + /// + public const string ToolName = "{toolname}"; + + /// + /// Template placeholder for version + /// + public const string Version = "{version}"; + + /// + /// Template placeholder for organization URL + /// + public const string Organization = "{organization}"; + + /// + /// Template placeholder for filename + /// + public const string Filename = "{filename}"; + + /// + /// Template placeholder for creation date + /// + public const string CreateDate = "{createdate}"; + + /// + /// Template placeholder for legend + /// + public const string Legend = "{legend}"; + + /// + /// Template placeholder for namespace + /// + public const string Namespace = "{namespace}"; + + /// + /// Template placeholder for theme + /// + public const string Theme = "{theme}"; + + /// + /// Template placeholder for padding size + /// + public const string PaddingSize = "{paddingsize}"; + + /// + /// Template placeholder for data content + /// + public const string Data = "{data}"; + + /// + /// Label used for the "Created" line in file headers + /// + public const string CreatedLabel = "Created"; + + /// + /// Double line ending used in file headers + /// + public const string LineEnding = "\r\n\r\n"; + + /// + /// Single line ending used in file headers + /// + public const string SingleLineEnding = "\r\n"; + } +} \ No newline at end of file diff --git a/LCG-UDG/Generation/Extensions.cs b/LCG-UDG/Generation/Extensions.cs index 29f8d51..ba2b8f3 100644 --- a/LCG-UDG/Generation/Extensions.cs +++ b/LCG-UDG/Generation/Extensions.cs @@ -1,4 +1,6 @@ -using System; +using McTools.Xrm.Connection; +using Microsoft.Xrm.Sdk.Metadata; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -6,8 +8,6 @@ using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; -using McTools.Xrm.Connection; -using Microsoft.Xrm.Sdk.Metadata; namespace Rappen.XTB.LCG { @@ -18,7 +18,7 @@ public static class Extensions public static AttributeMetadata GetAttribute(this Dictionary entities, string entity, string attribute) { - if (entities == null + if(entities == null || !entities.TryGetValue(entity, out var metadata) || metadata.Attributes == null) { @@ -35,24 +35,24 @@ public static bool WriteFile(this string data, string filename, string orgurl, S var content = GetDataContent(data, settings, version); content = header + "\r\n\r\n" + content; content = content.BeautifyContent(settings.TemplateSettings.Template.IndentStr); - - if (settings.SaveConfigurationInCommonFile) + + if(settings.SaveConfigurationInCommonFile) { string selection = GetInlineConfiguration(settings); content += "\r\n\r\n" + selection; } - + try { - if (File.Exists(filename)) + if(File.Exists(filename)) { content = PreserveOriginalDateIfContentUnchanged(filename, content); } - + File.WriteAllText(filename, content); return true; } - catch (Exception e) + catch(Exception e) { MessageBox.Show(e.Message, "Generate", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; @@ -63,37 +63,62 @@ private static string RemoveDateFromContent(string content) { var lines = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); var result = new List(); - - foreach (var line in lines) + + foreach(var line in lines) { - if (line.Contains(FileHeaderConstants.CreatedLabel) && line.Contains(":") && + if(line.Contains(FileHeaderConstants.CreatedLabel) && line.Contains(":") && Regex.IsMatch(line, DatePattern)) { continue; } + + if(line.Contains(FileHeaderConstants.FilenameLabel) && line.Contains(":")) + { + continue; + } result.Add(line); } - + return string.Join("\r\n", result); } private static string ExtractDateFromContent(string content) { var lines = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); - - foreach (var line in lines) + + foreach(var line in lines) { - if (line.Contains(FileHeaderConstants.CreatedLabel) && line.Contains(":")) + if(line.Contains(FileHeaderConstants.CreatedLabel) && line.Contains(":")) { - + var match = Regex.Match(line, DatePattern); - if (match.Success) + if(match.Success) { return match.Value; } } } - + + return null; + } + + private static string ExtractFilenameFromContent(string content) + { + var lines = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); + + foreach(var line in lines) + { + if(line.Contains(FileHeaderConstants.FilenameLabel) && line.Contains(":")) + { + var colonIndex = line.IndexOf(':'); + if(colonIndex >= 0 && colonIndex < line.Length - 1) + { + var filenamePart = line.Substring(colonIndex + 1).Trim(); + return filenamePart; + } + } + } + return null; } @@ -102,17 +127,23 @@ private static string PreserveOriginalDateIfContentUnchanged(string filename, st var existingContent = File.ReadAllText(filename); var contentWithoutDate = RemoveDateFromContent(content); var existingContentWithoutDate = RemoveDateFromContent(existingContent); - - if (contentWithoutDate.Equals(existingContentWithoutDate, StringComparison.Ordinal)) + + if(contentWithoutDate.Equals(existingContentWithoutDate, StringComparison.Ordinal)) { var originalDate = ExtractDateFromContent(existingContent); + var originalFilename = ExtractFilenameFromContent(existingContent); - if (!string.IsNullOrEmpty(originalDate)) - { + if(!string.IsNullOrEmpty(originalDate)) + { content = content.Replace(DateTime.Now.ToString(DateFormat), originalDate); } + + if(!string.IsNullOrEmpty(originalFilename)) + { + content = content.Replace(Path.GetFileName(filename), originalFilename); + } } - + return content; } @@ -160,17 +191,17 @@ private static string BeautifyContent(this string content, string indentstr) var lines = content.Split('\n').ToList(); var lastline = string.Empty; var indent = 0; - foreach (var line in lines.Select(l => l.Trim()).Where(l => !string.IsNullOrEmpty(l))) + foreach(var line in lines.Select(l => l.Trim()).Where(l => !string.IsNullOrEmpty(l))) { - if (AddBlankLineBetween(lastline, line)) + if(AddBlankLineBetween(lastline, line)) { fixedcontent.AppendLine(); } - if (lastline.EndsWith("{")) + if(lastline.EndsWith("{")) { indent++; } - if (line.Equals("}") && indent > 0) + if(line.Equals("}") && indent > 0) { indent--; } @@ -182,48 +213,48 @@ private static string BeautifyContent(this string content, string indentstr) private static bool AddBlankLineBetween(string lastline, string line) { - if (string.IsNullOrWhiteSpace(lastline) || lastline.Equals("{")) + if(string.IsNullOrWhiteSpace(lastline) || lastline.Equals("{")) { // Never two empty lines after each other return false; } - if (lastline.StartsWith("#region") || line.StartsWith("#region") || line.StartsWith("#endregion")) + if(lastline.StartsWith("#region") || line.StartsWith("#region") || line.StartsWith("#endregion")) { // Empty lines around region statements return true; } - if (lastline.StartsWith("using ") && !line.StartsWith("using ")) + if(lastline.StartsWith("using ") && !line.StartsWith("using ")) { // Empty lines after usings return true; } - if (line.StartsWith("namespace ")) + if(line.StartsWith("namespace ")) { // Empty lines before namespace return true; } - if (line.StartsWith("public enum")) + if(line.StartsWith("public enum")) { // Never empty line before enums, we keep it compact return false; } - if (lastline.Equals("}") && !line.Equals("}") && !string.IsNullOrWhiteSpace(line)) + if(lastline.Equals("}") && !line.Equals("}") && !string.IsNullOrWhiteSpace(line)) { // Never empty line between end blocks return true; } // Following rules are UML specific - if (line.StartsWith("@startuml") || lastline.StartsWith("@startuml") || line.StartsWith("@enduml")) + if(line.StartsWith("@startuml") || lastline.StartsWith("@startuml") || line.StartsWith("@enduml")) { return true; } - if (line.StartsWith("title") || line.StartsWith("header") || line.StartsWith("footer ")) + if(line.StartsWith("title") || line.StartsWith("header") || line.StartsWith("footer ")) { return true; } - if (line.StartsWith("skinparam") && !lastline.StartsWith("skinparam")) + if(line.StartsWith("skinparam") && !lastline.StartsWith("skinparam")) { return true; } - if (line.StartsWith("entity ")) + if(line.StartsWith("entity ")) { return true; } - if (line.StartsWith("Table ")) + if(line.StartsWith("Table ")) { return true; } @@ -236,20 +267,20 @@ bool WordBeginOrEnd(string text, int i) { var last = text.Substring(0, i).ToLowerInvariant(); var next = text.Substring(i).ToLowerInvariant(); - foreach (var word in OnlineSettings.Instance.CamelCaseWords.Where(word => last.EndsWith(word) || next.StartsWith(word))) + foreach(var word in OnlineSettings.Instance.CamelCaseWords.Where(word => last.EndsWith(word) || next.StartsWith(word))) { // Found a "word" in the string (for example "count" var isunbreakable = false; - foreach (var unbreak in OnlineSettings.Instance.CamelCaseWords) + foreach(var unbreak in OnlineSettings.Instance.CamelCaseWords) { // Check that this word is not also part of a bigger word (for example "account" var len = unbreak.Length; var pos = text.ToLowerInvariant().IndexOf(unbreak); - if (pos >= 0 && pos < i & pos + len > i) + if(pos >= 0 && pos < i & pos + len > i) { // Found word appears to split a bigger valid word, prevent that isunbreakable = true; break; } } - if (!isunbreakable) + if(!isunbreakable) { return true; } @@ -259,22 +290,22 @@ bool WordBeginOrEnd(string text, int i) var result = string.Empty; var nextCapital = true; - for (var i = 0; i < name.Length; i++) + for(var i = 0; i < name.Length; i++) { var chr = name[i]; - if ((chr < 'a') && + if((chr < 'a') && (chr < 'A' || chr > 'Z') && (chr < '0' || chr > '9')) { // Any non-letters/numbers are treated as word separators nextCapital = true; } - else if (chr > 'z') + else if(chr > 'z') { // Just ignore special character } else { nextCapital = nextCapital || WordBeginOrEnd(name, i); - if (nextCapital) + if(nextCapital) { result += chr.ToString().ToUpperInvariant(); } @@ -290,9 +321,9 @@ bool WordBeginOrEnd(string text, int i) public static string GetNonDisplayName(this Settings settings, string name) { - if (settings.DoStripPrefix && !string.IsNullOrEmpty(settings.StripPrefix)) + if(settings.DoStripPrefix && !string.IsNullOrEmpty(settings.StripPrefix)) { - foreach (var prefix in settings.StripPrefix.Split(',') + foreach(var prefix in settings.StripPrefix.Split(',') .Select(p => p.Trim()) .Where(p => !string.IsNullOrWhiteSpace(p) && name.ToLowerInvariant().StartsWith(p))) @@ -300,7 +331,7 @@ public static string GetNonDisplayName(this Settings settings, string name) name = name.Substring(prefix.Length); } } - if (settings.ConstantCamelCased) + if(settings.ConstantCamelCased) { name = name.CamelCaseIt(settings); } @@ -314,7 +345,7 @@ public static string ReplaceIfNotEmpty(this string template, string oldValue, st public static string MessageDetails(this Exception ex, int level = 0) { - if (ex == null) + if(ex == null) { return string.Empty; } @@ -323,12 +354,12 @@ public static string MessageDetails(this Exception ex, int level = 0) public static void Move(this List list, T item, bool down) { // From this tip: https://stackoverflow.com/a/450250/2866704 - if (item == null) + if(item == null) { return; } var oldIndex = list.IndexOf(item); - if (oldIndex == -1) + if(oldIndex == -1) { return; } @@ -356,7 +387,7 @@ public static string ShowPrompt(string text, string caption, string startvalue = prompt.CancelButton = cancellation; prompt.AcceptButton = confirmation; string result = null; - if (prompt.ShowDialog() == DialogResult.OK) + if(prompt.ShowDialog() == DialogResult.OK) { result = textBox.Text; } diff --git a/LCG-UDG/LCG-UDG-Common.csproj b/LCG-UDG/LCG-UDG-Common.csproj index 6c06366..387f312 100644 --- a/LCG-UDG/LCG-UDG-Common.csproj +++ b/LCG-UDG/LCG-UDG-Common.csproj @@ -245,6 +245,7 @@ About.cs + @@ -267,7 +268,6 @@ - UserControl diff --git a/LCG-UDG/constants/FileHeaderConstants.cs b/LCG-UDG/constants/FileHeaderConstants.cs new file mode 100644 index 0000000..acf6b92 --- /dev/null +++ b/LCG-UDG/constants/FileHeaderConstants.cs @@ -0,0 +1,78 @@ +namespace Rappen.XTB.LCG +{ + /// + /// Constants used for file header generation and template placeholders + /// + public static class FileHeaderConstants + { + /// + /// Template placeholder for tool name + /// + public const string ToolName = "{toolname}"; + + /// + /// Template placeholder for version + /// + public const string Version = "{version}"; + + /// + /// Template placeholder for organization URL + /// + public const string Organization = "{organization}"; + + /// + /// Template placeholder for filename + /// + public const string Filename = "{filename}"; + + /// + /// Template placeholder for creation date + /// + public const string CreateDate = "{createdate}"; + + /// + /// Template placeholder for legend + /// + public const string Legend = "{legend}"; + + /// + /// Template placeholder for namespace + /// + public const string Namespace = "{namespace}"; + + /// + /// Template placeholder for theme + /// + public const string Theme = "{theme}"; + + /// + /// Template placeholder for padding size + /// + public const string PaddingSize = "{paddingsize}"; + + /// + /// Template placeholder for data content + /// + public const string Data = "{data}"; + + /// + /// Label used for the "Created" line in file headers + /// + public const string CreatedLabel = "Created"; + + /// + /// Label used for the "Filename" line in file headers + /// + public const string FilenameLabel = "Filename"; + + /// + /// Double line ending used in file headers + /// + public const string LineEnding = "\r\n\r\n"; + + /// + /// Single line ending used in file headers + /// + public const string SingleLineEnding = "\r\n"; + } +} diff --git a/LCGTests/DatePreservationTests.cs b/LCGTests/DatePreservationTests.cs index d33983b..7ce951f 100644 --- a/LCGTests/DatePreservationTests.cs +++ b/LCGTests/DatePreservationTests.cs @@ -133,6 +133,61 @@ public class TestClass Assert.IsTrue(finalContent.Contains("modified_entity"), "Modified content should be present"); } + [TestMethod] + public void WriteFile_WhenOnlyFilenameChanged_ShouldPreserveOriginalFilename() + { + // Arrange + var settings = new Settings(); + var originalDate = "2023-01-15 10:30:45"; + var originalFilename = "OriginalFile.cs"; + var originalContent = $@"// ********************************************************************* +// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox +// Tool Author: Jonas Rapp https://jonasr.app/ +// GitHub : https://github.com/rappen/LCG-UDG/ +// Source Org : https://test.crm.dynamics.com +// Filename : {originalFilename} +// Created : {originalDate} +// ********************************************************************* + +namespace TestNamespace +{{ + public class TestClass + {{ + public const string EntityName = ""test_entity""; + }} +}}"; + + // Write original file + File.WriteAllText(_testFilePath, originalContent); + + // Act - Write content with different filename + var newContent = $@"// ********************************************************************* +// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox +// Tool Author: Jonas Rapp https://jonasr.app/ +// GitHub : https://github.com/rappen/LCG-UDG/ +// Source Org : https://test.crm.dynamics.com +// Filename : ModifiedFile.cs +// Created : {DateTime.Now:yyyy-MM-dd HH:mm:ss} +// ********************************************************************* + +namespace TestNamespace +{{ + public class TestClass + {{ + public const string EntityName = ""test_entity""; + }} +}}"; + + var result = newContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); + + // Assert + Assert.IsTrue(result); + var finalContent = File.ReadAllText(_testFilePath); + Assert.IsTrue(finalContent.Contains(originalFilename), "Original filename should be preserved"); + Assert.IsFalse(finalContent.Contains("ModifiedFile.cs"), "Modified filename should not be used"); + Assert.IsTrue(finalContent.Contains(originalDate), "Original date should also be preserved"); + } + [TestMethod] public void WriteFile_WhenFileDoesNotExist_ShouldUseCurrentDate() { From 9740c828e67c500c6dd02ec9ff070e6f396684b2 Mon Sep 17 00:00:00 2001 From: "Trachsel Markus, BKW (ext.)" Date: Sat, 6 Sep 2025 14:07:20 +0200 Subject: [PATCH 3/6] Add test file to project --- LCGTests/LCGTests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/LCGTests/LCGTests.csproj b/LCGTests/LCGTests.csproj index 36784d0..395f59a 100644 --- a/LCGTests/LCGTests.csproj +++ b/LCGTests/LCGTests.csproj @@ -228,6 +228,7 @@ + From 6dca0163632f6e4bef71ca91f8b5c86eb1bb2e4e Mon Sep 17 00:00:00 2001 From: "Trachsel Markus, BKW (ext.)" Date: Sat, 6 Sep 2025 14:15:32 +0200 Subject: [PATCH 4/6] Fixed tests --- LCG-UDG/Generation/Extensions.cs | 29 ++++++++- LCGTests/DatePreservationTests.cs | 100 +++++++++--------------------- 2 files changed, 59 insertions(+), 70 deletions(-) diff --git a/LCG-UDG/Generation/Extensions.cs b/LCG-UDG/Generation/Extensions.cs index ba2b8f3..1a4830d 100644 --- a/LCG-UDG/Generation/Extensions.cs +++ b/LCG-UDG/Generation/Extensions.cs @@ -63,6 +63,7 @@ private static string RemoveDateFromContent(string content) { var lines = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); var result = new List(); + var skipConfiguration = false; foreach(var line in lines) { @@ -76,6 +77,25 @@ private static string RemoveDateFromContent(string content) { continue; } + + // Skip configuration section + if(line.Contains("LCG-configuration-BEGIN")) + { + skipConfiguration = true; + continue; + } + + if(line.Contains("LCG-configuration-END")) + { + skipConfiguration = false; + continue; + } + + if(skipConfiguration) + { + continue; + } + result.Add(line); } @@ -128,7 +148,14 @@ private static string PreserveOriginalDateIfContentUnchanged(string filename, st var contentWithoutDate = RemoveDateFromContent(content); var existingContentWithoutDate = RemoveDateFromContent(existingContent); - if(contentWithoutDate.Equals(existingContentWithoutDate, StringComparison.Ordinal)) + // Debug output + System.Diagnostics.Debug.WriteLine("=== EXISTING CONTENT WITHOUT DATE ==="); + System.Diagnostics.Debug.WriteLine(existingContentWithoutDate); + System.Diagnostics.Debug.WriteLine("=== NEW CONTENT WITHOUT DATE ==="); + System.Diagnostics.Debug.WriteLine(contentWithoutDate); + System.Diagnostics.Debug.WriteLine("=== CONTENT EQUAL: " + contentWithoutDate.Trim().Equals(existingContentWithoutDate.Trim(), StringComparison.Ordinal) + " ==="); + + if(contentWithoutDate.Trim().Equals(existingContentWithoutDate.Trim(), StringComparison.Ordinal)) { var originalDate = ExtractDateFromContent(existingContent); var originalFilename = ExtractFilenameFromContent(existingContent); diff --git a/LCGTests/DatePreservationTests.cs b/LCGTests/DatePreservationTests.cs index 7ce951f..51f1426 100644 --- a/LCGTests/DatePreservationTests.cs +++ b/LCGTests/DatePreservationTests.cs @@ -30,6 +30,7 @@ public void WriteFile_WhenContentUnchanged_ShouldPreserveOriginalDate() { // Arrange var settings = new Settings(); + settings.NameSpace = "TestNamespace"; var originalDate = "2023-01-15 10:30:45"; var originalContent = $@"// ********************************************************************* // Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox @@ -52,28 +53,22 @@ public class TestClass File.WriteAllText(_testFilePath, originalContent); // Act - Write the same content again - var newContent = $@"// ********************************************************************* -// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox -// Tool Author: Jonas Rapp https://jonasr.app/ -// GitHub : https://github.com/rappen/LCG-UDG/ -// Source Org : https://test.crm.dynamics.com -// Filename : {Path.GetFileName(_testFilePath)} -// Created : {DateTime.Now:yyyy-MM-dd HH:mm:ss} -// ********************************************************************* - -namespace TestNamespace -{{ - public class TestClass - {{ - public const string EntityName = ""test_entity""; - }} -}}"; + var dataContent = @"public class TestClass +{ + public const string EntityName = ""test_entity""; +}"; - var result = newContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); + var result = dataContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); // Assert Assert.IsTrue(result); var finalContent = File.ReadAllText(_testFilePath); + + // Debug output + Console.WriteLine("=== FINAL CONTENT ==="); + Console.WriteLine(finalContent); + Console.WriteLine("=== END FINAL CONTENT ==="); + Assert.IsTrue(finalContent.Contains(originalDate), "Original date should be preserved"); Assert.IsFalse(finalContent.Contains(DateTime.Now.ToString("yyyy-MM-dd")), "Current date should not be used"); } @@ -83,6 +78,7 @@ public void WriteFile_WhenContentChanged_ShouldUpdateDate() { // Arrange var settings = new Settings(); + settings.NameSpace = "TestNamespace"; var originalDate = "2023-01-15 10:30:45"; var originalContent = $@"// ********************************************************************* // Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox @@ -105,25 +101,13 @@ public class TestClass File.WriteAllText(_testFilePath, originalContent); // Act - Write different content - var newContent = $@"// ********************************************************************* -// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox -// Tool Author: Jonas Rapp https://jonasr.app/ -// GitHub : https://github.com/rappen/LCG-UDG/ -// Source Org : https://test.crm.dynamics.com -// Filename : {Path.GetFileName(_testFilePath)} -// Created : {DateTime.Now:yyyy-MM-dd HH:mm:ss} -// ********************************************************************* - -namespace TestNamespace -{{ - public class TestClass - {{ - public const string EntityName = ""modified_entity""; - public const string NewProperty = ""new_value""; - }} -}}"; + var dataContent = @"public class TestClass +{ + public const string EntityName = ""modified_entity""; + public const string NewProperty = ""new_value""; +}"; - var result = newContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); + var result = dataContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); // Assert Assert.IsTrue(result); @@ -138,6 +122,7 @@ public void WriteFile_WhenOnlyFilenameChanged_ShouldPreserveOriginalFilename() { // Arrange var settings = new Settings(); + settings.NameSpace = "TestNamespace"; var originalDate = "2023-01-15 10:30:45"; var originalFilename = "OriginalFile.cs"; var originalContent = $@"// ********************************************************************* @@ -161,24 +146,12 @@ public class TestClass File.WriteAllText(_testFilePath, originalContent); // Act - Write content with different filename - var newContent = $@"// ********************************************************************* -// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox -// Tool Author: Jonas Rapp https://jonasr.app/ -// GitHub : https://github.com/rappen/LCG-UDG/ -// Source Org : https://test.crm.dynamics.com -// Filename : ModifiedFile.cs -// Created : {DateTime.Now:yyyy-MM-dd HH:mm:ss} -// ********************************************************************* - -namespace TestNamespace -{{ - public class TestClass - {{ - public const string EntityName = ""test_entity""; - }} -}}"; + var dataContent = @"public class TestClass +{ + public const string EntityName = ""test_entity""; +}"; - var result = newContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); + var result = dataContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); // Assert Assert.IsTrue(result); @@ -193,25 +166,14 @@ public void WriteFile_WhenFileDoesNotExist_ShouldUseCurrentDate() { // Arrange var settings = new Settings(); - var newContent = $@"// ********************************************************************* -// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox -// Tool Author: Jonas Rapp https://jonasr.app/ -// GitHub : https://github.com/rappen/LCG-UDG/ -// Source Org : https://test.crm.dynamics.com -// Filename : {Path.GetFileName(_testFilePath)} -// Created : {DateTime.Now:yyyy-MM-dd HH:mm:ss} -// ********************************************************************* - -namespace TestNamespace -{{ - public class TestClass - {{ - public const string EntityName = ""new_entity""; - }} -}}"; + settings.NameSpace = "TestNamespace"; + var dataContent = @"public class TestClass +{ + public const string EntityName = ""new_entity""; +}"; // Act - Write to new file - var result = newContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); + var result = dataContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); // Assert Assert.IsTrue(result); From 1a44d7e37599c8417d9a53072cefba054bfbb0b4 Mon Sep 17 00:00:00 2001 From: "Trachsel Markus, BKW (ext.)" Date: Sat, 6 Sep 2025 14:18:54 +0200 Subject: [PATCH 5/6] Extract testfile for tests --- LCG-UDG/Generation/Extensions.cs | 7 -- LCGTests/DatePreservationTests.cs | 81 ++---------------------- LCGTests/LCGTests.csproj | 6 +- LCGTests/TestContentHelper.cs | 42 ++++++++++++ LCGTests/testdata/ExpectedTestContent.cs | 16 +++++ 5 files changed, 70 insertions(+), 82 deletions(-) create mode 100644 LCGTests/TestContentHelper.cs create mode 100644 LCGTests/testdata/ExpectedTestContent.cs diff --git a/LCG-UDG/Generation/Extensions.cs b/LCG-UDG/Generation/Extensions.cs index 1a4830d..4d45d0e 100644 --- a/LCG-UDG/Generation/Extensions.cs +++ b/LCG-UDG/Generation/Extensions.cs @@ -148,13 +148,6 @@ private static string PreserveOriginalDateIfContentUnchanged(string filename, st var contentWithoutDate = RemoveDateFromContent(content); var existingContentWithoutDate = RemoveDateFromContent(existingContent); - // Debug output - System.Diagnostics.Debug.WriteLine("=== EXISTING CONTENT WITHOUT DATE ==="); - System.Diagnostics.Debug.WriteLine(existingContentWithoutDate); - System.Diagnostics.Debug.WriteLine("=== NEW CONTENT WITHOUT DATE ==="); - System.Diagnostics.Debug.WriteLine(contentWithoutDate); - System.Diagnostics.Debug.WriteLine("=== CONTENT EQUAL: " + contentWithoutDate.Trim().Equals(existingContentWithoutDate.Trim(), StringComparison.Ordinal) + " ==="); - if(contentWithoutDate.Trim().Equals(existingContentWithoutDate.Trim(), StringComparison.Ordinal)) { var originalDate = ExtractDateFromContent(existingContent); diff --git a/LCGTests/DatePreservationTests.cs b/LCGTests/DatePreservationTests.cs index 51f1426..3a8dfc0 100644 --- a/LCGTests/DatePreservationTests.cs +++ b/LCGTests/DatePreservationTests.cs @@ -32,43 +32,18 @@ public void WriteFile_WhenContentUnchanged_ShouldPreserveOriginalDate() var settings = new Settings(); settings.NameSpace = "TestNamespace"; var originalDate = "2023-01-15 10:30:45"; - var originalContent = $@"// ********************************************************************* -// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox -// Tool Author: Jonas Rapp https://jonasr.app/ -// GitHub : https://github.com/rappen/LCG-UDG/ -// Source Org : https://test.crm.dynamics.com -// Filename : {Path.GetFileName(_testFilePath)} -// Created : {originalDate} -// ********************************************************************* - -namespace TestNamespace -{{ - public class TestClass - {{ - public const string EntityName = ""test_entity""; - }} -}}"; + var originalContent = TestContentHelper.GetExpectedTestContent(Path.GetFileName(_testFilePath), originalDate); // Write original file File.WriteAllText(_testFilePath, originalContent); // Act - Write the same content again - var dataContent = @"public class TestClass -{ - public const string EntityName = ""test_entity""; -}"; - + var dataContent = TestContentHelper.GetTestDataContent(); var result = dataContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); // Assert Assert.IsTrue(result); var finalContent = File.ReadAllText(_testFilePath); - - // Debug output - Console.WriteLine("=== FINAL CONTENT ==="); - Console.WriteLine(finalContent); - Console.WriteLine("=== END FINAL CONTENT ==="); - Assert.IsTrue(finalContent.Contains(originalDate), "Original date should be preserved"); Assert.IsFalse(finalContent.Contains(DateTime.Now.ToString("yyyy-MM-dd")), "Current date should not be used"); } @@ -80,33 +55,13 @@ public void WriteFile_WhenContentChanged_ShouldUpdateDate() var settings = new Settings(); settings.NameSpace = "TestNamespace"; var originalDate = "2023-01-15 10:30:45"; - var originalContent = $@"// ********************************************************************* -// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox -// Tool Author: Jonas Rapp https://jonasr.app/ -// GitHub : https://github.com/rappen/LCG-UDG/ -// Source Org : https://test.crm.dynamics.com -// Filename : {Path.GetFileName(_testFilePath)} -// Created : {originalDate} -// ********************************************************************* - -namespace TestNamespace -{{ - public class TestClass - {{ - public const string EntityName = ""test_entity""; - }} -}}"; + var originalContent = TestContentHelper.GetExpectedTestContent(Path.GetFileName(_testFilePath), originalDate); // Write original file File.WriteAllText(_testFilePath, originalContent); // Act - Write different content - var dataContent = @"public class TestClass -{ - public const string EntityName = ""modified_entity""; - public const string NewProperty = ""new_value""; -}"; - + var dataContent = TestContentHelper.GetModifiedTestDataContent(); var result = dataContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); // Assert @@ -125,32 +80,13 @@ public void WriteFile_WhenOnlyFilenameChanged_ShouldPreserveOriginalFilename() settings.NameSpace = "TestNamespace"; var originalDate = "2023-01-15 10:30:45"; var originalFilename = "OriginalFile.cs"; - var originalContent = $@"// ********************************************************************* -// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox -// Tool Author: Jonas Rapp https://jonasr.app/ -// GitHub : https://github.com/rappen/LCG-UDG/ -// Source Org : https://test.crm.dynamics.com -// Filename : {originalFilename} -// Created : {originalDate} -// ********************************************************************* - -namespace TestNamespace -{{ - public class TestClass - {{ - public const string EntityName = ""test_entity""; - }} -}}"; + var originalContent = TestContentHelper.GetExpectedTestContent(originalFilename, originalDate); // Write original file File.WriteAllText(_testFilePath, originalContent); // Act - Write content with different filename - var dataContent = @"public class TestClass -{ - public const string EntityName = ""test_entity""; -}"; - + var dataContent = TestContentHelper.GetTestDataContent(); var result = dataContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); // Assert @@ -167,10 +103,7 @@ public void WriteFile_WhenFileDoesNotExist_ShouldUseCurrentDate() // Arrange var settings = new Settings(); settings.NameSpace = "TestNamespace"; - var dataContent = @"public class TestClass -{ - public const string EntityName = ""new_entity""; -}"; + var dataContent = TestContentHelper.GetNewTestDataContent(); // Act - Write to new file var result = dataContent.WriteFile(_testFilePath, "https://test.crm.dynamics.com", settings); diff --git a/LCGTests/LCGTests.csproj b/LCGTests/LCGTests.csproj index 395f59a..bef3cd6 100644 --- a/LCGTests/LCGTests.csproj +++ b/LCGTests/LCGTests.csproj @@ -229,8 +229,9 @@ - + + @@ -240,6 +241,9 @@ Always + + Always + diff --git a/LCGTests/TestContentHelper.cs b/LCGTests/TestContentHelper.cs new file mode 100644 index 0000000..950a932 --- /dev/null +++ b/LCGTests/TestContentHelper.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; + +namespace LateboundConstantGeneratorTests +{ + public static class TestContentHelper + { + private static readonly string TestDataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata"); + + public static string GetExpectedTestContent(string filename, string date) + { + var templatePath = Path.Combine(TestDataPath, "ExpectedTestContent.cs"); + var template = File.ReadAllText(templatePath); + return string.Format(template, filename, date); + } + + public static string GetTestDataContent() + { + return @"public class TestClass +{ + public const string EntityName = ""test_entity""; +}"; + } + + public static string GetModifiedTestDataContent() + { + return @"public class TestClass +{ + public const string EntityName = ""modified_entity""; + public const string NewProperty = ""new_value""; +}"; + } + + public static string GetNewTestDataContent() + { + return @"public class TestClass +{ + public const string EntityName = ""new_entity""; +}"; + } + } +} diff --git a/LCGTests/testdata/ExpectedTestContent.cs b/LCGTests/testdata/ExpectedTestContent.cs new file mode 100644 index 0000000..55184fe --- /dev/null +++ b/LCGTests/testdata/ExpectedTestContent.cs @@ -0,0 +1,16 @@ +// ********************************************************************* +// Created by : Latebound Constants Generator 1.2023.5.901 for XrmToolBox +// Tool Author: Jonas Rapp https://jonasr.app/ +// GitHub : https://github.com/rappen/LCG-UDG/ +// Source Org : https://test.crm.dynamics.com +// Filename : {0} +// Created : {1} +// ********************************************************************* + +namespace TestNamespace +{{ + public class TestClass + {{ + public const string EntityName = ""test_entity""; + }} +}} From 8177669630e4ed8079a2f50fd8b01d140399ef48 Mon Sep 17 00:00:00 2001 From: Jonas Rapp Date: Wed, 29 Jul 2026 13:51:45 +0200 Subject: [PATCH 6/6] Solve #131 issue --- LCG-UDG/Settings/Settings.cs | 108 ++++++++++++++++++++++++++++++++++- Rappen.XTB.Helper | 2 +- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/LCG-UDG/Settings/Settings.cs b/LCG-UDG/Settings/Settings.cs index 259a40e..5e0d664 100644 --- a/LCG-UDG/Settings/Settings.cs +++ b/LCG-UDG/Settings/Settings.cs @@ -1,6 +1,8 @@ -using System.Collections.Generic; +using Rappen.XRM.Helpers.Extensions; +using System.Collections.Generic; using System.IO; using System.Windows.Forms; +using System.Xml.Serialization; using XrmToolBox.Extensibility; namespace Rappen.XTB.LCG @@ -176,11 +178,41 @@ internal string GetTheme() public class EntityFilter { public bool Expanded { get; set; } = false; + + [XmlIgnore] public CheckState Custom { get; set; } = CheckState.Checked; + + [XmlElement("Custom")] + public string CustomSerialized + { + get => Custom.ToString(); + set => Custom = value.ToCheckState(CheckState.Checked); + } + + [XmlIgnore] public CheckState Managed { get; set; } = CheckState.Checked; + + [XmlElement("Managed")] + public string ManagedSerialized + { + get => Managed.ToString(); + set => Managed = value.ToCheckState(CheckState.Checked); + } + public bool ExcludeIntersect { get; set; } + internal CheckState Selected { get; set; } + + [XmlIgnore] public CheckState Records { get; set; } = CheckState.Checked; + + [XmlElement("Records")] + public string RecordsSerialized + { + get => Records.ToString(); + set => Records = value.ToCheckState(CheckState.Checked); + } + public bool Uncountable { get; set; } } @@ -188,12 +220,67 @@ public class AttributeFilter { public bool Expanded { get; set; } = false; public bool CheckAll { get; set; } + + [XmlIgnore] public CheckState Custom { get; set; } = CheckState.Checked; + + [XmlElement("Custom")] + public string CustomSerialized + { + get => Custom.ToString(); + set => Custom = value.ToCheckState(CheckState.Checked); + } + + [XmlIgnore] public CheckState Managed { get; set; } = CheckState.Checked; + + [XmlElement("Managed")] + public string ManagedSerialized + { + get => Managed.ToString(); + set => Managed = value.ToCheckState(CheckState.Checked); + } + + [XmlIgnore] public CheckState PrimaryKeyName { get; set; } = CheckState.Checked; + + [XmlElement("PrimaryKeyName")] + public string PrimaryKeyNameSerialized + { + get => PrimaryKeyName.ToString(); + set => PrimaryKeyName = value.ToCheckState(CheckState.Checked); + } + + [XmlIgnore] public CheckState Required { get; set; } = CheckState.Checked; + + [XmlElement("Required")] + public string RequiredSerialized + { + get => Required.ToString(); + set => Required = value.ToCheckState(CheckState.Checked); + } + + [XmlIgnore] public CheckState Logical { get; set; } = CheckState.Unchecked; + + [XmlElement("Logical")] + public string LogicalSerialized + { + get => Logical.ToString(); + set => Logical = value.ToCheckState(CheckState.Unchecked); + } + + [XmlIgnore] public CheckState Internal { get; set; } = CheckState.Unchecked; + + [XmlElement("Internal")] + public string InternalSerialized + { + get => Internal.ToString(); + set => Internal = value.ToCheckState(CheckState.Unchecked); + } + public bool ExcludeCreMod { get; set; } = true; public bool ExcludeOwner { get; set; } = true; internal bool AreUsed { get; set; } = false; @@ -204,8 +291,27 @@ public class RelationshipFilter { public bool Expanded { get; set; } = false; public bool CheckAll { get; set; } + + [XmlIgnore] public CheckState Custom { get; set; } = CheckState.Checked; + + [XmlElement("Custom")] + public string CustomSerialized + { + get => Custom.ToString(); + set => Custom = value.ToCheckState(CheckState.Checked); + } + + [XmlIgnore] public CheckState Managed { get; set; } = CheckState.Checked; + + [XmlElement("Managed")] + public string ManagedSerialized + { + get => Managed.ToString(); + set => Managed = value.ToCheckState(CheckState.Checked); + } + public bool Type1N { get; set; } = false; public bool TypeN1 { get; set; } = true; public bool TypeNN { get; set; } = true; diff --git a/Rappen.XTB.Helper b/Rappen.XTB.Helper index 7b60f84..7905fb3 160000 --- a/Rappen.XTB.Helper +++ b/Rappen.XTB.Helper @@ -1 +1 @@ -Subproject commit 7b60f8449564d3080ae165292eb53d951e8bc348 +Subproject commit 7905fb35e1e96387da39baff67414cf861d68ae8