tests/PSFaker.Tests.ps1
|
#Requires -Module Pester <# .SYNOPSIS PSFaker full test suite – targets 100% function coverage. Run with: Invoke-Pester -Path ./tests/PSFaker.Tests.ps1 -Output Detailed #> BeforeAll { $modulePath = Join-Path $PSScriptRoot '..' $modulePath = Join-Path $modulePath 'PSFaker.psm1' Import-Module $modulePath -Force # Seed for reproducibility in assertions that need it New-Faker -Seed 42 } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'New-Faker / Factory' { It 'creates a seeded generator without error' { { New-Faker -Seed 1234 } | Should -Not -Throw } It 'creates an unseeded generator without error' { { New-Faker } | Should -Not -Throw } It 'creates generator with locale parameter' { { New-Faker -Locale 'en_US' } | Should -Not -Throw } It 'produces same output when same seed is used twice' { New-Faker -Seed 99 $a = Get-FakeFirstName New-Faker -Seed 99 $b = Get-FakeFirstName $a | Should -Be $b } It 'resets unique cache on New-Faker call' { New-Faker -Seed 1 Reset-FakeUnique New-Faker -Seed 1 $script:UniqueCache.Count | Should -Be 0 } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Base – random primitives' { BeforeAll { New-Faker -Seed 1 } It 'Get-FakeRandomDigit returns 0-9' { 1..20 | ForEach-Object { Get-FakeRandomDigit } | ForEach-Object { $_ | Should -BeIn (0..9) } } It 'Get-FakeRandomDigitNotNull returns 1-9' { 1..20 | ForEach-Object { Get-FakeRandomDigitNotNull } | ForEach-Object { $_ | Should -BeIn (1..9) } } It 'Get-FakeRandomDigitNot never returns the excluded digit' { 1..30 | ForEach-Object { Get-FakeRandomDigitNot -Excluded 5 } | ForEach-Object { $_ | Should -Not -Be 5 } } It 'Get-FakeRandomDigitNot returns valid digits' { 1..20 | ForEach-Object { Get-FakeRandomDigitNot -Excluded 0 } | ForEach-Object { $_ | Should -BeIn (1..9) } } It 'Get-FakeRandomNumber returns an integer' { $n = Get-FakeRandomNumber $n | Should -BeOfType [int] } It 'Get-FakeRandomNumber with NbDigits returns correct digit count' { $n = Get-FakeRandomNumber -NbDigits 4 $n.ToString().Length | Should -BeLessOrEqual 4 } It 'Get-FakeRandomNumber with Strict=true has no leading zero for NbDigits=3' { 1..10 | ForEach-Object { Get-FakeRandomNumber -NbDigits 3 -Strict $true } | ForEach-Object { $_ | Should -BeGreaterOrEqual 100 } } It 'Get-FakeRandomFloat returns a float' { $f = Get-FakeRandomFloat $f | Should -BeOfType [double] } It 'Get-FakeRandomFloat respects Min and Max' { 1..20 | ForEach-Object { Get-FakeRandomFloat -Min 10 -Max 20 } | ForEach-Object { $_ | Should -BeGreaterOrEqual 10; $_ | Should -BeLessOrEqual 20 } } It 'Get-FakeRandomFloat respects NbMaxDecimals' { $f = Get-FakeRandomFloat -NbMaxDecimals 2 -Min 0 -Max 100 $str = $f.ToString() if ($str -match '\.') { ($str -split '\.')[1].Length | Should -BeLessOrEqual 2 } $true | Should -Be $true # no exception } It 'Get-FakeNumberBetween returns in range' { 1..20 | ForEach-Object { Get-FakeNumberBetween -Min 5 -Max 10 } | ForEach-Object { $_ | Should -BeGreaterOrEqual 5; $_ | Should -BeLessOrEqual 10 } } It 'Get-FakeNumberBetween defaults work' { $n = Get-FakeNumberBetween $n | Should -BeGreaterOrEqual 1000 $n | Should -BeLessOrEqual 9000 } It 'Get-FakeRandomLetter returns lowercase a-z' { 1..20 | ForEach-Object { Get-FakeRandomLetter } | ForEach-Object { $_ | Should -Match '^[a-z]$' } } It 'Get-FakeRandomElement picks from array' { $arr = @(1,2,3,4,5) 1..20 | ForEach-Object { Get-FakeRandomElement $arr } | ForEach-Object { $_ | Should -BeIn $arr } } It 'Get-FakeRandomElements returns correct count' { $arr = @('a','b','c','d','e') $result = Get-FakeRandomElements -Array $arr -Count 3 $result.Count | Should -Be 3 } It 'Get-FakeRandomElements picks from source array' { $arr = @('x','y','z') Get-FakeRandomElements -Array $arr -Count 5 | ForEach-Object { $_ | Should -BeIn $arr } } It 'Invoke-FakeShuffle shuffles a string' { $orig = 'hello' $shuf = Invoke-FakeShuffle 'hello' $shuf.Length | Should -Be 5 $source = ($shuf.ToCharArray() | Sort-Object) -join '' $dest = ($orig.ToCharArray() | Sort-Object) -join '' $source | Should -Be $dest } It 'Invoke-FakeShuffle shuffles an array' { $arr = @(1,2,3,4,5) $shuf = Invoke-FakeShuffle $arr $shuf.Count | Should -Be 5 $shuf | Sort-Object | Should -Be ($arr | Sort-Object) } It 'Format-FakeNumerify replaces # with digits' { $result = Format-FakeNumerify 'ABC-###-XY' $result | Should -Match '^ABC-\d{3}-XY$' } It 'Format-FakeLexify replaces ? with letters' { $result = Format-FakeLexify 'Hi-???' $result | Should -Match '^Hi-[a-z]{3}$' } It 'Format-FakeBothify replaces both # and ?' { $result = Format-FakeBothify '##??' $result | Should -Match '^\d{2}[a-z]{2}$' } It 'Format-FakeAsciify replaces * with printable ASCII' { $result = Format-FakeAsciify '***' $result.Length | Should -Be 3 $result.ToCharArray() | ForEach-Object { [int]$_ | Should -BeGreaterOrEqual 33 [int]$_ | Should -BeLessOrEqual 126 } } It 'Format-FakeRegexify produces a string' { $result = Format-FakeRegexify '[A-Z]{3}\d{2}' $result | Should -Not -BeNullOrEmpty $result | Should -BeOfType [string] } It 'Format-FakeRegexify with alternation produces one of the options' { 1..10 | ForEach-Object { Format-FakeRegexify '(yes|no)' } | ForEach-Object { $_ | Should -BeIn @('yes','no') } } It 'Format-FakeRegexify ? quantifier produces 0 or 1 char' { 1..10 | ForEach-Object { $r = Format-FakeRegexify 'a?' $r.Length | Should -BeIn (0,1) } } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Lorem' { BeforeAll { New-Faker -Seed 2 } It 'Get-FakeWord returns a non-empty string' { Get-FakeWord | Should -Not -BeNullOrEmpty } It 'Get-FakeWords returns array of correct size' { (Get-FakeWords -Nb 5).Count | Should -Be 5 } It 'Get-FakeWords with AsText returns a string' { Get-FakeWords -Nb 3 -AsText $true | Should -BeOfType [string] } It 'Get-FakeSentence ends with a period' { Get-FakeSentence | Should -Match '\.$' } It 'Get-FakeSentence starts with uppercase' { Get-FakeSentence | Should -Match '^[A-Z]' } It 'Get-FakeSentences returns array of correct size' { (Get-FakeSentences -Nb 4).Count | Should -Be 4 } It 'Get-FakeSentences AsText joins with space' { $t = Get-FakeSentences -Nb 2 -AsText $true $t | Should -BeOfType [string] $t | Should -Match '\. ' } It 'Get-FakeParagraph is a non-empty string' { Get-FakeParagraph | Should -Not -BeNullOrEmpty } It 'Get-FakeParagraph with VariableNbSentences=false has fixed count' { $p = Get-FakeParagraph -NbSentences 2 -VariableNbSentences $false $sentences = ($p -split '(?<=\.) ' | Where-Object { $_ }) $sentences.Count | Should -Be 2 } It 'Get-FakeParagraphs returns array of correct size' { (Get-FakeParagraphs -Nb 3).Count | Should -Be 3 } It 'Get-FakeParagraphs AsText joins with double newline' { $t = Get-FakeParagraphs -Nb 2 -AsText $true $t | Should -Match "`n`n" } It 'Get-FakeText respects MaxNbChars' { 1..5 | ForEach-Object { Get-FakeText -MaxNbChars 100 } | ForEach-Object { $_.Length | Should -BeLessOrEqual 100 } } It 'Get-FakeText default is 200 chars max' { Get-FakeText | Should -Not -BeNullOrEmpty (Get-FakeText).Length | Should -BeLessOrEqual 200 } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Person' { BeforeAll { New-Faker -Seed 3 } It 'Get-FakeTitleMale returns a male title' { Get-FakeTitleMale | Should -BeIn @('Mr.','Dr.','Prof.','Rev.') } It 'Get-FakeTitleFemale returns a female title' { Get-FakeTitleFemale | Should -BeIn @('Ms.','Mrs.','Dr.','Prof.','Miss') } It 'Get-FakeTitle with no gender returns a string' { Get-FakeTitle | Should -Not -BeNullOrEmpty } It 'Get-FakeTitle male returns male title' { 1..10 | ForEach-Object { Get-FakeTitle -Gender 'male' } | ForEach-Object { $_ | Should -BeIn @('Mr.','Dr.','Prof.','Rev.') } } It 'Get-FakeTitle female returns female title' { 1..10 | ForEach-Object { Get-FakeTitle -Gender 'female' } | ForEach-Object { $_ | Should -BeIn @('Ms.','Mrs.','Dr.','Prof.','Miss') } } It 'Get-FakeFirstNameMale returns a string' { Get-FakeFirstNameMale | Should -Not -BeNullOrEmpty } It 'Get-FakeFirstNameFemale returns a string' { Get-FakeFirstNameFemale | Should -Not -BeNullOrEmpty } It 'Get-FakeFirstName with no gender returns a string' { Get-FakeFirstName | Should -Not -BeNullOrEmpty } It 'Get-FakeFirstName with gender male returns from male list' { $males = @('James','John','Robert','Michael','William','David','Richard','Joseph', 'Thomas','Charles','Christopher','Daniel','Matthew','Anthony','Mark','Donald', 'Steven','Paul','Andrew','Joshua','Kenneth','Kevin','Brian','George','Timothy', 'Ronald','Edward','Jason','Jeffrey','Ryan','Jacob','Gary','Nicholas','Eric', 'Jonathan','Stephen','Larry','Justin','Scott','Brandon','Frank','Benjamin', 'Gregory','Samuel','Raymond','Patrick','Alexander','Jack','Dennis','Jerry') 1..10 | ForEach-Object { Get-FakeFirstName -Gender 'male' } | ForEach-Object { $_ | Should -BeIn $males } } It 'Get-FakeLastName returns a string' { Get-FakeLastName | Should -Not -BeNullOrEmpty } It 'Get-FakeNameSuffix returns a suffix' { Get-FakeNameSuffix | Should -BeIn @('Jr.','Sr.','I','II','III','IV','V','DVM','DDS','PhD','MD') } It 'Get-FakeName returns a non-empty string' { Get-FakeName | Should -Not -BeNullOrEmpty } It 'Get-FakeName with gender male does not throw' { { Get-FakeName -Gender 'male' } | Should -Not -Throw } It 'Get-FakeName with gender female does not throw' { { Get-FakeName -Gender 'female' } | Should -Not -Throw } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Address' { BeforeAll { New-Faker -Seed 4 } It 'Get-FakeCityPrefix returns a prefix' { Get-FakeCityPrefix | Should -Not -BeNullOrEmpty } It 'Get-FakeCitySuffix returns a suffix' { Get-FakeCitySuffix | Should -Not -BeNullOrEmpty } It 'Get-FakeCity returns a string' { Get-FakeCity | Should -Not -BeNullOrEmpty } It 'Get-FakeState returns a US state name' { $state = Get-FakeState $state | Should -Not -BeNullOrEmpty $state | Should -BeOfType [string] } It 'Get-FakeStateAbbr returns a 2-letter abbreviation' { Get-FakeStateAbbr | Should -Match '^[A-Z]{2}$' } It 'Get-FakeCountry returns a country name' { Get-FakeCountry | Should -Not -BeNullOrEmpty } It 'Get-FakeBuildingNumber returns a numeric string' { Get-FakeBuildingNumber | Should -Match '^\d+$' } It 'Get-FakeStreetName returns a string' { Get-FakeStreetName | Should -Not -BeNullOrEmpty } It 'Get-FakeSecondaryAddress returns Suite or Apt' { Get-FakeSecondaryAddress | Should -Match '^(Suite|Apt\.) \d+$' } It 'Get-FakeStreetAddress returns a string' { Get-FakeStreetAddress | Should -Not -BeNullOrEmpty } It 'Get-FakePostcode returns a valid US zip format' { Get-FakePostcode | Should -Match '^\d{5}(-\d{4})?$' } It 'Get-FakeAddress returns a formatted address' { $addr = Get-FakeAddress $addr | Should -Not -BeNullOrEmpty $addr | Should -Match ',' } It 'Get-FakeLatitude is in -90..90' { 1..10 | ForEach-Object { Get-FakeLatitude } | ForEach-Object { $_ | Should -BeGreaterOrEqual -90 $_ | Should -BeLessOrEqual 90 } } It 'Get-FakeLatitude respects custom min/max' { 1..10 | ForEach-Object { Get-FakeLatitude -Min 40 -Max 50 } | ForEach-Object { $_ | Should -BeGreaterOrEqual 40 $_ | Should -BeLessOrEqual 50 } } It 'Get-FakeLongitude is in -180..180' { 1..10 | ForEach-Object { Get-FakeLongitude } | ForEach-Object { $_ | Should -BeGreaterOrEqual -180 $_ | Should -BeLessOrEqual 180 } } It 'Get-FakeLongitude respects custom min/max' { 1..10 | ForEach-Object { Get-FakeLongitude -Min 0 -Max 10 } | ForEach-Object { $_ | Should -BeGreaterOrEqual 0 $_ | Should -BeLessOrEqual 10 } } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'PhoneNumber' { BeforeAll { New-Faker -Seed 5 } It 'Get-FakePhoneNumber returns digits and separators' { Get-FakePhoneNumber | Should -Match '[\d\s\-\.\(\)x]+' } It 'Get-FakeTollFreePhoneNumber starts with toll-free area code' { Get-FakeTollFreePhoneNumber | Should -Match '^\((800|888|877|866|855|844|833)\)' } It 'Get-FakeE164PhoneNumber starts with +' { Get-FakeE164PhoneNumber | Should -Match '^\+' } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Company' { BeforeAll { New-Faker -Seed 6 } It 'Get-FakeCompanySuffix returns a known suffix' { Get-FakeCompanySuffix | Should -BeIn @('LLC','Inc.','Ltd.','Corp.','and Sons','Group','Partners','Associates') } It 'Get-FakeCompany returns a non-empty string' { Get-FakeCompany | Should -Not -BeNullOrEmpty } It 'Get-FakeCatchPhrase returns a non-empty string' { Get-FakeCatchPhrase | Should -Not -BeNullOrEmpty } It 'Get-FakeBS returns a non-empty string' { Get-FakeBS | Should -Not -BeNullOrEmpty } It 'Get-FakeJobTitle returns a non-empty string' { Get-FakeJobTitle | Should -Not -BeNullOrEmpty } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Internet' { BeforeAll { New-Faker -Seed 7 } It 'Get-FakeTld returns a common TLD' { Get-FakeTld | Should -BeIn @('com','net','org','info','biz','io','co','dev','app','me','us','uk') } It 'Get-FakeDomainWord returns a string' { Get-FakeDomainWord | Should -Not -BeNullOrEmpty } It 'Get-FakeDomainName contains a dot' { Get-FakeDomainName | Should -Match '\.' } It 'Get-FakeUserName is non-empty and lowercase-ish' { $u = Get-FakeUserName $u | Should -Not -BeNullOrEmpty } It 'Get-FakeEmail contains @ and .' { $e = Get-FakeEmail $e | Should -Match '@' $e | Should -Match '\.' } It 'Get-FakeSafeEmail uses example domain' { Get-FakeSafeEmail | Should -Match '@example\.(com|org|net)$' } It 'Get-FakeFreeEmail uses free provider' { $e = Get-FakeFreeEmail $e | Should -Match '@(gmail|yahoo|hotmail|outlook|aol|icloud)\.com$' } It 'Get-FakeCompanyEmail contains @ and .' { Get-FakeCompanyEmail | Should -Match '@.+\..+' } It 'Get-FakePassword is at least 8 chars' { Get-FakePassword | Should -Not -BeNullOrEmpty (Get-FakePassword).Length | Should -BeGreaterOrEqual 8 } It 'Get-FakePassword respects custom min/max' { $p = Get-FakePassword -MinLength 12 -MaxLength 12 $p.Length | Should -Be 12 } It 'Get-FakeUrl starts with http' { Get-FakeUrl | Should -Match '^https?://' } It 'Get-FakeSlug contains only lowercase and dashes' { Get-FakeSlug | Should -Match '^[a-z][a-z\-]+[a-z]$' } It 'Get-FakeIPv4 matches IPv4 pattern' { Get-FakeIPv4 | Should -Match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' } It 'Get-FakeLocalIPv4 starts with 10.' { Get-FakeLocalIPv4 | Should -Match '^10\.' } It 'Get-FakeIPv6 contains colons' { Get-FakeIPv6 | Should -Match '^[0-9a-f]{4}(:[0-9a-f]{4}){7}$' } It 'Get-FakeMacAddress matches MAC pattern' { Get-FakeMacAddress | Should -Match '^([0-9A-F]{2}:){5}[0-9A-F]{2}$' } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'DateTime' { BeforeAll { New-Faker -Seed 8 } It 'Get-FakeUnixTime returns a positive long' { $u = Get-FakeUnixTime $u | Should -BeGreaterOrEqual 0 } It 'Get-FakeUnixTime respects Max' { $max = [datetime]::new(2000,1,1) $u = Get-FakeUnixTime -Max $max $u | Should -BeLessOrEqual 946684800 # epoch seconds for 2000-01-01 } It 'Get-FakeDateTime returns a DateTime' { Get-FakeDateTime | Should -BeOfType [datetime] } It 'Get-FakeDateTime is not in the future by default' { (Get-FakeDateTime) | Should -BeLessOrEqual ([datetime]::Now) } It 'Get-FakeDateTimeAD returns a DateTime' { Get-FakeDateTimeAD | Should -BeOfType [datetime] } It 'Get-FakeISO8601 matches ISO format' { Get-FakeISO8601 | Should -Match '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}' } It 'Get-FakeDate returns a formatted string' { Get-FakeDate | Should -Match '^\d{4}-\d{2}-\d{2}$' } It 'Get-FakeDate with custom format works' { Get-FakeDate -Format 'MM/dd/yyyy' | Should -Match '^\d{2}/\d{2}/\d{4}$' } It 'Get-FakeTime returns HH:mm:ss' { Get-FakeTime | Should -Match '^\d{2}:\d{2}:\d{2}$' } It 'Get-FakeDateTimeBetween returns DateTime in range' { $start = [datetime]::new(2020,1,1) $end = [datetime]::new(2021,1,1) $d = Get-FakeDateTimeBetween -StartDate $start -EndDate $end $d | Should -BeGreaterOrEqual $start $d | Should -BeLessOrEqual $end } It 'Get-FakeDateTimeThisCentury is >= 2000' { (Get-FakeDateTimeThisCentury).Year | Should -BeGreaterOrEqual 2000 } It 'Get-FakeDateTimeThisDecade is in current decade' { $decade = [datetime]::Now.Year - ([datetime]::Now.Year % 10) (Get-FakeDateTimeThisDecade).Year | Should -BeGreaterOrEqual $decade } It 'Get-FakeDateTimeThisYear is in current year' { (Get-FakeDateTimeThisYear).Year | Should -Be ([datetime]::Now.Year) } It 'Get-FakeDateTimeThisMonth is in current month' { $d = Get-FakeDateTimeThisMonth $d.Year | Should -Be ([datetime]::Now.Year) $d.Month | Should -Be ([datetime]::Now.Month) } It 'Get-FakeAmPm returns am or pm' { Get-FakeAmPm | Should -BeIn @('am','pm') } It 'Get-FakeDayOfMonth returns 01-31' { Get-FakeDayOfMonth | Should -Match '^(0[1-9]|[12]\d|3[01])$' } It 'Get-FakeDayOfWeek returns a day name' { Get-FakeDayOfWeek | Should -BeIn @('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday') } It 'Get-FakeMonth returns 01-12' { Get-FakeMonth | Should -Match '^(0[1-9]|1[0-2])$' } It 'Get-FakeMonthName returns a month name' { Get-FakeMonthName | Should -BeIn @('January','February','March','April','May','June', 'July','August','September','October','November','December') } It 'Get-FakeYear returns a 4-digit year' { Get-FakeYear | Should -Match '^\d{4}$' } It 'Get-FakeCentury returns a Roman numeral' { Get-FakeCentury | Should -Match '^[IVX]+' } It 'Get-FakeTimezone returns a known timezone string' { Get-FakeTimezone | Should -Match '/' } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Payment' { BeforeAll { New-Faker -Seed 9 } It 'Get-FakeCreditCardType returns a known type' { Get-FakeCreditCardType | Should -BeIn @('Visa','MasterCard','American Express','Discover','JCB','Diners Club') } It 'Get-FakeCreditCardNumber returns digits only' { Get-FakeCreditCardNumber | Should -Match '^\d+$' } It 'Get-FakeCreditCardNumber for Visa starts with 4 and is 16 digits' { $n = Get-FakeCreditCardNumber -Type 'Visa' $n | Should -Match '^4\d{15}$' } It 'Get-FakeCreditCardNumber for AmEx is 15 digits starting 34 or 37' { $n = Get-FakeCreditCardNumber -Type 'American Express' $n | Should -Match '^(34|37)\d{13}$' } It 'Get-FakeCreditCardNumber passes Luhn check' { $n = Get-FakeCreditCardNumber -Type 'Visa' $digits = $n.ToCharArray() | ForEach-Object { [int]::Parse($_) } $sum = 0; $alt = $false for ($i = $digits.Count - 1; $i -ge 0; $i--) { $d = $digits[$i] if ($alt) { $d *= 2; if ($d -gt 9) { $d -= 9 } } $sum += $d; $alt = !$alt } $sum % 10 | Should -Be 0 } It 'Get-FakeCreditCardExpirationDate returns a future DateTime' { (Get-FakeCreditCardExpirationDate) | Should -BeGreaterThan ([datetime]::Now) } It 'Get-FakeCreditCardDetails returns hashtable with required keys' { $d = Get-FakeCreditCardDetails $d.Keys | Should -Contain 'Type' $d.Keys | Should -Contain 'Number' $d.Keys | Should -Contain 'Name' $d.Keys | Should -Contain 'Expiry' } It 'Get-FakeIban returns string starting with 2 letters and 2 digits' { Get-FakeIban | Should -Match '^[A-Z]{2}\d{2}' } It 'Get-FakeIban with CountryCode uses that code' { Get-FakeIban -CountryCode 'DE' | Should -Match '^DE\d' } It 'Get-FakeSwiftBic returns 8-11 character string' { $s = Get-FakeSwiftBic $s.Length | Should -BeGreaterOrEqual 8 $s.Length | Should -BeLessOrEqual 11 } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Color' { BeforeAll { New-Faker -Seed 10 } It 'Get-FakeHexColor returns #RRGGBB format' { Get-FakeHexColor | Should -Match '^#[0-9a-f]{6}$' } It 'Get-FakeRgbColor returns R,G,B string' { Get-FakeRgbColor | Should -Match '^\d{1,3},\d{1,3},\d{1,3}$' } It 'Get-FakeRgbColorAsArray returns 3-element int array' { $a = Get-FakeRgbColorAsArray $a.Count | Should -Be 3 $a | ForEach-Object { $_ | Should -BeGreaterOrEqual 0; $_ | Should -BeLessOrEqual 255 } } It 'Get-FakeRgbCssColor returns rgb(...) string' { Get-FakeRgbCssColor | Should -Match '^rgb\(\d{1,3},\d{1,3},\d{1,3}\)$' } It 'Get-FakeSafeColorName returns a CSS safe name' { Get-FakeSafeColorName | Should -BeIn @('aqua','black','blue','fuchsia','gray','green', 'lime','maroon','navy','olive','orange','purple','red','silver','teal','white','yellow') } It 'Get-FakeColorName returns a string' { Get-FakeColorName | Should -Not -BeNullOrEmpty } It 'Get-FakeHslColor returns H,S,L string' { Get-FakeHslColor | Should -Match '^\d{1,3},\d{1,3},\d{1,3}$' } It 'Get-FakeHslColorAsArray returns 3-element array with valid ranges' { $a = Get-FakeHslColorAsArray $a.Count | Should -Be 3 $a[0] | Should -BeGreaterOrEqual 0; $a[0] | Should -BeLessOrEqual 360 $a[1] | Should -BeGreaterOrEqual 0; $a[1] | Should -BeLessOrEqual 100 $a[2] | Should -BeGreaterOrEqual 0; $a[2] | Should -BeLessOrEqual 100 } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'File' { BeforeAll { New-Faker -Seed 11 } It 'Get-FakeFileExtension returns a string without dot' { $e = Get-FakeFileExtension $e | Should -Not -BeNullOrEmpty $e | Should -Not -Match '^\.' # no leading dot } It 'Get-FakeMimeType returns a valid MIME type' { Get-FakeMimeType | Should -Match '^[a-z]+/[a-z0-9\.\-\+]+' } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'UUID' { BeforeAll { New-Faker -Seed 12 } It 'Get-FakeUuid returns RFC 4122 format' { Get-FakeUuid | Should -Match '^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$' } It 'Get-FakeUuid generates unique values' { $uuids = 1..20 | ForEach-Object { Get-FakeUuid } ($uuids | Sort-Object -Unique).Count | Should -Be 20 } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Barcode' { BeforeAll { New-Faker -Seed 13 } It 'Get-FakeEan13 returns 13 digits' { Get-FakeEan13 | Should -Match '^\d{13}$' } It 'Get-FakeEan13 passes EAN checksum' { $code = Get-FakeEan13 $digits = $code.ToCharArray() | ForEach-Object { [int]::Parse($_) } $sum = 0 for ($i = 0; $i -lt 13; $i++) { $w = if ($i % 2 -eq 0) { 1 } else { 3 } $sum += $digits[$i] * $w } $sum % 10 | Should -Be 0 } It 'Get-FakeEan8 returns 8 digits' { Get-FakeEan8 | Should -Match '^\d{8}$' } It 'Get-FakeEan8 passes EAN checksum' { $code = Get-FakeEan8 $digits = $code.ToCharArray() | ForEach-Object { [int]::Parse($_) } $sum = 0 for ($i = 0; $i -lt 8; $i++) { $w = if ($i % 2 -eq 0) { 1 } else { 3 } $sum += $digits[$i] * $w } $sum % 10 | Should -Be 0 } It 'Get-FakeIsbn13 starts with 978 or 979 and is 13 digits' { Get-FakeIsbn13 | Should -Match '^(978|979)\d{10}$' } It 'Get-FakeIsbn10 is 9 digits plus check char' { Get-FakeIsbn10 | Should -Match '^\d{9}[\dX]$' } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Miscellaneous' { BeforeAll { New-Faker -Seed 14 } It 'Get-FakeBoolean returns a bool' { Get-FakeBoolean | Should -BeOfType [bool] } It 'Get-FakeBoolean with ChanceOfTrue=100 always returns true' { 1..10 | ForEach-Object { Get-FakeBoolean -ChanceOfTrue 100 } | ForEach-Object { $_ | Should -Be $true } } It 'Get-FakeBoolean with ChanceOfTrue=0 always returns false' { 1..10 | ForEach-Object { Get-FakeBoolean -ChanceOfTrue 0 } | ForEach-Object { $_ | Should -Be $false } } It 'Get-FakeMd5 returns 32 hex chars' { Get-FakeMd5 | Should -Match '^[0-9a-f]{32}$' } It 'Get-FakeSha1 returns 40 hex chars' { Get-FakeSha1 | Should -Match '^[0-9a-f]{40}$' } It 'Get-FakeSha256 returns 64 hex chars' { Get-FakeSha256 | Should -Match '^[0-9a-f]{64}$' } It 'Get-FakeLocale returns a locale string' { Get-FakeLocale | Should -Match '^[a-z]{2}_[A-Z]{2}$' } It 'Get-FakeCountryCode returns a 2-letter code' { Get-FakeCountryCode | Should -Match '^[A-Z]{2}$' } It 'Get-FakeLanguageCode returns a 2-letter code' { Get-FakeLanguageCode | Should -Match '^[a-z]{2}$' } It 'Get-FakeCurrencyCode returns a 3-letter code' { Get-FakeCurrencyCode | Should -Match '^[A-Z]{3}$' } It 'Get-FakeEmoji returns a non-empty string' { Get-FakeEmoji | Should -Not -BeNullOrEmpty } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'UserAgent' { BeforeAll { New-Faker -Seed 15 } It 'Get-FakeChromeAgent contains Chrome' { Get-FakeChromeAgent | Should -Match 'Chrome' } It 'Get-FakeFirefoxAgent contains Firefox' { Get-FakeFirefoxAgent | Should -Match 'Firefox' } It 'Get-FakeSafariAgent contains Safari' { Get-FakeSafariAgent | Should -Match 'Safari' } It 'Get-FakeOperaAgent contains Opera' { Get-FakeOperaAgent | Should -Match 'Opera' } It 'Get-FakeIEAgent contains MSIE or Trident' { Get-FakeIEAgent | Should -Match '(MSIE|Trident)' } It 'Get-FakeUserAgent returns a non-empty string' { Get-FakeUserAgent | Should -Not -BeNullOrEmpty } It 'Get-FakeUserAgent returns Mozilla-prefixed string' { Get-FakeUserAgent | Should -Match '^Mozilla/' } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Biased' { BeforeAll { New-Faker -Seed 16 } It 'Get-FakeBiasedNumberBetween returns value in range' { 1..20 | ForEach-Object { Get-FakeBiasedNumberBetween -Min 10 -Max 20 } | ForEach-Object { $_ | Should -BeGreaterOrEqual 10 $_ | Should -BeLessOrEqual 20 } } It 'Get-FakeBiasedNumberBetween with sqrt skews toward max' { $vals = 1..100 | ForEach-Object { Get-FakeBiasedNumberBetween -Min 0 -Max 100 -Function 'sqrt' } $avg = ($vals | Measure-Object -Average).Average $avg | Should -BeGreaterThan 50 # sqrt bias toward max } It 'Get-FakeBiasedNumberBetween with log skews toward min' { $vals = 1..100 | ForEach-Object { Get-FakeBiasedNumberBetween -Min 0 -Max 100 -Function 'log' } $avg = ($vals | Measure-Object -Average).Average $avg | Should -BeLessThan 50 } It 'Get-FakeBiasedNumberBetween with unknown function returns in range' { $v = Get-FakeBiasedNumberBetween -Min 5 -Max 10 -Function 'linear' $v | Should -BeGreaterOrEqual 5 $v | Should -BeLessOrEqual 10 } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'HtmlLorem' { BeforeAll { New-Faker -Seed 17 } It 'Get-FakeHtmlLorem returns valid HTML string' { $html = Get-FakeHtmlLorem $html | Should -Match '<html>' $html | Should -Match '</html>' } It 'Get-FakeHtmlLorem contains head and body' { $html = Get-FakeHtmlLorem $html | Should -Match '<head>' $html | Should -Match '<body>' } It 'Get-FakeHtmlLorem with custom depth does not throw' { { Get-FakeHtmlLorem -MaxDepth 1 -MaxWidth 2 } | Should -Not -Throw } It 'Get-FakeHtmlLorem with MaxDepth=0 returns minimal HTML' { $html = Get-FakeHtmlLorem -MaxDepth 0 $html | Should -Match '<html>' } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'RealText' { BeforeAll { New-Faker -Seed 18 } It 'Get-FakeRealText returns a string' { Get-FakeRealText | Should -Not -BeNullOrEmpty } It 'Get-FakeRealText respects MaxNbChars' { 1..5 | ForEach-Object { Get-FakeRealText -MaxNbChars 100 } | ForEach-Object { $_.Length | Should -BeLessOrEqual 100 } } It 'Get-FakeRealText starts with uppercase' { Get-FakeRealText | Should -Match '^[A-Z]' } It 'Get-FakeRealText with IndexSize=1 does not throw' { { Get-FakeRealText -MaxNbChars 50 -IndexSize 1 } | Should -Not -Throw } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Modifiers – unique()' { BeforeAll { New-Faker -Seed 19 } It 'Get-FakeUnique returns a value' { $val = Get-FakeUnique -Generator { Get-FakeRandomDigit } $val | Should -Not -BeNullOrEmpty -Because 'should produce a digit' } It 'Get-FakeUnique never repeats values for same generator' { $seen = @{} 0..8 | ForEach-Object { $v = Get-FakeUnique -Generator { Get-FakeRandomDigit } $seen.ContainsKey($v.ToString()) | Should -Be $false $seen[$v.ToString()] = $true } } It 'Get-FakeUnique throws OverflowException when pool exhausted' { Reset-FakeUnique { 0..10 | ForEach-Object { Get-FakeUnique -Generator { Get-FakeRandomDigit } -MaxAttempts 5000 } } | Should -Throw } It 'Reset-FakeUnique clears the cache' { # fill digits 0-8 try { 0..10 | ForEach-Object { Get-FakeUnique -Generator { Get-FakeRandomDigit } -MaxAttempts 5000 } } catch {} Reset-FakeUnique # should now succeed again { Get-FakeUnique -Generator { Get-FakeRandomDigit } } | Should -Not -Throw } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Modifiers – optional()' { BeforeAll { New-Faker -Seed 20 } It 'Get-FakeOptional with Weight=1 always returns generator value' { 1..10 | ForEach-Object { Get-FakeOptional -Generator { 42 } -Weight 1 } | ForEach-Object { $_ | Should -Be 42 } } It 'Get-FakeOptional with Weight=0 always returns default' { 1..10 | ForEach-Object { Get-FakeOptional -Generator { 42 } -Weight 0 } | ForEach-Object { $_ | Should -BeNullOrEmpty } } It 'Get-FakeOptional with custom default returns it sometimes' { $results = 1..50 | ForEach-Object { Get-FakeOptional -Generator { 99 } -Weight 0.5 -Default 'N/A' } $results | Should -Contain 'N/A' $results | Should -Contain 99 } It 'Get-FakeOptional default weight is 0.5 (roughly)' { New-Faker -Seed 42 $nulls = (1..100 | ForEach-Object { Get-FakeOptional -Generator { 1 } } | Where-Object { $null -eq $_ }).Count $nulls | Should -BeGreaterThan 20 $nulls | Should -BeLessThan 80 } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Modifiers – valid()' { BeforeAll { New-Faker -Seed 21 } It 'Get-FakeValid only returns values passing the validator' { 1..20 | ForEach-Object { Get-FakeValid -Generator { Get-FakeRandomDigit } -Validator { param($n) $n % 2 -eq 0 } } | ForEach-Object { $_ % 2 | Should -Be 0 } } It 'Get-FakeValid throws OverflowException when no valid value exists' { { Get-FakeValid -Generator { Get-FakeRandomElement @(1,3,5) } -Validator { param($n) $n % 2 -eq 0 } -MaxAttempts 20 } | Should -Throw } It 'Get-FakeValid returns string values correctly' { $val = Get-FakeValid -Generator { Get-FakeTld } -Validator { param($s) $s -eq 'com' } -MaxAttempts 5000 $val | Should -Be 'com' } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Seeding / Reproducibility' { It 'Same seed produces same sequence of names' { New-Faker -Seed 777 $seq1 = 1..5 | ForEach-Object { Get-FakeName } New-Faker -Seed 777 $seq2 = 1..5 | ForEach-Object { Get-FakeName } $seq1 | Should -Be $seq2 } It 'Same seed produces same sequence of floats' { New-Faker -Seed 888 $seq1 = 1..5 | ForEach-Object { Get-FakeRandomFloat -Min 0 -Max 1 } New-Faker -Seed 888 $seq2 = 1..5 | ForEach-Object { Get-FakeRandomFloat -Min 0 -Max 1 } $seq1 | Should -Be $seq2 } It 'Different seeds produce different sequences' { New-Faker -Seed 1 $seq1 = 1..5 | ForEach-Object { Get-FakeRandomDigit } New-Faker -Seed 2 $seq2 = 1..5 | ForEach-Object { Get-FakeRandomDigit } ($seq1 -join '') | Should -Not -Be ($seq2 -join '') } } # ═══════════════════════════════════════════════════════════════════════════════ Describe 'Integration – combined data generation' { BeforeAll { New-Faker -Seed 100 } It 'Can generate a contact record' { $contact = @{ Name = Get-FakeName Email = Get-FakeEmail Phone = Get-FakePhoneNumber Address = Get-FakeAddress Company = Get-FakeCompany } $contact.Name | Should -Not -BeNullOrEmpty $contact.Email | Should -Match '@' $contact.Phone | Should -Match '\d' $contact.Address | Should -Match ',' $contact.Company | Should -Not -BeNullOrEmpty } It 'Can generate 10 unique email addresses' { Reset-FakeUnique $emails = 1..10 | ForEach-Object { Get-FakeUnique -Generator { Get-FakeEmail } } ($emails | Sort-Object -Unique).Count | Should -Be 10 } It 'Can generate a payment record with valid card' { $card = Get-FakeCreditCardDetails $card.Type | Should -Not -BeNullOrEmpty $card.Number | Should -Match '^\d+' $card.Expiry | Should -Match '^\d{2}/\d{2}$' } It 'Can build XML-like content using multiple providers' { $xml = "<contact firstName=`"$(Get-FakeFirstName)`" lastName=`"$(Get-FakeLastName)`" email=`"$(Get-FakeEmail)`">" $xml | Should -Match 'firstName="[A-Za-z]+' $xml | Should -Match 'email="[^"]+@[^"]+"' } It 'optional() and valid() can be combined' { $result = Get-FakeOptional -Generator { Get-FakeValid -Generator { Get-FakeRandomDigit } -Validator { param($n) $n -gt 5 } } -Weight 0.8 if ($null -ne $result) { $result | Should -BeGreaterThan 5 } $true | Should -Be $true } } |