ffaker 2.20.0 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changelog.md +21 -0
- data/README.md +15 -4
- data/REFERENCE.md +1423 -1396
- data/Rakefile +9 -40
- data/bin/console +9 -0
- data/ffaker.gemspec +9 -19
- data/lib/ffaker/address_br.rb +14 -2
- data/lib/ffaker/address_it.rb +0 -1
- data/lib/ffaker/address_ua.rb +1 -1
- data/lib/ffaker/animal_br.rb +12 -0
- data/lib/ffaker/book.rb +5 -5
- data/lib/ffaker/code.rb +1 -1
- data/lib/ffaker/company.rb +4 -7
- data/lib/ffaker/company_fr.rb +1 -1
- data/lib/ffaker/data/address_br/complement +3 -0
- data/lib/ffaker/data/address_br/neighborhood_prefixes +3 -0
- data/lib/ffaker/data/address_de/state +1 -0
- data/lib/ffaker/data/animal_br/common_names +423 -0
- data/lib/ffaker/data/jo_jo/first_names +356 -0
- data/lib/ffaker/data/jo_jo/full_names +225 -0
- data/lib/ffaker/data/jo_jo/last_names +153 -0
- data/lib/ffaker/data/jo_jo/stands +149 -0
- data/lib/ffaker/date.rb +31 -0
- data/lib/ffaker/geolocation.rb +2 -2
- data/lib/ffaker/html_ipsum.rb +7 -1
- data/lib/ffaker/identification_br.rb +1 -1
- data/lib/ffaker/identification_ec.rb +39 -0
- data/lib/ffaker/identification_es_cl.rb +2 -2
- data/lib/ffaker/identification_es_co.rb +1 -1
- data/lib/ffaker/identification_kr.rb +3 -3
- data/lib/ffaker/identification_pl.rb +4 -4
- data/lib/ffaker/identification_tw.rb +4 -3
- data/lib/ffaker/jo_jo.rb +24 -0
- data/lib/ffaker/name_pl.rb +1 -1
- data/lib/ffaker/number.rb +2 -2
- data/lib/ffaker/ssn_se.rb +2 -2
- data/lib/ffaker/string.rb +7 -7
- data/lib/ffaker/time.rb +4 -4
- data/lib/ffaker/utils/module_utils.rb +4 -5
- data/lib/ffaker/utils/unique_utils.rb +30 -21
- data/lib/ffaker/vehicle.rb +63 -1
- data/lib/{version.rb → ffaker/version.rb} +1 -1
- data/lib/ffaker.rb +8 -4
- data/scripts/reference.rb +15 -13
- data/test/helper.rb +2 -4
- data/test/test_address_br.rb +15 -2
- data/test/test_address_da.rb +3 -3
- data/test/test_address_fi.rb +2 -2
- data/test/test_address_se.rb +2 -2
- data/test/test_animal_br.rb +17 -0
- data/test/test_cheesy_lingo.rb +1 -1
- data/test/test_color.rb +3 -3
- data/test/test_date.rb +37 -0
- data/test/test_filesystem.rb +3 -3
- data/test/test_freedom_ipsum.rb +1 -1
- data/test/test_gender_it.rb +1 -1
- data/test/test_gender_ja.rb +1 -1
- data/test/test_gender_jp.rb +1 -1
- data/test/test_gender_pl.rb +1 -1
- data/test/test_healthcare_ru.rb +1 -1
- data/test/test_hipster_ipsum.rb +1 -1
- data/test/test_html_ipsum.rb +6 -0
- data/test/test_identification_ec.rb +33 -0
- data/test/test_identification_es_mx.rb +1 -1
- data/test/test_internet_se.rb +2 -1
- data/test/test_jo_jo.rb +29 -0
- data/test/test_lorem_br.rb +1 -1
- data/test/test_lorem_cn.rb +3 -3
- data/test/test_lorem_fr.rb +3 -3
- data/test/test_lorem_ie.rb +2 -2
- data/test/test_lorem_kr.rb +3 -3
- data/test/test_lorem_pl.rb +2 -2
- data/test/test_lorem_ru.rb +3 -3
- data/test/test_lorem_ua.rb +3 -3
- data/test/test_module_utils.rb +33 -0
- data/test/test_name_da.rb +1 -1
- data/test/test_name_ph.rb +1 -1
- data/test/test_name_ru.rb +2 -2
- data/test/test_name_ua.rb +2 -2
- data/test/test_phone_number_se.rb +1 -1
- data/test/test_phone_number_sg.rb +8 -8
- data/test/test_unique_utils.rb +25 -5
- data/test/test_vehicle.rb +28 -1
- metadata +24 -197
@@ -0,0 +1,149 @@
|
|
1
|
+
Anubis
|
2
|
+
Atum
|
3
|
+
Bastet
|
4
|
+
Cream
|
5
|
+
Death Thirteen
|
6
|
+
Geb
|
7
|
+
High Priestess
|
8
|
+
Horus
|
9
|
+
Judgement
|
10
|
+
Khnum
|
11
|
+
Osiris
|
12
|
+
Sethan
|
13
|
+
Tenore Sax
|
14
|
+
Tohth
|
15
|
+
Dark Blue Moon
|
16
|
+
Emperor
|
17
|
+
Ebony Devil
|
18
|
+
Empress
|
19
|
+
Hanged Man
|
20
|
+
Hermit Purple
|
21
|
+
Hierophant Green
|
22
|
+
Justice
|
23
|
+
Lovers
|
24
|
+
Magician's Red
|
25
|
+
Silver Chariot
|
26
|
+
Star Platinum
|
27
|
+
Strength
|
28
|
+
Sun
|
29
|
+
The Fool
|
30
|
+
The World
|
31
|
+
Tower of Gray
|
32
|
+
Wheel of Fortune
|
33
|
+
Yellow Temperance
|
34
|
+
Achtung Baby
|
35
|
+
Aqua Necklace
|
36
|
+
Atom Heart Father
|
37
|
+
Bad Company
|
38
|
+
Boy II Man
|
39
|
+
Cheap Trick
|
40
|
+
Cinderella
|
41
|
+
Crazy Diamond
|
42
|
+
Enigma
|
43
|
+
Earth Wind and Fire
|
44
|
+
Harvest
|
45
|
+
Heaven's Door
|
46
|
+
Highway Star
|
47
|
+
Killer Queen
|
48
|
+
Sheer Heart Attack
|
49
|
+
Bites the Dust
|
50
|
+
Love Deluxe
|
51
|
+
Pearl Jam
|
52
|
+
Ratt
|
53
|
+
Red Hot Chili Pepper
|
54
|
+
Super Fly
|
55
|
+
Surface
|
56
|
+
The Lock
|
57
|
+
The Hand
|
58
|
+
Stray Cat
|
59
|
+
Black Sabbath
|
60
|
+
Baby Face
|
61
|
+
Gold Experience
|
62
|
+
Sticky Fingers
|
63
|
+
Metallica
|
64
|
+
Purple Haze
|
65
|
+
Moody Blues
|
66
|
+
Sex Pistols
|
67
|
+
The Grateful Dead
|
68
|
+
Aerosmith
|
69
|
+
Beach Boy
|
70
|
+
Man in the Mirror
|
71
|
+
Baby Face (GoGo)
|
72
|
+
Chariot Requiem
|
73
|
+
Clash
|
74
|
+
Echoes
|
75
|
+
Gold Experience Requiem
|
76
|
+
Green Day
|
77
|
+
King Crimson
|
78
|
+
Kraft Work
|
79
|
+
Little Feet
|
80
|
+
Mr.President
|
81
|
+
Notorious B.I.G
|
82
|
+
Oasis
|
83
|
+
Rolling Stones
|
84
|
+
Soft Machine
|
85
|
+
Spice Girl
|
86
|
+
Talking Head
|
87
|
+
White Album
|
88
|
+
Whitesnake
|
89
|
+
C-Moon
|
90
|
+
Jail House Lock
|
91
|
+
Stone Free
|
92
|
+
Goo Goo Dolls
|
93
|
+
Under World
|
94
|
+
Sky High
|
95
|
+
Star Platinum
|
96
|
+
Bohemian Rhapsody
|
97
|
+
Burning Down the House
|
98
|
+
Diver Down
|
99
|
+
Dragon's Dream
|
100
|
+
Foo Fighters
|
101
|
+
Green
|
102
|
+
Highway to Hell
|
103
|
+
Kiss
|
104
|
+
Jumpin' Jack Flash
|
105
|
+
Limp Bizkit
|
106
|
+
Made in Heaven
|
107
|
+
Manhattan Transfer
|
108
|
+
Marilyn Manson
|
109
|
+
Planet Waves
|
110
|
+
Survivor
|
111
|
+
Weather Report
|
112
|
+
Yo-Yo Ma
|
113
|
+
20th Century Boy
|
114
|
+
Ball Breaker
|
115
|
+
Boku no Rhythm wo Kiitekure
|
116
|
+
Catch the Rainbow
|
117
|
+
Chocolate Disco
|
118
|
+
Civil War
|
119
|
+
Cream Starter
|
120
|
+
Dirty Deeds Done Dirt Cheap
|
121
|
+
D4C Love Train
|
122
|
+
Hey Ya!
|
123
|
+
In a Silent Way
|
124
|
+
Mandom
|
125
|
+
Oh! Lonesome Me
|
126
|
+
Scary Monsters
|
127
|
+
Sugar Mountain
|
128
|
+
Tatoo You!
|
129
|
+
Ticket to Ride
|
130
|
+
Tomb of the Boom
|
131
|
+
Tubular Bells
|
132
|
+
Tusk
|
133
|
+
Wired
|
134
|
+
Born This Way
|
135
|
+
California King Bed
|
136
|
+
Fun Fun Fun
|
137
|
+
Nut King Call
|
138
|
+
Paisley Park
|
139
|
+
Paper Moon King
|
140
|
+
Soft & Wet
|
141
|
+
Manic Depression
|
142
|
+
Voodoo Child
|
143
|
+
All Along Watchtower
|
144
|
+
Dolly Dagger
|
145
|
+
Nightbird Flying
|
146
|
+
Purple Haze Distortion
|
147
|
+
Rainy Day Dream Away
|
148
|
+
Remote Romance
|
149
|
+
House of Holy
|
data/lib/ffaker/date.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module FFaker
|
6
|
+
module Date
|
7
|
+
extend FFaker::ModuleUtils
|
8
|
+
extend self
|
9
|
+
|
10
|
+
# Generates a random date between 2 dates
|
11
|
+
def between(from, to)
|
12
|
+
FFaker::Time.between(from, to).to_date
|
13
|
+
end
|
14
|
+
|
15
|
+
# Generates a random date up to `days` days in the past
|
16
|
+
def backward(days = 365)
|
17
|
+
from = ::Date.today - days
|
18
|
+
to = ::Date.today - 1
|
19
|
+
|
20
|
+
between(from, to)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Generates a random date up to `days` days in the future
|
24
|
+
def forward(days = 365)
|
25
|
+
from = ::Date.today + 1
|
26
|
+
to = ::Date.today + days
|
27
|
+
|
28
|
+
between(from, to)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/ffaker/geolocation.rb
CHANGED
@@ -51,8 +51,8 @@ module FFaker
|
|
51
51
|
latitude_range = [upper_left[0], lower_right[0]].sort
|
52
52
|
longitude_range = [upper_left[1], lower_right[1]].sort
|
53
53
|
|
54
|
-
latitude = latitude_range[0] + rand * (latitude_range[1] - latitude_range[0])
|
55
|
-
longitude = longitude_range[0] + rand * (longitude_range[1] - longitude_range[0])
|
54
|
+
latitude = latitude_range[0] + (rand * (latitude_range[1] - latitude_range[0]))
|
55
|
+
longitude = longitude_range[0] + (rand * (longitude_range[1] - longitude_range[0]))
|
56
56
|
|
57
57
|
[latitude, longitude]
|
58
58
|
end
|
data/lib/ffaker/html_ipsum.rb
CHANGED
@@ -134,9 +134,15 @@ module FFaker
|
|
134
134
|
a = k([
|
135
135
|
content_tag_for(:strong, words(2).capitalize!),
|
136
136
|
content_tag_for(:em, paragraph),
|
137
|
+
content_tag_for(:mark, paragraph),
|
138
|
+
content_tag_for(:del, words(2)),
|
139
|
+
content_tag_for(:ins, words(2)),
|
140
|
+
content_tag_for(:sub, words(2)),
|
141
|
+
content_tag_for(:sup, words(2)),
|
137
142
|
content_tag_for(:code, words(2)),
|
143
|
+
content_tag_for(:small, words(2)),
|
138
144
|
(a 2).to_s
|
139
|
-
] + FFaker::Lorem.paragraphs(count))
|
145
|
+
] + FFaker::Lorem.paragraphs(count - 1))
|
140
146
|
fetch_sample(a, count: count).join(sep)
|
141
147
|
end
|
142
148
|
|
@@ -71,7 +71,7 @@ module FFaker
|
|
71
71
|
if document_digits.size + 1 == verification_multipliers.size && document_digits.uniq.size > 1
|
72
72
|
0.upto(1) do |i|
|
73
73
|
sum = verification_multipliers.drop(1 - i).each_with_index.inject(0) do |val, (value, j)|
|
74
|
-
val + document_digits[j] * value
|
74
|
+
val + (document_digits[j] * value)
|
75
75
|
end
|
76
76
|
validation_digits[i] = (sum %= 11) < 2 ? 0 : 11 - sum
|
77
77
|
document_digits.push(validation_digits[i])
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FFaker
|
4
|
+
module IdentificationEC
|
5
|
+
extend ModuleUtils
|
6
|
+
extend self
|
7
|
+
|
8
|
+
# https://medium.com/@bryansuarez/c%C3%B3mo-validar-c%C3%A9dula-y-ruc-en-ecuador-b62c5666186f
|
9
|
+
# Cedula de Identificacion
|
10
|
+
def ci
|
11
|
+
first_digits = ci_digits
|
12
|
+
"#{first_digits}#{last_digit(first_digits)}"
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def ci_digits
|
18
|
+
"#{FFaker.numerify('##')}#{rand(0..5)}#{FFaker.numerify('######')}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def last_digit(digits)
|
22
|
+
mod = digits_sum(digits) % 10
|
23
|
+
10 - mod if mod > 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def digits_sum(digits)
|
27
|
+
sum = 0
|
28
|
+
digits.chars.each_with_index do |char, index|
|
29
|
+
if index.even?
|
30
|
+
multiple = char.to_i * 2
|
31
|
+
sum += multiple > 9 ? multiple - 9 : multiple
|
32
|
+
else
|
33
|
+
sum += char.to_i
|
34
|
+
end
|
35
|
+
end
|
36
|
+
sum
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -20,10 +20,10 @@ module FFaker
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def dv(rut)
|
23
|
-
total = rut.to_s.rjust(8, '0').split(
|
23
|
+
total = rut.to_s.rjust(8, '0').split('').zip(%w[3 2 7 6 5 4 3 2]).sum do |a, b|
|
24
24
|
a.to_i * b.to_i
|
25
25
|
end
|
26
|
-
(11 - total % 11).to_s.gsub(
|
26
|
+
(11 - (total % 11)).to_s.gsub('10', 'k').gsub('11', '0')
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -8,11 +8,11 @@ module FFaker
|
|
8
8
|
# Resident Registration Number
|
9
9
|
# http://ko.wikipedia.org/wiki/%EC%A3%BC%EB%AF%BC%EB%93%B1%EB%A1%9D%EB%B2%88%ED%98%B8
|
10
10
|
def rrn
|
11
|
-
birth = fetch_sample(Date.new(1970, 1, 1)
|
11
|
+
birth = fetch_sample(::Date.new(1970, 1, 1)..::Date.new(1999, 12, 31)).strftime('%y%d%m')
|
12
12
|
sex = fetch_sample([1, 2])
|
13
13
|
loc = FFaker.numerify("#{fetch_sample(Array('00'..'95'))}###")
|
14
|
-
a, b, c, d, e, f, g, h, i, j, k, l = "#{birth}#{sex}#{loc}".split(
|
15
|
-
checksum = (11 - (2 * a + 3 * b + 4 * c + 5 * d + 6 * e + 7 * f + 8 * g + 9 * h + 2 * i + 3 * j + 4 * k + 5 * l) % 11) % 10
|
14
|
+
a, b, c, d, e, f, g, h, i, j, k, l = "#{birth}#{sex}#{loc}".split('').map(&:to_i)
|
15
|
+
checksum = (11 - (((2 * a) + (3 * b) + (4 * c) + (5 * d) + (6 * e) + (7 * f) + (8 * g) + (9 * h) + (2 * i) + (3 * j) + (4 * k) + (5 * l)) % 11)) % 10
|
16
16
|
"#{birth}-#{sex}#{loc}#{checksum}"
|
17
17
|
end
|
18
18
|
end
|
@@ -37,8 +37,8 @@ module FFaker
|
|
37
37
|
private
|
38
38
|
|
39
39
|
def generate_valid_pesel_date
|
40
|
-
from = Date.new(1800, 1, 1)
|
41
|
-
to = [Date.today, Date.new(2299, 12, 31)].min
|
40
|
+
from = ::Date.new(1800, 1, 1)
|
41
|
+
to = [::Date.today, ::Date.new(2299, 12, 31)].min
|
42
42
|
fetch_sample(from..to)
|
43
43
|
end
|
44
44
|
|
@@ -65,13 +65,13 @@ module FFaker
|
|
65
65
|
def pesel_checksum(date, serial_number)
|
66
66
|
pesel_digits = "#{date}#{serial_number}".split('').map(&:to_i)
|
67
67
|
a, b, c, d, e, f, g, h, i, j = pesel_digits
|
68
|
-
(a * 9 + b * 7 + c * 3 + d + e * 9 + f * 7 + g * 3 + h + i * 9 + j * 7) % 10
|
68
|
+
((a * 9) + (b * 7) + (c * 3) + d + (e * 9) + (f * 7) + (g * 3) + h + (i * 9) + (j * 7)) % 10
|
69
69
|
end
|
70
70
|
|
71
71
|
def identity_card_checksum(letter_part, number_part)
|
72
72
|
a, b, c = letter_part.codepoints.map { |codepoints| codepoints - 55 }
|
73
73
|
d, e, f, g, h = number_part.split('').map(&:to_i)
|
74
|
-
(a * 7 + b * 3 + c + 7 * d + 3 * e + f + 7 * g + 3 * h) % 10
|
74
|
+
((a * 7) + (b * 3) + c + (7 * d) + (3 * e) + f + (7 * g) + (3 * h)) % 10
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
@@ -5,7 +5,8 @@ module FFaker
|
|
5
5
|
extend ModuleUtils
|
6
6
|
extend self
|
7
7
|
|
8
|
-
AREA_CODE = { a: 10, b: 11, c: 12, d: 13, e: 14, f: 15, g: 16, h: 17, i: 34, j: 18, k: 19, l: 20, m: 21, n: 22,
|
8
|
+
AREA_CODE = { a: 10, b: 11, c: 12, d: 13, e: 14, f: 15, g: 16, h: 17, i: 34, j: 18, k: 19, l: 20, m: 21, n: 22,
|
9
|
+
o: 35, p: 23, q: 24, r: 25, s: 26, t: 27, u: 28, v: 29, w: 32, x: 30, y: 31, z: 33 }.freeze
|
9
10
|
|
10
11
|
# Identity Card Number
|
11
12
|
# https://en.wikipedia.org/wiki/National_identification_card_(Taiwan)#Identity_card_number
|
@@ -14,9 +15,9 @@ module FFaker
|
|
14
15
|
code = AREA_CODE[letter.to_sym]
|
15
16
|
gender = fetch_sample([1, 2])
|
16
17
|
serial = FFaker.numerify('#######')
|
17
|
-
a, b, c, d, e, f, g, h, i, j = "#{code}#{gender}#{serial}".
|
18
|
+
a, b, c, d, e, f, g, h, i, j = "#{code}#{gender}#{serial}".chars.map(&:to_i)
|
18
19
|
|
19
|
-
checksum = (9 * a + b + 2 * c + 3 * d + 4 * e + 5 * f + 6 * g + 7 * h + 8 * i + 9 * j) % 10
|
20
|
+
checksum = ((9 * a) + b + (2 * c) + (3 * d) + (4 * e) + (5 * f) + (6 * g) + (7 * h) + (8 * i) + (9 * j)) % 10
|
20
21
|
"#{letter.upcase}#{gender}#{serial}#{checksum}"
|
21
22
|
end
|
22
23
|
end
|
data/lib/ffaker/jo_jo.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FFaker
|
4
|
+
module JoJo
|
5
|
+
extend ModuleUtils
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def full_name
|
9
|
+
fetch_sample(FULL_NAMES)
|
10
|
+
end
|
11
|
+
|
12
|
+
def first_name
|
13
|
+
fetch_sample(FIRST_NAMES)
|
14
|
+
end
|
15
|
+
|
16
|
+
def last_name
|
17
|
+
fetch_sample(LAST_NAMES)
|
18
|
+
end
|
19
|
+
|
20
|
+
def stand
|
21
|
+
fetch_sample(STANDS)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/ffaker/name_pl.rb
CHANGED
@@ -11,7 +11,7 @@ module FFaker
|
|
11
11
|
GENDERS = %i[random female male].freeze
|
12
12
|
MALE_PREFIXES = %w[Pan].freeze
|
13
13
|
FEMALE_PREFIXES = %w[Pani].freeze
|
14
|
-
ACADEMIC_DEGREE_PREFIXES =
|
14
|
+
ACADEMIC_DEGREE_PREFIXES = ['lic.', 'inż.', 'mgr', 'mgr inż.', 'dr', 'dr hab.', 'prof.'].freeze
|
15
15
|
PREFIXES = (MALE_PREFIXES + FEMALE_PREFIXES + ACADEMIC_DEGREE_PREFIXES).freeze
|
16
16
|
|
17
17
|
# Generates a random full name for a given gender (random by default).
|
data/lib/ffaker/number.rb
CHANGED
@@ -18,9 +18,9 @@ module FFaker
|
|
18
18
|
private
|
19
19
|
|
20
20
|
def generate_pattern(digits)
|
21
|
-
raise ArgumentError
|
21
|
+
raise ArgumentError, 'Digits cannot be less than 1' if digits < 1
|
22
22
|
|
23
|
-
"#{fetch_sample(1..9)}#{
|
23
|
+
"#{fetch_sample(1..9)}#{'#' * (digits - 1)}"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/ffaker/ssn_se.rb
CHANGED
@@ -54,7 +54,7 @@ module FFaker
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def random_birth_time_between(from = ::Time.local(1940, 1, 1), to = ::Time.now)
|
57
|
-
::Time.at(from + rand * (to.to_f - from.to_f))
|
57
|
+
::Time.at(from + (rand * (to.to_f - from.to_f)))
|
58
58
|
end
|
59
59
|
|
60
60
|
def random_region_for(gender)
|
@@ -70,7 +70,7 @@ module FFaker
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def random_region_odd
|
73
|
-
rand(0..498) * 2 + 1
|
73
|
+
(rand(0..498) * 2) + 1
|
74
74
|
end
|
75
75
|
|
76
76
|
def three_character_string(number)
|
data/lib/ffaker/string.rb
CHANGED
@@ -21,7 +21,7 @@ module FFaker
|
|
21
21
|
@last_token = nil
|
22
22
|
|
23
23
|
# Drop surrounding /'s and split into characters
|
24
|
-
tokens = exp.inspect[1...-1].split(
|
24
|
+
tokens = exp.inspect[1...-1].split('')
|
25
25
|
result << process_token(tokens) until tokens.empty?
|
26
26
|
|
27
27
|
result
|
@@ -53,15 +53,15 @@ module FFaker
|
|
53
53
|
when '?'
|
54
54
|
# TODO: Let ? generate nothing
|
55
55
|
'' # We already printed its target
|
56
|
-
when '+'
|
56
|
+
when '+'
|
57
57
|
tokens.unshift(token) if rand(0..1) == 1 # Leave the `+` on to run again
|
58
58
|
process_token(@last_token) # Run the last one at least once
|
59
|
-
when '*'
|
59
|
+
when '*'
|
60
60
|
tokens.unshift(token) if rand(0..1) == 1 # Leave the `*` on to run again
|
61
61
|
return '' if rand(0..1) == 1 # Or maybe do nothing
|
62
62
|
|
63
63
|
process_token(@last_token) # Else run the last one again
|
64
|
-
when '{'
|
64
|
+
when '{'
|
65
65
|
number = +''
|
66
66
|
while (ch = tokens.shift) != '}'
|
67
67
|
number << ch
|
@@ -76,14 +76,14 @@ module FFaker
|
|
76
76
|
|
77
77
|
def generate_token(token, tokens)
|
78
78
|
case token
|
79
|
-
when /\w/
|
79
|
+
when /\w/
|
80
80
|
@last_token = [token]
|
81
81
|
token
|
82
|
-
when BACKSLASH
|
82
|
+
when BACKSLASH
|
83
83
|
token = tokens.shift
|
84
84
|
@last_token = ['\\', token]
|
85
85
|
special(token)
|
86
|
-
when '['
|
86
|
+
when '['
|
87
87
|
set = []
|
88
88
|
while (ch = tokens.shift) != ']'
|
89
89
|
set << ch
|
data/lib/ffaker/time.rb
CHANGED
@@ -22,17 +22,17 @@ module FFaker
|
|
22
22
|
|
23
23
|
def datetime(params = {})
|
24
24
|
years_back = params[:year_range] || 5
|
25
|
-
latest_year = params
|
25
|
+
latest_year = params[:year_latest] || 0
|
26
26
|
year = (rand * years_back).ceil + (::DateTime.now.year - latest_year - years_back)
|
27
27
|
month = rand(1..12)
|
28
|
-
day = rand(1
|
28
|
+
day = rand(1..::Date.new(year, month, -1).day)
|
29
29
|
hours = params[:hours] || rand(0..23)
|
30
30
|
minutes = params[:minutes] || rand(0..59)
|
31
31
|
series = [date = ::DateTime.new(year, month, day, hours, minutes)]
|
32
32
|
return date unless params[:series]
|
33
33
|
|
34
34
|
params[:series].each do |some_time_after|
|
35
|
-
series << series.last + (rand * some_time_after).ceil
|
35
|
+
series << (series.last + (rand * some_time_after).ceil)
|
36
36
|
end
|
37
37
|
series
|
38
38
|
end
|
@@ -44,7 +44,7 @@ module FFaker
|
|
44
44
|
def between(from, to)
|
45
45
|
from_value = convert_to_time(from)
|
46
46
|
to_value = convert_to_time(to)
|
47
|
-
::Time.at(from_value + rand * (to_value.to_f - from_value.to_f))
|
47
|
+
::Time.at(from_value + (rand * (to_value.to_f - from_value.to_f)))
|
48
48
|
end
|
49
49
|
|
50
50
|
private
|
@@ -25,7 +25,7 @@ module FFaker
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def underscore(string)
|
28
|
-
string.gsub(
|
28
|
+
string.gsub('::', '/')
|
29
29
|
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
30
30
|
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
31
31
|
.tr('-', '_')
|
@@ -33,14 +33,14 @@ module FFaker
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def unique(max_retries = 10_000)
|
36
|
-
|
36
|
+
FFaker::UniqueUtils.add_instance(self, max_retries)
|
37
37
|
end
|
38
38
|
|
39
39
|
# http://en.wikipedia.org/wiki/Luhn_algorithm
|
40
40
|
def luhn_check(number)
|
41
41
|
multiplications = []
|
42
42
|
|
43
|
-
number.split(
|
43
|
+
number.split('').each_with_index do |digit, i|
|
44
44
|
multiplications << i.even? ? digit.to_i * 2 : digit.to_i
|
45
45
|
end
|
46
46
|
|
@@ -51,9 +51,8 @@ module FFaker
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
control_digit = (sum % 10).zero? ? 0 : (sum / 10 + 1) * 10 - sum
|
54
|
+
control_digit = (sum % 10).zero? ? 0 : (((sum / 10) + 1) * 10) - sum
|
55
55
|
control_digit.to_s
|
56
56
|
end
|
57
|
-
|
58
57
|
end
|
59
58
|
end
|
@@ -1,43 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'set'
|
4
|
+
|
3
5
|
module FFaker
|
4
6
|
class UniqueUtils
|
5
|
-
|
6
|
-
@generator = generator
|
7
|
-
@max_retries = max_retries
|
8
|
-
@previous_results = Hash.new { |hash, key| hash[key] = Set.new }
|
9
|
-
end
|
7
|
+
RetryLimitExceeded = Class.new(StandardError)
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
class << self
|
10
|
+
def add_instance(generator, max_retries)
|
11
|
+
instances[generator] ||= FFaker::UniqueUtils.new(generator, max_retries)
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def instances
|
15
|
+
Thread.current[:ffaker_unique_utils] ||= {}
|
16
|
+
end
|
18
17
|
|
19
|
-
|
18
|
+
def clear
|
19
|
+
instances.values.each(&:clear)
|
20
|
+
instances.clear
|
21
|
+
end
|
22
|
+
end
|
20
23
|
|
21
|
-
def
|
22
|
-
@
|
24
|
+
def initialize(generator, max_retries)
|
25
|
+
@generator = generator
|
26
|
+
@max_retries = max_retries
|
23
27
|
end
|
24
28
|
|
25
|
-
def
|
26
|
-
|
29
|
+
def clear
|
30
|
+
previous_results.clear
|
27
31
|
end
|
28
32
|
|
29
33
|
private
|
30
34
|
|
31
|
-
def
|
35
|
+
def method_missing(name, *arguments)
|
32
36
|
@max_retries.times do
|
33
|
-
result = @generator.
|
37
|
+
result = @generator.public_send(name, *arguments)
|
34
38
|
|
35
|
-
next if
|
39
|
+
next if previous_results[[name, arguments]].include?(result)
|
36
40
|
|
37
|
-
|
41
|
+
previous_results[[name, arguments]] << result
|
38
42
|
return result
|
39
43
|
end
|
40
|
-
|
44
|
+
|
45
|
+
raise RetryLimitExceeded, "Retry limit exceeded for #{name}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def previous_results
|
49
|
+
@previous_results ||= Hash.new { |hash, key| hash[key] = Set.new }
|
41
50
|
end
|
42
51
|
end
|
43
52
|
end
|
data/lib/ffaker/vehicle.rb
CHANGED
@@ -2,6 +2,68 @@
|
|
2
2
|
|
3
3
|
module FFaker
|
4
4
|
module Vehicle
|
5
|
+
module VIN
|
6
|
+
extend ModuleUtils
|
7
|
+
extend self
|
8
|
+
|
9
|
+
# https://en.wikibooks.org/wiki/Vehicle_Identification_Numbers_(VIN_codes)/World_Manufacturer_Identifier_(WMI)
|
10
|
+
VALID_WMI_REGIONS = [*'A'..'C', *'J'..'N', 'P', *'R'..'Z', *'1'..'9'].freeze
|
11
|
+
|
12
|
+
VALID_YEAR_CHARS = %w[
|
13
|
+
5 6 7 8 9 A B C D E F G H J K L M N P R S T V W X Y 1 2 3 4 5 6 7 8 9
|
14
|
+
].freeze # 2005-2039
|
15
|
+
|
16
|
+
# https://en.wikibooks.org/wiki/Vehicle_Identification_Numbers_(VIN_codes)/Check_digit
|
17
|
+
TRANSLITERATION_VALUES = {
|
18
|
+
'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8,
|
19
|
+
'J' => 1, 'K' => 2, 'L' => 3, 'M' => 4, 'N' => 5, 'P' => 7, 'R' => 9,
|
20
|
+
'S' => 2, 'T' => 3, 'U' => 4, 'V' => 5, 'W' => 6, 'X' => 7, 'Y' => 8, 'Z' => 9
|
21
|
+
}.freeze
|
22
|
+
POSITION_WEIGHTS = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2].freeze
|
23
|
+
|
24
|
+
VALID_ALPHA = TRANSLITERATION_VALUES.keys
|
25
|
+
VALID_ALPHANUMERIC = [*VALID_ALPHA, *'1'..'9'].freeze
|
26
|
+
|
27
|
+
# Generate a VIN that is compliant with specifications of US Title 49 Section 565.15
|
28
|
+
# https://www.govinfo.gov/content/pkg/CFR-2019-title49-vol6/xml/CFR-2019-title49-vol6-part565.xml#seqnum565.15
|
29
|
+
#
|
30
|
+
# Position Meaning
|
31
|
+
# 1-3 Manufacturer ID aka WMI (alpha and digits)
|
32
|
+
# 4-8 Vehicle Description ("For passenger cars ..[position 7].. shall be alphabetic")
|
33
|
+
# 9 Check Digit (0-9 or "X")
|
34
|
+
# 10 Year (see VIN_VALID_YEARS)
|
35
|
+
# 11 Plant of manufacture (alpha and digits)
|
36
|
+
# 12-17 Serial number (digits only)
|
37
|
+
#
|
38
|
+
# I, O and Q are NOT allowed. VIN_VALID_ALPHA has valid alpha characters.
|
39
|
+
def vin
|
40
|
+
generated_vin = [
|
41
|
+
# Manufacturer ID / WMI
|
42
|
+
fetch_sample(VALID_WMI_REGIONS),
|
43
|
+
fetch_sample(VALID_ALPHANUMERIC, count: 2),
|
44
|
+
# Vehicle Description
|
45
|
+
fetch_sample(VALID_ALPHANUMERIC, count: 3),
|
46
|
+
fetch_sample(VALID_ALPHA),
|
47
|
+
fetch_sample(VALID_ALPHANUMERIC),
|
48
|
+
'0', # check digit placeholder
|
49
|
+
fetch_sample(VALID_YEAR_CHARS), # Year of Manufacture
|
50
|
+
fetch_sample(VALID_ALPHANUMERIC), # Plant ID
|
51
|
+
FFaker.numerify('######') # Serial Number
|
52
|
+
].join
|
53
|
+
|
54
|
+
# Calculate the Check Digit
|
55
|
+
weighted_sum = generated_vin.chars.each_with_index.sum do |char, idx|
|
56
|
+
(TRANSLITERATION_VALUES[char] || char).to_i * POSITION_WEIGHTS[idx]
|
57
|
+
end
|
58
|
+
|
59
|
+
check_digit = weighted_sum % 11
|
60
|
+
check_digit = 'X' if check_digit == 10
|
61
|
+
generated_vin[8] = check_digit.to_s
|
62
|
+
|
63
|
+
generated_vin
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
5
67
|
extend ModuleUtils
|
6
68
|
extend self
|
7
69
|
|
@@ -37,7 +99,7 @@ module FFaker
|
|
37
99
|
end
|
38
100
|
|
39
101
|
def vin
|
40
|
-
|
102
|
+
VIN.vin
|
41
103
|
end
|
42
104
|
|
43
105
|
def year
|