ffaker 2.20.0 → 2.22.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|