Skip to content

Commit

Permalink
[1673] Ensure mix_case returns at least one lower and one upper case …
Browse files Browse the repository at this point in the history
…letter
  • Loading branch information
brad authored and bpleslie committed Aug 23, 2019
1 parent 6d9ef88 commit 76566d9
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 18 deletions.
4 changes: 3 additions & 1 deletion doc/default/alphanumeric.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# Keyword arguments: number
Faker::Alphanumeric.alpha(number: 10) #=> "zlvubkrwga"

# Keyword arguments: number
# Keyword arguments: number, min_alpha, min_numeric
Faker::Alphanumeric.alphanumeric(number: 10) #=> "3yfq2phxtb"
Faker::Alphanumeric.alphanumeric(number: 10, min_alpha: 3) #=> "3yfq2phxtb"
Faker::Alphanumeric.alphanumeric(number: 10, min_alpha: 3, min_numeric: 3) #=> "3yfq2phx8b"
```
4 changes: 3 additions & 1 deletion doc/default/lorem.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ Faker::Lorem.words(number: 4, supplemental: true) #=> ["colloco", "qui", "vergo"

Faker::Lorem.multibyte #=> 😀

# Keyword arguments: number
# Keyword arguments: number, min_alpha, min_numeric
Faker::Lorem.characters #=> "uw1ep04lhs0c4d931n1jmrspprf5wrj85fefue0y7y6m56b6omquh7br7dhqijwlawejpl765nb1716idmp3xnfo85v349pzy2o9rir23y2qhflwr71c1585fnynguiphkjm8p0vktwitcsm16lny7jzp9t4drwav3qmhz4yjq4k04x14gl6p148hulyqioo72tf8nwrxxcclfypz2lc58lsibgfe5w5p0xv95peafjjmm2frkhdc6duoky0aha"
Faker::Lorem.characters(number: 10) #=> "ang9cbhoa8"
Faker::Lorem.characters(number: 10, min_alpha: 4) #=> "ang9cbhoa8"
Faker::Lorem.characters(number: 10, min_alpha: 4, min_numeric: 1) #=> "ang9cbhoa8"

# Keyword arguments: word_count, supplemental, random_words_to_add
# The 'random_words_to_add' argument increases the sentence's word count by a random value within (0..random_words_to_add).
Expand Down
3 changes: 2 additions & 1 deletion lib/faker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ def random
class Base
Numbers = Array(0..9)
ULetters = Array('A'..'Z')
Letters = ULetters + Array('a'..'z')
LLetters = Array('a'..'z')
Letters = ULetters + LLetters

class << self
## by default numerify results do not start with a zero
Expand Down
42 changes: 36 additions & 6 deletions lib/faker/default/alphanumeric.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,52 @@

module Faker
class Alphanumeric < Base
class << self
ALPHABET = ('a'..'z').to_a
ALPHANUMS = ALPHABET + (0..9).to_a
ALPHANUMS = LLetters + Numbers

class << self
def alpha(number: 32)
char_count = resolve(number)
return '' if char_count.to_i < 1

Array.new(char_count) { sample(ALPHABET) }.join
Array.new(char_count) { sample(self::LLetters) }.join
end

def alphanumeric(number: 32)
##
# Produces a random string of alphanumeric characters
#
# @param [Integer] number
# @param [Integer] min_alpha
# @param [Integer] min_numeric
#
# @return [String]
#
# @example Faker::Alphanumeric.alphanumeric(number: 10) #=> "3yfq2phxtb"
# @example Faker::Alphanumeric.alphanumeric(number: 10, min_alpha: 3) #=> "3yfq2phxtb"
# @example Faker::Alphanumeric.alphanumeric(number: 10, min_alpha: 3, min_numeric: 3) #=> "3yfq2phx8b"
#
# @faker.version 2.1.3
def alphanumeric(number: 32, min_alpha: 0, min_numeric: 0)
char_count = resolve(number)
return '' if char_count.to_i < 1
raise ArgumentError, 'min_alpha must be greater than or equal to 0' if min_alpha&.negative?
raise ArgumentError, 'min_numeric must be greater than or equal to 0' if min_numeric&.negative?

if min_alpha.zero? && min_numeric.zero?
return Array.new(char_count) { sample(ALPHANUMS) }.join
end

if min_alpha + min_numeric > char_count
raise ArgumentError, 'min_alpha + min_numeric must be <= number'
end

random_count = char_count - min_alpha - min_numeric

alphas = Array.new(min_alpha) { sample(self::LLetters) }
numbers = Array.new(min_numeric) { sample(self::Numbers) }
randoms = Array.new(random_count) { sample(ALPHANUMS) }

Array.new(char_count) { sample(ALPHANUMS) }.join
combined = alphas + numbers + randoms
combined.shuffle.join
end
end
end
Expand Down
26 changes: 24 additions & 2 deletions lib/faker/default/internet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,26 @@ def username(specifier: nil, separators: %w[. _])
end
end

##
# Produces a randomized string of characters
#
# @param [Integer] min_length
# @param [Integer] max_length
# @param [Boolean] mix_case
# @param [Boolean] special_characters
#
# @return [String]
#
# @example Faker::Internet.password #=> "Vg5mSvY1UeRg7"
# @example Faker::Internet.password(min_length: 8) #=> "YfGjIk0hGzDqS0"
# @example Faker::Internet.password(min_length: 10, max_length: 20) #=> "EoC9ShWd1hWq4vBgFw"
# @example Faker::Internet.password(min_length: 10, max_length: 20, mix_case: true) #=> "3k5qS15aNmG"
# @example Faker::Internet.password(min_length: 10, max_length: 20, mix_case: true, special_characters: true) #=> "*%NkOnJsH4"
#
# @faker.version 2.1.3
def password(min_length: 8, max_length: 16, mix_case: true, special_characters: false)
temp = Lorem.characters(number: min_length)
min_alpha = mix_case ? 2 : 0
temp = Lorem.characters(number: min_length, min_alpha: min_alpha)
diff_length = max_length - min_length

if diff_length.positive?
Expand All @@ -65,8 +83,12 @@ def password(min_length: 8, max_length: 16, mix_case: true, special_characters:
end

if mix_case
alpha_count = 0
temp.chars.each_with_index do |char, index|
temp[index] = char.upcase if index.even?
if char =~ /[[:alpha:]]/
temp[index] = char.upcase if alpha_count.even?
alpha_count += 1
end
end
end

Expand Down
19 changes: 17 additions & 2 deletions lib/faker/default/lorem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,23 @@ def character
sample(Types::CHARACTERS)
end

def characters(number: 255)
Alphanumeric.alphanumeric(number: number)
##
# Produces a random string of alphanumeric characters
#
# @param [Integer] number
# @param [Integer] min_alpha
# @param [Integer] min_numeric
#
# @return [String]
#
# @example Faker::Lorem.characters #=> "uw1ep04lhs0c4d931n1jmrspprf5wrj85fefue0y7y6m56b6omquh7br7dhqijwlawejpl765nb1716idmp3xnfo85v349pzy2o9rir23y2qhflwr71c1585fnynguiphkjm8p0vktwitcsm16lny7jzp9t4drwav3qmhz4yjq4k04x14gl6p148hulyqioo72tf8nwrxxcclfypz2lc58lsibgfe5w5p0xv95peafjjmm2frkhdc6duoky0aha"
# @example Faker::Lorem.characters(number: 10) #=> "ang9cbhoa8"
# @example Faker::Lorem.characters(number: 10, min_alpha: 4) #=> "ang9cbhoa8"
# @example Faker::Lorem.characters(number: 10, min_alpha: 4, min_numeric: 1) #=> "ang9cbhoa8"
#
# @faker.version 2.1.3
def characters(number: 255, min_alpha: 0, min_numeric: 0)
Alphanumeric.alphanumeric(number: number, min_alpha: min_alpha, min_numeric: min_numeric)
end

def multibyte
Expand Down
36 changes: 34 additions & 2 deletions test/faker/default/test_alphanum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,42 @@ def setup
end

def alpha
assert @tester.alpha(characters: 5).match(/[a-z]{5}/)
assert @tester.alpha(number: 5).match(/[a-z]{5}/)
end

def alphanum
assert @tester.alphanumeric(characters: 5).match(/[a-z0-9]{5}/)
assert @tester.alphanumeric(number: 5).match(/[a-z0-9]{5}/)
end

def test_alphanumeric_invalid_min_alpha
assert_raise ArgumentError do
@tester.alphanumeric(number: 5, min_alpha: -1)
end
end

def test_alphanumeric_invalid_min_numeric
assert_raise ArgumentError do
@tester.alphanumeric(number: 5, min_numeric: -1)
end
end

def test_alphanumeric_with_invalid_mins
assert_raise ArgumentError do
@tester.alphanumeric(number: 5, min_numeric: 4, min_alpha: 3)
end
end

def test_alphanumeric_with_min_alpha
letters = @tester.alphanumeric(number: 5, min_alpha: 2).split('').map do |char|
char =~ /[[:alpha:]]/
end
assert letters.compact.size >= 2
end

def test_alphanumeric_with_min_numeric
numbers = @tester.alphanumeric(number: 5, min_numeric: 4).split('').map do |char|
char =~ /[[:digit:]]/
end
assert numbers.compact.size >= 4
end
end
15 changes: 12 additions & 3 deletions test/faker/default/test_faker_internet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ def test_password

def test_password_with_integer_arg
(1..32).each do |min_length|
assert @tester.password(min_length: min_length).length >= min_length
assert @tester.password(min_length: min_length, mix_case: false).length >= min_length
end
end

def test_password_max_with_integer_arg
(1..32).each do |min_length|
max_length = min_length + 4
assert @tester.password(min_length: min_length, max_length: max_length).length <= max_length
assert @tester.password(min_length: min_length, max_length: max_length, mix_case: false).length <= max_length
end
end

Expand All @@ -118,7 +118,16 @@ def test_password_could_achieve_max_length
end

def test_password_with_mixed_case
assert @tester.password.match(/[A-Z]+/)
password = @tester.password
upcase_count = 0
downcase_count = 0
password.chars.each do |char|
if char =~ /[[:alpha:]]/
char.capitalize == char ? upcase_count += 1 : downcase_count += 1
end
end
assert upcase_count >= 1
assert downcase_count >= 1
end

def test_password_without_mixed_case
Expand Down

0 comments on commit 76566d9

Please sign in to comment.