Skip to content

Commit 0b8ec8f

Browse files
Version 3.3.3 - Bug fixes, more unit tests
1 parent 7225b89 commit 0b8ec8f

File tree

11 files changed

+210
-83
lines changed

11 files changed

+210
-83
lines changed

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ The pattern is as follows:
2727
### Groups
2828
- `(\d){5}` - Five digits between 0 and 9.
2929
- `\L(\d){3}\L` - A upper-case letter, five digits between 0 and 9 and another upper-case letter.
30-
- `(.[100-101]){3}` - Three items, each will include a dot '.' and either 100 or 101 e.g. *'.100.100.101'*
30+
- `(.[100-101]){3}` - Three items, each will include a dot '.' and either 100 or 101 e.g. *'.100.100.100'*
3131

3232
### Ranges
3333
- `[a-z]` - A single lower-case letter between a and z.
@@ -46,7 +46,7 @@ The pattern is as follows:
4646

4747
### Named Parameters
4848
A named pattern is surrounded with @ characters and links to a predefined pattern loaded from a file. The `default.tdg-patterns` file located in the same directory as the tdg executable file contains a list of named patterns which can be used in other patterns you write. For example to generate you could write something like `([1-9]\d\d-\d\d-\d\d\d\d)` or you can use the named parameter in the file `(@ssn@)` to a similar value. You can add more patterns to the file as you wish. Named patterns can also include other named patterns if you so wish. Take a look at the `@us_address_type1@` pattern in the file as an example of a compound pattern than uses other patterns to produce an output.
49-
'5 Sunset Terrace, Charles County, New Hampshire, *Pl^\'
49+
'3516 Delaware Terrace, Hunterdon County, Florida, yrwcB'
5050

5151
### CommandLine tool
5252
You can use the `tdg.exe` application to generate test data from the command line. It can handle provided templates directly from the command line or from a file. The tool also supports exporting the generated output to either the command line or another file.
@@ -63,23 +63,23 @@ You can use the `tdg.exe` application to generate test data from the command lin
6363
### Examples
6464
- Single repeating symbols using the following syntax
6565
- `tdg -t 'Letters \<<\L{20}>> and Numbers \<<\d{12}>>'`
66-
- Produces items like *'Letters XTUXPTCMQOZIUHKDJSHB and Numbers 050283646151'*.
66+
- Produces items like *'Letters MCKVNPVFNLYOYQLEISKI and Numbers 364796587178'*.
6767
- Repeating patterns containing multiple letters or numbers of random length.
68-
- `tdg -t '\<<(\L){5}>>'` - Will generate 5 random upper-case characters. e.g. *'QAIRF'*
69-
- `tdg -t '\<<(\L\L\d){24}>>'` - Will generate 24 repeating letter-letter-number values e.g. *'JL4BB2MB2BD2LN7VS8KR5AG1RV4AU6UZ7XA2VZ9GO1QH4FF6UI9EY9QI1JJ2UM2NG1MO5MZ7'*
68+
- `tdg -t '\<<(\L){5}>>'` - Will generate 5 random upper-case characters. e.g. *'BAYFW'*
69+
- `tdg -t '\<<(\L\L\d){24}>>'` - Will generate 24 repeating letter-letter-number values e.g. *'DY6CJ9OX0IU7ZY4WS9VQ6YX0AM3QB4XS1HF7UG0RX8WH7CS1HA3CD5FF0OC8PY8OK0NR7SB4'*
7070
- Variable length data can be generated also
71-
- `tdg -t '\<<(\L){10,20}>>'` - Will generate a string containing between 10 and 20 characters of random value e.g. *'DDKJYQMQVGMUQBTHRCM'*
72-
- `tdg -t 'Letters \<<\L{2,20}>> and Numbers \<<\d{2,12}>>'` produces items like *'Letters TLCYCAITRDHJE and Numbers 78292'*
71+
- `tdg -t '\<<(\L){10,20}>>'` - Will generate a string containing between 10 and 20 characters of random value e.g. *'ETVBQJXUEIBDUPPCZSG'*
72+
- `tdg -t 'Letters \<<\L{2,20}>> and Numbers \<<\d{2,12}>>'` produces items like *'Letters EBZZ and Numbers 86504'*
7373
- Input can contain several placeholders.
7474
- `tdg -t '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>>.' -c 100`
75-
- Produces 100 items like *'Hi there Souo Tagvic how are you doing? Your SSN is 142-92-7979.'*
75+
- Produces 100 items like *'Hi there Puevja Kpu how are you doing? Your SSN is 649-57-0837.'*
7676
- Generate 100 SSN like values and output to console window.
7777
- `tdg -t '\<<[1-9]\d\d-\d\d-\d\d\d\d>>' -c 100`
78-
- Produces 100 items like *'j63-29-0787'*.
78+
- Produces 100 items like *'i78-77-7377'*.
7979
- Generate 100 strings with random name like values and output to file.
8080
- `tdg -t 'Hi there \<<\L\v\l\v \L\v\l\l\v\v\l\l\v>> how are you doing?' -c 100 -o C:\test1.txt`
81-
- Produces 100 items like *'Tamu Eekfaihxu'*.
82-
- `tdg -t '\<<Letters \w{2,20} and Numbers \d{2,12}\n>>'` produces the following output: *'Letters lfO and Numbers 6341622612
81+
- Produces 100 items like *'Tahi Qosweazco'*.
82+
- `tdg -t '\<<Letters \w{2,20} and Numbers \d{2,12}\n>>'` produces the following output: *'Letters jTmjHwIEh and Numbers 5805354
8383
'*
8484

8585
## More Information
@@ -94,23 +94,23 @@ If you are familiar with Regular Expressions then most of the syntax used will b
9494
`\<<\L\v\l\v>>` is a placeholder containing the pattern of symbols `\L\v\l\v`.
9595

9696
### Symbol Repetition
97-
Individual symbols can be repeated by a supplying a repeat section immediately after the symbol. For example `\L{5}` will produce 5 upper case letters. You can also add some randomness to the mix by supplying a range: `\L{min,max}`. The pattern `\L{1,100}` will produce between 1 and 100 upper case letters. Here's one *'TFCOTJYFEHYMBROKBGNDDEHBMIONFPNEDJHFFJCSHXPMTWJMBWFJQESPXABKVKAPTTJRKJFREVVGOVIPYBMJJDO'*
97+
Individual symbols can be repeated by a supplying a repeat section immediately after the symbol. For example `\L{5}` will produce 5 upper case letters. You can also add some randomness to the mix by supplying a range: `\L{min,max}`. The pattern `\L{1,100}` will produce between 1 and 100 upper case letters. Here's one *'IRVSDAVDWXRUJQLKRWONRICEYUBTSFNTODTZNMTFIMOTXJDXKQWMAZEAORUJYBLRKXFGWMWFDJFFUIGOQEJBI'*
9898

9999
### Symbol Grouping
100-
Individual symbols can be grouped together using parenthesis characters. When grouped together they can be repeated using the same repeat syntax. `(\l\d){5}` will produce something like *'z6r2e3s8x8'*.
100+
Individual symbols can be grouped together using parenthesis characters. When grouped together they can be repeated using the same repeat syntax. `(\l\d){5}` will produce something like *'a7p9t4w6k2'*.
101101
You can also include the random range syntax from above.
102102

103103
### Alternating Symbols and Groups
104104
Patterns can contain several individual symbols or groups of symbols and randomly alternate between them when generating the output value. `\<<\C|\c{10}|\V\V\V|(\v\v){2,3}>>` will produce either a single upper-case consonant, 10 lower-case consonants, 3 upper-case vowels or between 10 and 15 lower-case vowels. Which one gets outputed is randomly selected when processing the pattern.
105105

106106
### Other patterns:
107-
- `'\<<This is a \L\L string>>'` will produce something similar to *'This is a ZS string'*.
108-
- `'\<<This is a \d{19} string>>'` will produce something similar to *'This is a 9461665273400644796 string'*.
107+
- `'\<<This is a \L\L string>>'` will produce something similar to *'This is a GB string'*.
108+
- `'\<<This is a \d{19} string>>'` will produce something similar to *'This is a 8301909763679223277 string'*.
109109
- Individual symbols can be repeated a specific number of times using the syntax `\L{10}` which will generate 10 upper case letters.
110110
- Individual symbols can be repeated a random number of times using the syntax `\L{10,20}` which will generate between 10 and 20 upper case letters.
111111
- 1 or more Symbols can be combined into patterns by wrapping them in parenthesis e.g. `(\*\L\d)`.
112-
- Patterns can be repeated a specific number of times using the syntax `(\L\d){10}` which will generate 10 repeated letter-number pairs e.g. *'F6F3B7B0J4Y9J5C3C2Y7'*.
113-
- Patterns can be repeated a random number of times using the syntax `(\L\d){10,20}` which will generate between 10 and 20 repeated letter-number pairs e.g. *'V9U6E6F4W2D9F7C7C6J6P1T8K0M0J3F7E9'*.
112+
- Patterns can be repeated a specific number of times using the syntax `(\L\d){10}` which will generate 10 repeated letter-number pairs e.g. *'S3J3E6H1B9N7C9D9Z2K7'*.
113+
- Patterns can be repeated a random number of times using the syntax `(\L\d){10,20}` which will generate between 10 and 20 repeated letter-number pairs e.g. *'L2R6B8Z4F4L6M5R5Z8O6W8'*.
114114

115115
### Profiling results
116116
*These timings are taken from unit tests making direct API calls, the command line tool will have higher times as it has additional IO work to output the values to screen or file. Should still be fast.*

VERSION

0 Bytes
Binary file not shown.

src/DataGenerator/gk.DataGenerator.CommandLine/CommandLineArgs.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public string GetUsage()
3535
{
3636
var help = new HelpText
3737
{
38-
Heading = new HeadingInfo("Test Data Generator", "3.3.2"),
38+
Heading = new HeadingInfo("Test Data Generator", "3.3.3"),
3939
Copyright = new CopyrightInfo("Gary Kenneally (@SecretDeveloper)", 2014),
4040
AdditionalNewLineAfterOption = false,
4141
AddDashesToOption = true

src/DataGenerator/gk.DataGenerator.CommandLine/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using Eloquent;
6+
using gk.DataGenerator.Exceptions;
67
using gk.DataGenerator.Generators;
78

89
namespace gk.DataGenerator.tdg

src/DataGenerator/gk.DataGenerator/Generators/GenerationException.cs renamed to src/DataGenerator/gk.DataGenerator/Exceptions/GenerationException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
22

3-
namespace gk.DataGenerator.Generators
3+
namespace gk.DataGenerator.Exceptions
44
{
55
/// <summary>
66
/// Used when a exception needs to be thrown by the test data generator.

src/DataGenerator/gk.DataGenerator/Extensions.cs

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/DataGenerator/gk.DataGenerator/FileReader.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public static NamedPatterns LoadNamedPatterns(string path)
1616
return result;
1717
}
1818

19+
/*
1920
public static void SerializeDictionary(NamedPatterns namedPatterns, string path)
2021
{
2122
using (var fs = XmlWriter.Create(path, new XmlWriterSettings(){Indent = true,OmitXmlDeclaration = true}))
@@ -28,5 +29,6 @@ public static void SerializeDictionary(NamedPatterns namedPatterns, string path)
2829
2930
}
3031
}
32+
*/
3133
}
3234
}

src/DataGenerator/gk.DataGenerator/Generators/AlphaNumericGenerator.cs

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO;
55
using System.Text;
66
using System.Text.RegularExpressions;
7+
using gk.DataGenerator.Exceptions;
78

89
namespace gk.DataGenerator.Generators
910
{
@@ -55,11 +56,6 @@ public static class AlphaNumericGenerator
5556
public static int ErrorContext
5657
{
5758
get { return _ErrorSnippet_ContextLength; }
58-
set
59-
{
60-
if(value<0) throw new ArgumentException("Context length cannot be less than 0.");
61-
_ErrorSnippet_ContextLength = value;
62-
}
6359
}
6460

6561

@@ -215,9 +211,9 @@ public static string GenerateFromPattern(string pattern, NamedPatterns namedPatt
215211
// check are we entering a repeat symbol section
216212
// Format = "L{4}" = repeat L symbol 4 times.
217213
bool repeatSymbol = index < pattern.Length -1 && pattern[index + 1] == _Quantifier_Start;
218-
if (isEscaped && repeatSymbol)
214+
if (repeatSymbol)
219215
{
220-
AppendRepeatedSymbol(sb, pattern, ref index, true);
216+
AppendRepeatedSymbol(sb, pattern, ref index, isEscaped);
221217
isEscaped = false;
222218
continue; // skip to next character - index has already been forwarded to new position
223219
}
@@ -319,15 +315,12 @@ private static bool IsEscaped(string template, int ndx)
319315
private static void AppendRepeatedSymbol(StringBuilder sb, string characters, ref int index, bool isEscaped)
320316
{
321317
var symbol = characters[index++];
322-
string repeatExpression = GetSurroundedContent(characters, ref index, _Quantifier_Start, _Quantifier_End);
323-
int repeat = GetRepeatValueFromRepeatExpression(repeatExpression);
324-
325-
326-
for (int x = 0; x < repeat; x++)
327-
{
328-
AppendCharacterDerivedFromSymbol(sb, symbol, isEscaped);
329-
}
330-
318+
var surroundedTuple = GetSurroundedContent(characters, ref index, _Quantifier_Start, _Quantifier_End);
319+
int repeat = GetRepeatValueFromRepeatExpression(surroundedTuple.Item1);
320+
for (int x = 0; x < repeat; x++)
321+
{
322+
AppendCharacterDerivedFromSymbol(sb, symbol, isEscaped);
323+
}
331324
}
332325

333326
/// <summary>
@@ -342,7 +335,7 @@ private static void AppendContentFromSectionExpression(StringBuilder sb, string
342335
var tuple = GetPatternAndRepeatValueFromExpression(characters,_Section_Start, _Section_End, ref index);
343336

344337
var exp = tuple.Item2;
345-
if (exp.IndexOf(_Alternation)>-1)
338+
if (tuple.Item3) // containse alternations
346339
{
347340
// alternates in expression 'LL|ll|vv'
348341
var alternates = exp.Split(_Alternation);
@@ -374,6 +367,13 @@ private static void AppendContentFromSectionExpression(StringBuilder sb, string
374367
curNdx++;
375368
continue;
376369
}
370+
371+
372+
if (!isEscaped && chx == _Section_Start)
373+
{
374+
AppendContentFromSectionExpression(sb, exp, ref curNdx, namedPatterns);
375+
continue; // skip to next character - index has already been forwarded to new position
376+
}
377377

378378
// check are we entering a set pattern that may include a quantifier
379379
// Format = "[Vv]{4}" = generate 4 random ordered characters comprising of either V or v characters
@@ -389,6 +389,16 @@ private static void AppendContentFromSectionExpression(StringBuilder sb, string
389389
continue;
390390
}
391391

392+
// check are we entering a repeat symbol section
393+
// Format = "L{4}" = repeat L symbol 4 times.
394+
bool repeatSymbol = curNdx < exp.Length - 1 && exp[curNdx + 1] == _Quantifier_Start;
395+
if (repeatSymbol)
396+
{
397+
AppendRepeatedSymbol(sb, exp, ref curNdx, isEscaped);
398+
isEscaped = false;
399+
continue; // skip to next character - index has already been forwarded to new position
400+
}
401+
392402
AppendCharacterDerivedFromSymbol(sb, chx, isEscaped);
393403
curNdx++; // increment to move to next character.
394404
isEscaped = false;
@@ -487,7 +497,6 @@ private static string GetRandomCharacterFromRange(string range)
487497
min = min + (t * (max - min));
488498
ret = min.ToString(GenerateFloatingFormatWithScale(scale), CultureInfo.InvariantCulture);
489499
}
490-
return ret;
491500
}
492501

493502
return ret;
@@ -512,14 +521,18 @@ private static string GenerateFloatingFormatWithScale(int scale)
512521
/// <param name="index"></param>
513522
/// <param name="startChar"></param>
514523
/// <returns></returns>
515-
private static Tuple<int,string> GetPatternAndRepeatValueFromExpression(string characters, char startChar, char endChar, ref int index)
524+
private static Tuple<int,string, bool> GetPatternAndRepeatValueFromExpression(string characters, char startChar, char endChar, ref int index)
516525
{
517-
string pattern = GetSurroundedContent(characters, ref index, startChar, endChar);
518-
string repeatExpression = GetSurroundedContent(characters, ref index, _Quantifier_Start, _Quantifier_End);
526+
527+
var stringAndAlternations = GetSurroundedContent(characters, ref index, startChar, endChar);
528+
string pattern = stringAndAlternations.Item1;
529+
bool containsAlternations = stringAndAlternations.Item2;
530+
531+
stringAndAlternations = GetSurroundedContent(characters, ref index, _Quantifier_Start, _Quantifier_End);
519532

520-
int repeat = GetRepeatValueFromRepeatExpression(repeatExpression);
533+
int repeat = GetRepeatValueFromRepeatExpression(stringAndAlternations.Item1);
521534

522-
return new Tuple<int, string>(repeat, pattern);
535+
return new Tuple<int, string, bool>(repeat, pattern, containsAlternations);
523536
}
524537

525538
/// <summary>
@@ -551,20 +564,24 @@ private static int GetRepeatValueFromRepeatExpression(string repeatExpression)
551564
}
552565

553566

554-
private static string GetSurroundedContent(string characters, ref int index, char sectionStartChar, char sectionEndChar)
567+
private static Tuple<string,bool> GetSurroundedContent(string characters, ref int index, char sectionStartChar, char sectionEndChar)
555568
{
569+
var result = new Tuple<string, bool>("", false);
556570
if (index == characters.Length)
557-
return ""; // throw new GenerationException("Expected '" + sectionStartChar + "' at " + index + " but reached end of pattern instead.");
571+
return result;
558572
if (characters[index].Equals(sectionStartChar) == false)
559-
return ""; // return blank string if expected character is not found.
573+
return result;
560574

575+
bool containsAlternations = false;
561576
int patternStart = index + 1;
562577

563578
var sectionDepth = sectionStartChar.Equals(sectionEndChar)?0:1; // start off inside current section
564579
var patternEnd = patternStart;
565580
while (patternEnd < characters.Length)
566581
{
567582
if (characters[patternEnd] == sectionStartChar) sectionDepth++;
583+
//check for Alternations in base group.
584+
if (sectionDepth == 1 && characters[patternEnd].Equals(_Alternation)) containsAlternations = true;
568585

569586
if (characters[patternEnd] == sectionEndChar)
570587
{
@@ -589,7 +606,8 @@ private static string GetSurroundedContent(string characters, ref int index, cha
589606
}
590607

591608
index = index + patternLength + 2; // update index position.
592-
return characters.Substring(patternStart, patternLength);
609+
result = new Tuple<string, bool>(characters.Substring(patternStart, patternLength), containsAlternations);
610+
return result;
593611
}
594612

595613
private static void AppendCharacterDerivedFromSymbol(StringBuilder sb, char symbol, bool isEscaped)

src/DataGenerator/gk.DataGenerator/NamedPatterns.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ public bool HasPattern(string name)
2626
{
2727
return Patterns.Any(n => n.Name.Equals(name));
2828
}
29-
30-
public void AddPattern(string name, string pattern)
31-
{
32-
Patterns.Add(new NamedPattern(){Name = name, Pattern = pattern});
33-
}
3429
}
3530

3631
public class NamedPattern

src/DataGenerator/gk.DataGenerator/gk.DataGenerator.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,7 @@
6767
<ItemGroup>
6868
<Compile Include="FileReader.cs" />
6969
<Compile Include="Generators\AlphaNumericGenerator.cs" />
70-
<Compile Include="Extensions.cs" />
71-
<Compile Include="Generators\GenerationException.cs" />
70+
<Compile Include="Exceptions\GenerationException.cs" />
7271
<Compile Include="NamedPatterns.cs" />
7372
<Compile Include="Properties\AssemblyInfo.cs" />
7473
<Compile Include="Strings.Designer.cs">

0 commit comments

Comments
 (0)