diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..bc2c017 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/src/TestDataGenerator.Tests/bin/Debug/netcoreapp2.2/TestDataGenerator.Tests.dll", + "args": [], + "cwd": "${workspaceFolder}/src/TestDataGenerator.Tests", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..d5b0e90 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/src/TestDataGenerator.Tests/TestDataGenerator.Tests.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/src/TestDataGenerator.Tests/TestDataGenerator.Tests.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "${workspaceFolder}/src/TestDataGenerator.Tests/TestDataGenerator.Tests.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/src/LocalTestRun.testrunconfig b/src/LocalTestRun.testrunconfig deleted file mode 100644 index c71f41b..0000000 --- a/src/LocalTestRun.testrunconfig +++ /dev/null @@ -1,21 +0,0 @@ - - - This is a default test run configuration for a local test run. - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/TestDataGenerator.Core.Tests/Benchmarks.cs b/src/TestDataGenerator.Core.Tests/Benchmarks.cs deleted file mode 100644 index f603409..0000000 --- a/src/TestDataGenerator.Core.Tests/Benchmarks.cs +++ /dev/null @@ -1,261 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Running; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TestDataGenerator.Core; -using TestDataGenerator.Core.Generators; - -namespace TestDataGenerator.Tests -{ - [TestClass] - public class BenchmarkInit - { - //[TestMethod] - public void RunBenchmarks() - { - BenchmarkRunner.Run(new ManualConfig() {}); - } - } - - public class TDGBenchmarks - { - public GenerationConfig _GenerationConfig; - - [Setup] - public void SetupData() - { - _GenerationConfig = new GenerationConfig(); - } - - #region Benchmarks - - [Benchmark] - public string Benchmark_Template_L() - { - var pattern = @"<<\L>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - - [Benchmark] - public string Benchmark_Template_L_Repeat_50() - { - var pattern = @"<<\L{50}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [Benchmark] - public string Benchmark_Template_L_Repeat_1_to_50() - { - var pattern = @"<<\L{1,50}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [Benchmark] - public string Benchmark_Template_Set_10_100() - { - var pattern = @"<<[10-100]>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [Benchmark] - public string Benchmark_Template_Set_10_100_Repeat_100() - { - var pattern = @"<<[10-100]{100}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [Benchmark] - public string Benchmark_Template_Set_Decimal_10_100() - { - var pattern = @"<<[10.00-100]>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [Benchmark] - public string Benchmark_Template_Set_Decimal_10_100_Repeat_100() - { - var pattern = @"<<[10.00-100]{100}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [Benchmark] - public string Benchmark_Template_MultipleCharacters_Repeat() - { - var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [Benchmark] - public string Benchmark_Pattern_L() - { - var pattern = @"\L"; - return AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [Benchmark] - public string Benchmark_Pattern_L_Repeat_50() - { - var pattern = @"\L{50}"; - return AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [Benchmark] - public string Benchmark_Pattern_L_Repeat_1_to_50() - { - var pattern = @"\L{1,50}"; - return AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [Benchmark] - public string Benchmark_Pattern_Set_10_100() - { - var pattern = @"[10-100]"; - return AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [Benchmark] - public string Benchmark_Pattern_Set_10_100_Repeat_100() - { - var pattern = @"[10-100]{100}"; - return AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [Benchmark] - public string Benchmark_Pattern_Set_Decimal_10_100() - { - var pattern = @"[10.00-100]"; - return AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [Benchmark] - public string Benchmark_Pattern_Set_Decimal_10_100_Repeat_100() - { - var pattern = @"[10.00-100]{100}"; - return AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [Benchmark] - public string Benchmark_Pattern_MultipleCharacters_Repeat() - { - var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; - return AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [Benchmark] - public string Benchmark_Template_L_With_Config() - { - var pattern = @"<<\L>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); - } - - - [Benchmark] - public string Benchmark_Template_L_Repeat_50_With_Config() - { - var pattern = @"<<\L{50}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Template_L_Repeat_1_to_50_With_Config() - { - var pattern = @"<<\L{1,50}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Template_Set_10_100_With_Config() - { - var pattern = @"<<[10-100]>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Template_Set_10_100_Repeat_100_With_Config() - { - var pattern = @"<<[10-100]{100}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Template_Set_Decimal_10_100_With_Config() - { - var pattern = @"<<[10.00-100]>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Template_Set_Decimal_10_100_Repeat_100_With_Config() - { - var pattern = @"<<[10.00-100]{100}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Template_MultipleCharacters_Repeat_With_Config() - { - var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; - return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Pattern_L_With_Config() - { - var pattern = @"\L"; - return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Pattern_L_Repeat_50_With_Config() - { - var pattern = @"\L{50}"; - return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Pattern_L_Repeat_1_to_50_With_Config() - { - var pattern = @"\L{1,50}"; - return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Pattern_Set_10_100_With_Config() - { - var pattern = @"[10-100]"; - return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Pattern_Set_10_100_Repeat_100_With_Config() - { - var pattern = @"[10-100]{100}"; - return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Pattern_Set_Decimal_10_100_With_Config() - { - var pattern = @"[10.00-100]"; - return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Pattern_Set_Decimal_10_100_Repeat_100_With_Config() - { - var pattern = @"[10.00-100]{100}"; - return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); - } - - [Benchmark] - public string Benchmark_Pattern_MultipleCharacters_Repeat_With_Config() - { - var pattern = @"\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}"; - return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); - } - - #endregion - - } -} diff --git a/src/TestDataGenerator.Core.Tests/Properties/AssemblyInfo.cs b/src/TestDataGenerator.Core.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 8089e67..0000000 --- a/src/TestDataGenerator.Core.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Test Data Generator")] -[assembly: AssemblyDescription("Test data generation tool.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("SecretDeveloper")] -[assembly: AssemblyProduct("CommandLine")] -[assembly: AssemblyCopyright("SecretDeveloper (Gary Kenneally) [2014]")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM componenets. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("11f94b95-e46c-499f-94b2-150cf4017e4d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/TestDataGenerator.Core.Tests/TestDataGenerator.Core.Tests.csproj b/src/TestDataGenerator.Core.Tests/TestDataGenerator.Core.Tests.csproj deleted file mode 100644 index b8f570c..0000000 --- a/src/TestDataGenerator.Core.Tests/TestDataGenerator.Core.Tests.csproj +++ /dev/null @@ -1,161 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {1142072E-6FBE-4496-9356-7862723F40A1} - Library - Properties - TestDataGenerator.Tests - TestDataGenerator.Tests - v4.5 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - - - - - 3.5 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - ..\ - true - - - true - full - false - ..\..\TestOutput\ - DEBUG - prompt - 4 - false - - - none - true - ..\..\TestOutput\ - TRACE - prompt - 4 - false - AnyCPU - - - - ..\packages\BenchmarkDotNet.0.10.1\lib\net45\BenchmarkDotNet.dll - True - - - ..\packages\BenchmarkDotNet.Core.0.10.1\lib\net45\BenchmarkDotNet.Core.dll - True - - - ..\packages\BenchmarkDotNet.Toolchains.Roslyn.0.10.1\lib\net45\BenchmarkDotNet.Toolchains.Roslyn.dll - True - - - ..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll - True - - - ..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll - True - - - False - - - - ..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll - True - - - 3.5 - - - - ..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll - True - - - ..\packages\System.Threading.Tasks.Extensions.4.0.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll - True - - - - - - - - - - - False - Microsoft .NET Framework 4 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - false - - - False - Windows Installer 4.5 - true - - - - - - Always - - - Always - - - Always - - - - - {7e0afb0b-0000-4d8a-a3cc-eadd3bc14298} - TestDataGenerator.Core - - - - - - - - - - \ No newline at end of file diff --git a/src/TestDataGenerator.Core.Tests/TextTests.cs b/src/TestDataGenerator.Core.Tests/TextTests.cs deleted file mode 100644 index 247f86d..0000000 --- a/src/TestDataGenerator.Core.Tests/TextTests.cs +++ /dev/null @@ -1,1775 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TestDataGenerator.Core; -using TestDataGenerator.Core.Exceptions; -using TestDataGenerator.Core.Generators; - -namespace TestDataGenerator.Tests -{ - [TestClass] - [ExcludeFromCodeCoverage] - public class TextTests - { - private const int _ErrorSnippet_ContextLength = 50; - - #region Template - - [TestMethod] - [TestCategory("Template")] - public void Can_GenerateFromTemplate_Overload1() - { - var template = @"Generated <<\L\L>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"Generated [A-Z]{2}")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_GenerateFromTemplate_Overload2() - { - var template = @"Generated <<\L\L>>"; - var config = new GenerationConfig() {Seed = "100"}; - string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"Generated [A-Z]{2}")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_GenerateFromTemplate_Overload3() - { - var template = @"<<@superhero@>>"; - - var config = new GenerationConfig(); - config.NamedPatterns.Patterns.Add(new NamedPattern() - { - Name = "superhero", - Pattern = "(Batman|Superman|Spiderman)" - }); - string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"(Batman|Superman|Spiderman)")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Load_File_Supplied_In_Config_Absolute() - { - var template = @"<<@noun@ @verb@ @noun@ @verb@>>"; - - var random = new Random(100); - var config = new GenerationConfig() {Seed = "200"}; - config.Random = random; - config.PatternFiles.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "language.tdg-patterns")); - - string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - Assert.IsTrue(text.Length > 0); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Load_File_Supplied_In_Config_Relative() - { - var template = @"<<@noun@ @verb@ @noun@ @verb@>>"; - - var config = new GenerationConfig() {Seed = "100"}; - config.PatternFiles.Add("language.tdg-patterns"); - - string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - Assert.IsTrue(text.Length > 0); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Load_File_Supplied_In_Config_Relative_No_Extension() - { - var template = @"<<@noun@ @verb@ @noun@ @verb@>>"; - - var config = new GenerationConfig() {Seed = "100"}; - config.PatternFiles.Add("language"); - - string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - Assert.IsTrue(text.Length > 0); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Escape_Template() - { - var template = @"Generated \<<\L\L>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - Assert.AreEqual(text, @"Generated <<\L\L>>"); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_UnEscape_Template() - { - var template = @"Generated \\<<\L\L>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"Generated \\\\[A-Z]{2}")); - } - - - [TestMethod] - [TestCategory("Template")] - public void Can_Escape_Config() - { - var template = @"\<# blah #>abc"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - Assert.AreEqual(@"\<# blah #>abc", text); - - // space at start - template = @". <# blah #>abc"; - text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - Assert.AreEqual(@". <# blah #>abc", text); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Template_No_Symbols() - { - var template = "Generated <>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"Generated [L]{2}")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Template_for_ReadMe1() - { - var template = @"Hi there <<\L\v{0,2}\l{0,2}\v \L\v{0,2}\l{0,2}\v{0,2}\l{0,2}\l>> how are you doing?"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, - new Regex( - @"Hi there [A-Z][aeiou]{0,2}[a-z]{0,2}[aeiou] [A-Z][aeiou]{0,2}[a-z]{0,2}[aeiou]{0,2}[a-z]{0,2}[a-z] how are you doing\?")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Template_for_ReadMe2() - { - var template = @"<>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"aa[1-9]\d{2}-\d{2}-\d{4}")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Template_for_ReadMe3() - { - - var template = - @"Hi there <<\L\v{0,2}\l{0,2}\v \L\v{0,2}\l{0,2}\v{0,2}\l{0,2}\l>> how are you doing? Your SSN is <<[1-9]\d\d-\d\d-\d\d\d\d>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - - StringAssert.Matches(text, - new Regex( - @"Hi there [A-Z][aeiou]{0,2}[a-z]{0,2}[aeiou] [A-Z][aeiou]{0,2}[a-z]{0,2}[aeiou]{0,2}[a-z]{0,2}[a-z] how are you doing\? Your SSN is [1-9]\d{2}-\d{2}-\d{4}")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Template_with_Symbols() - { - var template = @"Generated <>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"Generated [L][A-Z]")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Template_Multiple() - { - var template = @"Generated <<\L\L>> and <<(\d){5}>> with <<\d>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"Generated [A-Z]{2} and [0-9]{5} with [0-9]")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Template_Harder() - { - var template = - @"This is a very basic <<(\l){10}>> which can be used to create <<\l\l\l\l>> of varying <<\l\l\l\l\l>>. The main purpose is to generate dummy <<\L\l\l\l>> which can be used for <<\l\l\l\l\l\l\l>>."; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, - new Regex( - @"This is a very basic [a-z]{10} which can be used to create [a-z]{4} of varying [a-z]{5}. The main purpose is to generate dummy [A-Z][a-z]{3} which can be used for [a-z]{7}.")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Template_With_Alternatives_Symbols() - { - var template = @"<<\C|\c{10}|\V\V\V|\v{2,3}>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, - new Regex(@"[BCDFGHJKLMNPQRSTVWXYZ]{1}|[bcdfghjklmnpqrstvwxyz]{10}|[AEIOU]{3}|[aeiou]{2,3}")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Template_With_Alternative_Groups() - { - var template = @"<<(\C)|\c{10}|(\V\V\V){20}|(\v\v\v\v\v){2,3}>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, - new Regex(@"[BCDFGHJKLMNPQRSTVWXYZ]{1}|[bcdfghjklmnpqrstvwxyz]{10}|[AEIOU]{60}|[aeiou]{10,15}")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Pattern_With_Alternatives() - { - var template = @"Alternatives <<(\C|(\c){10}|\V\V\V|\v{2,3})>>"; - var config = new GenerationConfig(); - string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - Console.WriteLine("Seed:{0}", config.Seed); - StringAssert.Matches(text, - new Regex( - @"Alternatives ([BCDFGHJKLMNPQRSTVWXYZ]{1}|[bcdfghjklmnpqrstvwxyz]{10}|[AEIOU]{3}|[aeiou]{2,3})")); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Pattern_With_Alternatives2() - { - var template = @"Alternatives <<(A|B){1000}>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"Alternatives (A|B){1000}")); - } - - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Pattern_With_Alternatives_Repeated_Symbols() - { - var template = @"Alternatives <<(\C{1}|\c{10}|\V{3}|\v{2,3})>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, - new Regex( - @"Alternatives ([BCDFGHJKLMNPQRSTVWXYZ]{1})|([bcdfghjklmnpqrstvwxyz]{10})|([AEIOU]{3}|[aeiou]{2,3})")); - if (text.Contains("|")) Assert.Fail(text); - } - - [TestMethod] - [TestCategory("Template")] - public void Can_Generate_From_Pattern_With_calculated_quantity() - { - var template = @"<<\v{2,3}>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"([aeiou]{2,3})")); - if (text.Contains("|")) Assert.Fail(text); - } - - #endregion - - #region Sets - - [TestMethod] - [TestCategory("Sets")] - public void Can_Escape_Sets() - { - var template = @"<<\[LL]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^\[LL]$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_NonRange_Set() - { - var template = @"<<[AEI]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[AEI]{1}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Set() - { - var template = @"<<[A-I]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[ABCDEFGHI]{1}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Set_Lower() - { - var template = @"<<[a-i]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[abcdefghi]{1}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Set2() - { - var template = @"<<[A-B]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[AB]{1}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Set3() - { - var template = @"<<[W-X]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[W-X]{1}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Repeated_Set1() - { - var template = @"<<[W-X]{10}>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[W-X]{10}$")); - } - - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Repeated_Set2() - { - var template = @"<<([W-X]{10}[W-X]{10})>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[W-X]{10}[W-X]{10}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Repeated_Set3() - { - var template = @"<<([W-X]{10,100}[1-9]{10,100})>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[W-X]{10,100}[1-9]{10,100}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Repeated_Set4() - { - // empty repeat expressions should result in a single instance - {} == {1} - var template = @"<<([W-X]{})>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[W-X]$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Section_Repeated_Escape_Chars() - { - // empty repeat expressions should result in a single instance - {} == {1} - var template = @"(\\){10}"; - string text = AlphaNumericGenerator.GenerateFromPattern(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(template)); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Repeated_Escape_Chars() - { - // empty repeat expressions should result in a single instance - {} == {1} - var template = @"\\{10}"; - string text = AlphaNumericGenerator.GenerateFromPattern(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(template)); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Repeated_Chars() - { - // empty repeat expressions should result in a single instance - {} == {1} - var template = @"(a){10}"; - string text = AlphaNumericGenerator.GenerateFromPattern(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(@"aaaaaaaaaa", new Regex(template)); - } - - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Negated_Range() - { - // empty repeat expressions should result in a single instance - {} == {1} - var template = @"[^5-9]"; - string text = AlphaNumericGenerator.GenerateFromPattern(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(template)); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Negated_Range_And_Characters() - { - // empty repeat expressions should result in a single instance - {} == {1} - var template = @"[^A-Z5-9!£$%^&*()_+]"; - string text = AlphaNumericGenerator.GenerateFromPattern(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(template)); - } - - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric() - { - var template = @"<<[1-9]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[1-9]$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric5() - { - var template = @"<<[1-8]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[1-8]$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric2() - { - var template = @"<<[100-150]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - int e = int.Parse(text); - if (e < 100 || e > 150) Assert.Fail("Number not between 100 and 150."); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric3() - { - var template = @"<<(.[100-101]){3}>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^(.(100|101)){1}(.(100|101)){1}(.(100|101)){1}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric4() - { - var template = @"<<(.[100-101]){1,3}>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^(.(100|101))?(.(100|101))?(.(100|101))?$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric_DecimalFormat() - { - var template = @"<<([1.00-10.00])>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - double d; - if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) - Assert.Fail(); - if (d < 1.00d || d > 10.00d) - Assert.Fail(); - } - - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric_DecimalFormat2() - { - var template = @"<<([1.00-2.00])>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - double d; - if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) - Assert.Fail(); - if (d < 1.00 || d > 2.00d) Assert.Fail(); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric_DecimalFormat3() - { - var template = @"<<([1.1-1.2])>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - double d; - if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) - Assert.Fail(); - if (d < 1.1 || d > 1.2d) Assert.Fail(); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric_DecimalFormat4() - { - var template = @"<<([12345.12345-12345.12346])>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - double d; - if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) - Assert.Fail(); - if (d < 12345.12345 || d > 12345.12346d) Assert.Fail(); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_Range_Numeric_DecimalFormat5() - { - var template = @"<<([12345.9999-12346])>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - double d; - if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) - Assert.Fail(); - if (d < 12345.9999d || d > 12346d) Assert.Fail(); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_MultipleRange_Set() - { - var template = @"<<[A-B][1-3]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[A-B]{1}[1-3]{1}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_MultipleRange_Set2() - { - var template = @"<<[1-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, - new Regex(@"^[1-9]{1}[0-9]{1}[0-9]{1}-[0-9]{1}[0-9]{1}-[0-9]{1}[0-9]{1}[0-9]{1}[0-9]{1}$")); - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_MultipleRange_Set3() - { - var template = @"<<[1-28]/[1-12]/[1960-2013]>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - DateTime dt; - if ( - DateTime.TryParseExact(text, @"d/M/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, - out dt) == false) Assert.Fail("invalid Date"); - - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_MultipleRange_Set4() - { - var template = @"<<[a-c1-3_]{100}>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[a-c1-3_]{100}$")); - Assert.IsTrue(text.Contains("_")); // check that we have produced at least 1 underscore. - } - - [TestMethod] - [TestCategory("Sets")] - public void Can_Generate_MultipleRange_Set5() - { - var template = @"<<[a-c1-3_*?ABC]{100}>>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"^[a-c1-3_*?ABC]{100}$")); - Assert.IsTrue(text.Contains("_")); - Assert.IsTrue(text.Contains("*")); - Assert.IsTrue(text.Contains("?")); - Assert.IsTrue(text.Contains("A")); - Assert.IsTrue(text.Contains("B")); - Assert.IsTrue(text.Contains("C")); - } - - #endregion - - #region ErrorMessages - - [TestMethod] - [TestCategory("ErrorMessages")] - public void Can_BuildErrorSnippet_Start() - { - var template = @"[a-z"; - int ndx = 4; - - try - { - string text = AlphaNumericGenerator.GenerateFromPattern(template); - } - catch (GenerationException genEx) - { - Assert.AreEqual(@"Expected ']' but it was not found. -[a- - ^ ", genEx.Message); - } - catch (Exception) - { - Assert.Fail("Incorrect exception thrown."); - } - } - - #endregion - - #region Pattern - - [TestMethod] - [TestCategory("Pattern")] - public void GeneratePattern_Overloads() - { - var pattern = @"\L\L\L\L\L\L-\L\L-\L\L\L\L\L"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(15, text.Length); - StringAssert.Matches(text, new Regex("[A-Z]{6}-[A-Z]{2}-[A-Z]{5}")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void GeneratePattern_Overloads2() - { - var pattern = @"\L\L\L\L\L\L-\L\L-\L\L\L\L\L"; - var config = new GenerationConfig(){Seed = "300"}; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config: config); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(15, text.Length); - Assert.AreEqual(text,"LVMPQS-IY-CXIRW"); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_AlphaNumeric_multiple() - { - - var pattern = @"\L\L\L\L\L\L-\L\L-\L\L\L\L\L"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(15, text.Length); - StringAssert.Matches(text, new Regex("[A-Z]{6}-[A-Z]{2}-[A-Z]{5}")); - - pattern = @"\l\l\l\l\l\l"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(6, text.Length); - StringAssert.Matches(text, new Regex("[a-z]*")); - - pattern = @"\d\d\d\d\d\d\L\L\L\L\l\l\l\l"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(14, text.Length); - StringAssert.Matches(text, new Regex("[0-9]{6}[A-Z]{4}[a-z]{4}")); - - pattern = @"\d\d\d-\d\d-\d\d\d\d"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(11, text.Length); - StringAssert.Matches(text, new Regex(@"[\d]{3}-[\d]{2}-[\d]{4}")); - - //Test for escaped characters. - pattern = @"L\LLLLL"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(6, text.Length); - StringAssert.Matches(text, new Regex("L[A-Z]{1}LLLL")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_AlphaNumeric() - { - - var pattern = @"\L\l\V\v\C\c\d\d"; - string text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"[A-Z]{1}[a-z]{1}[AEIOU]{1}[aeiou]{1}[QWRTYPSDFGHJKLZXCVBNM]{1}[qwrtypsdfghjklzxcvbnm]{1}[\d]{1}[\d]{1}")); - - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Simple_Patterns() - { - var pattern = @"\L\L\L\L\L\L-\L\L-\L\L\L\L\L"; - string text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(15, text.Length); - StringAssert.Matches(text, new Regex("[A-Z]{6}-[A-Z]{2}-[A-Z]{5}")); - - pattern = @"\l\l\l\l\l\l"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(6, text.Length); - StringAssert.Matches(text, new Regex("[a-z]*")); - - pattern = @"\d\d\d\d\d\d\L\L\L\L\l\l\l\l"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(14, text.Length); - StringAssert.Matches(text, new Regex("[0-9]{6}[A-Z]{4}[a-z]{4}")); - - pattern = @"[1-9]\d\d-\d\d-\d\d\d\d"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(11, text.Length); - StringAssert.Matches(text, new Regex(@"[1-9]\d{2}-\d{2}-\d{4}")); - - //Test for escaped characters. - pattern = @"L\LLLLL"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(6, text.Length); - StringAssert.Matches(text, new Regex("L[A-Z]{1}LLLL")); - - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Character() - { - var pattern = @"w{3}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"w{3}")); - - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Character_Inside_Group() - { - var pattern = @"(\dC{3}\d{3}){3}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^(\dC{3}\d{3}){3}$")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Character_Inside_Group2() - { - var pattern = @"(\d(C){3}){3}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^(\d(C){3}){3}$")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Character_Inside_Group3() - { - var pattern = @"(\d(C){3})"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^(\d(C){3})$")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Character_Inside_Group4() - { - var pattern = @"(\d(\\)\d)"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^(\d(\\)\d$)")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Symbol_Inside_Group() - { - var pattern = @"(\w{3})"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"\w{3}")); - - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Symbol_Inside_Group2() - { - var pattern = @"(\w(\d{2}|\v{2})\w{3})"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"\w(\d{2}|[aeiou]{2})\w{3}")); - - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Pattern() - { - var pattern = @"(\L\L\d\d){3}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"[A-Z]{2}[0-9]{2}[A-Z]{2}[0-9]{2}[A-Z]{2}[0-9]{2}")); - - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Symbol() - { - var pattern = @"\L{3}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"[A-Z]{3}")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Mixed_Pattern_With_Random_Length() - { - string pattern = @"\L{10,20}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"[A-Z]{10,20}")); - - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Output_NonEscaped_Symbols() - { - string pattern = @"X"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"X")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Output_Repeated_Symbols() - { - string pattern = @"\d{10}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"[\d]{10}")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Output_Escaped_Slash() - { - string pattern = @"[\\]{1,10}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"[\\]{1,10}")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Mixed_Pattern() - { - string pattern = @"\L\L(\L\L\d\d){3}\L\L(\L){23}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"[A-Z]{2}[A-Z]{2}[0-9]{2}[A-Z]{2}[0-9]{2}[A-Z]{2}[0-9]{2}[A-Z]{2}[A-Z]{23}")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Repeat_Pattern_Long() - { - var pattern = @"(\L){1}(\d){1}(\L){2}(\d){2}(\L){4}(\d){4}(\L){8}(\d){8}(\L){16}(\d){16}(\L){32}(\d){32}(\L){64}(\d){64}(\L){128}(\d){128}(\L){256}(\d){256}(\L){512}(\d){512}(\L){1024}(\d){1024}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"[A-Z]{1}[0-9]{1}[A-Z]{2}[0-9]{2}[A-Z]{4}[0-9]{4}[A-Z]{8}[0-9]{8}[A-Z]{16}[0-9]{16}[A-Z]{32}[0-9]{32}[A-Z]{64}[0-9]{64}[A-Z]{128}[0-9]{128}[A-Z]{256}[0-9]{256}[A-Z]{512}[0-9]{512}[A-Z]{1024}[0-9]{1024}")); - Assert.AreEqual((1+2+4+8+16+32+64+128+256+512+1024)*2, text.Length); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Expressions_With_Alternates() - { - var pattern = @"(\L\L|\d\d)"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^([A-Z]{2}|[0-9]{2})$")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Expressions_With_Alternates2() - { - var pattern = @"(\L\L|\d\d|[AEIOU]|[100-120])"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^([A-Z]{2}|[0-9]{2}|[AEIOU]|\d\d\d)$")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Zero_Repeats_Invalid_End() - { - var pattern = @"(\L\L\d\d)33}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^[A-Z]{2}[0-9]{2}33}$")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Zero_Repeats() - { - var pattern = @"\L\L\d\d"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^[A-Z]{2}[0-9]{2}$")); - } - - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Complex1() - { - var pattern = @"\{'\w':('\w{3,25}'|[1-100])\}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\{'\w':('\w{3,25}'|\d{1,3})\}$")); - } - - - #endregion - - #region Symbols - - [TestMethod] - [TestCategory("Symbols")] - public void Can_Generate_All_Symbols() - { - var pattern = @"\."; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^.$")); - - pattern = @"\a"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^[A-Za-z]$")); - - pattern = @"\W"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\W$")); - - pattern = @"\w"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\w$")); - - pattern = @"\L"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^[A-Z]$")); - - pattern = @"\l"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^[a-z]$")); - - pattern = @"\V"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^[AEIOU]$")); - - pattern = @"\v"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^[aeiou]$")); - - pattern = @"\C"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^[BCDFGHJKLMNPQRSTVWXYZ]$")); - - pattern = @"\c"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^[bcdfghjklmnpqrstvwxyz]$")); - - pattern = @"\D"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\D$")); - - pattern = @"\d"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\d$")); - - pattern = @"\s"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\s$", RegexOptions.ECMAScript)); // ECMA compliant needed as \s ECMA includes [SPACE] but .NET Regex does not. - - pattern = @"\t"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\t$")); - - pattern = @"\n"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\n$")); - - pattern = @"\r"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\r$")); - - pattern = @"\\"; - text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - StringAssert.Matches(text, new Regex(@"^\\$")); - } - - #endregion - - #region NamedPatterns - - [TestMethod] - [TestCategory("NamedPatterns")] - public void Can_Generate_NamedPatterns() - { - //var namedPatterns = FileReader.LoadNamedPatterns("default.tdg-patterns"); - - var pattern = @"<<(@name_firstname_male@)>>"; - var text = AlphaNumericGenerator.GenerateFromTemplate(pattern, new GenerationConfig(){LoadDefaultPatternFile = true}); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.IsTrue(text.Length>0); - - } - - [TestMethod] - [TestCategory("NamedPatterns")] - public void Can_Generate_NamedPatterns_CompoundPattern() - { - //var namedPatterns = FileReader.LoadNamedPatterns("default.tdg-patterns"); - - var pattern = @"<<(@address_us_type1@)>>"; - var text = AlphaNumericGenerator.GenerateFromTemplate(pattern, new GenerationConfig(){LoadDefaultPatternFile = true}); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.IsTrue(text.Length>0); - - } - - [TestMethod] - [TestCategory("NamedPatterns")] - public void Can_Generate_NamedPatterns_All_Defaults_Name() - { - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - - var namedPatterns = FileReader.LoadNamedPatterns(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "default.tdg-patterns")); - - foreach (var dic in namedPatterns.Patterns) - { - var text = AlphaNumericGenerator.GenerateFromPattern("@"+dic.Name+"@", config: new GenerationConfig(){LoadDefaultPatternFile = true}); - Console.WriteLine(@"'{0}' produced '{1}'", dic.Name, text); - Assert.IsTrue(text.Length > 0); - } - sw.Stop(); - Console.WriteLine(@"All {0} default patterns generated in {1} milliseconds." - , namedPatterns.Patterns.Count - , sw.ElapsedMilliseconds); - } - - [TestMethod] - [TestCategory("NamedPatterns")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Exception_Invalid_Named_Pattern() - { - var config = new GenerationConfig() - { - PatternFiles = - new List() - { - Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "invalid.tdg-patterns") - } - }; - - AlphaNumericGenerator.GenerateFromPattern("@blah@", config:config); - } - - [TestMethod] - [TestCategory("NamedPatterns")] - public void Can_Generate_NamedPatterns_All_Defaults_Patterns() - { - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - - var namedPatterns = FileReader.LoadNamedPatterns(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "default.tdg-patterns")); - - foreach (var dic in namedPatterns.Patterns) - { - var text = AlphaNumericGenerator.GenerateFromPattern(dic.Pattern, config:new GenerationConfig() { LoadDefaultPatternFile = true }); - Console.WriteLine(@"'{0}' produced '{1}'", dic.Name, text); - Assert.IsTrue(text.Length > 0); - } - sw.Stop(); - Console.WriteLine(@"All {0} default patterns generated in {1} milliseconds." - , namedPatterns.Patterns.Count - , sw.ElapsedMilliseconds); - } - - - #endregion - - #region Profiling - - [TestMethod] - [TestCategory("Profiling")] - public void Profile_Random_Repeat() - { - var pattern = @"<<\L{50,51}>>"; - var testLimit = 1000; - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - for (var i = 0; i < testLimit; i++) - { - var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); - //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - } - sw.Stop(); - - Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); - } - - [TestMethod] - [TestCategory("Profiling")] - public void Profile_NonRandom_Repeat() - { - var pattern = @"<<\L{50}>>"; - var testLimit = 1000; - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - for (var i = 0; i < testLimit; i++) - { - var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); - //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - } - sw.Stop(); - - Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); - } - - [TestMethod] - [TestCategory("Profiling")] - public void Profile_NonRandom_Repeat_LowVolume() - { - var pattern = @"<<\L{50}>>"; - var testLimit = 2; - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - for (var i = 0; i < testLimit; i++) - { - var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); - //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - } - sw.Stop(); - - Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); - } - - [TestMethod] - [TestCategory("Profiling")] - public void Profile_Large_NonRandom_Repeat() - { - var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; - var testLimit = 1000; - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - for (var i = 0; i < testLimit; i++) - { - var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); - //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - } - sw.Stop(); - Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); - } - - [TestMethod] - [TestCategory("Profiling")] - public void Profile_Large_NonRandom_Repeat_LowVolume() - { - var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; - var testLimit = 1; - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - for (var i = 0; i < testLimit; i++) - { - var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); - //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - } - sw.Stop(); - Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); - } - - [TestMethod] - [TestCategory("Profiling")] - public void Profile_Large_NonRandom_NonSeeded_Repeat() - { - var pattern = @"(\w){64}"; - var testLimit = 10000; - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - for (var i = 0; i < testLimit; i++) - { - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - } - sw.Stop(); - Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); - } - - [TestMethod] - [TestCategory("Profiling")] - public void Profile_Large_NonRandom_Seeded_Repeat() - { - var pattern = @"(\w){64}"; - var testLimit = 10000; - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - for (var i = 0; i < testLimit; i++) - { - var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config: new GenerationConfig(){Seed = "100"}); - //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - } - sw.Stop(); - Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); - } - - [TestMethod] - [TestCategory("Profiling")] - public void Profile_Small_NonRandom_Seeded_Repeat() - { - var pattern = @"(\w){64}"; - var testLimit = 100; - var sw = new System.Diagnostics.Stopwatch(); - sw.Start(); - for (var i = 0; i < testLimit; i++) - { - var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config: new GenerationConfig() { Seed = "100" }); - //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - } - sw.Stop(); - Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); - } - - - [TestMethod] - [TestCategory("Profiling")] - public void Profile_Comparison_With_String_Append() - { - var testIterations = 100000; - var pattern = @"(A){100}"; - var patternOutput = "A"; - var patternCount = 100; - - // Control - var sb = new StringBuilder(); - var sw = new System.Diagnostics.Stopwatch(); - sw.Reset(); - sw.Start(); - for (var i = 0; i < testIterations; i++) - { - for (var j = 0; j < patternCount; j++) - { - sb.Append(patternOutput); - } - } - sw.Stop(); - Console.WriteLine(@"StringBuilder - {0} iterations of the following pattern {1} completed in {2} milliseconds.", testIterations, pattern, sw.ElapsedMilliseconds); - - sw.Reset(); - sw.Start(); - for (var i = 0; i < testIterations; i++) - { - AlphaNumericGenerator.GenerateFromPattern(pattern); - } - sw.Stop(); - Console.WriteLine(@"GenerateFromPattern(pattern) - {0} iterations of the following pattern {1} completed in {2} milliseconds.", testIterations, pattern, sw.ElapsedMilliseconds); - - - var config = new GenerationConfig() {Seed = "100"}; - sw.Reset(); - sw.Start(); - for (var i = 0; i < testIterations; i++) - { - AlphaNumericGenerator.GenerateFromPattern(pattern, config); - } - sw.Stop(); - Console.WriteLine(@"GenerateFromPattern(pattern, config) - {0} iterations of the following pattern {1} completed in {2} milliseconds.", testIterations, pattern, sw.ElapsedMilliseconds); - - } - - #endregion - - #region Negation - - - [TestMethod] - [TestCategory("Negation")] - public void Can_Generate_Correct_Output_from_Negated_Set() - { - var pattern = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - var text = AlphaNumericGenerator.GenerateFromPattern("[^"+pattern+"]"); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.IsTrue(pattern.IndexOf(text, StringComparison.InvariantCulture) == -1); - } - - [TestMethod] - [TestCategory("Negation")] - public void Can_Generate_Correct_Output_from_Negated_Set_Range() - { - var pattern = @"A-Z"; - var text = AlphaNumericGenerator.GenerateFromPattern("[^" + pattern + "]"); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.IsTrue(pattern.IndexOf(text, StringComparison.InvariantCulture) == -1); - } - - [TestMethod] - [TestCategory("Negation")] - public void Can_Generate_Correct_Output_from_Negated_Set_Range2() - { - var pattern = @"3-6"; - var text = AlphaNumericGenerator.GenerateFromPattern("[^" + pattern + "]"); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.IsTrue("3456".IndexOf(text, StringComparison.InvariantCultureIgnoreCase) == -1); - } - - [TestMethod] - [TestCategory("Negation")] - public void Can_Generate_Correct_Output_from_Negated_Set_Range_Multiple() - { - var pattern = @"A-Za-z"; - var text = AlphaNumericGenerator.GenerateFromPattern("[^" + pattern + "]"); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.IsTrue("ABCDEFGHIJKLMNOPQRSTUVWXYZ".IndexOf(text, StringComparison.InvariantCultureIgnoreCase) == -1); - } - - [TestMethod] - [TestCategory("Negation")] - public void Can_Generate_Correct_Output_from_Negated_Set_Range_Repeated() - { - var pattern = @"[^3-6]{10}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.IsTrue("3456".IndexOf(text, StringComparison.InvariantCultureIgnoreCase) == -1); - } - - [TestMethod] - [TestCategory("Negation")] - public void Can_Generate_Correct_Output_from_Negated_Set_Range_Multiple_Repeated() - { - var pattern = @"[^A-Za-z]{10}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.IsTrue("ABCDEFGHIJKLMNOPQRSTUVWXYZ".IndexOf(text, StringComparison.InvariantCultureIgnoreCase) == -1); - } - - #endregion - - #region NegativeTesting - - [TestMethod] - [TestCategory("NegativeTesting")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Exception_Missing_Placeholder_End() - { - var template = "This is a very basic <<(l){10}>> which can be used to create <>. The main purpose is to generate dummy <> which can be used for <>."; - AlphaNumericGenerator.GenerateFromTemplate(template); - } - - [TestMethod] - [TestCategory("NegativeTesting")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Exception_Missing_Placeholder_End_End() - { - var template = "This is a very basic <<(l){10}>> which can be used to create <> of varying <>. The main purpose is to generate dummy <> which can be used for <>"; - AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [TestMethod] - [TestCategory("NegativeTesting")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Exception_Negated_Set_Range_InvalidNumeric() - { - var pattern = @"[^30-60]"; - AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [TestMethod] - [TestCategory("NegativeTesting")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Exception_Negated_Set_Range_InvalidNumeric2() - { - var pattern = @"[^3-60]"; - AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [TestMethod] - [TestCategory("NegativeTesting")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Exception_Negated_Set_Range_InvalidNumeric3() - { - var pattern = @"[^3.00-6]"; - AlphaNumericGenerator.GenerateFromPattern(pattern); - } - - [TestMethod] - [TestCategory("NegativeTesting")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Exception_Invalid_Config() - { - var pattern = @"<#{ asdsd }#>"; - AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [TestMethod] - [TestCategory("NegativeTesting")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Exception_Invalid_Config2() - { - var pattern = @"<#"; - AlphaNumericGenerator.GenerateFromTemplate(pattern); - } - - [TestMethod] - [TestCategory("NegativeTesting")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Missing_Pattern_File() - { - var template = @"<<@superhero@>>"; - - var namedPatterns = new NamedPatterns(); - namedPatterns.Patterns.Add(new NamedPattern() { Name = "superhero", Pattern = "(Batman|Superman|Spiderman)" }); - - var config = new GenerationConfig() { Seed = "100" }; - config.PatternFiles.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "notpresent.tdg-pattern")); - config.NamedPatterns = namedPatterns; - - string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"(Batman|Superman|Spiderman)")); - } - - - [TestMethod] - [TestCategory("NegativeTesting")] - [ExpectedException(typeof(GenerationException))] - public void Can_Throw_Invalid_Pattern_File() - { - var template = @"<<@superhero@>>"; - - var namedPatterns = new NamedPatterns(); - namedPatterns.Patterns.Add(new NamedPattern() { Name = "superhero", Pattern = "(Batman|Superman|Spiderman)" }); - - var config = new GenerationConfig() { Seed = "100" }; - config.PatternFiles.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg.exe")); - config.NamedPatterns = namedPatterns; - - string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - StringAssert.Matches(text, new Regex(@"(Batman|Superman|Spiderman)")); - } - - #endregion - - #region ConfigurationTesting - /* - [TestMethod] - [TestCategory("ConfigurationTesting")] - public void Can_Configure_Random_Seed_From_Config() - { - int ndx = 0; - - var configStr = "<# { 'Seed':100 } #>"; - var template = configStr+@"Generated <>"; - var config = AlphaNumericGenerator.GetConfiguration(template, ref ndx); - Assert.AreEqual("100", config.Seed); - Assert.AreEqual(configStr.Length, ndx); - } - */ - - [TestMethod] - [TestCategory("ConfigurationTesting")] - public void Can_Configure_And_Produce_Output_With_Seed() - { - var template = "<# { \"Seed\":\"100\" } #>Generated <>"; - string text = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, text); - - Assert.AreEqual(text, "Generated LZ"); - } - - [TestMethod] - [TestCategory("ConfigurationTesting")] - public void Can_Configure_And_Produce_Output_With_Seed2() - { - var template = @"<# { 'Seed':100 } #>Generated <<\.\w\W\L\l\V\v\d\D\S\s>>"; - string actual = AlphaNumericGenerator.GenerateFromTemplate(template); - Console.WriteLine(@"'{0}' produced '{1}'", template, actual); - - Assert.AreEqual(@"Generated |k]XjUo6Go ", actual); - } - - /* - [TestMethod] - [TestCategory("ConfigurationTesting")] - public void Can_Catch_Config_Not_At_Beginning_Template() - { - var template = @"<# { 'Seed':100 } #>Generated <<\.\w\W\L\l\V\v\d\D\S\s>>"; - int index = 1; - var config = AlphaNumericGenerator.GetConfiguration(template, ref index); - Assert.IsNull(config); - } - */ - - #endregion - - #region UtilityTesting - - [TestMethod] - [TestCategory("UtilityTesting")] - public void Can_Deserialize() - { - var config = Utility.DeserializeJson("{\"seed\":\"100\"}"); - Assert.IsNotNull(config); - Assert.AreEqual("100", config.Seed); - } - - [TestMethod] - [TestCategory("UtilityTesting")] - public void Can_Serialize() - { - var config = new GenerationConfig(); - config.Seed = "300"; - var configStr = Utility.SerializeJson(config); - Console.WriteLine("SerializeJson produced" + configStr); - Assert.IsNotNull(configStr); - Assert.AreEqual("{\"LoadDefaultPatternFile\":false,\"NamedPatterns\":{\"Patterns\":[]},\"patternfiles\":[],\"seed\":\"300\"}", configStr); - } - - #endregion - - #region "special functions" - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Anagram() - { - var pattern = @"[ABC]{:anagram:}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(3, text.Length); - Assert.IsTrue(text.Contains("A")); - Assert.IsTrue(text.Contains("B")); - Assert.IsTrue(text.Contains("C")); - } - - [TestMethod] - [TestCategory("Pattern")] - public void Can_Generate_Anagram_Long() - { - var input = "abcdefghijklmnopqrstuvwxyz"; - var pattern = @"["+input+"]{:anagram:}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern); - Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); - Assert.AreEqual(input.Length, text.Length); - foreach (var ch in input.ToCharArray()) - { - Assert.IsTrue(text.Contains(ch.ToString())); - } - } - - #endregion - - #region Randomness - [TestMethod] - [TestCategory("Randomness")] - public void Level_Of_Randomness() - { - var pattern = @"(\L\L\L\L\L\L-\L\L-\L\L\L\L\L\n){1000}"; - var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config:new GenerationConfig() { Seed = "100" }); - var segments = new List(text.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries)); - - Console.WriteLine(@"'{0}' produced {1} values, out of which, {2} are unique and {3} are duplicates.", pattern, segments.Count, segments.Distinct().Count(), segments.Count - segments.Distinct().Count()); - } - - [TestMethod] - [TestCategory("Randomness")] - public void Level_Of_Loop() - { - var pattern = @"(\L\L\L\L\L\L-\L\L-\L\L\L\L\L)"; - var segments = new List(); - - var config = new GenerationConfig(); - - for (var i = 0; i < 1000; i++) - { - segments.Add(AlphaNumericGenerator.GenerateFromPattern(pattern, config:config)); - } - - Console.WriteLine(@"'{0}' produced {1} values, out of which, {2} are unique and {3} are duplicates.", pattern, segments.Count, segments.Distinct().Count(), segments.Count - segments.Distinct().Count()); - } - - [TestMethod] - [TestCategory("Randomness")] - public void Seed_As_String_IsUsed() - { - var pattern = @"(\L\L\L\L\L\L-\L\L-\L\L\L\L\L)"; - var config = new GenerationConfig(); - - var segments = new Dictionary(); - for (var i = 0; i < 1000; i++) - { - segments.Add(AlphaNumericGenerator.GenerateFromPattern(pattern, config: config), ""); - config.Seed += "a"; // reset the seed each loop which should result in new random generations. - } - Console.WriteLine(@"'{0}' produced {1} values, out of which, {2} are unique and {3} are duplicates.", pattern, segments.Count, segments.Distinct().Count(), segments.Count - segments.Distinct().Count()); - } - - [TestMethod] - [TestCategory("Randomness")]public void Weird_s_shortkey_bug() - { - var pattern = @"\s"; - var config = new GenerationConfig(); - for (var i = 0; i < 1000; i++) - { - config.Seed = i.ToString(); - var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config); - Console.WriteLine(@"'{0}' with seed '{1}' produced '{2}'", pattern, config.Seed, text); - StringAssert.Matches(text, new Regex(@"^\s$", RegexOptions.ECMAScript)); // ECMA compliant needed as \s ECMA includes [SPACE] but .NET Regex does not. - config.Seed += "a"; // reset the seed each loop which should result in new random generations. - } - - } - #endregion -} -} - diff --git a/src/TestDataGenerator.Core.sln b/src/TestDataGenerator.Core.sln deleted file mode 100644 index 33dcaaf..0000000 --- a/src/TestDataGenerator.Core.sln +++ /dev/null @@ -1,46 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4C7BFE94-A402-499A-9A2C-BB0A44E261D5}" - ProjectSection(SolutionItems) = preProject - DataGenerator.vsmdi = DataGenerator.vsmdi - LocalTestRun.testrunconfig = LocalTestRun.testrunconfig - Performance1.psess = Performance1.psess - ..\VERSION = ..\VERSION - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{3A492DFF-FDA0-4AC7-BD29-745203BDC70E}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestDataGenerator.Core", "TestDataGenerator.Core\TestDataGenerator.Core.csproj", "{7E0AFB0B-0000-4D8A-A3CC-EADD3BC14298}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestDataGenerator.Core.Tests", "TestDataGenerator.Core.Tests\TestDataGenerator.Core.Tests.csproj", "{1142072E-6FBE-4496-9356-7862723F40A1}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7E0AFB0B-0000-4D8A-A3CC-EADD3BC14298}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7E0AFB0B-0000-4D8A-A3CC-EADD3BC14298}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7E0AFB0B-0000-4D8A-A3CC-EADD3BC14298}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7E0AFB0B-0000-4D8A-A3CC-EADD3BC14298}.Release|Any CPU.Build.0 = Release|Any CPU - {1142072E-6FBE-4496-9356-7862723F40A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1142072E-6FBE-4496-9356-7862723F40A1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1142072E-6FBE-4496-9356-7862723F40A1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1142072E-6FBE-4496-9356-7862723F40A1}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(TestCaseManagementSettings) = postSolution - CategoryFile = DataGenerator.vsmdi - EndGlobalSection -EndGlobal diff --git a/src/TestDataGenerator.Core.sln.DotSettings b/src/TestDataGenerator.Core.sln.DotSettings deleted file mode 100644 index d9d3bae..0000000 --- a/src/TestDataGenerator.Core.sln.DotSettings +++ /dev/null @@ -1,2 +0,0 @@ - - HINT \ No newline at end of file diff --git a/src/TestDataGenerator.Core/Generators/AlphaNumericGenerator.cs b/src/TestDataGenerator.Core/Generators/AlphaNumericGenerator.cs deleted file mode 100644 index f4d7623..0000000 --- a/src/TestDataGenerator.Core/Generators/AlphaNumericGenerator.cs +++ /dev/null @@ -1,775 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using TestDataGenerator.Core.Exceptions; - -namespace TestDataGenerator.Core.Generators -{ - public static class AlphaNumericGenerator - { - private static readonly Dictionary _ShortHands = GetShortHandMap(); - - private const string _Config_Start = "<#"; - private const string _Config_End = "#>"; - - private const string _Placeholder_Start = "<<"; - private const string _Placeholder_End = ">>"; - - private const char _Section_Start = '('; - private const char _Section_End = ')'; - - private const char _Set_Start = '['; - private const char _Set_End = ']'; - - private const char _Quantifier_Start = '{'; - private const char _Quantifier_End = '}'; - - private const char _Alternation = '|'; - private const char _Escape = '\\'; - private const char _Negation = '^'; - - private const char _NamedPattern_Start = '@'; - private const char _NamedPattern_End = '@'; - - private const string _Anagram = ":anagram:"; - - private const int _ErrorSnippet_ContextLength = 50; - - #region public - - /// - /// Takes in a string that contains 0 or more <<placeholder>> values and replaces the placeholder item with the expression it defines. - /// - /// - /// - /// - public static string GenerateFromTemplate(string template, GenerationConfig generationConfig=null) - { - int index = 0; - - // CONFIG - if (generationConfig == null) generationConfig = LoadAndRemoveConfigFromTemplate(ref template); - if (generationConfig == null) generationConfig = new GenerationConfig(); - - // PATTERNS - // Load provided ones as well if there are any. - var defaultPatterns = GetDefaultNamedPatterns(generationConfig); - defaultPatterns.Patterns.ForEach(generationConfig.NamedPatterns.Patterns.Add); - - // Load all from the PatternFiles in config - AppendPatternsFromConfigToCollection(generationConfig, generationConfig.NamedPatterns); - - var sb = new StringBuilder(); - - while (index < template.Length) - { - // Find our next placeholder - int start = FindPositionOfNext(template, index, _Placeholder_Start, _Placeholder_End); - if (start == -1) - { - sb.Append(template.Substring(index)); //add remaining string. - break; // all done! - } - - bool isEscaped = IsEscaped(template, start); //start >= 1 && template[start - 1].Equals(_Escape); - if (isEscaped) start = start - 1; - sb.Append(template.Substring(index, start - index)); // Append everything up to start as it is. - if (isEscaped) start = start + 1; - start = start + _Placeholder_Start.Length; // move past '<<' to start of expression - - int end = FindPositionOfNext(template, start, _Placeholder_End, _Placeholder_Start); // find end of placeholder - if (end == -1) - { - throw new GenerationException("Unable to find closing placeholder after "+start); - } - - var pattern = template.Substring(start, end - start); // grab our expression - if (isEscaped) - sb.Append("<<"+pattern+">>"); - else - GenerateFromPattern(sb, pattern, generationConfig); // generate value from expression - index = end+2; // update our index. - } - - return sb.ToString(); - } - - public static string GenerateFromPattern(string pattern, GenerationConfig config = null) - { - if (config == null) config = new GenerationConfig(); - var sb = new StringBuilder(); - - // add default pattern file entries - if (config.LoadDefaultPatternFile) - { - GetDefaultNamedPatterns(config).Patterns.ForEach(config.NamedPatterns.Patterns.Add); - } - - if (config.PatternFiles != null) - { - // Load all from the PatternFiles in config - AppendPatternsFromConfigToCollection(config, config.NamedPatterns); - } - - GenerateFromPattern(sb, pattern, config); - return sb.ToString(); - } - - #endregion - - #region Generate - - private static void GenerateFromPattern(StringBuilder sb, string pattern, GenerationConfig config) - { - if (string.IsNullOrEmpty(pattern)) - throw new GenerationException("Argument 'pattern' cannot be null."); - - ProcessPattern(sb, pattern, config); - } - - private static void GenerateFromAlternatedPattern(StringBuilder sb, string exp, ContentOptions contentOptions, GenerationConfig config) - { - var alternates = exp.Split(_Alternation); - for (int x = 0; x < contentOptions.Repeat; x++) - { - exp = alternates[config.Random.Next(0, alternates.Length)]; - GenerateFromPattern(sb, exp, config); - } - } - - private static void GenerateFromAnagramPattern(StringBuilder sb, string exp, ContentOptions contentOptions, GenerationConfig config) - { - for (int x = 0; x < contentOptions.Repeat; x++) - { - var arr = exp.ToCharArray(); - arr = arr.OrderBy(r => config.Random.Next()).ToArray(); - foreach(var ch in arr) - AppendCharacterDerivedFromSymbol(sb, ch, false, config); - } - } - - private static string GenerateFloatingFormatWithScale(int scale) - { - var t = "0."; - for (int i = 0; i < scale; i++) - { - t += "#"; - } - return t; - } - - #endregion - - #region Get - - /// - /// Recieves a "A-Z" type string and returns the appropriate list of characters. - /// - /// - /// - /// - /// - private static string GetRandomCharacterFromRange(string range, bool isNegated, GenerationConfig config) - { - string ret; - string possibles=_ShortHands["."]; - var items = range.Split('-'); - double i; - if (!Double.TryParse(items[0], out i)) - ret = GetRandomAlphaItemFromRange(isNegated, config, items, possibles); - else - ret = GetRandomNumericItemFromRange(isNegated, config, items, possibles); - - return ret; - } - - private static Dictionary GetShortHandMap() - { - var shorthands = new Dictionary(); - shorthands["l"] = "abcdefghijklmnopqrstuvwxyz"; - shorthands["L"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - shorthands["V"] = "AEIOU"; - shorthands["v"] = "aeiou"; - shorthands["C"] = "BCDFGHJKLMNPQRSTVWXYZ"; - shorthands["c"] = "bcdfghjklmnpqrstvwxyz"; - shorthands["s"] = " \f\n\r\t\v"; - shorthands["d"] = "0123456789"; - - var nonAlphaNonWhiteSpace = ".,;:\"'!&?£$€$%^<>{}[]()*\\+-=@#|~/"; - shorthands["W"] = shorthands["s"] + nonAlphaNonWhiteSpace + " "; // [^A-Za-z0-9_]. - - shorthands["a"] = shorthands["l"] + shorthands["L"]; - shorthands["D"] = shorthands["l"] + shorthands["L"] + shorthands["W"]; - shorthands["w"] = shorthands["l"] + shorthands["L"] + shorthands["d"] + "_"; // [A-Za-z0-9_]. - shorthands["S"] = shorthands["l"] + shorthands["L"] + shorthands["d"] + "_" + nonAlphaNonWhiteSpace; // [^ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000-\u200a​\u2028\u2029​\u202f\u205f​\u3000\ufeff] - shorthands["."] = shorthands["a"] + shorthands["d"] + shorthands["W"]; - - return shorthands; - } - - private static string GetRandomAlphaItemFromRange(bool isNegated, GenerationConfig config, string[] items, string possibles) - { - string ret = ""; - if (_ShortHands["l"].Contains(items[0])) possibles = _ShortHands["l"]; - if (_ShortHands["L"].Contains(items[0])) possibles = _ShortHands["L"]; - - var start = possibles.IndexOf(items[0].ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal); - if (start > -1) - { - var end = possibles.IndexOf(items[1].ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal); - possibles = possibles.Substring(start, end - start + 1); - if (isNegated) possibles = Regex.Replace(_ShortHands["."],"[" + possibles + "]", ""); - ret = possibles[config.Random.Next(0, possibles.Length)].ToString(CultureInfo.InvariantCulture); - } - return ret; - } - - private static string GetRandomNumericItemFromRange(bool isNegated, GenerationConfig config, string[] items, string possibles) - { - string ret = ""; - - double min; - if (double.TryParse(items[0], NumberStyles.Number, CultureInfo.InvariantCulture, out min)) - { - double max; - if (double.TryParse(items[1], NumberStyles.Number, CultureInfo.InvariantCulture, out max)) - { - int scale = 0; - if (items[0].Contains(".")) - scale = items[0].Split('.')[1].Length; - - if (isNegated) - { - if (scale > 0 || min < 0 || min > 9 || max < 0 || max > 9) - throw new GenerationException("Negated numeric sets are restricted to integers between 0 and 9."); - - var negs = ExpandNegatedMinMax(min, max); - possibles = Regex.Replace(possibles, "[" + negs + "]", ""); - if (possibles.Length == 0) return ""; // No allowable values remain - return empty string - ret = possibles[config.Random.Next(0, possibles.Length)].ToString(CultureInfo.InvariantCulture); - } - else - { - var t = config.Random.NextDouble(); - min = min + (t*(max - min)); - ret = min.ToString(GenerateFloatingFormatWithScale(scale), CultureInfo.InvariantCulture); - } - } - } - return ret; - } - - /// - /// Dervives the correct repeat value from the provided expression. - /// - /// String in the form of '{n}' or '{n,m}' where n and m are integers - /// - /// - private static int GetRepeatValueFromRepeatExpression(string repeatExpression, GenerationConfig config) - { - if (string.IsNullOrWhiteSpace(repeatExpression)) return 1; - - int repeat; - if (repeatExpression.Contains(",")) - { - // {min,max} has been provided - parse and get value. - var vals = repeatExpression.Split(','); - int min, max; - - if (vals.Length < 2 || !int.TryParse(vals[0], out min) || !int.TryParse(vals[1], out max) || min > max || min < 0) - { - var msg = "Invalid repeat section, random length parameters must be in the format {min,max} where min and max are greater than zero and min is less than max.\n"; - msg += BuildErrorIndicationText(repeatExpression, 0); - throw new GenerationException(msg); - } - - repeat = config.Random.Next(min, max + 1); - } - else if (!int.TryParse(repeatExpression, out repeat)) repeat = -1; - - if (repeat < 0) - throw new GenerationException("Invalid repeat section, repeat value must not be less than zero. '" + repeatExpression + "'"); - return repeat; - } - - private static string GetContent(string characters, ref int index, string openingContainerChar, string closingContainerChar) - { - if (index + openingContainerChar.Length >= characters.Length) - return ""; - - int patternStart = index + openingContainerChar.Length; - var patternEnd = patternStart; - var sectionDepth = openingContainerChar.Equals(closingContainerChar) ? 0 : 1; // start off inside current section - while (patternEnd < characters.Length) - { - if (characters.Substring(patternEnd, openingContainerChar.Length).Equals(openingContainerChar)) sectionDepth++; - //check for Alternations in base group. - - if (characters.Substring(patternEnd, closingContainerChar.Length).Equals(closingContainerChar)) - { - sectionDepth--; - if (sectionDepth == 0) break; - } - patternEnd++; - } - - if (sectionDepth > 0) // make sure we found closing char - { - var msg = "Expected '" + closingContainerChar + "' but it was not found." + Environment.NewLine; - msg += BuildErrorIndicationText(characters, patternStart); - throw new GenerationException(msg); - } - - int patternLength = patternEnd - patternStart; - - index = index + patternLength + openingContainerChar.Length + closingContainerChar.Length; // update index position. - return characters.Substring(patternStart, patternLength); - } - - private static ContentOptions GetContentOptions(string characters, ref int index, string openingContainerChar, string closingContainerChar, GenerationConfig config) - { - var result = new ContentOptions - { - Content = GetContent(characters, ref index, openingContainerChar, closingContainerChar) - }; - - result.ContainsAlternation = ContainsAlternations(result.Content); - - if (result.Content[0].Equals(_Negation)) - { - result.IsNegated = true; - result.Content = result.Content.Replace("^", ""); - } - - if (characters.Length <= index || !characters[index].Equals(_Quantifier_Start)) return result; - - result.QuantifierContent = GetContent(characters, ref index, _Quantifier_Start.ToString(CultureInfo.InvariantCulture), _Quantifier_End.ToString(CultureInfo.InvariantCulture)); - - // check for special functions - if (result.QuantifierContent.Contains(":")) - { - result.IsAnagram = ContainsAnagram(result.QuantifierContent); - } - else - { - result.Repeat = GetRepeatValueFromRepeatExpression(result.QuantifierContent, config); - } - - return result; - } - - private static NamedPatterns GetDefaultNamedPatterns(GenerationConfig generationConfig) - { - var patterns = new NamedPatterns(); - if (generationConfig == null || generationConfig.LoadDefaultPatternFile == false) - return patterns; // Dont attempt to load default pattern files with every execution -- too slow. - - var path = FileReader.GetPatternFilePath("default"); - if (File.Exists(path)) - { - patterns = FileReader.LoadNamedPatterns(path, false); - } - - return patterns; - } - - private static GenerationConfig GetConfiguration(string template, ref int index) - { - if (index > 0) - return null; //throw new GenerationException("Configuration items must be at the start of the template (index 0)"); - - if (!template.TrimStart().StartsWith(_Config_Start)) - return null; - - var configString = GetContent(template, ref index, _Config_Start, _Config_End).ToLowerInvariant().Replace('\'', '"'); - - GenerationConfig config; - try - { - config = Utility.DeserializeJson(configString); - if (config.NamedPatterns == null) config.NamedPatterns = new NamedPatterns(); - } - catch (Exception ex) - { - var msg = BuildErrorIndicationText(template, _Config_Start.Length); - throw new GenerationException(string.Format("Unable to parse configuration string. Please check that all key names are within double quotes.\n '{0}'\n{1}", msg, ex.Message)); - } - return config; - } - - #endregion - - #region Utility - - private static GenerationConfig LoadAndRemoveConfigFromTemplate(ref string template) - { - int index = 0; - // If we have no provided config attempt to get one from the template. - GenerationConfig config = GetConfiguration(template, ref index); - if (config != null) - { - // Remove all config sections from template. - template = template.Substring(index); - } - return config; - } - - private static int FindPositionOfNext(string template, int index, string toFind, string notBefore) - { - bool found = false; - var ndx = index; - var notBeforeNdx = index; - while (!found) - { - ndx = template.IndexOf(toFind, ndx, StringComparison.Ordinal); - if (ndx == -1) break; - - notBeforeNdx = template.IndexOf(notBefore, notBeforeNdx, StringComparison.Ordinal); - - if (notBeforeNdx > -1 && notBeforeNdx < ndx) - { - string msg = @"Found unexpected token '" + notBefore + "' when expecting to find '" + toFind + "'."; - msg = msg + Environment.NewLine + BuildErrorIndicationText(template, notBeforeNdx); - throw new GenerationException(msg); - } - found = true; - } - return ndx; - } - - private static bool IsEscaped(string template, int ndx) - { - int slashes = 0; - var c = ndx - 1; - while (c >= 0) - { - if (template[c] != _Escape) break; - - slashes++; - c--; - } - return (slashes != 0) && slashes % 2 != 0; - } - - private static void ProcessPattern(StringBuilder sb, string exp, GenerationConfig config) - { - bool isEscaped = false; - var curNdx = 0; - while (curNdx < exp.Length) - { - var chx = exp[curNdx]; - if (chx == _Escape) - { - if (isEscaped) - { - // "\\" handling - isEscaped = false; - } - else - { - // "...\..." detected, entering escaped symbol handling on next pass. - isEscaped = true; - curNdx++; - continue; - } - } - - if (!isEscaped && chx == _Section_Start) - { - AppendContentFromSectionExpression(sb, exp, ref curNdx, config); - continue; // skip to next character - index has already been forwarded to new position - } - - // check are we entering a set pattern that may include a quantifier - // Format = "[Vv]{4}" = generate 4 random ordered characters comprising of either V or v characters - if (!isEscaped && chx == _Set_Start) - { - AppendContentFromSetExpression(sb, exp, ref curNdx, config); - continue; // skip to next character - index has already been forwarded to new position - } - - if (!isEscaped && chx == _NamedPattern_Start) - { - AppendContentFromNamedPattern(sb, exp, ref curNdx, config); - continue; - } - - // check are we entering a repeat symbol section - // Format = "L{4}" = repeat L symbol 4 times. - // Format = "\\{4}" = repeat \ symbol 4 times. - bool repeatSymbol = curNdx < exp.Length - 1 && exp[curNdx + 1] == _Quantifier_Start; - if (repeatSymbol) - { - AppendRepeatedSymbol(sb, exp, ref curNdx, isEscaped, config); - isEscaped = false; - continue; // skip to next character - index has already been forwarded to new position - } - - AppendCharacterDerivedFromSymbol(sb, chx, isEscaped, config); - curNdx++; // increment to move to next character. - isEscaped = false; - } - } - - private static string ExpandNegatedMinMax(double min, double max) - { - string ret = ""; - for (double i = min; i <= max; i++) - { - ret += i.ToString(CultureInfo.InvariantCulture); - } - return ret; - } - - private static bool ContainsAnagram(string content) - { - return content.ToLower().Equals(_Anagram); - } - - private static bool ContainsAlternations(string characters) - { - var patternEnd = 0; - var sectionDepth = 0; - - next: - while (patternEnd < characters.Length) - { - if (characters[patternEnd].Equals(_Section_Start)) sectionDepth++; - //check for Alternations in base group. - if (sectionDepth == 0 && characters[patternEnd].Equals(_Alternation)) return true; - - if (characters[patternEnd].Equals(_Section_End)) - { - sectionDepth--; - if (sectionDepth == 0) goto next; - } - patternEnd++; - } - return false; - } - - private static string BuildErrorIndicationText(string template, int ndx) - { - try - { - var templateLength = template.Length; - var ndxStart = ndx - _ErrorSnippet_ContextLength > 0 ? ndx - _ErrorSnippet_ContextLength : 0; - var ndxEnd = ndx + _ErrorSnippet_ContextLength > templateLength ? templateLength - 1 : ndx + _ErrorSnippet_ContextLength; - - var line = template.Substring(ndxStart, ndxEnd - ndxStart); - line = line.Replace('\n', ' ').Replace('\r', ' '); - var indicator = new string(' ', ndx - ndxStart) + "^" + new string(' ', ndxEnd - ndx + 1); - - return line + Environment.NewLine + indicator; - } - catch (Exception ex) - { - return "An error occured close to index " + ndx; - } - } - - #endregion - - #region Append - - private static void AppendPatternsFromConfigToCollection(GenerationConfig config, NamedPatterns patternCollection) - { - if (config.PatternFiles == null) return; - - foreach (var patternFile in config.PatternFiles) - { - var correctedPath = FileReader.GetPatternFilePath(patternFile); - - try - { - var patt = FileReader.LoadNamedPatterns(correctedPath); - foreach (var pattern in patt.Patterns) - { - patternCollection.Patterns.Add(pattern); - } - } - catch (Exception ex) - { - throw new GenerationException("Error loading PatternFile:" + patternFile + "\n\n" + ex.Message); - } - } - } - - /// - /// Calculates the content from a repeated symbol when the following form is encountered 's{repeat}' where s is a symbol. - /// The calculated value is append to sb. - /// - /// - /// - /// - /// - /// True if the the previous character was an escape char. - /// - /// - private static void AppendRepeatedSymbol(StringBuilder sb, string characters, ref int index, bool isEscaped, GenerationConfig config) - { - var symbol = characters[index++]; - var repeatExpression = GetContent(characters, ref index, _Quantifier_Start.ToString(CultureInfo.InvariantCulture), _Quantifier_End.ToString(CultureInfo.InvariantCulture)); - var repeat = GetRepeatValueFromRepeatExpression(repeatExpression, config); - - for (int x = 0; x < repeat; x++) - { - AppendCharacterDerivedFromSymbol(sb, symbol, isEscaped, config); - } - } - - /// - /// Calculates the content from a repeated expression when the following form is enountered '[exp]{repeat}'. - /// - /// - /// - /// - /// - /// - private static void AppendContentFromSectionExpression(StringBuilder sb, string characters, ref int index, GenerationConfig config) - { - var contentOptions = GetContentOptions(characters, ref index, _Section_Start.ToString(CultureInfo.InvariantCulture), _Section_End.ToString(CultureInfo.InvariantCulture), config); - - var exp = contentOptions.Content; - if (contentOptions.ContainsAlternation) // contains alternations - { - GenerateFromAlternatedPattern(sb, exp, contentOptions, config); - return; - } - - for (int x = 0; x < contentOptions.Repeat; x++) - { - ProcessPattern(sb, exp, config); - } - } - - private static void AppendContentFromNamedPattern(StringBuilder sb, string characters, ref int index, GenerationConfig config) - { - var ndx = index; - var tuple = GetContentOptions(characters, ref index, _NamedPattern_Start.ToString(CultureInfo.InvariantCulture), _NamedPattern_End.ToString(CultureInfo.InvariantCulture), config); - - if (config.NamedPatterns.HasPattern(tuple.Content)) // $namedPattern; - { - GenerateFromPattern(sb, config.NamedPatterns.GetPattern(tuple.Content).Pattern, config); - } - else - { - var msg = BuildErrorIndicationText(characters, ndx); - msg = "Unknown pattern '" + tuple.Content + "' encountered. Check that the pattern is included in the provided tdg-pattern files or named pattern collection." + Environment.NewLine + msg; - throw new GenerationException(msg); - } - } - - /// - /// Calculates the content from a set expression when the following form is enountered '[exp]{repeat}'. - /// - /// - /// - /// - /// - private static void AppendContentFromSetExpression(StringBuilder sb, string characters, ref int index, GenerationConfig config) - { - var contentOptions = GetContentOptions(characters, ref index, _Set_Start.ToString(CultureInfo.InvariantCulture), _Set_End.ToString(CultureInfo.InvariantCulture), config); - - if (contentOptions.IsAnagram) - { - GenerateFromAnagramPattern(sb, contentOptions.Content, contentOptions, config); - return; - } - - if (contentOptions.Content.Contains("-")) // Ranged - [0-7] or [a-z] or [1-9A-Za-z] for fun. - { - MatchCollection ranges = new Regex(@"[A-Za-z]-[A-Za-z]|\d+\.?\d*-\d+\.?\d*|.").Matches(contentOptions.Content); - if (contentOptions.IsNegated) - { - var possibles = _ShortHands["."]; - foreach (var range in ranges) - { - if (range.ToString().Contains("-")) - { - //TODO - Cleanup - Only here to throw an exception for invalid ranges - GetRandomCharacterFromRange(range.ToString(), contentOptions.IsNegated, config); - var regex = new Regex("[" + range + "]"); - possibles = regex.Replace(possibles, ""); - } - else - { - // single character item to negate, just remove it from the list of possibles. - possibles = possibles.Replace(range.ToString(), ""); - } - } - - for (int i = 0; i < contentOptions.Repeat; i++) - { - sb.Append(possibles[config.Random.Next(0, possibles.Length)]); - } - } - else - { - for (int i = 0; i < contentOptions.Repeat; i++) - { - var range = ranges[config.Random.Next(0, ranges.Count)].ToString(); - sb.Append(range.Contains("-") ? GetRandomCharacterFromRange(range, contentOptions.IsNegated, config) : range); - } - } - } - else - { - var possibles = contentOptions.Content; - if (contentOptions.IsNegated) - possibles = Regex.Replace(_ShortHands["."], "[" + possibles + "]", ""); - - for (int i = 0; i < contentOptions.Repeat; i++) - { - sb.Append(possibles[config.Random.Next(0, possibles.Length)]); - } - } - } - - private static void AppendCharacterDerivedFromSymbol(StringBuilder sb, char symbol, bool isEscaped, GenerationConfig config) - { - if (!isEscaped) - { - sb.Append(symbol); // not a symbol - append as is. - return; - } - - var symbolAsString = symbol.ToString(); - - if (_ShortHands.ContainsKey(symbolAsString)) - { - AppendRandomCharacterFromString(sb, _ShortHands[symbolAsString], config); - } - else - { - switch (symbol) - { - case 'n': - sb.Append("\n"); - break; - case 'r': - sb.Append("\r"); - break; - case 't': - sb.Append("\t"); - break; - default: - // Just append the character as it is not a symbol. - sb.Append(symbol); - break; - } - } - } - - private static void AppendRandomCharacterFromString(StringBuilder sb, string allowedCharacters, GenerationConfig config) - { - sb.Append(allowedCharacters[config.Random.Next(allowedCharacters.Length)]); - } - - #endregion - } -} diff --git a/src/TestDataGenerator.Core/Properties/AssemblyInfo.cs b/src/TestDataGenerator.Core/Properties/AssemblyInfo.cs deleted file mode 100644 index e75a0bc..0000000 --- a/src/TestDataGenerator.Core/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Test Data Generator")] -[assembly: AssemblyDescription("Test data generation library.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("SecretDeveloper")] -[assembly: AssemblyProduct("Library")] -[assembly: AssemblyCopyright("Gary Kenneally (@SecretDeveloper) [2016]")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("36626db1-4b84-41b4-bf97-4a35087bee0f")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("5.1.0")] diff --git a/src/TestDataGenerator.Core/TestDataGenerator.Core.csproj b/src/TestDataGenerator.Core/TestDataGenerator.Core.csproj deleted file mode 100644 index ec86b2c..0000000 --- a/src/TestDataGenerator.Core/TestDataGenerator.Core.csproj +++ /dev/null @@ -1,110 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {7E0AFB0B-0000-4D8A-A3CC-EADD3BC14298} - Library - Properties - TestDataGenerator.Core - TestDataGenerator.Core - v4.5 - 512 - - - - - 3.5 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - ..\ - true - - - true - full - false - ..\..\BuildOutput\ - DEBUG;TRACE - prompt - 4 - false - AllRules.ruleset - - - pdbonly - true - ..\..\BuildOutput\ - TRACE - prompt - 4 - false - true - - - - - 3.5 - - - - - - - - - - - - - - - True - True - Strings.resx - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - - - ResXFileCodeGenerator - Strings.Designer.cs - - - - - - \ No newline at end of file diff --git a/src/TestDataGenerator.Tests/Benchmarks.cs b/src/TestDataGenerator.Tests/Benchmarks.cs new file mode 100644 index 0000000..1042a9b --- /dev/null +++ b/src/TestDataGenerator.Tests/Benchmarks.cs @@ -0,0 +1,266 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Running; +using TestDataGenerator.Core; +using TestDataGenerator.Core.Generators; + +namespace TestDataGenerator.Tests +{ + public class BenchmarkInit + { + //[TestMethod] + public void RunBenchmarks() + { + BenchmarkRunner.Run(new ManualConfig() { }); + } + } + + + [SimpleJob(RuntimeMoniker.Net48)] + [SimpleJob(RuntimeMoniker.Mono)] + [SimpleJob(RuntimeMoniker.NetCoreApp21)] + [SimpleJob(RuntimeMoniker.NetCoreApp30)] + [RPlotExporter, RankColumn] + public class TDGBenchmarks + { + public GenerationConfig _GenerationConfig; + + [GlobalSetup] + public void SetupData() + { + _GenerationConfig = new GenerationConfig(); + } + + #region Benchmarks + + [Benchmark] + public string Benchmark_Template_L() + { + var pattern = @"<<\L>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern); + } + + + [Benchmark] + public string Benchmark_Template_L_Repeat_50() + { + var pattern = @"<<\L{50}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern); + } + + [Benchmark] + public string Benchmark_Template_L_Repeat_1_to_50() + { + var pattern = @"<<\L{1,50}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern); + } + + [Benchmark] + public string Benchmark_Template_Set_10_100() + { + var pattern = @"<<[10-100]>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern); + } + + [Benchmark] + public string Benchmark_Template_Set_10_100_Repeat_100() + { + var pattern = @"<<[10-100]{100}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern); + } + + [Benchmark] + public string Benchmark_Template_Set_Decimal_10_100() + { + var pattern = @"<<[10.00-100]>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern); + } + + [Benchmark] + public string Benchmark_Template_Set_Decimal_10_100_Repeat_100() + { + var pattern = @"<<[10.00-100]{100}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern); + } + + [Benchmark] + public string Benchmark_Template_MultipleCharacters_Repeat() + { + var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern); + } + + [Benchmark] + public string Benchmark_Pattern_L() + { + var pattern = @"\L"; + return AlphaNumericGenerator.GenerateFromPattern(pattern); + } + + [Benchmark] + public string Benchmark_Pattern_L_Repeat_50() + { + var pattern = @"\L{50}"; + return AlphaNumericGenerator.GenerateFromPattern(pattern); + } + + [Benchmark] + public string Benchmark_Pattern_L_Repeat_1_to_50() + { + var pattern = @"\L{1,50}"; + return AlphaNumericGenerator.GenerateFromPattern(pattern); + } + + [Benchmark] + public string Benchmark_Pattern_Set_10_100() + { + var pattern = @"[10-100]"; + return AlphaNumericGenerator.GenerateFromPattern(pattern); + } + + [Benchmark] + public string Benchmark_Pattern_Set_10_100_Repeat_100() + { + var pattern = @"[10-100]{100}"; + return AlphaNumericGenerator.GenerateFromPattern(pattern); + } + + [Benchmark] + public string Benchmark_Pattern_Set_Decimal_10_100() + { + var pattern = @"[10.00-100]"; + return AlphaNumericGenerator.GenerateFromPattern(pattern); + } + + [Benchmark] + public string Benchmark_Pattern_Set_Decimal_10_100_Repeat_100() + { + var pattern = @"[10.00-100]{100}"; + return AlphaNumericGenerator.GenerateFromPattern(pattern); + } + + [Benchmark] + public string Benchmark_Pattern_MultipleCharacters_Repeat() + { + var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; + return AlphaNumericGenerator.GenerateFromPattern(pattern); + } + + [Benchmark] + public string Benchmark_Template_L_With_Config() + { + var pattern = @"<<\L>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); + } + + + [Benchmark] + public string Benchmark_Template_L_Repeat_50_With_Config() + { + var pattern = @"<<\L{50}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Template_L_Repeat_1_to_50_With_Config() + { + var pattern = @"<<\L{1,50}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Template_Set_10_100_With_Config() + { + var pattern = @"<<[10-100]>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Template_Set_10_100_Repeat_100_With_Config() + { + var pattern = @"<<[10-100]{100}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Template_Set_Decimal_10_100_With_Config() + { + var pattern = @"<<[10.00-100]>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Template_Set_Decimal_10_100_Repeat_100_With_Config() + { + var pattern = @"<<[10.00-100]{100}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Template_MultipleCharacters_Repeat_With_Config() + { + var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; + return AlphaNumericGenerator.GenerateFromTemplate(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Pattern_L_With_Config() + { + var pattern = @"\L"; + return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Pattern_L_Repeat_50_With_Config() + { + var pattern = @"\L{50}"; + return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Pattern_L_Repeat_1_to_50_With_Config() + { + var pattern = @"\L{1,50}"; + return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Pattern_Set_10_100_With_Config() + { + var pattern = @"[10-100]"; + return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Pattern_Set_10_100_Repeat_100_With_Config() + { + var pattern = @"[10-100]{100}"; + return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Pattern_Set_Decimal_10_100_With_Config() + { + var pattern = @"[10.00-100]"; + return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Pattern_Set_Decimal_10_100_Repeat_100_With_Config() + { + var pattern = @"[10.00-100]{100}"; + return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); + } + + [Benchmark] + public string Benchmark_Pattern_MultipleCharacters_Repeat_With_Config() + { + var pattern = @"\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}"; + return AlphaNumericGenerator.GenerateFromPattern(pattern, _GenerationConfig); + } + + #endregion + + } +} diff --git a/src/TestDataGenerator.Tests/TestDataGenerator.Tests.csproj b/src/TestDataGenerator.Tests/TestDataGenerator.Tests.csproj new file mode 100644 index 0000000..1cbf6ea --- /dev/null +++ b/src/TestDataGenerator.Tests/TestDataGenerator.Tests.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp2.2 + false + + + + + + + + + + + + + + + + Always + + + + + \ No newline at end of file diff --git a/src/TestDataGenerator.Tests/TextTests.cs b/src/TestDataGenerator.Tests/TextTests.cs new file mode 100644 index 0000000..bed4799 --- /dev/null +++ b/src/TestDataGenerator.Tests/TextTests.cs @@ -0,0 +1,1760 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using TestDataGenerator.Core; +using TestDataGenerator.Core.Exceptions; +using TestDataGenerator.Core.Generators; +using Xunit; + + +namespace TestDataGenerator.Tests +{ + public class TextTests + { + private const int _ErrorSnippet_ContextLength = 50; + + #region Template + + [Fact] + public void Can_GenerateFromTemplate_Overload1() + { + var template = @"Generated <<\L\L>>"; + string text = TestDataGenerator.Core.Generators.AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"Generated [A-Z]{2}"), text); + } + + [Fact] + + public void Can_GenerateFromTemplate_Overload2() + { + var template = @"Generated <<\L\L>>"; + var config = new GenerationConfig() { Seed = "100" }; + string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"Generated [A-Z]{2}"), text); + } + + [Fact] + + public void Can_GenerateFromTemplate_Overload3() + { + var template = @"<<@superhero@>>"; + + var config = new GenerationConfig(); + config.NamedPatterns.Patterns.Add(new NamedPattern() + { + Name = "superhero", + Pattern = "(Batman|Superman|Spiderman)" + }); + string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"(Batman|Superman|Spiderman)"), text); + } + + [Fact] + + public void Can_Load_File_Supplied_In_Config_Absolute() + { + var template = @"<<@noun@ @verb@ @noun@ @verb@>>"; + + var random = new Random(100); + var config = new GenerationConfig() { Seed = "200" }; + config.Random = random; + config.PatternFiles.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "language.tdg-patterns")); + + string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.True(text.Length > 0); + } + + [Fact] + + public void Can_Load_File_Supplied_In_Config_Relative() + { + var template = @"<<@noun@ @verb@ @noun@ @verb@>>"; + + var config = new GenerationConfig() { Seed = "100" }; + config.PatternFiles.Add("language.tdg-patterns"); + + string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.True(text.Length > 0); + } + + [Fact] + + public void Can_Load_File_Supplied_In_Config_Relative_No_Extension() + { + var template = @"<<@noun@ @verb@ @noun@ @verb@>>"; + + var config = new GenerationConfig() { Seed = "100" }; + config.PatternFiles.Add("language"); + + string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.True(text.Length > 0); + } + + [Fact] + + public void Can_Escape_Template() + { + var template = @"Generated \<<\L\L>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Equal(@"Generated <<\L\L>>", text); + } + + [Fact] + + public void Can_UnEscape_Template() + { + var template = @"Generated \\<<\L\L>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"Generated \\\\[A-Z]{2}"), text); + } + + + [Fact] + public void Can_Escape_Config() + { + var template = @"\<# blah #>abc"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Equal(@"\<# blah #>abc", text); + + // space at start + template = @". <# blah #>abc"; + text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Equal(@". <# blah #>abc", text); + } + + [Fact] + + public void Can_Generate_From_Template_No_Symbols() + { + var template = "Generated <>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"Generated [L]{2}"), text); + } + + [Fact] + public void Can_Generate_From_Template_for_ReadMe1() + { + var template = @"Hi there <<\L\v{0,2}\l{0,2}\v \L\v{0,2}\l{0,2}\v{0,2}\l{0,2}\l>> how are you doing?"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"Hi there [A-Z][aeiou]{0,2}[a-z]{0,2}[aeiou] [A-Z][aeiou]{0,2}[a-z]{0,2}[aeiou]{0,2}[a-z]{0,2}[a-z] how are you doing\?"), text); + } + + [Fact] + public void Can_Generate_From_Template_for_ReadMe2() + { + var template = @"<>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"aa[1-9]\d{2}-\d{2}-\d{4}"), text); + } + + [Fact] + public void Can_Generate_From_Template_for_ReadMe3() + { + + var template = + @"Hi there <<\L\v{0,2}\l{0,2}\v \L\v{0,2}\l{0,2}\v{0,2}\l{0,2}\l>> how are you doing? Your SSN is <<[1-9]\d\d-\d\d-\d\d\d\d>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + + Assert.Matches(new Regex( + @"Hi there [A-Z][aeiou]{0,2}[a-z]{0,2}[aeiou] [A-Z][aeiou]{0,2}[a-z]{0,2}[aeiou]{0,2}[a-z]{0,2}[a-z] how are you doing\? Your SSN is [1-9]\d{2}-\d{2}-\d{4}") + , text); + } + + [Fact] + public void Can_Generate_From_Template_with_Symbols() + { + var template = @"Generated <>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"Generated [L][A-Z]"), text); + } + + [Fact] + public void Can_Generate_From_Template_Multiple() + { + var template = @"Generated <<\L\L>> and <<(\d){5}>> with <<\d>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"Generated [A-Z]{2} and [0-9]{5} with [0-9]"), text); + } + + [Fact] + public void Can_Generate_From_Template_Harder() + { + var template = + @"This is a very basic <<(\l){10}>> which can be used to create <<\l\l\l\l>> of varying <<\l\l\l\l\l>>. The main purpose is to generate dummy <<\L\l\l\l>> which can be used for <<\l\l\l\l\l\l\l>>."; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex( + @"This is a very basic [a-z]{10} which can be used to create [a-z]{4} of varying [a-z]{5}. The main purpose is to generate dummy [A-Z][a-z]{3} which can be used for [a-z]{7}.") + , text); + } + + [Fact] + public void Can_Generate_From_Template_With_Alternatives_Symbols() + { + var template = @"<<\C|\c{10}|\V\V\V|\v{2,3}>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"[BCDFGHJKLMNPQRSTVWXYZ]{1}|[bcdfghjklmnpqrstvwxyz]{10}|[AEIOU]{3}|[aeiou]{2,3}"), text); + } + + [Fact] + public void Can_Generate_From_Template_With_Alternative_Groups() + { + var template = @"<<(\C)|\c{10}|(\V\V\V){20}|(\v\v\v\v\v){2,3}>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches( + new Regex(@"[BCDFGHJKLMNPQRSTVWXYZ]{1}|[bcdfghjklmnpqrstvwxyz]{10}|[AEIOU]{60}|[aeiou]{10,15}"), text); + } + + [Fact] + public void Can_Generate_From_Pattern_With_Alternatives() + { + var template = @"Alternatives <<(\C|(\c){10}|\V\V\V|\v{2,3})>>"; + var config = new GenerationConfig(); + string text = AlphaNumericGenerator.GenerateFromTemplate(template, config); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Console.WriteLine("Seed:{0}", config.Seed); + Assert.Matches( + new Regex( + @"Alternatives ([BCDFGHJKLMNPQRSTVWXYZ]{1}|[bcdfghjklmnpqrstvwxyz]{10}|[AEIOU]{3}|[aeiou]{2,3})"), text); + } + + [Fact] + public void Can_Generate_From_Pattern_With_Alternatives2() + { + var template = @"Alternatives <<(A|B){1000}>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"Alternatives (A|B){1000}"), text); + } + + + [Fact] + + public void Can_Generate_From_Pattern_With_Alternatives_Repeated_Symbols() + { + var template = @"Alternatives <<(\C{1}|\c{10}|\V{3}|\v{2,3})>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex( + @"Alternatives ([BCDFGHJKLMNPQRSTVWXYZ]{1})|([bcdfghjklmnpqrstvwxyz]{10})|([AEIOU]{3}|[aeiou]{2,3})"), text); + if (text.Contains("|")) Assert.True(false, text); + } + + [Fact] + public void Can_Generate_From_Pattern_With_calculated_quantity() + { + var template = @"<<\v{2,3}>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"([aeiou]{2,3})"), text); + if (text.Contains("|")) Assert.True(false, text); + } + + #endregion + + #region Sets + + [Fact] + [Trait("Category", "Sets")] + public void Can_Escape_Sets() + { + var template = @"<<\[LL]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^\[LL]$"), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_NonRange_Set() + { + var template = @"<<[AEI]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[AEI]{1}$"), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Set() + { + var template = @"<<[A-I]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[ABCDEFGHI]{1}$"), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Set_Lower() + { + var template = @"<<[a-i]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[abcdefghi]{1}$"), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Set2() + { + var template = @"<<[A-B]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[AB]{1}$"), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Set3() + { + var template = @"<<[W-X]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[W-X]{1}$"), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Repeated_Set1() + { + var template = @"<<[W-X]{10}>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[W-X]{10}$"), text); + } + + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Repeated_Set2() + { + var template = @"<<([W-X]{10}[W-X]{10})>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[W-X]{10}[W-X]{10}$"), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Repeated_Set3() + { + var template = @"<<([W-X]{10,100}[1-9]{10,100})>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[W-X]{10,100}[1-9]{10,100}$"), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Repeated_Set4() + { + // empty repeat expressions should result in a single instance - {} == {1} + var template = @"<<([W-X]{})>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[W-X]$"), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Section_Repeated_Escape_Chars() + { + // empty repeat expressions should result in a single instance - {} == {1} + var template = @"(\\){10}"; + string text = AlphaNumericGenerator.GenerateFromPattern(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(template), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Repeated_Escape_Chars() + { + // empty repeat expressions should result in a single instance - {} == {1} + var template = @"\\{10}"; + string text = AlphaNumericGenerator.GenerateFromPattern(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(template), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Repeated_Chars() + { + // empty repeat expressions should result in a single instance - {} == {1} + var template = @"(a){10}"; + string text = AlphaNumericGenerator.GenerateFromPattern(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(template), @"aaaaaaaaaa"); + } + + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Negated_Range() + { + // empty repeat expressions should result in a single instance - {} == {1} + var template = @"[^5-9]"; + string text = AlphaNumericGenerator.GenerateFromPattern(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(template), text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Negated_Range_And_Characters() + { + // empty repeat expressions should result in a single instance - {} == {1} + var template = @"[^A-Z5-9!£$%^&*()_+]"; + string text = AlphaNumericGenerator.GenerateFromPattern(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(template), text); + } + + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric() + { + var template = @"<<[1-9]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + var re = new Regex(@"^[1-9]$"); + Assert.Matches(re, text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric5() + { + var template = @"<<[1-8]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + var re = new Regex(@"^[1-8]$"); + Assert.Matches(re, text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric2() + { + var template = @"<<[100-150]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + int e = int.Parse(text); + if (e < 100 || e > 150) Assert.True(false, "Number not between 100 and 150."); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric3() + { + var template = @"<<(.[100-101]){3}>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + var re = new Regex(@"^(.(100|101)){1}(.(100|101)){1}(.(100|101)){1}$"); + Assert.Matches(re, text); + + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric4() + { + var template = @"<<(.[100-101]){1,3}>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + var re = new Regex(@"^(.(100|101))?(.(100|101))?(.(100|101))?$"); + Assert.Matches(re, text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric_DecimalFormat() + { + var template = @"<<([1.00-10.00])>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + double d; + if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) + Assert.False(true); + if (d < 1.00d || d > 10.00d) + Assert.True(false); + } + + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric_DecimalFormat2() + { + var template = @"<<([1.00-2.00])>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + double d; + if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) + Assert.True(false); + if (d < 1.00 || d > 2.00d) Assert.True(false); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric_DecimalFormat3() + { + var template = @"<<([1.1-1.2])>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + double d; + if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) + Assert.True(false); + if (d < 1.1 || d > 1.2d) Assert.True(false); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric_DecimalFormat4() + { + var template = @"<<([12345.12345-12345.12346])>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + double d; + if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) + Assert.True(false); + if (d < 12345.12345 || d > 12345.12346d) Assert.True(false); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_Range_Numeric_DecimalFormat5() + { + var template = @"<<([12345.9999-12346])>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + double d; + if (!double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) + Assert.True(false); + if (d < 12345.9999d || d > 12346d) Assert.True(false); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_MultipleRange_Set() + { + var template = @"<<[A-B][1-3]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + + var re = new Regex(@"^[A-B]{1}[1-3]{1}$"); + Assert.Matches(re, text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_MultipleRange_Set2() + { + var template = @"<<[1-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + var re = new Regex(@"^[1-9]{1}[0-9]{1}[0-9]{1}-[0-9]{1}[0-9]{1}-[0-9]{1}[0-9]{1}[0-9]{1}[0-9]{1}$"); + + Assert.Matches(re, text); + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_MultipleRange_Set3() + { + var template = @"<<[1-28]/[1-12]/[1960-2013]>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + DateTime dt; + if ( + DateTime.TryParseExact(text, @"d/M/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, + out dt) == false) Assert.True(false, "invalid Date"); + + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_MultipleRange_Set4() + { + var template = @"<<[a-c1-3_]{100}>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[a-c1-3_]{100}$"), text); + Assert.Contains("_", text); // check that we have produced at least 1 underscore. + } + + [Fact] + [Trait("Category", "Sets")] + public void Can_Generate_MultipleRange_Set5() + { + var template = @"<<[a-c1-3_*?ABC]{100}>>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + Assert.Matches(new Regex(@"^[a-c1-3_*?ABC]{100}$"), text); + Assert.Contains("_", text); + Assert.Contains("*", text); + Assert.Contains("?", text); + Assert.Contains("A", text); + Assert.Contains("B", text); + Assert.Contains("C", text); + } + + #endregion + + #region ErrorMessages + + [Fact] + [Trait("Category", "ErrorMessages")] + public void Can_BuildErrorSnippet_Start() + { + var template = @"[a-z"; + var expected = "Expected ']' but it was not found.\r\n[a-\r\n ^ "; + try + { + string text = AlphaNumericGenerator.GenerateFromPattern(template); + } + catch (GenerationException genEx) + { + Assert.Equal(expected, genEx.Message); + Console.WriteLine("Expected='" + expected + "'"); + Console.WriteLine("Actual ='" + genEx.Message + "'"); + } + catch (Exception) + { + Assert.True(false, "Incorrect exception thrown."); + } + } + + #endregion + + #region Pattern + + [Fact] + [Trait("Category", "Pattern")] + public void GeneratePattern_Overloads() + { + var pattern = @"\L\L\L\L\L\L-\L\L-\L\L\L\L\L"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(15, text.Length); + Assert.Matches(new Regex("[A-Z]{6}-[A-Z]{2}-[A-Z]{5}"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void GeneratePattern_Overloads2() + { + var pattern = @"\L\L\L\L\L\L-\L\L-\L\L\L\L\L"; + var config = new GenerationConfig() { Seed = "300" }; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config: config); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(15, text.Length); + Assert.Matches(text, "LVMPQS-IY-CXIRW"); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_AlphaNumeric_multiple() + { + + var pattern = @"\L\L\L\L\L\L-\L\L-\L\L\L\L\L"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(15, text.Length); + Assert.Matches(new Regex("[A-Z]{6}-[A-Z]{2}-[A-Z]{5}"), text); + + pattern = @"\l\l\l\l\l\l"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(6, text.Length); + Assert.Matches(new Regex("[a-z]*"), text); + + pattern = @"\d\d\d\d\d\d\L\L\L\L\l\l\l\l"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(14, text.Length); + Assert.Matches(new Regex("[0-9]{6}[A-Z]{4}[a-z]{4}"), text); + + pattern = @"\d\d\d-\d\d-\d\d\d\d"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(11, text.Length); + Assert.Matches(new Regex(@"[\d]{3}-[\d]{2}-[\d]{4}"), text); + + //Test for escaped characters. + pattern = @"L\LLLLL"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(6, text.Length); + Assert.Matches(new Regex("L[A-Z]{1}LLLL"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_AlphaNumeric() + { + + var pattern = @"\L\l\V\v\C\c\d\d"; + string text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"[A-Z]{1}[a-z]{1}[AEIOU]{1}[aeiou]{1}[QWRTYPSDFGHJKLZXCVBNM]{1}[qwrtypsdfghjklzxcvbnm]{1}[\d]{1}[\d]{1}"), text); + + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Simple_Patterns() + { + var pattern = @"\L\L\L\L\L\L-\L\L-\L\L\L\L\L"; + string text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(15, text.Length); + Assert.Matches(new Regex("[A-Z]{6}-[A-Z]{2}-[A-Z]{5}"), text); + + pattern = @"\l\l\l\l\l\l"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(6, text.Length); + Assert.Matches(new Regex("[a-z]*"), text); + + pattern = @"\d\d\d\d\d\d\L\L\L\L\l\l\l\l"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(14, text.Length); + Assert.Matches(new Regex("[0-9]{6}[A-Z]{4}[a-z]{4}"), text); + + pattern = @"[1-9]\d\d-\d\d-\d\d\d\d"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(11, text.Length); + Assert.Matches(new Regex(@"[1-9]\d{2}-\d{2}-\d{4}"), text); + + //Test for escaped characters. + pattern = @"L\LLLLL"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(6, text.Length); + Assert.Matches(new Regex("L[A-Z]{1}LLLL"), text); + + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Character() + { + var pattern = @"w{3}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"w{3}"), text); + + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Character_Inside_Group() + { + var pattern = @"(\dC{3}\d{3}){3}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^(\dC{3}\d{3}){3}$"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Character_Inside_Group2() + { + var pattern = @"(\d(C){3}){3}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^(\d(C){3}){3}$"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Character_Inside_Group3() + { + var pattern = @"(\d(C){3})"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^(\d(C){3})$"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Character_Inside_Group4() + { + var pattern = @"(\d(\\)\d)"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^(\d(\\)\d$)"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Symbol_Inside_Group() + { + var pattern = @"(\w{3})"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"\w{3}"), text); + + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Symbol_Inside_Group2() + { + var pattern = @"(\w(\d{2}|\v{2})\w{3})"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"\w(\d{2}|[aeiou]{2})\w{3}"), text); + + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Pattern() + { + var pattern = @"(\L\L\d\d){3}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"[A-Z]{2}[0-9]{2}[A-Z]{2}[0-9]{2}[A-Z]{2}[0-9]{2}"), text); + + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Symbol() + { + var pattern = @"\L{3}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"[A-Z]{3}"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Mixed_Pattern_With_Random_Length() + { + string pattern = @"\L{10,20}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"[A-Z]{10,20}"), text); + + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Output_NonEscaped_Symbols() + { + string pattern = @"X"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"X"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Output_Repeated_Symbols() + { + string pattern = @"\d{10}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"[\d]{10}"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Output_Escaped_Slash() + { + string pattern = @"[\\]{1,10}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"[\\]{1,10}"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Mixed_Pattern() + { + string pattern = @"\L\L(\L\L\d\d){3}\L\L(\L){23}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"[A-Z]{2}[A-Z]{2}[0-9]{2}[A-Z]{2}[0-9]{2}[A-Z]{2}[0-9]{2}[A-Z]{2}[A-Z]{23}"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Repeat_Pattern_Long() + { + var pattern = @"(\L){1}(\d){1}(\L){2}(\d){2}(\L){4}(\d){4}(\L){8}(\d){8}(\L){16}(\d){16}(\L){32}(\d){32}(\L){64}(\d){64}(\L){128}(\d){128}(\L){256}(\d){256}(\L){512}(\d){512}(\L){1024}(\d){1024}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"[A-Z]{1}[0-9]{1}[A-Z]{2}[0-9]{2}[A-Z]{4}[0-9]{4}[A-Z]{8}[0-9]{8}[A-Z]{16}[0-9]{16}[A-Z]{32}[0-9]{32}[A-Z]{64}[0-9]{64}[A-Z]{128}[0-9]{128}[A-Z]{256}[0-9]{256}[A-Z]{512}[0-9]{512}[A-Z]{1024}[0-9]{1024}") + , text); + Assert.Equal((1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512 + 1024) * 2, text.Length); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Expressions_With_Alternates() + { + var pattern = @"(\L\L|\d\d)"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^([A-Z]{2}|[0-9]{2})$"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Expressions_With_Alternates2() + { + var pattern = @"(\L\L|\d\d|[AEIOU]|[100-120])"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^([A-Z]{2}|[0-9]{2}|[AEIOU]|\d\d\d)$"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Zero_Repeats_Invalid_End() + { + var pattern = @"(\L\L\d\d)33}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^[A-Z]{2}[0-9]{2}33}$"), text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Zero_Repeats() + { + var pattern = @"\L\L\d\d"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^[A-Z]{2}[0-9]{2}$"), text); + } + + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Complex1() + { + var pattern = @"\{'\w':('\w{3,25}'|[1-100])\}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\{'\w':('\w{3,25}'|\d{1,3})\}$"), text); + } + + + #endregion + + #region Symbols + + [Fact] + [Trait("Category", "Symbols")] + public void Can_Generate_All_Symbols() + { + var pattern = @"\."; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^.$"), text); + + pattern = @"\a"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^[A-Za-z]$"), text); + + pattern = @"\W"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\W$"), text); + + pattern = @"\w"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\w$"), text); + + pattern = @"\L"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^[A-Z]$"), text); + + pattern = @"\l"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^[a-z]$"), text); + + pattern = @"\V"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^[AEIOU]$"), text); + + pattern = @"\v"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^[aeiou]$"), text); + + pattern = @"\C"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^[BCDFGHJKLMNPQRSTVWXYZ]$"), text); + + pattern = @"\c"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^[bcdfghjklmnpqrstvwxyz]$"), text); + + pattern = @"\D"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\D$"), text); + + pattern = @"\d"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\d$"), text); + + pattern = @"\s"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\s$", RegexOptions.ECMAScript), text); // ECMA compliant needed as \s ECMA includes [SPACE] but .NET Regex does not. + + pattern = @"\t"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\t$"), text); + + pattern = @"\n"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\n$"), text); + + pattern = @"\r"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\r$"), text); + + pattern = @"\\"; + text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Matches(new Regex(@"^\\$"), text); + } + + #endregion + + #region NamedPatterns + + [Fact] + [Trait("Category", "NamedPatterns")] + public void Can_Generate_NamedPatterns() + { + //var namedPatterns = FileReader.LoadNamedPatterns("default.tdg-patterns"); + + var pattern = @"<<(@name_firstname_male@)>>"; + var text = AlphaNumericGenerator.GenerateFromTemplate(pattern, new GenerationConfig() { LoadDefaultPatternFile = true }); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.True(text.Length > 0); + + } + + [Fact] + [Trait("Category", "NamedPatterns")] + public void Can_Generate_NamedPatterns_CompoundPattern() + { + //var namedPatterns = FileReader.LoadNamedPatterns("default.tdg-patterns"); + + var pattern = @"<<(@address_us_type1@)>>"; + var text = AlphaNumericGenerator.GenerateFromTemplate(pattern, new GenerationConfig() { LoadDefaultPatternFile = true }); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.True(text.Length > 0); + + } + + [Fact] + [Trait("Category", "NamedPatterns")] + public void Can_Generate_NamedPatterns_All_Defaults_Name() + { + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + + var namedPatterns = FileReader.LoadNamedPatterns(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "default.tdg-patterns")); + + foreach (var dic in namedPatterns.Patterns) + { + var text = AlphaNumericGenerator.GenerateFromPattern("@" + dic.Name + "@", config: new GenerationConfig() { LoadDefaultPatternFile = true }); + Console.WriteLine(@"'{0}' produced '{1}'", dic.Name, text); + Assert.True(text.Length > 0); + } + sw.Stop(); + Console.WriteLine(@"All {0} default patterns generated in {1} milliseconds." + , namedPatterns.Patterns.Count + , sw.ElapsedMilliseconds); + } + + [Fact] + [Trait("Category", "NamedPatterns")] + + public void Can_Throw_Exception_Invalid_Named_Pattern() + { + var config = new GenerationConfig() + { + PatternFiles = + new List() + { + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "invalid.tdg-patterns") + } + }; + + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern("@blah@", config: config)); + } + + [Fact] + [Trait("Category", "NamedPatterns")] + public void Can_Generate_NamedPatterns_All_Defaults_Patterns() + { + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + + var namedPatterns = FileReader.LoadNamedPatterns(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "default.tdg-patterns")); + + foreach (var dic in namedPatterns.Patterns) + { + var text = AlphaNumericGenerator.GenerateFromPattern(dic.Pattern, config: new GenerationConfig() { LoadDefaultPatternFile = true }); + Console.WriteLine(@"'{0}' produced '{1}'", dic.Name, text); + Assert.True(text.Length > 0); + } + sw.Stop(); + Console.WriteLine(@"All {0} default patterns generated in {1} milliseconds." + , namedPatterns.Patterns.Count + , sw.ElapsedMilliseconds); + } + + + #endregion + + #region Profiling + + [Fact] + [Trait("Category", "Profiling")] + public void Profile_Random_Repeat() + { + var pattern = @"<<\L{50,51}>>"; + var testLimit = 1000; + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + for (var i = 0; i < testLimit; i++) + { + var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); + //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + } + sw.Stop(); + + Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); + } + + [Fact] + [Trait("Category", "Profiling")] + public void Profile_NonRandom_Repeat() + { + var pattern = @"<<\L{50}>>"; + var testLimit = 1000; + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + for (var i = 0; i < testLimit; i++) + { + var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); + //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + } + sw.Stop(); + + Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); + } + + [Fact] + [Trait("Category", "Profiling")] + public void Profile_NonRandom_Repeat_LowVolume() + { + var pattern = @"<<\L{50}>>"; + var testLimit = 2; + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + for (var i = 0; i < testLimit; i++) + { + var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); + //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + } + sw.Stop(); + + Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); + } + + [Fact] + [Trait("Category", "Profiling")] + public void Profile_Large_NonRandom_Repeat() + { + var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; + var testLimit = 1000; + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + for (var i = 0; i < testLimit; i++) + { + var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); + //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + } + sw.Stop(); + Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); + } + + [Fact] + [Trait("Category", "Profiling")] + public void Profile_Large_NonRandom_Repeat_LowVolume() + { + var pattern = @"<<\L{1}\d{1}\L{2}\d{2}\L{4}\d{4}\L{8}\d{8}\L{16}\d{16}\L{32}\d{32}\L{64}\d{64}\L{128}\d{128}\L{256}\d{256}\L{512}\d{512}\L{1024}\d{1024}>>"; + var testLimit = 1; + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + for (var i = 0; i < testLimit; i++) + { + var text = AlphaNumericGenerator.GenerateFromTemplate(pattern); + //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + } + sw.Stop(); + Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); + } + + [Fact] + [Trait("Category", "Profiling")] + public void Profile_Large_NonRandom_NonSeeded_Repeat() + { + var pattern = @"(\w){64}"; + var testLimit = 10000; + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + for (var i = 0; i < testLimit; i++) + { + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + } + sw.Stop(); + Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); + } + + [Fact] + [Trait("Category", "Profiling")] + public void Profile_Large_NonRandom_Seeded_Repeat() + { + var pattern = @"(\w){64}"; + var testLimit = 10000; + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + for (var i = 0; i < testLimit; i++) + { + var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config: new GenerationConfig() { Seed = "100" }); + //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + } + sw.Stop(); + Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); + } + + [Fact] + [Trait("Category", "Profiling")] + public void Profile_Small_NonRandom_Seeded_Repeat() + { + var pattern = @"(\w){64}"; + var testLimit = 100; + var sw = new System.Diagnostics.Stopwatch(); + sw.Start(); + for (var i = 0; i < testLimit; i++) + { + var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config: new GenerationConfig() { Seed = "100" }); + //Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + } + sw.Stop(); + Console.WriteLine(@"{0} instances of the following template generated in {1} milliseconds.\n'{2}'", testLimit, sw.ElapsedMilliseconds, pattern); + } + + + [Fact] + [Trait("Category", "Profiling")] + public void Profile_Comparison_With_String_Append() + { + var testIterations = 100000; + var pattern = @"(A){100}"; + var patternOutput = "A"; + var patternCount = 100; + + // Control + var sb = new StringBuilder(); + var sw = new System.Diagnostics.Stopwatch(); + sw.Reset(); + sw.Start(); + for (var i = 0; i < testIterations; i++) + { + for (var j = 0; j < patternCount; j++) + { + sb.Append(patternOutput); + } + } + sw.Stop(); + Console.WriteLine(@"StringBuilder - {0} iterations of the following pattern {1} completed in {2} milliseconds.", testIterations, pattern, sw.ElapsedMilliseconds); + + sw.Reset(); + sw.Start(); + for (var i = 0; i < testIterations; i++) + { + AlphaNumericGenerator.GenerateFromPattern(pattern); + } + sw.Stop(); + Console.WriteLine(@"GenerateFromPattern(pattern) - {0} iterations of the following pattern {1} completed in {2} milliseconds.", testIterations, pattern, sw.ElapsedMilliseconds); + + + var config = new GenerationConfig() { Seed = "100" }; + sw.Reset(); + sw.Start(); + for (var i = 0; i < testIterations; i++) + { + AlphaNumericGenerator.GenerateFromPattern(pattern, config); + } + sw.Stop(); + Console.WriteLine(@"GenerateFromPattern(pattern, config) - {0} iterations of the following pattern {1} completed in {2} milliseconds.", testIterations, pattern, sw.ElapsedMilliseconds); + + } + + #endregion + + #region Negation + + + [Fact] + [Trait("Category", "Negation")] + public void Can_Generate_Correct_Output_from_Negated_Set() + { + var pattern = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + var text = AlphaNumericGenerator.GenerateFromPattern("[^" + pattern + "]"); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.True(pattern.IndexOf(text, StringComparison.InvariantCulture) == -1); + } + + [Fact] + [Trait("Category", "Negation")] + public void Can_Generate_Correct_Output_from_Negated_Set_Range() + { + var pattern = @"A-Z"; + var text = AlphaNumericGenerator.GenerateFromPattern("[^" + pattern + "]"); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.True(pattern.IndexOf(text, StringComparison.InvariantCulture) == -1); + } + + [Fact] + [Trait("Category", "Negation")] + public void Can_Generate_Correct_Output_from_Negated_Set_Range2() + { + var pattern = @"3-6"; + var text = AlphaNumericGenerator.GenerateFromPattern("[^" + pattern + "]"); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.True("3456".IndexOf(text, StringComparison.InvariantCultureIgnoreCase) == -1); + } + + [Fact] + [Trait("Category", "Negation")] + public void Can_Generate_Correct_Output_from_Negated_Set_Range_Multiple() + { + var pattern = @"A-Za-z"; + var text = AlphaNumericGenerator.GenerateFromPattern("[^" + pattern + "]"); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.True("ABCDEFGHIJKLMNOPQRSTUVWXYZ".IndexOf(text, StringComparison.InvariantCultureIgnoreCase) == -1); + } + + [Fact] + [Trait("Category", "Negation")] + public void Can_Generate_Correct_Output_from_Negated_Set_Range_Repeated() + { + var pattern = @"[^3-6]{10}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.True("3456".IndexOf(text, StringComparison.InvariantCultureIgnoreCase) == -1); + } + + [Fact] + [Trait("Category", "Negation")] + public void Can_Generate_Correct_Output_from_Negated_Set_Range_Multiple_Repeated() + { + var pattern = @"[^A-Za-z]{10}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.True("ABCDEFGHIJKLMNOPQRSTUVWXYZ".IndexOf(text, StringComparison.InvariantCultureIgnoreCase) == -1); + } + + #endregion + + #region NegativeTesting + + [Fact] + [Trait("Category", "NegativeTesting")] + public void Can_Throw_Exception_Missing_Placeholder_End() + { + var template = "This is a very basic <<(l){10}>> which can be used to create <>. The main purpose is to generate dummy <> which can be used for <>."; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromTemplate(template)); + + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Missing_Placeholder_End_End() + { + var template = "This is a very basic <<(l){10}>> which can be used to create <> of varying <>. The main purpose is to generate dummy <> which can be used for <(() => AlphaNumericGenerator.GenerateFromTemplate(template)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_IncompletePattern() + { + var pattern = "(LLXX"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_InvalidCardinality_Start() + { + var pattern = "(LLXX){33"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Invalid_Cardinaliy_Less_Than_Zero() + { + var pattern = "(LLXX){-1}"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_InvalidPattern_Null() + { + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(null)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Mixed_Pattern_With_Invalid_Random_Length_Character() + { + string pattern = "(L){10,}"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Mixed_Pattern_With_Invalid_Random_Length_Min_Max() + { + string pattern = "(L){10,0}"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Invalid_Repeat_Pattern() + { + var pattern = "(LLXX){w}"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Unknown_NamedPatterns() + { + var pattern = @"<<(@blahblahblah21@)>>"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromTemplate(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Negated_Set_Range_InvalidNumeric() + { + var pattern = @"[^30-60]"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Negated_Set_Range_InvalidNumeric2() + { + var pattern = @"[^3-60]"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Negated_Set_Range_InvalidNumeric3() + { + var pattern = @"[^3.00-6]"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Invalid_Config() + { + var pattern = @"<#{ asdsd }#>"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromPattern(pattern)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + + public void Can_Throw_Exception_Invalid_Config2() + { + var template = @"<#"; + Assert.Throws(() => AlphaNumericGenerator.GenerateFromTemplate(template)); + } + + [Fact] + [Trait("Category", "NegativeTesting")] + public void Can_Throw_Missing_Pattern_File() + { + var template = @"<<@superhero@>>"; + + var namedPatterns = new NamedPatterns(); + namedPatterns.Patterns.Add(new NamedPattern() { Name = "superhero", Pattern = "(Batman|Superman|Spiderman)" }); + + var config = new GenerationConfig() { Seed = "100" }; + config.PatternFiles.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg-patterns", "notpresent.tdg-pattern")); + config.NamedPatterns = namedPatterns; + + Assert.Throws(() => AlphaNumericGenerator.GenerateFromTemplate(template, config)); + } + + + [Fact] + [Trait("Category", "NegativeTesting")] + public void Can_Throw_Invalid_Pattern_File() + { + var template = @"<<@superhero@>>"; + + var namedPatterns = new TestDataGenerator.Core.NamedPatterns(); + namedPatterns.Patterns.Add(new TestDataGenerator.Core.NamedPattern() { Name = "superhero", Pattern = "(Batman|Superman|Spiderman)" }); + + var config = new TestDataGenerator.Core.GenerationConfig() { Seed = "100" }; + config.PatternFiles.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tdg.exe")); + config.NamedPatterns = namedPatterns; + + Assert.Throws(() => AlphaNumericGenerator.GenerateFromTemplate(template, config)); + } + + #endregion + + #region ConfigurationTesting + /* + [Fact] + [Trait("Category", "ConfigurationTesting")] + public void Can_Configure_Random_Seed_From_Config() + { + int ndx = 0; + + var configStr = "<# { 'Seed':100 } #>"; + var template = configStr+@"Generated <>"; + var config = AlphaNumericGenerator.GetConfiguration(template, ref ndx); + Assert.Equal("100", config.Seed); + Assert.Equal(configStr.Length, ndx); + } + */ + + [Fact] + [Trait("Category", "ConfigurationTesting")] + public void Can_Configure_And_Produce_Output_With_Seed() + { + var template = "<# { \"Seed\":\"100\" } #>Generated <>"; + string text = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, text); + + Assert.Equal("Generated LZ", text); + } + + [Fact] + [Trait("Category", "ConfigurationTesting")] + public void Can_Configure_And_Produce_Output_With_Seed2() + { + var template = @"<# { 'Seed':100 } #>Generated <<\.\w\W\L\l\V\v\d\D\S\s>>"; + string actual = AlphaNumericGenerator.GenerateFromTemplate(template); + Console.WriteLine(@"'{0}' produced '{1}'", template, actual); + + Assert.Equal(@"Generated |k]XjUo6Go ", actual); + } + + /* + [Fact] + [Trait("Category", "ConfigurationTesting")] + public void Can_Catch_Config_Not_At_Beginning_Template() + { + var template = @"<# { 'Seed':100 } #>Generated <<\.\w\W\L\l\V\v\d\D\S\s>>"; + int index = 1; + var config = AlphaNumericGenerator.GetConfiguration(template, ref index); + Assert.IsNull(config); + } + */ + + #endregion + + #region UtilityTesting + + [Fact] + [Trait("Category", "UtilityTesting")] + public void Can_Deserialize() + { + var config = Utility.DeserializeJson("{\"seed\":\"100\"}"); + Assert.NotNull(config); + Assert.Equal("100", config.Seed); + } + + [Fact] + [Trait("Category", "UtilityTesting")] + public void Can_Serialize() + { + var config = new GenerationConfig(); + config.Seed = "300"; + var configStr = Utility.SerializeJson(config); + Console.WriteLine("SerializeJson produced" + configStr); + Assert.NotNull(configStr); + Assert.Equal("{\"LoadDefaultPatternFile\":false,\"NamedPatterns\":{\"Patterns\":[]},\"patternfiles\":[],\"seed\":\"300\"}", configStr); + } + + #endregion + + #region "special functions" + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Anagram() + { + var pattern = @"[ABC]{:anagram:}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(3, text.Length); + Assert.Contains("A", text); + Assert.Contains("B", text); + Assert.Contains("C", text); + } + + [Fact] + [Trait("Category", "Pattern")] + public void Can_Generate_Anagram_Long() + { + var input = "abcdefghijklmnopqrstuvwxyz"; + var pattern = @"[" + input + "]{:anagram:}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern); + Console.WriteLine(@"'{0}' produced '{1}'", pattern, text); + Assert.Equal(input.Length, text.Length); + foreach (var ch in input.ToCharArray()) + { + Assert.Contains(ch.ToString(), text); + } + } + + #endregion + + #region Randomness + [Fact] + [Trait("Category", "Randomness")] + public void Level_Of_Randomness() + { + var pattern = @"(\L\L\L\L\L\L-\L\L-\L\L\L\L\L\n){1000}"; + var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config: new GenerationConfig() { Seed = "100" }); + var segments = new List(text.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries)); + + Console.WriteLine(@"'{0}' produced {1} values, out of which, {2} are unique and {3} are duplicates.", pattern, segments.Count, segments.Distinct().Count(), segments.Count - segments.Distinct().Count()); + } + + [Fact] + [Trait("Category", "Randomness")] + public void Level_Of_Loop() + { + var pattern = @"(\L\L\L\L\L\L-\L\L-\L\L\L\L\L)"; + var segments = new List(); + + var config = new GenerationConfig(); + + for (var i = 0; i < 1000; i++) + { + segments.Add(AlphaNumericGenerator.GenerateFromPattern(pattern, config: config)); + } + + Console.WriteLine(@"'{0}' produced {1} values, out of which, {2} are unique and {3} are duplicates.", pattern, segments.Count, segments.Distinct().Count(), segments.Count - segments.Distinct().Count()); + } + + [Fact] + [Trait("Category", "Randomness")] + public void Seed_As_String_IsUsed() + { + var pattern = @"(\L\L\L\L\L\L-\L\L-\L\L\L\L\L)"; + var config = new GenerationConfig(); + + var segments = new Dictionary(); + for (var i = 0; i < 1000; i++) + { + segments.Add(AlphaNumericGenerator.GenerateFromPattern(pattern, config: config), ""); + config.Seed += "a"; // reset the seed each loop which should result in new random generations. + } + Console.WriteLine(@"'{0}' produced {1} values, out of which, {2} are unique and {3} are duplicates.", pattern, segments.Count, segments.Distinct().Count(), segments.Count - segments.Distinct().Count()); + } + + [Fact] + [Trait("Category", "Randomness")] + public void Weird_s_shortkey_bug() + { + var pattern = @"\s"; + var config = new GenerationConfig(); + for (var i = 0; i < 1000; i++) + { + config.Seed = i.ToString(); + var text = AlphaNumericGenerator.GenerateFromPattern(pattern, config); + Console.WriteLine(@"'{0}' with seed '{1}' produced '{2}'", pattern, config.Seed, text); + Assert.Matches(new Regex(@"^\s$", RegexOptions.ECMAScript), text); // ECMA compliant needed as \s ECMA includes [SPACE] but .NET Regex does not. + config.Seed += "a"; // reset the seed each loop which should result in new random generations. + } + + } + #endregion + } +} + diff --git a/src/TestDataGenerator.Core.Tests/packages.config b/src/TestDataGenerator.Tests/packages.config similarity index 100% rename from src/TestDataGenerator.Core.Tests/packages.config rename to src/TestDataGenerator.Tests/packages.config diff --git a/src/TestDataGenerator.Core.Tests/tdg-patterns/default.tdg-patterns b/src/TestDataGenerator.Tests/tdg-patterns/default.tdg-patterns similarity index 100% rename from src/TestDataGenerator.Core.Tests/tdg-patterns/default.tdg-patterns rename to src/TestDataGenerator.Tests/tdg-patterns/default.tdg-patterns diff --git a/src/TestDataGenerator.Core.Tests/tdg-patterns/invalid.tdg-patterns b/src/TestDataGenerator.Tests/tdg-patterns/invalid.tdg-patterns similarity index 100% rename from src/TestDataGenerator.Core.Tests/tdg-patterns/invalid.tdg-patterns rename to src/TestDataGenerator.Tests/tdg-patterns/invalid.tdg-patterns diff --git a/src/TestDataGenerator.Core.Tests/tdg-patterns/language.tdg-patterns b/src/TestDataGenerator.Tests/tdg-patterns/language.tdg-patterns similarity index 100% rename from src/TestDataGenerator.Core.Tests/tdg-patterns/language.tdg-patterns rename to src/TestDataGenerator.Tests/tdg-patterns/language.tdg-patterns diff --git a/src/TestDataGenerator.sln b/src/TestDataGenerator.sln new file mode 100644 index 0000000..f6d978b --- /dev/null +++ b/src/TestDataGenerator.sln @@ -0,0 +1,48 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestDataGenerator", "TestDataGenerator\TestDataGenerator.csproj", "{D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestDataGenerator.Tests", "TestDataGenerator.Tests\TestDataGenerator.Tests.csproj", "{2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Debug|x64.ActiveCfg = Debug|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Debug|x64.Build.0 = Debug|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Debug|x86.ActiveCfg = Debug|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Debug|x86.Build.0 = Debug|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Release|Any CPU.Build.0 = Release|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Release|x64.ActiveCfg = Release|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Release|x64.Build.0 = Release|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Release|x86.ActiveCfg = Release|Any CPU + {D2E96BE7-0E1B-4E39-BFA3-DD21A9C20F95}.Release|x86.Build.0 = Release|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Debug|x64.ActiveCfg = Debug|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Debug|x64.Build.0 = Debug|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Debug|x86.ActiveCfg = Debug|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Debug|x86.Build.0 = Debug|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Release|Any CPU.Build.0 = Release|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Release|x64.ActiveCfg = Release|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Release|x64.Build.0 = Release|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Release|x86.ActiveCfg = Release|Any CPU + {2BE0DF58-FFE7-43B1-80C7-B7479BD1BA4B}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/src/TestDataGenerator.Core/Exceptions/GenerationException.cs b/src/TestDataGenerator/Exceptions/GenerationException.cs similarity index 100% rename from src/TestDataGenerator.Core/Exceptions/GenerationException.cs rename to src/TestDataGenerator/Exceptions/GenerationException.cs diff --git a/src/TestDataGenerator.Core/FileReader.cs b/src/TestDataGenerator/FileReader.cs similarity index 100% rename from src/TestDataGenerator.Core/FileReader.cs rename to src/TestDataGenerator/FileReader.cs diff --git a/src/TestDataGenerator.Core/GenerationConfig.cs b/src/TestDataGenerator/GenerationConfig.cs similarity index 100% rename from src/TestDataGenerator.Core/GenerationConfig.cs rename to src/TestDataGenerator/GenerationConfig.cs diff --git a/src/TestDataGenerator/Generators/AlphaNumericGenerator.cs b/src/TestDataGenerator/Generators/AlphaNumericGenerator.cs new file mode 100644 index 0000000..087417a --- /dev/null +++ b/src/TestDataGenerator/Generators/AlphaNumericGenerator.cs @@ -0,0 +1,775 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using TestDataGenerator.Core.Exceptions; + +namespace TestDataGenerator.Core.Generators +{ + public static class AlphaNumericGenerator + { + private static readonly Dictionary _ShortHands = GetShortHandMap(); + + private const string _Config_Start = "<#"; + private const string _Config_End = "#>"; + + private const string _Placeholder_Start = "<<"; + private const string _Placeholder_End = ">>"; + + private const char _Section_Start = '('; + private const char _Section_End = ')'; + + private const char _Set_Start = '['; + private const char _Set_End = ']'; + + private const char _Quantifier_Start = '{'; + private const char _Quantifier_End = '}'; + + private const char _Alternation = '|'; + private const char _Escape = '\\'; + private const char _Negation = '^'; + + private const char _NamedPattern_Start = '@'; + private const char _NamedPattern_End = '@'; + + private const string _Anagram = ":anagram:"; + + private const int _ErrorSnippet_ContextLength = 50; + + #region public + + /// + /// Takes in a string that contains 0 or more <<placeholder>> values and replaces the placeholder item with the expression it defines. + /// + /// + /// + /// + public static string GenerateFromTemplate(string template, GenerationConfig generationConfig = null) + { + int index = 0; + + // CONFIG + if (generationConfig == null) generationConfig = LoadAndRemoveConfigFromTemplate(ref template); + if (generationConfig == null) generationConfig = new GenerationConfig(); + + // PATTERNS + // Load provided ones as well if there are any. + var defaultPatterns = GetDefaultNamedPatterns(generationConfig); + defaultPatterns.Patterns.ForEach(generationConfig.NamedPatterns.Patterns.Add); + + // Load all from the PatternFiles in config + AppendPatternsFromConfigToCollection(generationConfig, generationConfig.NamedPatterns); + + var sb = new StringBuilder(); + + while (index < template.Length) + { + // Find our next placeholder + int start = FindPositionOfNext(template, index, _Placeholder_Start, _Placeholder_End); + if (start == -1) + { + sb.Append(template.Substring(index)); //add remaining string. + break; // all done! + } + + bool isEscaped = IsEscaped(template, start); //start >= 1 && template[start - 1].Equals(_Escape); + if (isEscaped) start = start - 1; + sb.Append(template.Substring(index, start - index)); // Append everything up to start as it is. + if (isEscaped) start = start + 1; + start = start + _Placeholder_Start.Length; // move past '<<' to start of expression + + int end = FindPositionOfNext(template, start, _Placeholder_End, _Placeholder_Start); // find end of placeholder + if (end == -1) + { + throw new GenerationException("Unable to find closing placeholder after " + start); + } + + var pattern = template.Substring(start, end - start); // grab our expression + if (isEscaped) + sb.Append("<<" + pattern + ">>"); + else + GenerateFromPattern(sb, pattern, generationConfig); // generate value from expression + index = end + 2; // update our index. + } + + return sb.ToString(); + } + + public static string GenerateFromPattern(string pattern, GenerationConfig config = null) + { + if (config == null) config = new GenerationConfig(); + var sb = new StringBuilder(); + + // add default pattern file entries + if (config.LoadDefaultPatternFile) + { + GetDefaultNamedPatterns(config).Patterns.ForEach(config.NamedPatterns.Patterns.Add); + } + + if (config.PatternFiles != null) + { + // Load all from the PatternFiles in config + AppendPatternsFromConfigToCollection(config, config.NamedPatterns); + } + + GenerateFromPattern(sb, pattern, config); + return sb.ToString(); + } + + #endregion + + #region Generate + + private static void GenerateFromPattern(StringBuilder sb, string pattern, GenerationConfig config) + { + if (string.IsNullOrEmpty(pattern)) + throw new GenerationException("Argument 'pattern' cannot be null."); + + ProcessPattern(sb, pattern, config); + } + + private static void GenerateFromAlternatedPattern(StringBuilder sb, string exp, ContentOptions contentOptions, GenerationConfig config) + { + var alternates = exp.Split(_Alternation); + for (int x = 0; x < contentOptions.Repeat; x++) + { + exp = alternates[config.Random.Next(0, alternates.Length)]; + GenerateFromPattern(sb, exp, config); + } + } + + private static void GenerateFromAnagramPattern(StringBuilder sb, string exp, ContentOptions contentOptions, GenerationConfig config) + { + for (int x = 0; x < contentOptions.Repeat; x++) + { + var arr = exp.ToCharArray(); + arr = arr.OrderBy(r => config.Random.Next()).ToArray(); + foreach (var ch in arr) + AppendCharacterDerivedFromSymbol(sb, ch, false, config); + } + } + + private static string GenerateFloatingFormatWithScale(int scale) + { + var t = "0."; + for (int i = 0; i < scale; i++) + { + t += "#"; + } + return t; + } + + #endregion + + #region Get + + /// + /// Recieves a "A-Z" type string and returns the appropriate list of characters. + /// + /// + /// + /// + /// + private static string GetRandomCharacterFromRange(string range, bool isNegated, GenerationConfig config) + { + string ret; + string possibles = _ShortHands["."]; + var items = range.Split('-'); + double i; + if (!Double.TryParse(items[0], out i)) + ret = GetRandomAlphaItemFromRange(isNegated, config, items, possibles); + else + ret = GetRandomNumericItemFromRange(isNegated, config, items, possibles); + + return ret; + } + + private static Dictionary GetShortHandMap() + { + var shorthands = new Dictionary(); + shorthands["l"] = "abcdefghijklmnopqrstuvwxyz"; + shorthands["L"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + shorthands["V"] = "AEIOU"; + shorthands["v"] = "aeiou"; + shorthands["C"] = "BCDFGHJKLMNPQRSTVWXYZ"; + shorthands["c"] = "bcdfghjklmnpqrstvwxyz"; + shorthands["s"] = " \f\n\r\t\v"; + shorthands["d"] = "0123456789"; + + var nonAlphaNonWhiteSpace = ".,;:\"'!&?£$€$%^<>{}[]()*\\+-=@#|~/"; + shorthands["W"] = shorthands["s"] + nonAlphaNonWhiteSpace + " "; // [^A-Za-z0-9_]. + + shorthands["a"] = shorthands["l"] + shorthands["L"]; + shorthands["D"] = shorthands["l"] + shorthands["L"] + shorthands["W"]; + shorthands["w"] = shorthands["l"] + shorthands["L"] + shorthands["d"] + "_"; // [A-Za-z0-9_]. + shorthands["S"] = shorthands["l"] + shorthands["L"] + shorthands["d"] + "_" + nonAlphaNonWhiteSpace; // [^ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000-\u200a​\u2028\u2029​\u202f\u205f​\u3000\ufeff] + shorthands["."] = shorthands["a"] + shorthands["d"] + shorthands["W"]; + + return shorthands; + } + + private static string GetRandomAlphaItemFromRange(bool isNegated, GenerationConfig config, string[] items, string possibles) + { + string ret = ""; + if (_ShortHands["l"].Contains(items[0])) possibles = _ShortHands["l"]; + if (_ShortHands["L"].Contains(items[0])) possibles = _ShortHands["L"]; + + var start = possibles.IndexOf(items[0].ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal); + if (start > -1) + { + var end = possibles.IndexOf(items[1].ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal); + possibles = possibles.Substring(start, end - start + 1); + if (isNegated) possibles = Regex.Replace(_ShortHands["."], "[" + possibles + "]", ""); + ret = possibles[config.Random.Next(0, possibles.Length)].ToString(CultureInfo.InvariantCulture); + } + return ret; + } + + private static string GetRandomNumericItemFromRange(bool isNegated, GenerationConfig config, string[] items, string possibles) + { + string ret = ""; + + double min; + if (double.TryParse(items[0], NumberStyles.Number, CultureInfo.InvariantCulture, out min)) + { + double max; + if (double.TryParse(items[1], NumberStyles.Number, CultureInfo.InvariantCulture, out max)) + { + int scale = 0; + if (items[0].Contains(".")) + scale = items[0].Split('.')[1].Length; + + if (isNegated) + { + if (scale > 0 || min < 0 || min > 9 || max < 0 || max > 9) + throw new GenerationException("Negated numeric sets are restricted to integers between 0 and 9."); + + var negs = ExpandNegatedMinMax(min, max); + possibles = Regex.Replace(possibles, "[" + negs + "]", ""); + if (possibles.Length == 0) return ""; // No allowable values remain - return empty string + ret = possibles[config.Random.Next(0, possibles.Length)].ToString(CultureInfo.InvariantCulture); + } + else + { + var t = config.Random.NextDouble(); + min = min + (t * (max - min)); + ret = min.ToString(GenerateFloatingFormatWithScale(scale), CultureInfo.InvariantCulture); + } + } + } + return ret; + } + + /// + /// Dervives the correct repeat value from the provided expression. + /// + /// String in the form of '{n}' or '{n,m}' where n and m are integers + /// + /// + private static int GetRepeatValueFromRepeatExpression(string repeatExpression, GenerationConfig config) + { + if (string.IsNullOrWhiteSpace(repeatExpression)) return 1; + + int repeat; + if (repeatExpression.Contains(",")) + { + // {min,max} has been provided - parse and get value. + var vals = repeatExpression.Split(','); + int min, max; + + if (vals.Length < 2 || !int.TryParse(vals[0], out min) || !int.TryParse(vals[1], out max) || min > max || min < 0) + { + var msg = "Invalid repeat section, random length parameters must be in the format {min,max} where min and max are greater than zero and min is less than max.\n"; + msg += BuildErrorIndicationText(repeatExpression, 0); + throw new GenerationException(msg); + } + + repeat = config.Random.Next(min, max + 1); + } + else if (!int.TryParse(repeatExpression, out repeat)) repeat = -1; + + if (repeat < 0) + throw new GenerationException("Invalid repeat section, repeat value must not be less than zero. '" + repeatExpression + "'"); + return repeat; + } + + private static string GetContent(string characters, ref int index, string openingContainerChar, string closingContainerChar) + { + if (index + openingContainerChar.Length >= characters.Length) + return ""; + + int patternStart = index + openingContainerChar.Length; + var patternEnd = patternStart; + var sectionDepth = openingContainerChar.Equals(closingContainerChar) ? 0 : 1; // start off inside current section + while (patternEnd < characters.Length) + { + if (characters.Substring(patternEnd, openingContainerChar.Length).Equals(openingContainerChar)) sectionDepth++; + //check for Alternations in base group. + + if (characters.Substring(patternEnd, closingContainerChar.Length).Equals(closingContainerChar)) + { + sectionDepth--; + if (sectionDepth == 0) break; + } + patternEnd++; + } + + if (sectionDepth > 0) // make sure we found closing char + { + var msg = "Expected '" + closingContainerChar + "' but it was not found." + Environment.NewLine; + msg += BuildErrorIndicationText(characters, patternStart); + throw new GenerationException(msg); + } + + int patternLength = patternEnd - patternStart; + + index = index + patternLength + openingContainerChar.Length + closingContainerChar.Length; // update index position. + return characters.Substring(patternStart, patternLength); + } + + private static ContentOptions GetContentOptions(string characters, ref int index, string openingContainerChar, string closingContainerChar, GenerationConfig config) + { + var result = new ContentOptions + { + Content = GetContent(characters, ref index, openingContainerChar, closingContainerChar) + }; + + result.ContainsAlternation = ContainsAlternations(result.Content); + + if (result.Content[0].Equals(_Negation)) + { + result.IsNegated = true; + result.Content = result.Content.Replace("^", ""); + } + + if (characters.Length <= index || !characters[index].Equals(_Quantifier_Start)) return result; + + result.QuantifierContent = GetContent(characters, ref index, _Quantifier_Start.ToString(CultureInfo.InvariantCulture), _Quantifier_End.ToString(CultureInfo.InvariantCulture)); + + // check for special functions + if (result.QuantifierContent.Contains(":")) + { + result.IsAnagram = ContainsAnagram(result.QuantifierContent); + } + else + { + result.Repeat = GetRepeatValueFromRepeatExpression(result.QuantifierContent, config); + } + + return result; + } + + private static NamedPatterns GetDefaultNamedPatterns(GenerationConfig generationConfig) + { + var patterns = new NamedPatterns(); + if (generationConfig == null || generationConfig.LoadDefaultPatternFile == false) + return patterns; // Dont attempt to load default pattern files with every execution -- too slow. + + var path = FileReader.GetPatternFilePath("default"); + if (File.Exists(path)) + { + patterns = FileReader.LoadNamedPatterns(path, false); + } + + return patterns; + } + + private static GenerationConfig GetConfiguration(string template, ref int index) + { + if (index > 0) + return null; //throw new GenerationException("Configuration items must be at the start of the template (index 0)"); + + if (!template.TrimStart().StartsWith(_Config_Start)) + return null; + + var configString = GetContent(template, ref index, _Config_Start, _Config_End).ToLowerInvariant().Replace('\'', '"'); + + GenerationConfig config; + try + { + config = Utility.DeserializeJson(configString); + if (config.NamedPatterns == null) config.NamedPatterns = new NamedPatterns(); + } + catch (Exception ex) + { + var msg = BuildErrorIndicationText(template, _Config_Start.Length); + throw new GenerationException(string.Format("Unable to parse configuration string. Please check that all key names are within double quotes.\n '{0}'\n{1}", msg, ex.Message)); + } + return config; + } + + #endregion + + #region Utility + + private static GenerationConfig LoadAndRemoveConfigFromTemplate(ref string template) + { + int index = 0; + // If we have no provided config attempt to get one from the template. + GenerationConfig config = GetConfiguration(template, ref index); + if (config != null) + { + // Remove all config sections from template. + template = template.Substring(index); + } + return config; + } + + private static int FindPositionOfNext(string template, int index, string toFind, string notBefore) + { + bool found = false; + var ndx = index; + var notBeforeNdx = index; + while (!found) + { + ndx = template.IndexOf(toFind, ndx, StringComparison.Ordinal); + if (ndx == -1) break; + + notBeforeNdx = template.IndexOf(notBefore, notBeforeNdx, StringComparison.Ordinal); + + if (notBeforeNdx > -1 && notBeforeNdx < ndx) + { + string msg = @"Found unexpected token '" + notBefore + "' when expecting to find '" + toFind + "'."; + msg = msg + Environment.NewLine + BuildErrorIndicationText(template, notBeforeNdx); + throw new GenerationException(msg); + } + found = true; + } + return ndx; + } + + private static bool IsEscaped(string template, int ndx) + { + int slashes = 0; + var c = ndx - 1; + while (c >= 0) + { + if (template[c] != _Escape) break; + + slashes++; + c--; + } + return (slashes != 0) && slashes % 2 != 0; + } + + private static void ProcessPattern(StringBuilder sb, string exp, GenerationConfig config) + { + bool isEscaped = false; + var curNdx = 0; + while (curNdx < exp.Length) + { + var chx = exp[curNdx]; + if (chx == _Escape) + { + if (isEscaped) + { + // "\\" handling + isEscaped = false; + } + else + { + // "...\..." detected, entering escaped symbol handling on next pass. + isEscaped = true; + curNdx++; + continue; + } + } + + if (!isEscaped && chx == _Section_Start) + { + AppendContentFromSectionExpression(sb, exp, ref curNdx, config); + continue; // skip to next character - index has already been forwarded to new position + } + + // check are we entering a set pattern that may include a quantifier + // Format = "[Vv]{4}" = generate 4 random ordered characters comprising of either V or v characters + if (!isEscaped && chx == _Set_Start) + { + AppendContentFromSetExpression(sb, exp, ref curNdx, config); + continue; // skip to next character - index has already been forwarded to new position + } + + if (!isEscaped && chx == _NamedPattern_Start) + { + AppendContentFromNamedPattern(sb, exp, ref curNdx, config); + continue; + } + + // check are we entering a repeat symbol section + // Format = "L{4}" = repeat L symbol 4 times. + // Format = "\\{4}" = repeat \ symbol 4 times. + bool repeatSymbol = curNdx < exp.Length - 1 && exp[curNdx + 1] == _Quantifier_Start; + if (repeatSymbol) + { + AppendRepeatedSymbol(sb, exp, ref curNdx, isEscaped, config); + isEscaped = false; + continue; // skip to next character - index has already been forwarded to new position + } + + AppendCharacterDerivedFromSymbol(sb, chx, isEscaped, config); + curNdx++; // increment to move to next character. + isEscaped = false; + } + } + + private static string ExpandNegatedMinMax(double min, double max) + { + string ret = ""; + for (double i = min; i <= max; i++) + { + ret += i.ToString(CultureInfo.InvariantCulture); + } + return ret; + } + + private static bool ContainsAnagram(string content) + { + return content.ToLower().Equals(_Anagram); + } + + private static bool ContainsAlternations(string characters) + { + var patternEnd = 0; + var sectionDepth = 0; + + next: + while (patternEnd < characters.Length) + { + if (characters[patternEnd].Equals(_Section_Start)) sectionDepth++; + //check for Alternations in base group. + if (sectionDepth == 0 && characters[patternEnd].Equals(_Alternation)) return true; + + if (characters[patternEnd].Equals(_Section_End)) + { + sectionDepth--; + if (sectionDepth == 0) goto next; + } + patternEnd++; + } + return false; + } + + private static string BuildErrorIndicationText(string template, int ndx) + { + try + { + var templateLength = template.Length; + var ndxStart = ndx - _ErrorSnippet_ContextLength > 0 ? ndx - _ErrorSnippet_ContextLength : 0; + var ndxEnd = ndx + _ErrorSnippet_ContextLength > templateLength ? templateLength - 1 : ndx + _ErrorSnippet_ContextLength; + + var line = template.Substring(ndxStart, ndxEnd - ndxStart); + line = line.Replace('\n', ' ').Replace('\r', ' '); + var indicator = new string(' ', ndx - ndxStart) + "^" + new string(' ', ndxEnd - ndx + 1); + + return line + Environment.NewLine + indicator; + } + catch + { + return "An error occurred close to index " + ndx; + } + } + + #endregion + + #region Append + + private static void AppendPatternsFromConfigToCollection(GenerationConfig config, NamedPatterns patternCollection) + { + if (config.PatternFiles == null) return; + + foreach (var patternFile in config.PatternFiles) + { + var correctedPath = FileReader.GetPatternFilePath(patternFile); + + try + { + var patt = FileReader.LoadNamedPatterns(correctedPath); + foreach (var pattern in patt.Patterns) + { + patternCollection.Patterns.Add(pattern); + } + } + catch (Exception ex) + { + throw new GenerationException("Error loading PatternFile:" + patternFile + "\n\n" + ex.Message); + } + } + } + + /// + /// Calculates the content from a repeated symbol when the following form is encountered 's{repeat}' where s is a symbol. + /// The calculated value is append to sb. + /// + /// + /// + /// + /// + /// True if the the previous character was an escape char. + /// + /// + private static void AppendRepeatedSymbol(StringBuilder sb, string characters, ref int index, bool isEscaped, GenerationConfig config) + { + var symbol = characters[index++]; + var repeatExpression = GetContent(characters, ref index, _Quantifier_Start.ToString(CultureInfo.InvariantCulture), _Quantifier_End.ToString(CultureInfo.InvariantCulture)); + var repeat = GetRepeatValueFromRepeatExpression(repeatExpression, config); + + for (int x = 0; x < repeat; x++) + { + AppendCharacterDerivedFromSymbol(sb, symbol, isEscaped, config); + } + } + + /// + /// Calculates the content from a repeated expression when the following form is enountered '[exp]{repeat}'. + /// + /// + /// + /// + /// + /// + private static void AppendContentFromSectionExpression(StringBuilder sb, string characters, ref int index, GenerationConfig config) + { + var contentOptions = GetContentOptions(characters, ref index, _Section_Start.ToString(CultureInfo.InvariantCulture), _Section_End.ToString(CultureInfo.InvariantCulture), config); + + var exp = contentOptions.Content; + if (contentOptions.ContainsAlternation) // contains alternations + { + GenerateFromAlternatedPattern(sb, exp, contentOptions, config); + return; + } + + for (int x = 0; x < contentOptions.Repeat; x++) + { + ProcessPattern(sb, exp, config); + } + } + + private static void AppendContentFromNamedPattern(StringBuilder sb, string characters, ref int index, GenerationConfig config) + { + var ndx = index; + var tuple = GetContentOptions(characters, ref index, _NamedPattern_Start.ToString(CultureInfo.InvariantCulture), _NamedPattern_End.ToString(CultureInfo.InvariantCulture), config); + + if (config.NamedPatterns.HasPattern(tuple.Content)) // $namedPattern; + { + GenerateFromPattern(sb, config.NamedPatterns.GetPattern(tuple.Content).Pattern, config); + } + else + { + var msg = BuildErrorIndicationText(characters, ndx); + msg = "Unknown pattern '" + tuple.Content + "' encountered. Check that the pattern is included in the provided tdg-pattern files or named pattern collection." + Environment.NewLine + msg; + throw new GenerationException(msg); + } + } + + /// + /// Calculates the content from a set expression when the following form is enountered '[exp]{repeat}'. + /// + /// + /// + /// + /// + private static void AppendContentFromSetExpression(StringBuilder sb, string characters, ref int index, GenerationConfig config) + { + var contentOptions = GetContentOptions(characters, ref index, _Set_Start.ToString(CultureInfo.InvariantCulture), _Set_End.ToString(CultureInfo.InvariantCulture), config); + + if (contentOptions.IsAnagram) + { + GenerateFromAnagramPattern(sb, contentOptions.Content, contentOptions, config); + return; + } + + if (contentOptions.Content.Contains("-")) // Ranged - [0-7] or [a-z] or [1-9A-Za-z] for fun. + { + MatchCollection ranges = new Regex(@"[A-Za-z]-[A-Za-z]|\d+\.?\d*-\d+\.?\d*|.").Matches(contentOptions.Content); + if (contentOptions.IsNegated) + { + var possibles = _ShortHands["."]; + foreach (var range in ranges) + { + if (range.ToString().Contains("-")) + { + //TODO - Cleanup - Only here to throw an exception for invalid ranges + GetRandomCharacterFromRange(range.ToString(), contentOptions.IsNegated, config); + var regex = new Regex("[" + range + "]"); + possibles = regex.Replace(possibles, ""); + } + else + { + // single character item to negate, just remove it from the list of possibles. + possibles = possibles.Replace(range.ToString(), ""); + } + } + + for (int i = 0; i < contentOptions.Repeat; i++) + { + sb.Append(possibles[config.Random.Next(0, possibles.Length)]); + } + } + else + { + for (int i = 0; i < contentOptions.Repeat; i++) + { + var range = ranges[config.Random.Next(0, ranges.Count)].ToString(); + sb.Append(range.Contains("-") ? GetRandomCharacterFromRange(range, contentOptions.IsNegated, config) : range); + } + } + } + else + { + var possibles = contentOptions.Content; + if (contentOptions.IsNegated) + possibles = Regex.Replace(_ShortHands["."], "[" + possibles + "]", ""); + + for (int i = 0; i < contentOptions.Repeat; i++) + { + sb.Append(possibles[config.Random.Next(0, possibles.Length)]); + } + } + } + + private static void AppendCharacterDerivedFromSymbol(StringBuilder sb, char symbol, bool isEscaped, GenerationConfig config) + { + if (!isEscaped) + { + sb.Append(symbol); // not a symbol - append as is. + return; + } + + var symbolAsString = symbol.ToString(); + + if (_ShortHands.ContainsKey(symbolAsString)) + { + AppendRandomCharacterFromString(sb, _ShortHands[symbolAsString], config); + } + else + { + switch (symbol) + { + case 'n': + sb.Append("\n"); + break; + case 'r': + sb.Append("\r"); + break; + case 't': + sb.Append("\t"); + break; + default: + // Just append the character as it is not a symbol. + sb.Append(symbol); + break; + } + } + } + + private static void AppendRandomCharacterFromString(StringBuilder sb, string allowedCharacters, GenerationConfig config) + { + sb.Append(allowedCharacters[config.Random.Next(allowedCharacters.Length)]); + } + + #endregion + } +} diff --git a/src/TestDataGenerator.Core/Generators/ContentOptions.cs b/src/TestDataGenerator/Generators/ContentOptions.cs similarity index 100% rename from src/TestDataGenerator.Core/Generators/ContentOptions.cs rename to src/TestDataGenerator/Generators/ContentOptions.cs diff --git a/src/TestDataGenerator.Core/Generators/Utility.cs b/src/TestDataGenerator/Generators/Utility.cs similarity index 100% rename from src/TestDataGenerator.Core/Generators/Utility.cs rename to src/TestDataGenerator/Generators/Utility.cs diff --git a/src/TestDataGenerator.Core/NamedPatterns.cs b/src/TestDataGenerator/NamedPatterns.cs similarity index 100% rename from src/TestDataGenerator.Core/NamedPatterns.cs rename to src/TestDataGenerator/NamedPatterns.cs diff --git a/src/TestDataGenerator.Core/Strings.Designer.cs b/src/TestDataGenerator/Strings.Designer.cs similarity index 100% rename from src/TestDataGenerator.Core/Strings.Designer.cs rename to src/TestDataGenerator/Strings.Designer.cs diff --git a/src/TestDataGenerator.Core/Strings.resx b/src/TestDataGenerator/Strings.resx similarity index 100% rename from src/TestDataGenerator.Core/Strings.resx rename to src/TestDataGenerator/Strings.resx diff --git a/src/TestDataGenerator/TestDataGenerator.csproj b/src/TestDataGenerator/TestDataGenerator.csproj new file mode 100644 index 0000000..9f5c4f4 --- /dev/null +++ b/src/TestDataGenerator/TestDataGenerator.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + +