From 8e7dde55456c6757362db616e89b98cb59f774be Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Tue, 30 Apr 2019 07:13:24 +0100 Subject: [PATCH] Added the Bank faker (and the Regexify class) (#122) * Added documentation. * Added the BankFaker to the main faker object. * Added some bank data. * Added the Regexify class for generating fake data from a regular expression. * Split up regex replacements into separate files so we can test them individually. * Implemented the BankFaker * Added coverage tasks. --- .gitignore | 1 + .vscode/tasks.json | 57 +++++++- FakerDotNet.sln.DotSettings | 1 + README.md | 1 + doc/bank.md | 18 +++ src/FakerDotNet/Data/BankData.cs | 132 ++++++++++++++++++ src/FakerDotNet/Faker.cs | 1 + src/FakerDotNet/FakerContainer.cs | 12 +- src/FakerDotNet/FakerUtils/Regexify.cs | 36 +++++ .../RegexifyParsers/DitchAnchors.cs | 15 ++ .../RegexifyParsers/IRegexifyParser.cs | 7 + .../RegexifyParsers/NumberPatternToRange.cs | 16 +++ .../RegexifyParsers/ParseLetters.cs | 19 +++ .../RegexifyParsers/ParseNumbers.cs | 19 +++ .../FakerUtils/RegexifyParsers/ParseRanges.cs | 55 ++++++++ .../ReplaceOneOfLettersWithLetter.cs | 24 ++++ .../ReplaceOneOfRangeWithLetter.cs | 40 ++++++ .../ReplaceOneOfWordsWithWord.cs | 23 +++ src/FakerDotNet/Fakers/BankFaker.cs | 70 ++++++++++ .../FakerDotNet.Tests/FakerContainerTests.cs | 13 ++ .../FakerDotNet.Tests.csproj | 3 +- tests/FakerDotNet.Tests/FakerTests.cs | 6 + .../RegexifyParsers/DitchAnchorsTests.cs | 42 ++++++ .../NumberPatternToRangeTests.cs | 34 +++++ .../RegexifyParsers/ParseLettersTests.cs | 54 +++++++ .../RegexifyParsers/ParseNumbersTests.cs | 54 +++++++ .../RegexifyParsers/ParseRangesTests.cs | 73 ++++++++++ .../ReplaceOneOfLettersWithLetterTests.cs | 34 +++++ .../ReplaceOneOfRangeWithLetterTests.cs | 52 +++++++ .../ReplaceOneOfWordsWithWordTests.cs | 34 +++++ .../FakerUtils/RegexifyTests.cs | 46 ++++++ .../Fakers/BankFakerTests.cs | 80 +++++++++++ 32 files changed, 1069 insertions(+), 3 deletions(-) create mode 100644 doc/bank.md create mode 100644 src/FakerDotNet/Data/BankData.cs create mode 100644 src/FakerDotNet/FakerUtils/Regexify.cs create mode 100644 src/FakerDotNet/FakerUtils/RegexifyParsers/DitchAnchors.cs create mode 100644 src/FakerDotNet/FakerUtils/RegexifyParsers/IRegexifyParser.cs create mode 100644 src/FakerDotNet/FakerUtils/RegexifyParsers/NumberPatternToRange.cs create mode 100644 src/FakerDotNet/FakerUtils/RegexifyParsers/ParseLetters.cs create mode 100644 src/FakerDotNet/FakerUtils/RegexifyParsers/ParseNumbers.cs create mode 100644 src/FakerDotNet/FakerUtils/RegexifyParsers/ParseRanges.cs create mode 100644 src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfLettersWithLetter.cs create mode 100644 src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfRangeWithLetter.cs create mode 100644 src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfWordsWithWord.cs create mode 100644 src/FakerDotNet/Fakers/BankFaker.cs create mode 100644 tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/DitchAnchorsTests.cs create mode 100644 tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/NumberPatternToRangeTests.cs create mode 100644 tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseLettersTests.cs create mode 100644 tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseNumbersTests.cs create mode 100644 tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseRangesTests.cs create mode 100644 tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfLettersWithLetterTests.cs create mode 100644 tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfRangeWithLetterTests.cs create mode 100644 tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfWordsWithWordTests.cs create mode 100644 tests/FakerDotNet.Tests/FakerUtils/RegexifyTests.cs create mode 100644 tests/FakerDotNet.Tests/Fakers/BankFakerTests.cs diff --git a/.gitignore b/.gitignore index 3e759b7..72bceff 100644 --- a/.gitignore +++ b/.gitignore @@ -328,3 +328,4 @@ ASALocalRun/ # MFractors (Xamarin productivity tool) working folder .mfractor/ +lcov.info diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 1362179..337d274 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -9,7 +9,62 @@ "build", "${workspaceFolder}/tests/FakerDotNet.Tests/FakerDotNet.Tests.csproj" ], - "problemMatcher": "$msCompile" + "problemMatcher": "$msCompile", + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "test", + "command": "dotnet", + "type": "process", + "args": [ + "test", + "${workspaceFolder}/tests/FakerDotNet.Tests/FakerDotNet.Tests.csproj" + ], + "problemMatcher": "$msCompile", + "group": { + "kind": "test", + "isDefault": true + } + }, + { + "label": "test with coverage", + "command": "dotnet", + "type": "process", + "args": [ + "test", + "/p:CollectCoverage=true", + "/p:CoverletOutputFormat=lcov", + "/p:CoverletOutput=${workspaceFolder}/lcov.info", + "${workspaceFolder}/tests/FakerDotNet.Tests/FakerDotNet.Tests.csproj" + ], + "problemMatcher": "$msCompile", + "group": { + "kind": "test", + "isDefault": true + } + }, + { + "label": "watch test with coverage", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "--project", + "${workspaceFolder}/src/FakerDotNet/FakerDotNet.csproj", + "test", + "/p:CollectCoverage=true", + "/p:CoverletOutputFormat=lcov", + "/p:CoverletOutput=${workspaceFolder}/lcov.info", + "${workspaceFolder}/tests/FakerDotNet.Tests/FakerDotNet.Tests.csproj" + ], + "problemMatcher": "$msCompile", + "group": { + "kind": "test", + "isDefault": true + } } ] } \ No newline at end of file diff --git a/FakerDotNet.sln.DotSettings b/FakerDotNet.sln.DotSettings index c2f8165..0df24f5 100644 --- a/FakerDotNet.sln.DotSettings +++ b/FakerDotNet.sln.DotSettings @@ -2,4 +2,5 @@ IP RNG True + True True \ No newline at end of file diff --git a/README.md b/README.md index d176fa5..e1a7883 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ A .NET port of the Ruby [faker](https://github.com/stympy/faker) gem - [Faker.Ancient](doc/ancient.md) - [Faker.App](doc/app.md) - [Faker.Avatar](doc/avatar.md) + - [Faker.Bank](doc/bank.md) - [Faker.Beer](doc/beer.md) - [Faker.Book](doc/book.md) - [Faker.Boolean](doc/boolean.md) diff --git a/doc/bank.md b/doc/bank.md new file mode 100644 index 0000000..d0b65a6 --- /dev/null +++ b/doc/bank.md @@ -0,0 +1,18 @@ +# Faker.Bank + +```cs + +Faker.Bank.AccountNumber() //=> 6738582379 + +Faker.Bank.AccountNumber(13) //=> 673858237902 + +Faker.Bank.Iban() //=> "GB19DZJM33188515981979" + +// Optional argument bankCountryCode +// All countries should be supported +Faker.Bank.Iban("be") //=> "BE8975388567752043" + +Faker.Bank.Name() //=> "ABN AMRO CORPORATE FINANCE LIMITED" + +Faker.Bank.SwiftBic() //=> "AAFMGB21" +``` diff --git a/src/FakerDotNet/Data/BankData.cs b/src/FakerDotNet/Data/BankData.cs new file mode 100644 index 0000000..edf77e0 --- /dev/null +++ b/src/FakerDotNet/Data/BankData.cs @@ -0,0 +1,132 @@ +using System.Collections.Generic; + +namespace FakerDotNet.Data +{ + internal static class BankData + { + public static readonly IEnumerable Names = new[] + { + "UBS CLEARING AND EXECUTION SERVICES LIMITED", + "ABN AMRO CORPORATE FINANCE LIMITED", + "ABN AMRO FUND MANAGERS LIMITED", + "ABN AMRO HOARE GOVETT SECURITIES", + "ABN AMRO HOARE GOVETT CORPORATE FINANCE LTD.", + "ALKEN ASSET MANAGEMENT", + "ALKEN ASSET MANAGEMENT", + "ABN AMRO HOARE GOVETT LIMITED", + "AAC CAPITAL PARTNERS LIMITED", + "ABBOTSTONE AGRICULTURAL PROPERTY UNIT TRUST", + "ABN AMRO QUOTED INVESTMENTS (UK) LIMITED", + "ABN AMRO MEZZANINE (UK) LIMITED", + "ABBEY LIFE", + "SANTANDER UK PLC", + "OTKRITIE SECURITIES LIMITED", + "ABC INTERNATIONAL BANK PLC", + "ALLIED BANK PHILIPPINES (UK) PLC", + "ABU DHABI ISLAMIC BANK", + "ABG SUNDAL COLLIER LIMITED", + "PGMS (GLASGOW) LIMITED", + "ABINGWORTH MANAGEMENT LIMITED", + "THE ROYAL BANK OF SCOTLAND PLC (FORMER RBS NV)" + }; + + public static readonly IEnumerable SwiftBics = new[] + { + "AACCGB21", + "AACNGB21", + "AAFMGB21", + "AAHOGB21", + "AAHVGB21", + "AANLGB21", + "AANLGB2L", + "AAOGGB21", + "AAPEGB21", + "AAPUGB21", + "AAQIGB21", + "ABAZGB21", + "ABBEGB21", + "ABBYGB2L", + "ABCCGB22", + "ABCEGB2L", + "ABCMGB21", + "ABDIGB21", + "ABECGB21", + "ABFIGB21", + "ABMNGB21", + "ABNAGB21VOC" + }; + + public static readonly IReadOnlyDictionary IbanDetails = + new Dictionary + { + {"ad", (24, @"\d{8}[A-Z0-9]{12}")}, // Andorra + {"ae", (23, @"\d{19}")}, // United Arab Emirates + {"al", (28, @"\d{8}[A-Z0-9]{16}")}, // Albania + {"at", (20, @"\d{16}")}, // Austria + {"az", (28, @"[A-Z]{4}[A-Z0-9]{20}")}, // Azerbaijan, Republic of + {"ba", (20, @"\d{16}")}, // Bosnia + {"be", (16, @"\d{12}")}, // Belgium + {"bg", (22, @"[A-Z]{4}\d{6}[A-Z0-9]{8}")}, // Bulgaria + {"bh", (22, @"[A-Z]{4}[A-Z0-9]{14}")}, // Bahrain + {"br", (29, @"[0-9]{8}[0-9]{5}[0-9]{10}[A-Z]{1}[A-Z0-9]{1}")}, // Brazil + {"ch", (21, @"\d{5}[A-Z0-9]{12}")}, // Switzerland + {"cr", (22, @"0\d{3}\d{14}")}, // Costa Rica + {"cy", (28, @"\d{8}[A-Z0-9]{16}")}, // Cyprus + {"cz", (24, @"\d{20}")}, // Czech Republic + {"de", (22, @"\d{18}")}, // Germany + {"dk", (18, @"\d{14}")}, // Denmark + {"do", (28, @"[A-Z]{4}\d{20}")}, // Dominican Republic + {"ee", (20, @"\d{16}")}, // Estonia + {"es", (24, @"\d{20}")}, // Spain + {"fi", (18, @"\d{14}")}, // Finland + {"fo", (18, @"\d{14}")}, // Faroe Islands + {"fr", (27, @"\d{10}[A-Z0-9]{11}\d{2}")}, // France + {"gb", (22, @"[A-Z]{4}\d{14}")}, // United Kingdom + {"ge", (22, @"[A-Z]{2}\d{16}")}, // Georgia + {"gi", (23, @"[A-Z]{4}[A-Z0-9]{15}")}, // Gibraltar + {"gl", (18, @"\d{14}")}, // Greenland + {"gr", (27, @"\d{7}[A-Z0-9]{16}")}, // Greece + {"gt", (28, @"[A-Z0-9]{4}\d{2}\d{2}[A-Z0-9]{16}")}, // Guatemala + {"hr", (21, @"\d{17}")}, // Croatia + {"hu", (28, @"\d{24}")}, // Hungary + {"ie", (22, @"[A-Z]{4}\d{14}")}, // Ireland + {"il", (23, @"\d{19}")}, // Israel + {"is", (26, @"\d{22}")}, // Iceland + {"it", (27, @"[A-Z]\d{10}[A-Z0-9]{12}")}, // Italy + {"kw", (30, @"[A-Z]{4}\d{22}")}, // Kuwait + {"kz", (20, @"[0-9]{3}[A-Z0-9]{13}")}, // Kazakhstan + {"lb", (28, @"\d{4}[A-Z0-9]{20}")}, // Lebanon + {"li", (21, @"\d{5}[A-Z0-9]{12}")}, // Liechtenstein + {"lt", (20, @"\d{16}")}, // Lithuania + {"lu", (20, @"\d{3}[A-Z0-9]{13}")}, // Luxembourg + {"lv", (21, @"[A-Z]{4}[A-Z0-9]{13}")}, // Latvia + {"mc", (27, @"\d{10}[A-Z0-9]{11}\d{2}")}, // Monaco + {"md", (24, @"[A-Z]{2}[A-Z0-9]{18}")}, // Moldova + {"me", (22, @"\d{18}")}, // Montenegro + {"mk", (19, @"\d{3}[A-Z0-9]{10}\d{2}")}, // Macedonia + {"mr", (27, @"\d{23}")}, // Mauritania + {"mt", (31, @"[A-Z]{4}\d{5}[A-Z0-9]{18}")}, // Malta + {"mu", (30, @"[A-Z]{4}\d{19}[A-Z]{3}")}, // Mauritius + {"nl", (18, @"[A-Z]{4}\d{10}")}, // Netherlands + {"no", (15, @"\d{11}")}, // Norway + {"pk", (24, @"[A-Z]{4}[A-Z0-9]{16}")}, // Pakistan + {"pl", (28, @"\d{8}[A-Z0-9]{16}")}, // Poland + {"ps", (29, @"[A-Z]{4}[A-Z0-9]{21}")}, // Palestinian Territory, Occupied + {"pt", (25, @"\d{21}")}, // Portugal + {"qa", (29, @"[A-Z]{4}[A-Z0-9]{21}")}, // Qatar + {"ro", (24, @"[A-Z]{4}[A-Z0-9]{16}")}, // Romania + {"rs", (22, @"\d{18}")}, // Serbia + {"sa", (24, @"\d{2}[A-Z0-9]{18}")}, // Saudi Arabia + {"se", (24, @"\d{20}")}, // Sweden + {"si", (19, @"\d{15}")}, // Slovenia + {"sk", (24, @"\d{20}")}, // Slovakia + {"sm", (27, @"[A-Z]\d{10}[A-Z0-9]{12}")}, // San Marino + {"tl", (23, @"\d{19}")}, // Timor-Leste + {"tn", (24, @"\d{20}")}, // Tunisia + {"tr", (26, @"\d{5}[A-Z0-9]{17}")}, // Turkey + {"ua", (29, @"\d{25}")}, // Ukraine + {"vg", (24, @"[A-Z]{4}\d{16}")}, // Virgin Islands, British + {"xk", (20, @"\d{16}")}, // Kosovo, Republic of + }; + } +} diff --git a/src/FakerDotNet/Faker.cs b/src/FakerDotNet/Faker.cs index fd323de..87daab0 100644 --- a/src/FakerDotNet/Faker.cs +++ b/src/FakerDotNet/Faker.cs @@ -10,6 +10,7 @@ public static class Faker public static IAncientFaker Ancient { get; } = Container.Ancient; public static IAppFaker App { get; } = Container.App; public static IAvatarFaker Avatar { get; } = Container.Avatar; + public static IBankFaker Bank { get; } = Container.Bank; public static IBeerFaker Beer { get; } = Container.Beer; public static IBookFaker Book { get; } = Container.Book; public static IBooleanFaker Boolean { get; } = Container.Boolean; diff --git a/src/FakerDotNet/FakerContainer.cs b/src/FakerDotNet/FakerContainer.cs index 82ce4f3..a13e180 100644 --- a/src/FakerDotNet/FakerContainer.cs +++ b/src/FakerDotNet/FakerContainer.cs @@ -1,4 +1,5 @@ -using FakerDotNet.Fakers; +using FakerDotNet.Fakers; +using FakerDotNet.FakerUtils; namespace FakerDotNet { @@ -8,6 +9,7 @@ internal interface IFakerContainer IAncientFaker Ancient { get; } IAppFaker App { get; } IAvatarFaker Avatar { get; } + IBankFaker Bank { get; } IBeerFaker Beer { get; } IBookFaker Book { get; } IBooleanFaker Boolean { get; } @@ -59,6 +61,8 @@ internal interface IFakerContainer IUniversityFaker University { get; } IVehicleFaker Vehicle { get; } IZeldaFaker Zelda { get; } + + IRegexify Regexify { get; } } internal class FakerContainer : IFakerContainer @@ -69,6 +73,7 @@ public FakerContainer() Ancient = new AncientFaker(this); App = new AppFaker(this); Avatar = new AvatarFaker(this); + Bank = new BankFaker(this); Beer = new BeerFaker(this); Book = new BookFaker(this); Boolean = new BooleanFaker(); @@ -120,12 +125,15 @@ public FakerContainer() University = new UniversityFaker(this); Vehicle = new VehicleFaker(this); Zelda = new ZeldaFaker(this); + + Regexify = new Regexify(this); } public IAddressFaker Address { get; } public IAncientFaker Ancient { get; } public IAppFaker App { get; } public IAvatarFaker Avatar { get; } + public IBankFaker Bank { get; } public IBeerFaker Beer { get; } public IBookFaker Book { get; } public IBooleanFaker Boolean { get; } @@ -177,5 +185,7 @@ public FakerContainer() public IUniversityFaker University { get; } public IVehicleFaker Vehicle { get; } public IZeldaFaker Zelda { get; } + + public IRegexify Regexify { get; } } } diff --git a/src/FakerDotNet/FakerUtils/Regexify.cs b/src/FakerDotNet/FakerUtils/Regexify.cs new file mode 100644 index 0000000..e3e1354 --- /dev/null +++ b/src/FakerDotNet/FakerUtils/Regexify.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Linq; +using FakerDotNet.FakerUtils.RegexifyParsers; + +namespace FakerDotNet.FakerUtils +{ + internal interface IRegexify + { + string Parse(string pattern); + } + + internal class Regexify : IRegexify + { + private readonly IList _parsers; + + public Regexify(IFakerContainer fakerContainer) + { + _parsers = new IRegexifyParser[] + { + new DitchAnchors(), + new NumberPatternToRange(), + new ParseRanges(fakerContainer), + new ReplaceOneOfWordsWithWord(fakerContainer), + new ReplaceOneOfRangeWithLetter(fakerContainer), + new ReplaceOneOfLettersWithLetter(fakerContainer), + new ParseNumbers(fakerContainer), + new ParseLetters(fakerContainer), + }; + } + + public string Parse(string pattern) + { + return _parsers.Aggregate(pattern ?? "", (result, replacer) => replacer.Run(result)); + } + } +} diff --git a/src/FakerDotNet/FakerUtils/RegexifyParsers/DitchAnchors.cs b/src/FakerDotNet/FakerUtils/RegexifyParsers/DitchAnchors.cs new file mode 100644 index 0000000..96fb5fb --- /dev/null +++ b/src/FakerDotNet/FakerUtils/RegexifyParsers/DitchAnchors.cs @@ -0,0 +1,15 @@ +using System.Text.RegularExpressions; + +namespace FakerDotNet.FakerUtils.RegexifyParsers +{ + internal class DitchAnchors : IRegexifyParser + { + public string Run(string pattern) + { + var result = pattern; + result = Regex.Replace(result, @"^\/?\^?", ""); + result = Regex.Replace(result, @"\$\/?$", ""); + return result; + } + } +} diff --git a/src/FakerDotNet/FakerUtils/RegexifyParsers/IRegexifyParser.cs b/src/FakerDotNet/FakerUtils/RegexifyParsers/IRegexifyParser.cs new file mode 100644 index 0000000..9425be1 --- /dev/null +++ b/src/FakerDotNet/FakerUtils/RegexifyParsers/IRegexifyParser.cs @@ -0,0 +1,7 @@ +namespace FakerDotNet.FakerUtils.RegexifyParsers +{ + internal interface IRegexifyParser + { + string Run(string pattern); + } +} diff --git a/src/FakerDotNet/FakerUtils/RegexifyParsers/NumberPatternToRange.cs b/src/FakerDotNet/FakerUtils/RegexifyParsers/NumberPatternToRange.cs new file mode 100644 index 0000000..f00ffce --- /dev/null +++ b/src/FakerDotNet/FakerUtils/RegexifyParsers/NumberPatternToRange.cs @@ -0,0 +1,16 @@ +using System.Text.RegularExpressions; + +namespace FakerDotNet.FakerUtils.RegexifyParsers +{ + internal class NumberPatternToRange : IRegexifyParser + { + public string Run(string pattern) + { + var result = pattern; + result = Regex.Replace(result, @"\{(\d+)\}", + m => $@"{{{m.Groups[1].Value},{m.Groups[1].Value}}}"); // All {2} become {2,2} + result = Regex.Replace(result, @"\?", "{0,1}"); // All ? become {0,1} + return result; + } + } +} diff --git a/src/FakerDotNet/FakerUtils/RegexifyParsers/ParseLetters.cs b/src/FakerDotNet/FakerUtils/RegexifyParsers/ParseLetters.cs new file mode 100644 index 0000000..4f4329d --- /dev/null +++ b/src/FakerDotNet/FakerUtils/RegexifyParsers/ParseLetters.cs @@ -0,0 +1,19 @@ +using System.Text.RegularExpressions; + +namespace FakerDotNet.FakerUtils.RegexifyParsers +{ + internal class ParseLetters : IRegexifyParser + { + private readonly IFakerContainer _fakerContainer; + + public ParseLetters(IFakerContainer fakerContainer) + { + _fakerContainer = fakerContainer; + } + + public string Run(string pattern) + { + return Regex.Replace(pattern, @"\\w", _ => _fakerContainer.Lorem.Character()); + } + } +} diff --git a/src/FakerDotNet/FakerUtils/RegexifyParsers/ParseNumbers.cs b/src/FakerDotNet/FakerUtils/RegexifyParsers/ParseNumbers.cs new file mode 100644 index 0000000..a92440e --- /dev/null +++ b/src/FakerDotNet/FakerUtils/RegexifyParsers/ParseNumbers.cs @@ -0,0 +1,19 @@ +using System.Text.RegularExpressions; + +namespace FakerDotNet.FakerUtils.RegexifyParsers +{ + internal class ParseNumbers : IRegexifyParser + { + private readonly IFakerContainer _fakerContainer; + + public ParseNumbers(IFakerContainer fakerContainer) + { + _fakerContainer = fakerContainer; + } + + public string Run(string pattern) + { + return Regex.Replace(pattern, @"\\d", _ => _fakerContainer.Number.Digit()); + } + } +} diff --git a/src/FakerDotNet/FakerUtils/RegexifyParsers/ParseRanges.cs b/src/FakerDotNet/FakerUtils/RegexifyParsers/ParseRanges.cs new file mode 100644 index 0000000..1c9ee94 --- /dev/null +++ b/src/FakerDotNet/FakerUtils/RegexifyParsers/ParseRanges.cs @@ -0,0 +1,55 @@ +using System.Linq; +using System.Text.RegularExpressions; + +namespace FakerDotNet.FakerUtils.RegexifyParsers +{ + internal class ParseRanges : IRegexifyParser + { + private readonly IFakerContainer _fakerContainer; + + public ParseRanges(IFakerContainer fakerContainer) + { + _fakerContainer = fakerContainer; + } + + public string Run(string pattern) + { + var rangeEvaluator = GetRangeEvaluator(); + var copyEvaluator = GetCopyEvaluator(); + + var result = pattern; + result = Regex.Replace(result, @"(\[[^\]]+\])\{(\d+),(\d+)\}", rangeEvaluator); // [12]{1,2} becomes [12] or [12][12] + result = Regex.Replace(result, @"(\([^\)]+\))\{(\d+),(\d+)\}", rangeEvaluator); // (12|34){1,2} becomes (12|34) or (12|34)(12|34) + result = Regex.Replace(result, @"(\\?.)\{(\d+),(\d+)\}", rangeEvaluator); // A{1,2} becomes A or AA + result = Regex.Replace(result, @"(\\?.)\{(\d+)\}", copyEvaluator); // \d{3} becomes \d\d\d + return result; + } + + private MatchEvaluator GetRangeEvaluator() + { + return m => + { + var value = m.Groups[1].Value; + var min = int.Parse(m.Groups[2].Value); + var max = int.Parse(m.Groups[3].Value); + var values = Enumerable + .Range(0, (int) _fakerContainer.Number.Between(min, max)) + .Select(_ => value); + return string.Join("", values); + }; + } + + private static MatchEvaluator GetCopyEvaluator() + { + return m => + { + var value = m.Groups[1].Value; + var count = int.Parse(m.Groups[2].Value); + var values = Enumerable + .Range(0, count) + .Select(_ => value); + return string.Join("", values); + }; + } + } +} diff --git a/src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfLettersWithLetter.cs b/src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfLettersWithLetter.cs new file mode 100644 index 0000000..cb2ed7d --- /dev/null +++ b/src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfLettersWithLetter.cs @@ -0,0 +1,24 @@ +using System.Text.RegularExpressions; +using FakerDotNet.Extensions; + +namespace FakerDotNet.FakerUtils.RegexifyParsers +{ + internal class ReplaceOneOfLettersWithLetter : IRegexifyParser + { + private readonly IFakerContainer _fakerContainer; + + public ReplaceOneOfLettersWithLetter(IFakerContainer fakerContainer) + { + _fakerContainer = fakerContainer; + } + + public string Run(string pattern) + { + return Regex.Replace(pattern, @"\[([^\]]+)\]", m => + { + var elements = m.Groups[1].Value.Characters(); + return _fakerContainer.Random.Element(elements); + }); // All [ABC] become B (or A or C) + } + } +} diff --git a/src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfRangeWithLetter.cs b/src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfRangeWithLetter.cs new file mode 100644 index 0000000..b26308b --- /dev/null +++ b/src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfRangeWithLetter.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +namespace FakerDotNet.FakerUtils.RegexifyParsers +{ + internal class ReplaceOneOfRangeWithLetter : IRegexifyParser + { + private readonly IFakerContainer _fakerContainer; + + public ReplaceOneOfRangeWithLetter(IFakerContainer fakerContainer) + { + _fakerContainer = fakerContainer; + } + + public string Run(string pattern) + { + return Regex.Replace(pattern, @"\[([^\]]+)\]", m => + { + return Regex.Replace(m.Value, @"(\w\-\w)", range => + { + var v = range.Value.Split('-'); + var min = v[0]; + var max = v[1]; + var elements = BuildRange(min, max); + return _fakerContainer.Random.Element(elements); + }); + }); // All A-Z inside of [] become C (or X, or whatever) + } + + private static IEnumerable BuildRange(string min, string max) + { + var minChar = char.Parse(min); + var maxChar = char.Parse(max); + return Enumerable.Range(minChar, maxChar - minChar + 1) + .Select(c => new string((char) c, 1)) + .ToArray(); + } + } +} diff --git a/src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfWordsWithWord.cs b/src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfWordsWithWord.cs new file mode 100644 index 0000000..08217f2 --- /dev/null +++ b/src/FakerDotNet/FakerUtils/RegexifyParsers/ReplaceOneOfWordsWithWord.cs @@ -0,0 +1,23 @@ +using System.Text.RegularExpressions; + +namespace FakerDotNet.FakerUtils.RegexifyParsers +{ + internal class ReplaceOneOfWordsWithWord : IRegexifyParser + { + private readonly IFakerContainer _fakerContainer; + + public ReplaceOneOfWordsWithWord(IFakerContainer fakerContainer) + { + _fakerContainer = fakerContainer; + } + + public string Run(string pattern) + { + return Regex.Replace(pattern, @"\((.*?)\)", m => + { + var elements = Regex.Replace(m.Value, @"[\(\)]", "").Split('|'); + return _fakerContainer.Random.Element(elements); // (this|that) becomes 'this' or 'that' + }); + } + } +} diff --git a/src/FakerDotNet/Fakers/BankFaker.cs b/src/FakerDotNet/Fakers/BankFaker.cs new file mode 100644 index 0000000..5b52f90 --- /dev/null +++ b/src/FakerDotNet/Fakers/BankFaker.cs @@ -0,0 +1,70 @@ +using System; +using System.Linq; +using System.Numerics; +using FakerDotNet.Data; +using FakerDotNet.Extensions; + +namespace FakerDotNet.Fakers +{ + public interface IBankFaker + { + string AccountNumber(int digits = 10); + string Iban(string countryCode = "GB"); + string Name(); + string SwiftBic(); + } + + internal class BankFaker : IBankFaker + { + private readonly IFakerContainer _fakerContainer; + + public BankFaker(IFakerContainer fakerContainer) + { + _fakerContainer = fakerContainer; + } + + public string AccountNumber(int digits = 10) + { + return string.Join("", Enumerable.Range(0, digits).Select(_ => _fakerContainer.Number.Digit())); + } + + public string Iban(string countryCode = "GB") + { + var key = (countryCode ?? "").ToLowerInvariant(); + + if (countryCode == null || !BankData.IbanDetails.ContainsKey(key)) + { + throw new ArgumentException($"Could not find iban details for {countryCode}"); + } + + var (_, pattern) = BankData.IbanDetails[key]; + var account = _fakerContainer.Regexify.Parse(pattern); + var checksum = IbanChecksum(countryCode, account); + + return $"{countryCode.ToUpperInvariant()}{checksum}{account}"; + } + + public string Name() + { + return _fakerContainer.Random.Element(BankData.Names); + } + + public string SwiftBic() + { + return _fakerContainer.Random.Element(BankData.SwiftBics); + } + + private static string IbanChecksum(string countryCode, string account) + { + var accountToNumberValues = $"{account}{countryCode}00" + .ToUpperInvariant() + .Characters() + .Select(c => char.IsLetter(c, 0) ? char.Parse(c) - 55 : int.Parse(c)) + .ToArray(); + var accountToNumber = BigInteger.Parse(string.Join("", accountToNumberValues)); + var checksum = 98 - (accountToNumber % 97); + var result = checksum.ToString().PadLeft(2, '0'); + return result; + } + } +} diff --git a/tests/FakerDotNet.Tests/FakerContainerTests.cs b/tests/FakerDotNet.Tests/FakerContainerTests.cs index 7a8998c..948dc02 100644 --- a/tests/FakerDotNet.Tests/FakerContainerTests.cs +++ b/tests/FakerDotNet.Tests/FakerContainerTests.cs @@ -1,4 +1,5 @@ using FakerDotNet.Fakers; +using FakerDotNet.FakerUtils; using NUnit.Framework; namespace FakerDotNet.Tests @@ -39,6 +40,12 @@ public void Avatar_returns_IAvatarFaker() Assert.IsInstanceOf(_fakerContainer.Avatar); } + [Test] + public void Bank_returns_IBankFaker() + { + Assert.IsInstanceOf(_fakerContainer.Bank); + } + [Test] public void Beer_returns_IBeerFaker() { @@ -344,5 +351,11 @@ public void Zelda_returns_IZeldaFaker() { Assert.IsInstanceOf(_fakerContainer.Zelda); } + + [Test] + public void Regexify_returns_IRegexify() + { + Assert.IsInstanceOf(_fakerContainer.Regexify); + } } } diff --git a/tests/FakerDotNet.Tests/FakerDotNet.Tests.csproj b/tests/FakerDotNet.Tests/FakerDotNet.Tests.csproj index 8474473..4300501 100644 --- a/tests/FakerDotNet.Tests/FakerDotNet.Tests.csproj +++ b/tests/FakerDotNet.Tests/FakerDotNet.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.0 @@ -7,6 +7,7 @@ + diff --git a/tests/FakerDotNet.Tests/FakerTests.cs b/tests/FakerDotNet.Tests/FakerTests.cs index df35245..14ff2d0 100644 --- a/tests/FakerDotNet.Tests/FakerTests.cs +++ b/tests/FakerDotNet.Tests/FakerTests.cs @@ -31,6 +31,12 @@ public void Avatar_returns_IAvatarFaker() Assert.IsInstanceOf(Faker.Avatar); } + [Test] + public void Bank_returns_IBankFaker() + { + Assert.IsInstanceOf(Faker.Bank); + } + [Test] public void Beer_returns_IBeerFaker() { diff --git a/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/DitchAnchorsTests.cs b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/DitchAnchorsTests.cs new file mode 100644 index 0000000..4add90c --- /dev/null +++ b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/DitchAnchorsTests.cs @@ -0,0 +1,42 @@ +using FakerDotNet.FakerUtils.RegexifyParsers; +using NUnit.Framework; + +namespace FakerDotNet.Tests.FakerUtils.RegexifyParsers +{ + [TestFixture] + [Parallelizable] + public class DitchAnchorsTests + { + [SetUp] + public void SetUp() + { + _parser = new DitchAnchors(); + } + + private IRegexifyParser _parser; + + [Test] + public void Run_removes_both_start_and_end_anchors() + { + const string pattern = @"^hello$"; + + Assert.AreEqual(@"hello", _parser.Run(pattern)); + } + + [Test] + public void Run_removes_end_anchor() + { + const string pattern = @"hello$"; + + Assert.AreEqual(@"hello", _parser.Run(pattern)); + } + + [Test] + public void Run_removes_start_anchor() + { + const string pattern = @"^hello"; + + Assert.AreEqual(@"hello", _parser.Run(pattern)); + } + } +} \ No newline at end of file diff --git a/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/NumberPatternToRangeTests.cs b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/NumberPatternToRangeTests.cs new file mode 100644 index 0000000..f7586fb --- /dev/null +++ b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/NumberPatternToRangeTests.cs @@ -0,0 +1,34 @@ +using FakerDotNet.FakerUtils.RegexifyParsers; +using NUnit.Framework; + +namespace FakerDotNet.Tests.FakerUtils.RegexifyParsers +{ + [TestFixture] + [Parallelizable] + public class NumberPatternToRangeTests + { + [SetUp] + public void SetUp() + { + _parser = new NumberPatternToRange(); + } + + private IRegexifyParser _parser; + + [Test] + public void Run_turns_numbers_surrounded_by_curly_braces_into_number_range() + { + const string pattern = @"{2}"; + + Assert.AreEqual(@"{2,2}", _parser.Run(pattern)); + } + + [Test] + public void Run_turns_question_mark_into_number_range() + { + const string pattern = @"?"; + + Assert.AreEqual(@"{0,1}", _parser.Run(pattern)); + } + } +} \ No newline at end of file diff --git a/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseLettersTests.cs b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseLettersTests.cs new file mode 100644 index 0000000..ddd46ce --- /dev/null +++ b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseLettersTests.cs @@ -0,0 +1,54 @@ +using FakeItEasy; +using FakerDotNet.FakerUtils.RegexifyParsers; +using NUnit.Framework; + +namespace FakerDotNet.Tests.FakerUtils.RegexifyParsers +{ + [TestFixture] + [Parallelizable] + public class ParseLettersTests + { + [SetUp] + public void SetUp() + { + _fakerContainer = A.Fake(); + _parser = new ParseLetters(_fakerContainer); + } + + private IFakerContainer _fakerContainer; + private IRegexifyParser _parser; + + [Test] + public void Run_only_parses_letter_regex() + { + const string pattern = @"ABC \w\w\w-\w"; + + A.CallTo(() => _fakerContainer.Lorem.Character()) + .ReturnsNextFromSequence("f", "e", "d", "a"); + + Assert.AreEqual(@"ABC fed-a", _parser.Run(pattern)); + } + + [Test] + public void Run_returns_a_letter_when_pattern_contains_letter_regex() + { + const string pattern = @"\w"; + + A.CallTo(() => _fakerContainer.Lorem.Character()) + .Returns("x"); + + Assert.AreEqual(@"x", _parser.Run(pattern)); + } + + [Test] + public void Run_returns_multiple_letters_for_all_letter_regex() + { + const string pattern = @"\w\w \w \w\w\w"; + + A.CallTo(() => _fakerContainer.Lorem.Character()) + .ReturnsNextFromSequence("j", "s", "x", "b", "e", "f"); + + Assert.AreEqual(@"js x bef", _parser.Run(pattern)); + } + } +} \ No newline at end of file diff --git a/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseNumbersTests.cs b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseNumbersTests.cs new file mode 100644 index 0000000..041e192 --- /dev/null +++ b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseNumbersTests.cs @@ -0,0 +1,54 @@ +using FakeItEasy; +using FakerDotNet.FakerUtils.RegexifyParsers; +using NUnit.Framework; + +namespace FakerDotNet.Tests.FakerUtils.RegexifyParsers +{ + [TestFixture] + [Parallelizable] + public class ParseNumbersTests + { + [SetUp] + public void SetUp() + { + _fakerContainer = A.Fake(); + _parser = new ParseNumbers(_fakerContainer); + } + + private IFakerContainer _fakerContainer; + private IRegexifyParser _parser; + + [Test] + public void Run_only_parses_number_regex() + { + const string pattern = @"John Smith is \d\d years old"; + + A.CallTo(() => _fakerContainer.Number.Digit()) + .ReturnsNextFromSequence("5", "4"); + + Assert.AreEqual(@"John Smith is 54 years old", _parser.Run(pattern)); + } + + [Test] + public void Run_returns_a_number_when_pattern_contains_number_regex() + { + const string pattern = @"\d"; + + A.CallTo(() => _fakerContainer.Number.Digit()) + .Returns("2"); + + Assert.AreEqual(@"2", _parser.Run(pattern)); + } + + [Test] + public void Run_returns_multiple_numbers_for_all_number_regex() + { + const string pattern = @"\d\d \d \d\d\d"; + + A.CallTo(() => _fakerContainer.Number.Digit()) + .ReturnsNextFromSequence("2", "4", "1", "3", "2", "6"); + + Assert.AreEqual(@"24 1 326", _parser.Run(pattern)); + } + } +} \ No newline at end of file diff --git a/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseRangesTests.cs b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseRangesTests.cs new file mode 100644 index 0000000..9a5471c --- /dev/null +++ b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ParseRangesTests.cs @@ -0,0 +1,73 @@ +using FakeItEasy; +using FakerDotNet.FakerUtils.RegexifyParsers; +using NUnit.Framework; + +namespace FakerDotNet.Tests.FakerUtils.RegexifyParsers +{ + [TestFixture] + [Parallelizable] + public class ParseRangesTests + { + [SetUp] + public void SetUp() + { + _fakerContainer = A.Fake(); + _parser = new ParseRanges(_fakerContainer); + } + + private IFakerContainer _fakerContainer; + private IRegexifyParser _parser; + + [Test] + public void Run_returns_copies_of_character_within_specified_range_in_regex() + { + const string pattern = @"A{1,2}"; + + A.CallTo(() => _fakerContainer.Number.Between(1, 2)) + .Returns(2); + + Assert.AreEqual("AA", _parser.Run(pattern)); + } + + [Test] + public void Run_returns_copies_of_number_pattern_a_specified_number_of_times() + { + const string pattern = @"\d{3}"; + + Assert.AreEqual(@"\d\d\d", _parser.Run(pattern)); + } + + [Test] + public void Run_returns_copies_of_number_pattern_within_specified_range_in_regex() + { + const string pattern = @"\d{1,3}"; + + A.CallTo(() => _fakerContainer.Number.Between(1, 3)) + .Returns(3); + + Assert.AreEqual(@"\d\d\d", _parser.Run(pattern)); + } + + [Test] + public void Run_returns_duplicates_of_parenthesis_within_specified_range_in_regex() + { + const string pattern = @"(12|34){1,2}"; + + A.CallTo(() => _fakerContainer.Number.Between(1, 2)) + .Returns(2); + + Assert.AreEqual(@"(12|34)(12|34)", _parser.Run(pattern)); + } + + [Test] + public void Run_returns_duplicates_of_square_brackets_within_specified_range_in_regex() + { + const string pattern = @"[12]{1,2}"; + + A.CallTo(() => _fakerContainer.Number.Between(1, 2)) + .Returns(2); + + Assert.AreEqual(@"[12][12]", _parser.Run(pattern)); + } + } +} \ No newline at end of file diff --git a/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfLettersWithLetterTests.cs b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfLettersWithLetterTests.cs new file mode 100644 index 0000000..454c980 --- /dev/null +++ b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfLettersWithLetterTests.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using FakeItEasy; +using FakerDotNet.FakerUtils.RegexifyParsers; +using NUnit.Framework; + +namespace FakerDotNet.Tests.FakerUtils.RegexifyParsers +{ + [TestFixture] + [Parallelizable] + public class ReplaceOneOfLettersWithLetterTests + { + [SetUp] + public void SetUp() + { + _fakerContainer = A.Fake(); + _parser = new ReplaceOneOfLettersWithLetter(_fakerContainer); + } + + private IFakerContainer _fakerContainer; + private IRegexifyParser _parser; + + [Test] + public void Run_returns_item_from_between_square_brackets() + { + const string pattern = @"[ABC]"; + + A.CallTo(() => _fakerContainer.Random.Element( + A>.That.IsSameSequenceAs("A", "B", "C"))) + .Returns("B"); + + Assert.AreEqual(@"B", _parser.Run(pattern)); + } + } +} \ No newline at end of file diff --git a/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfRangeWithLetterTests.cs b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfRangeWithLetterTests.cs new file mode 100644 index 0000000..a8fb012 --- /dev/null +++ b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfRangeWithLetterTests.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using FakeItEasy; +using FakerDotNet.FakerUtils.RegexifyParsers; +using NUnit.Framework; + +namespace FakerDotNet.Tests.FakerUtils.RegexifyParsers +{ + [TestFixture] + [Parallelizable] + public class ReplaceOneOfRangeWithLetterTests + { + [SetUp] + public void SetUp() + { + _fakerContainer = A.Fake(); + _parser = new ReplaceOneOfRangeWithLetter(_fakerContainer); + } + + private IFakerContainer _fakerContainer; + private IRegexifyParser _parser; + + [Test] + public void Run_returns_a_character_from_the_range_between_square_brackets() + { + const string pattern = @"[A-F]"; + + A.CallTo(() => _fakerContainer.Random.Element( + A>.That.IsSameSequenceAs("A", "B", "C", "D", "E", "F"))) + .Returns("E"); + + Assert.AreEqual(@"[E]", _parser.Run(pattern)); + } + + [Test] + public void Run_returns_characters_from_multiple_ranges_between_square_brackets() + { + const string pattern = @"[A-FK-P0-9]"; + + A.CallTo(() => _fakerContainer.Random.Element( + A>.That.IsSameSequenceAs("A", "B", "C", "D", "E", "F"))) + .Returns("C"); + A.CallTo(() => _fakerContainer.Random.Element( + A>.That.IsSameSequenceAs("K", "L", "M", "N", "O", "P"))) + .Returns("M"); + A.CallTo(() => _fakerContainer.Random.Element( + A>.That.IsSameSequenceAs("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"))) + .Returns("4"); + + Assert.AreEqual(@"[CM4]", _parser.Run(pattern)); + } + } +} \ No newline at end of file diff --git a/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfWordsWithWordTests.cs b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfWordsWithWordTests.cs new file mode 100644 index 0000000..5576be2 --- /dev/null +++ b/tests/FakerDotNet.Tests/FakerUtils/RegexifyParsers/ReplaceOneOfWordsWithWordTests.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using FakeItEasy; +using FakerDotNet.FakerUtils.RegexifyParsers; +using NUnit.Framework; + +namespace FakerDotNet.Tests.FakerUtils.RegexifyParsers +{ + [TestFixture] + [Parallelizable] + public class ReplaceOneOfWordsWithWordTests + { + [SetUp] + public void SetUp() + { + _fakerContainer = A.Fake(); + _parser = new ReplaceOneOfWordsWithWord(_fakerContainer); + } + + private IFakerContainer _fakerContainer; + private IRegexifyParser _parser; + + [Test] + public void Run_returns_a_word_from_the_words_between_the_parenthesis() + { + const string pattern = @"(this|that)"; + + A.CallTo(() => _fakerContainer.Random.Element( + A>.That.IsSameSequenceAs("this", "that"))) + .Returns("that"); + + Assert.AreEqual(@"that", _parser.Run(pattern)); + } + } +} \ No newline at end of file diff --git a/tests/FakerDotNet.Tests/FakerUtils/RegexifyTests.cs b/tests/FakerDotNet.Tests/FakerUtils/RegexifyTests.cs new file mode 100644 index 0000000..2712494 --- /dev/null +++ b/tests/FakerDotNet.Tests/FakerUtils/RegexifyTests.cs @@ -0,0 +1,46 @@ +using System.Text.RegularExpressions; +using FakerDotNet.FakerUtils; +using NUnit.Framework; + +namespace FakerDotNet.Tests.FakerUtils +{ + [TestFixture] + [Parallelizable] + public class RegexifyTests + { + [SetUp] + public void SetUp() + { + _fakerContainer = new FakerContainer(); + _regexify = new Regexify(_fakerContainer); + } + + private IFakerContainer _fakerContainer; + private IRegexify _regexify; + + [Test] + public void Parse_returns_empty_string_when_pattern_is_null() + { + const string pattern = null; + + Assert.AreEqual("", _regexify.Parse(pattern)); + } + + [Test] + public void Parse_returns_empty_string_when_pattern_is_an_empty_string() + { + const string pattern = ""; + + Assert.AreEqual("", _regexify.Parse(pattern)); + } + + [Test] + public void Parse_returns_a_string_from_a_pattern() + { + const string pattern = + @"^[A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}$"; + + Assert.That(Regex.IsMatch(_regexify.Parse(pattern), pattern)); + } + } +} diff --git a/tests/FakerDotNet.Tests/Fakers/BankFakerTests.cs b/tests/FakerDotNet.Tests/Fakers/BankFakerTests.cs new file mode 100644 index 0000000..fddb48a --- /dev/null +++ b/tests/FakerDotNet.Tests/Fakers/BankFakerTests.cs @@ -0,0 +1,80 @@ +using FakeItEasy; +using FakerDotNet.Data; +using FakerDotNet.Fakers; +using NUnit.Framework; + +namespace FakerDotNet.Tests.Fakers +{ + [TestFixture] + [Parallelizable] + public class BankFakerTests + { + [SetUp] + public void SetUp() + { + _fakerContainer = A.Fake(); + _bankFaker = new BankFaker(_fakerContainer); + } + + private IFakerContainer _fakerContainer; + private IBankFaker _bankFaker; + + [Test] + public void AccountNumber_returns_an_account_number() + { + A.CallTo(() => _fakerContainer.Number.Digit()) + .ReturnsNextFromSequence("6", "7", "3", "8", "5", "8", "2", "3", "7", "9"); + + Assert.AreEqual("6738582379", _bankFaker.AccountNumber()); + } + + [Test] + public void AccountNumber_with_digits_returns_an_account_number() + { + A.CallTo(() => _fakerContainer.Number.Digit()) + .ReturnsNextFromSequence("6", "7", "3", "8", "5", "8", "2", "3", "7", "9", "0", "2"); + + Assert.AreEqual("673858237902", _bankFaker.AccountNumber(13)); + } + + [Test] + public void Iban_returns_an_iban() + { + var ibanDetails = BankData.IbanDetails["gb"]; + + A.CallTo(() => _fakerContainer.Regexify.Parse(ibanDetails.pattern)) + .Returns("DZJM33188515981979"); + + Assert.AreEqual("GB19DZJM33188515981979", _bankFaker.Iban()); + } + + [Test] + public void Iban_with_country_code_returns_an_iban() + { + var ibanDetails = BankData.IbanDetails["be"]; + + A.CallTo(() => _fakerContainer.Regexify.Parse(ibanDetails.pattern)) + .Returns("75388567752043"); + + Assert.AreEqual("BE8975388567752043", _bankFaker.Iban("be")); + } + + [Test] + public void Name_returns_a_name() + { + A.CallTo(() => _fakerContainer.Random.Element(BankData.Names)) + .Returns("ABN AMRO CORPORATE FINANCE LIMITED"); + + Assert.AreEqual("ABN AMRO CORPORATE FINANCE LIMITED", _bankFaker.Name()); + } + + [Test] + public void SwiftBic_returns_a_swift_bic() + { + A.CallTo(() => _fakerContainer.Random.Element(BankData.SwiftBics)) + .Returns("AAFMGB21"); + + Assert.AreEqual("AAFMGB21", _bankFaker.SwiftBic()); + } + } +}