diff --git a/spkl/SparkleXrm.Tasks.Tests/CodeParserTests.cs b/spkl/SparkleXrm.Tasks.Tests/CodeParserTests.cs new file mode 100644 index 00000000..4368f61f --- /dev/null +++ b/spkl/SparkleXrm.Tasks.Tests/CodeParserTests.cs @@ -0,0 +1,49 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using SparkleXrm.Tasks; +using System.Text; + +namespace SparkleXrm.Tasks.Tests +{ + [TestClass] + public class CodeParserTests + { + private CrmPluginRegistrationAttribute _crmPluginRegistrationAttr = new CrmPluginRegistrationAttribute( + "Create", + "opportunity", + StageEnum.PostOperation, + ExecutionModeEnum.Synchronous, + "", + "PostOpportunityCreate", + 1, + IsolationModeEnum.Sandbox); + + [TestMethod] + [TestCategory("Unit Tests")] + public void AddAttributeTest_SingleLine() + { + var codeParser = new CodeParser(string.Format(TestCode.SingleLinePluginDefinitionTemplate, "")); + codeParser.AddAttribute(_crmPluginRegistrationAttr, "MyCompany.Plugins.OpportunityPlugin"); + + var expectedPluginDeifintionSB = string.Format( + TestCode.SingleLinePluginDefinitionTemplate, + _crmPluginRegistrationAttr.GetAttributeCode("\r\n") + "\r\n"); + + Assert.AreEqual(codeParser.Code, expectedPluginDeifintionSB.ToString()); + } + + [TestMethod] + [TestCategory("Unit Tests")] + public void AddAttributeTest_MultiLine() + { + var codeParser = new CodeParser(string.Format(TestCode.MultiLinePluginDefinitionTemplate, "")); + codeParser.AddAttribute(_crmPluginRegistrationAttr, "MyCompany.Plugins.OpportunityPlugin"); + + var expectedPluginDeifintionSB = string.Format( + TestCode.MultiLinePluginDefinitionTemplate, + _crmPluginRegistrationAttr.GetAttributeCode("\r\n ")); + + Assert.AreEqual(codeParser.Code, expectedPluginDeifintionSB.ToString()); + } + } +} diff --git a/spkl/SparkleXrm.Tasks.Tests/Resources/MultiLinePluginDefinitionTemplate.txt b/spkl/SparkleXrm.Tasks.Tests/Resources/MultiLinePluginDefinitionTemplate.txt new file mode 100644 index 00000000..c78dd59d --- /dev/null +++ b/spkl/SparkleXrm.Tasks.Tests/Resources/MultiLinePluginDefinitionTemplate.txt @@ -0,0 +1,4 @@ +namespace MyCompany.Plugins {{{0} + public class OpportunityPlugin : Plugin {{ + }} +}} \ No newline at end of file diff --git a/spkl/SparkleXrm.Tasks.Tests/Resources/SingleLinePluginDefinitionTemplate.txt b/spkl/SparkleXrm.Tasks.Tests/Resources/SingleLinePluginDefinitionTemplate.txt new file mode 100644 index 00000000..e475d87c --- /dev/null +++ b/spkl/SparkleXrm.Tasks.Tests/Resources/SingleLinePluginDefinitionTemplate.txt @@ -0,0 +1 @@ +namespace MyCompany.Plugins{{{0}public class OpportunityPlugin : Plugin {{ }} }} \ No newline at end of file diff --git a/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj b/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj index 8c125153..4ed20585 100644 --- a/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj +++ b/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj @@ -113,6 +113,7 @@ + @@ -159,6 +160,12 @@ + + + + + + diff --git a/spkl/SparkleXrm.Tasks.Tests/TestCode.Designer.cs b/spkl/SparkleXrm.Tasks.Tests/TestCode.Designer.cs index a9f842e4..4ddd095d 100644 --- a/spkl/SparkleXrm.Tasks.Tests/TestCode.Designer.cs +++ b/spkl/SparkleXrm.Tasks.Tests/TestCode.Designer.cs @@ -19,7 +19,7 @@ namespace SparkleXrm.Tasks.Tests { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class TestCode { @@ -142,5 +142,26 @@ internal static string DecoratedPlugin { return ResourceManager.GetString("DecoratedPlugin", resourceCulture); } } + + /// + /// Looks up a localized string similar to namespace MyCompany.Plugins {{ + /// {0}public class OpportunityPlugin : Plugin {{ + /// }} + ///}}. + /// + internal static string MultiLinePluginDefinitionTemplate { + get { + return ResourceManager.GetString("MultiLinePluginDefinitionTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to namespace MyCompany.Plugins{{{0}public class OpportunityPlugin : Plugin {{ }} }}. + /// + internal static string SingleLinePluginDefinitionTemplate { + get { + return ResourceManager.GetString("SingleLinePluginDefinitionTemplate", resourceCulture); + } + } } } diff --git a/spkl/SparkleXrm.Tasks.Tests/TestCode.resx b/spkl/SparkleXrm.Tasks.Tests/TestCode.resx index 07869d3b..07403b77 100644 --- a/spkl/SparkleXrm.Tasks.Tests/TestCode.resx +++ b/spkl/SparkleXrm.Tasks.Tests/TestCode.resx @@ -127,4 +127,10 @@ Resources\DecoratedPlugin.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + Resources\MultiLinePluginDefinitionTemplate.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + Resources\SingleLinePluginDefinitionTemplate.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + \ No newline at end of file diff --git a/spkl/SparkleXrm.Tasks/CodeParser.cs b/spkl/SparkleXrm.Tasks/CodeParser.cs index d7d146e6..de41ceec 100644 --- a/spkl/SparkleXrm.Tasks/CodeParser.cs +++ b/spkl/SparkleXrm.Tasks/CodeParser.cs @@ -160,7 +160,7 @@ public int RemoveExistingAttributes() return count; } - + public void AddAttribute(CrmPluginRegistrationAttribute attribute, string className) { @@ -169,20 +169,36 @@ public void AddAttribute(CrmPluginRegistrationAttribute attribute, string classN if (classLocation == null) throw new Exception(String.Format("Cannot find class {0}", className)); - var pos = _code.IndexOf(classLocation.Value); + // start index of "public class OpportunityPluign" + var classStartIndex = _code.IndexOf(classLocation.Value); + + // start index of "{ public class OpportunityPluign" + var openBraceBeforeClassIndex = _code.LastIndexOf("{", classStartIndex - 1); - // Find previouse line break - var lineBreak = _code.LastIndexOf("\r\n", pos - 1); + // start index of " { public class OpportunityPluign" + var eolBeforeClassIndex = _code.LastIndexOf("\r\n", classStartIndex - 1, classStartIndex - 1 - openBraceBeforeClassIndex); - // Indentation - var indentation = _code.Substring(lineBreak, pos - lineBreak); + // discover indentation between class and EOL (inclusive of EOL character) + var indentation = "\r\n"; + if (eolBeforeClassIndex != -1) + { + indentation = _code.Substring(eolBeforeClassIndex, classStartIndex - eolBeforeClassIndex); + } - // Add the attribute + // generate the attribut code var attributeCode = attribute.GetAttributeCode(indentation); - // Insert - _code = _code.Insert(lineBreak, attributeCode); + if (eolBeforeClassIndex == -1) + { + // insert attribute code at class start + eolBeforeClassIndex = classStartIndex; + + // add EOL between attribute code and class + attributeCode += "\r\n"; + } + // insert attribute code + _code = _code.Insert(eolBeforeClassIndex, attributeCode); } #endregion }