faker 3.2.0 → 3.5.2

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.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +437 -2
  3. data/README.md +29 -14
  4. data/lib/faker/books/lovecraft.rb +2 -3
  5. data/lib/faker/default/address.rb +2 -2
  6. data/lib/faker/default/alphanumeric.rb +1 -1
  7. data/lib/faker/default/chile_rut.rb +23 -17
  8. data/lib/faker/default/code.rb +64 -18
  9. data/lib/faker/default/company.rb +99 -5
  10. data/lib/faker/default/crypto.rb +13 -4
  11. data/lib/faker/default/date.rb +61 -5
  12. data/lib/faker/default/driving_licence.rb +19 -8
  13. data/lib/faker/default/finance.rb +2 -2
  14. data/lib/faker/default/hipster.rb +2 -3
  15. data/lib/faker/default/html.rb +230 -0
  16. data/lib/faker/default/id_number.rb +38 -24
  17. data/lib/faker/default/internet.rb +19 -53
  18. data/lib/faker/default/invoice.rb +3 -3
  19. data/lib/faker/default/json.rb +9 -4
  20. data/lib/faker/default/lorem.rb +6 -3
  21. data/lib/faker/default/{nhs.rb → national_health_service.rb} +8 -4
  22. data/lib/faker/default/number.rb +1 -1
  23. data/lib/faker/default/omniauth.rb +4 -4
  24. data/lib/faker/default/phone_number.rb +37 -18
  25. data/lib/faker/default/placeholdit.rb +1 -1
  26. data/lib/faker/default/south_africa.rb +3 -3
  27. data/lib/faker/{music/show.rb → default/theater.rb} +8 -8
  28. data/lib/faker/default/types.rb +5 -6
  29. data/lib/faker/default/vehicle.rb +23 -11
  30. data/lib/faker/games/final_fantasy_xiv.rb +73 -0
  31. data/lib/faker/games/heroes_of_the_storm.rb +0 -11
  32. data/lib/faker/japanese_media/fullmetal_alchemist_brotherhood.rb +10 -10
  33. data/lib/faker/locations/australia.rb +40 -38
  34. data/lib/faker/movies/star_wars.rb +1 -1
  35. data/lib/faker/movies/{room.rb → the_room.rb} +4 -4
  36. data/lib/faker/music/smashing_pumpkins.rb +64 -0
  37. data/lib/faker/travel/airport.rb +2 -2
  38. data/lib/faker/travel/train_station.rb +54 -0
  39. data/lib/faker/tv_shows/archer.rb +51 -0
  40. data/lib/faker/tv_shows/buffy.rb +0 -13
  41. data/lib/faker/tv_shows/dr_who.rb +0 -13
  42. data/lib/faker/tv_shows/south_park.rb +15 -0
  43. data/lib/faker/tv_shows/the_fresh_prince_of_bel_air.rb +0 -13
  44. data/lib/faker/version.rb +1 -1
  45. data/lib/faker.rb +20 -8
  46. data/lib/helpers/deprecator.rb +118 -0
  47. data/lib/helpers/positional_generator.rb +480 -0
  48. data/lib/locales/README.md +18 -2
  49. data/lib/locales/bg.yml +0 -1
  50. data/lib/locales/da-DK.yml +529 -35
  51. data/lib/locales/de-AT.yml +3487 -26
  52. data/lib/locales/de-CH.yml +4359 -12
  53. data/lib/locales/de.yml +7182 -100
  54. data/lib/locales/ee.yml +0 -1
  55. data/lib/locales/en/address.yml +1826 -561
  56. data/lib/locales/en/archer.yml +75 -0
  57. data/lib/locales/en/australia.yml +106 -105
  58. data/lib/locales/en/bank.yml +1 -1
  59. data/lib/locales/en/cosmere.yml +1 -1
  60. data/lib/locales/en/dog.yml +262 -7
  61. data/lib/locales/en/dota.yml +120 -67
  62. data/lib/locales/en/final_fantasy_xiv.yml +754 -0
  63. data/lib/locales/en/finance.yml +4 -4
  64. data/lib/locales/en/food.yml +2 -1
  65. data/lib/locales/en/{fma_brotherhood.yml → fullmetal_alchemist_brotherhood.yml} +3 -3
  66. data/lib/locales/en/harry_potter.yml +1 -1
  67. data/lib/locales/en/id_number.yml +1 -1
  68. data/lib/locales/en/internet.yml +0 -4
  69. data/lib/locales/en/minecraft.yml +4 -4
  70. data/lib/locales/en/music.yml +25 -25
  71. data/lib/locales/en/opera.yml +1 -1
  72. data/lib/locales/en/phone_number.yml +78 -3
  73. data/lib/locales/en/restaurant.yml +1 -1
  74. data/lib/locales/en/smashing_pumpkins.yml +382 -0
  75. data/lib/locales/en/south_park.yml +360 -2
  76. data/lib/locales/en/{room.yml → the_room.yml} +1 -1
  77. data/lib/locales/en/{show.yml → theater.yml} +1 -1
  78. data/lib/locales/en/train_station.yml +280 -0
  79. data/lib/locales/en/vehicle.yml +1 -1
  80. data/lib/locales/en-AU.yml +718 -47
  81. data/lib/locales/en-CA.yml +373 -19
  82. data/lib/locales/en-GB.yml +116 -9
  83. data/lib/locales/en-IND.yml +1259 -17
  84. data/lib/locales/en-KE.yml +212 -0
  85. data/lib/locales/en-MS.yml +364 -18
  86. data/lib/locales/en-NEP.yml +212 -38
  87. data/lib/locales/en-NZ.yml +1153 -124
  88. data/lib/locales/en-PAK.yml +392 -11
  89. data/lib/locales/en-SG.yml +581 -17
  90. data/lib/locales/en-US.yml +6914 -74
  91. data/lib/locales/en-au-ocker.yml +266 -24
  92. data/lib/locales/es-AR.yml +4569 -4600
  93. data/lib/locales/es-MX.yml +0 -1
  94. data/lib/locales/es.yml +0 -1
  95. data/lib/locales/fr/address.yml +761 -8
  96. data/lib/locales/fr/internet.yml +0 -1
  97. data/lib/locales/fr/name.yml +2 -1
  98. data/lib/locales/fr-CA.yml +2733 -44
  99. data/lib/locales/fr-CH.yml +0 -1
  100. data/lib/locales/fr.yml +3 -1
  101. data/lib/locales/hy.yml +3624 -120
  102. data/lib/locales/id.yml +839 -12
  103. data/lib/locales/it.yml +1304 -33
  104. data/lib/locales/ja/book.yml +492 -3
  105. data/lib/locales/ja/football.yml +115 -0
  106. data/lib/locales/ja/lorem.yml +1 -1
  107. data/lib/locales/ja/sport.yml +130 -0
  108. data/lib/locales/ja/touhou.yml +466 -0
  109. data/lib/locales/ko.yml +1361 -21
  110. data/lib/locales/lt.yml +297 -16
  111. data/lib/locales/lv.yml +0 -1
  112. data/lib/locales/nb-NO.yml +518 -30
  113. data/lib/locales/nl.yml +9 -2
  114. data/lib/locales/pl.yml +0 -1
  115. data/lib/locales/pt-BR.yml +8205 -665
  116. data/lib/locales/pt.yml +844 -45
  117. data/lib/locales/ru.yml +1353 -70
  118. data/lib/locales/sk.yml +4410 -44
  119. data/lib/locales/sv.yml +99 -0
  120. data/lib/locales/tr.yml +0 -2
  121. data/lib/locales/uk.yml +1808 -45
  122. data/lib/locales/zh-CN/bank.yml +17 -0
  123. metadata +26 -154
  124. data/History.md +0 -176
@@ -119,8 +119,8 @@ module Faker
119
119
  return numerify(letterified_string, leading_zero: true)
120
120
  end
121
121
 
122
- # provide a zip code that is valid for the state provided
123
- # see http://www.fincen.gov/forms/files/us_state_territory_zip_codes.pdf
122
+ # provide a zip code that may be valid for the state provided
123
+ # note: zip code may appear in the correct format for the state provided but may not be an actual state zip.
124
124
  bothify(fetch("address.postcode_by_state.#{state_abbreviation}"))
125
125
  end
126
126
 
@@ -60,7 +60,7 @@ module Faker
60
60
  randoms = Array.new(random_count) { sample(ALPHANUMS) }
61
61
 
62
62
  combined = alphas + numbers + randoms
63
- combined.shuffle.join
63
+ shuffle!(combined).join
64
64
  end
65
65
  end
66
66
  end
@@ -8,18 +8,19 @@ module Faker
8
8
  ##
9
9
  # Produces a random Chilean RUT (Rol Unico Tributario, ID with 8 digits).
10
10
  #
11
- # @param min_rut [Integer] Specifies the minimum value of the rut.
12
- # @param fixed [Boolean] Determines if the rut is fixed (returns the min_rut value).
11
+ # @param min_rut [Integer] Specifies the minimum value of the RUT.
12
+ # @param max_rut [Integer] Specifies the maximum value of the RUT.
13
+ # @param fixed [Boolean] Determines if the RUT is fixed (returns the min_rut value).
13
14
  # @return [Number]
14
15
  #
15
16
  # @example
16
17
  # Faker::ChileRut.rut #=> 11235813
17
- # Faker::ChileRut.rut(min_rut: 20890156) #=> 31853211
18
- # Faker::ChileRut.rut(min_rut: 20890156, fixed: true) #=> 20890156
18
+ # Faker::ChileRut.rut(min_rut: 10_000_000, max_rut: 30_000_000) #=> 21853211
19
+ # Faker::ChileRut.rut(min_rut: 20_890_156, fixed: true) #=> 20890156
19
20
  #
20
- # @faker.version 1.9.2
21
- def rut(min_rut: 1, fixed: false)
22
- @last_rut = fixed ? min_rut : rand_in_range(min_rut, 99_999_999)
21
+ # @faker.version next
22
+ def rut(min_rut: 1, max_rut: 99_999_999, fixed: false)
23
+ @last_rut = fixed ? min_rut : rand_in_range(min_rut, max_rut)
23
24
  end
24
25
 
25
26
  ##
@@ -68,25 +69,30 @@ module Faker
68
69
  ##
69
70
  # Produces a random Chilean RUT (Rol Unico Tributario, ID with 8 digits) with a dv (digito verificador, check-digit).
70
71
  #
71
- # @param min_rut [Integer] Specifies the minimum value of the rut.
72
- # @param fixed [Boolean] Determines if the rut is fixed (returns the min_rut value).
72
+ # @param min_rut [Integer] Specifies the minimum value of the RUT.
73
+ # @param max_rut [Integer] Specifies the maximum value of the RUT.
74
+ # @param fixed [Boolean] Determines if the RUT is fixed (returns the min_rut value).
73
75
  # @return [String]
74
76
  #
75
77
  # @example
76
78
  # Faker::ChileRut.full_rut #=> "30686957-4"
77
- # Faker::ChileRut.full_rut(min_rut: 20890156) #=> "30686957-4"
78
- # Faker::ChileRut.full_rut(min_rut: 30686957, fixed: true) #=> "30686957-4"
79
+ # Faker::ChileRut.full_rut(min_rut: 10_000_000, max_rut: 30_000_000) #=> "20686957-4"
80
+ # Faker::ChileRut.full_rut(min_rut: 30_686_957, fixed: true) #=> "30686957-4"
79
81
  #
80
82
  # @faker.version next
81
- def full_rut(min_rut: 0, fixed: false, formatted: false)
82
- if formatted
83
- "#{rut(min_rut: min_rut, fixed: fixed).to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1.').reverse}-#{dv}"
84
- else
85
- "#{rut(min_rut: min_rut, fixed: fixed)}-#{dv}"
86
- end
83
+ def full_rut(min_rut: 1, max_rut: 99_999_999, fixed: false, formatted: false)
84
+ this_rut = rut(min_rut: min_rut, max_rut: max_rut, fixed: fixed)
85
+ this_rut = format_rut(this_rut) if formatted
86
+ "#{this_rut}-#{dv}"
87
87
  end
88
88
 
89
89
  attr_reader :last_rut
90
+
91
+ private
92
+
93
+ def format_rut(rut)
94
+ rut.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1.').reverse
95
+ end
90
96
  end
91
97
  end
92
98
  end
@@ -93,11 +93,23 @@ module Faker
93
93
  # @faker.version 2.2.0
94
94
  def nric(min_age: 18, max_age: 65)
95
95
  birthyear = Date.birthday(min_age: min_age, max_age: max_age).year
96
- prefix = birthyear < 2000 ? 'S' : 'T'
97
- values = birthyear.to_s[-2..]
98
- values << regexify(/\d{5}/)
99
- check_alpha = generate_nric_check_alphabet(values, prefix)
100
- "#{prefix}#{values}#{check_alpha}"
96
+
97
+ generate(:string) do |g|
98
+ g.computed(name: :prefix) do
99
+ if birthyear < 2000
100
+ 'S'
101
+ else
102
+ 'T'
103
+ end
104
+ end
105
+ g.computed(name: :yy) do
106
+ birthyear.to_s[-2..]
107
+ end
108
+ g.int(name: :values, length: 5)
109
+ g.computed(name: :check, deps: %i[prefix yy values]) do |prefix, yy, values|
110
+ generate_nric_check_alphabet("#{yy}#{values}", prefix)
111
+ end
112
+ end
101
113
  end
102
114
 
103
115
  ##
@@ -156,6 +168,7 @@ module Faker
156
168
 
157
169
  # Reporting body identifier
158
170
  RBI = %w[01 10 30 33 35 44 45 49 50 51 52 53 54 86 91 98 99].freeze
171
+ private_constant :RBI
159
172
 
160
173
  def generate_imei
161
174
  str = Array.new(15, 0)
@@ -197,15 +210,29 @@ module Faker
197
210
  end
198
211
 
199
212
  def generate_base10_isbn
200
- values = regexify(/\d{9}/)
201
- remainder = sum(values) { |value, index| (index + 1) * value.to_i } % 11
202
- values << "-#{remainder == 10 ? 'X' : remainder}"
213
+ generate(:string) do |g|
214
+ g.int(name: :values, length: 9)
215
+ g.lit('-')
216
+ g.computed(name: :checksum, deps: [:values]) do |values|
217
+ remainder = sum(values.to_s) { |value, offset| (offset + 1) * value.to_i } % 11
218
+ if remainder == 10
219
+ 'X'
220
+ else
221
+ remainder.to_s
222
+ end
223
+ end
224
+ end
203
225
  end
204
226
 
205
227
  def generate_base13_isbn
206
- values = regexify(/\d{12}/)
207
- remainder = sum(values) { |value, index| index.even? ? value.to_i : value.to_i * 3 } % 10
208
- values << "-#{(10 - remainder) % 10}"
228
+ generate(:string) do |g|
229
+ g.int(name: :values, length: 12)
230
+ g.lit('-')
231
+ g.computed(name: :checksum, deps: [:values]) do |values|
232
+ remainder = sum(values.to_s) { |value, offset| offset.even? ? value.to_i : value.to_i * 3 } % 10
233
+ (10 - remainder) % 10
234
+ end
235
+ end
209
236
  end
210
237
 
211
238
  def sum(values)
@@ -215,23 +242,42 @@ module Faker
215
242
  end
216
243
 
217
244
  def generate_base8_ean
218
- values = regexify(/\d{7}/)
219
- check_digit = 10 - values.chars.each_with_index.inject(0) { |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT8[i] } % 10
220
- values << (check_digit == 10 ? 0 : check_digit).to_s
245
+ generate(:string) do |g|
246
+ g.int(name: :values, length: 7)
247
+ g.computed(name: :checksum, deps: [:values]) do |values|
248
+ check_digit = 10 - values.to_s.chars.each_with_index.inject(0) { |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT8[i] } % 10
249
+ if check_digit == 10
250
+ 0
251
+ else
252
+ check_digit
253
+ end
254
+ end
255
+ end
221
256
  end
222
257
 
223
258
  def generate_base13_ean
224
- values = regexify(/\d{12}/)
225
- check_digit = 10 - values.chars.each_with_index.inject(0) { |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT13[i] } % 10
226
- values << (check_digit == 10 ? 0 : check_digit).to_s
259
+ generate(:string) do |g|
260
+ g.int(name: :values, length: 12)
261
+ g.computed(name: :checksum, deps: [:values]) do |values|
262
+ check_digit = 10 - values.to_s.chars.each_with_index.inject(0) { |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT13[i] } % 10
263
+ if check_digit == 10
264
+ 0
265
+ else
266
+ check_digit
267
+ end
268
+ end
269
+ end
227
270
  end
228
271
 
229
272
  EAN_CHECK_DIGIT8 = [3, 1, 3, 1, 3, 1, 3].freeze
273
+ private_constant :EAN_CHECK_DIGIT8
274
+
230
275
  EAN_CHECK_DIGIT13 = [1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3].freeze
276
+ private_constant :EAN_CHECK_DIGIT13
231
277
 
232
278
  def rut_verificator_digit(rut)
233
279
  total = rut.to_s.rjust(8, '0').chars.zip(%w[3 2 7 6 5 4 3 2]).collect { |a, b| a.to_i * b.to_i }.inject(:+)
234
- (11 - total % 11).to_s.gsub(/10/, 'k').gsub(/11/, '0')
280
+ (11 - total % 11).to_s.gsub('10', 'k').gsub('11', '0')
235
281
  end
236
282
 
237
283
  def generate_nric_check_alphabet(values, prefix)
@@ -343,7 +343,12 @@ module Faker
343
343
  #
344
344
  # @faker.version 1.9.2
345
345
  def south_african_pty_ltd_registration_number
346
- regexify(%r{\d{4}/\d{4,10}/07})
346
+ generate(:string) do |g|
347
+ g.int(length: 4)
348
+ g.lit('/')
349
+ g.int(ranges: [1000..9_999_999_999])
350
+ g.lit('/07')
351
+ end
347
352
  end
348
353
 
349
354
  ##
@@ -356,7 +361,18 @@ module Faker
356
361
  #
357
362
  # @faker.version 1.9.2
358
363
  def south_african_close_corporation_registration_number
359
- regexify(%r{(CK\d{2}|\d{4})/\d{4,10}/23})
364
+ generate(:string) do |g|
365
+ g.oneof do |one|
366
+ one.group do |g_|
367
+ g_.lit('CK')
368
+ g_.int(length: 2)
369
+ end
370
+ one.int(length: 4)
371
+ end
372
+ g.lit('/')
373
+ g.int(ranges: [1000..9_999_999_999])
374
+ g.lit('/23')
375
+ end
360
376
  end
361
377
 
362
378
  ##
@@ -369,7 +385,12 @@ module Faker
369
385
  #
370
386
  # @faker.version 1.9.2
371
387
  def south_african_listed_company_registration_number
372
- regexify(%r{\d{4}/\d{4,10}/06})
388
+ generate(:string) do |g|
389
+ g.int(length: 4)
390
+ g.lit('/')
391
+ g.int(ranges: [1000..9_999_999_999])
392
+ g.lit('/06')
393
+ end
373
394
  end
374
395
 
375
396
  ##
@@ -382,7 +403,12 @@ module Faker
382
403
  #
383
404
  # @faker.version 1.9.2
384
405
  def south_african_trust_registration_number
385
- regexify(%r{IT\d{2,4}/\d{2,10}})
406
+ generate(:string) do |g|
407
+ g.lit('IT')
408
+ g.int(ranges: [10..9999])
409
+ g.lit('/')
410
+ g.int(ranges: [10..9_999_999_999])
411
+ end
386
412
  end
387
413
 
388
414
  ##
@@ -438,6 +464,61 @@ module Faker
438
464
  fetch('company.sic_code')
439
465
  end
440
466
 
467
+ ##
468
+ # Get a random Indian Goods and Services Tax (GST) number.
469
+ # For more on Indian tax number here:
470
+ # https://simple.wikipedia.org/wiki/GSTIN
471
+ # @params state code [String] Any state code.
472
+ #
473
+ # @return [String]
474
+ # @example
475
+ # Faker::Company.indian_gst_number #=> "15VQPNZ2126J2ZU"
476
+ # Faker::Company.indian_gst_number(state_code: "22") #=> "22ZVWEY6632K0ZN"
477
+ #
478
+ # @faker.version 3.2.1
479
+ def indian_gst_number(state_code: nil)
480
+ # Check if state code is valid
481
+ state_code_ranges = [('02'..'38'), ['98']]
482
+ if state_code && !(state_code_ranges[0].include?(state_code) || state_code == '98')
483
+ raise ArgumentError, 'state code must be in a range of 02 to 38 or 98'
484
+ end
485
+
486
+ PositionalGenerator.new(:string) do |gen|
487
+ # Generate a state code if not given
488
+ if state_code
489
+ gen.lit(state_code, name: :state_code_param)
490
+ else
491
+ gen.letter(name: :state_code_param, length: 1, ranges: state_code_ranges)
492
+ end
493
+
494
+ # Construct taxpayer number
495
+ gen.group(name: :taxpayer_number) do |g_|
496
+ g_.letter(length: 3, ranges: ['A'..'Z'])
497
+ g_.letter(length: 1, ranges: [%w[A B C F G H L J P T K]])
498
+ g_.letter(length: 1, ranges: ['A'..'Z'])
499
+ g_.int(length: 4, ranges: [0..9999])
500
+ g_.letter(length: 1, ranges: ['A'..'Z'])
501
+ end
502
+
503
+ gen.int(name: :registration_number, length: 1, ranges: [0..9])
504
+
505
+ gen.letter(name: :z_char, length: 1, ranges: [['Z']])
506
+
507
+ gen.computed(deps: %i[state_code_param taxpayer_number registration_number]) do |state_code_param, taxpayer_number, registration_number|
508
+ gst_base = "#{state_code_param}#{taxpayer_number}#{registration_number}"
509
+ chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.chars
510
+ values = gst_base.chars
511
+ sum = values.map.with_index do |char, index|
512
+ product = chars.index(char) * (index.odd? ? 2 : 1)
513
+ (product / chars.length).floor + (product % chars.length)
514
+ end.reduce(:+)
515
+
516
+ checksum = (chars.length - (sum % chars.length)) % chars.length
517
+ chars[checksum]
518
+ end
519
+ end.generate
520
+ end
521
+
441
522
  private
442
523
 
443
524
  # Mod11 functionality from https://github.com/badmanski/mod11/blob/master/lib/mod11.rb
@@ -567,7 +648,7 @@ module Faker
567
648
  end
568
649
 
569
650
  control = control.to_s[-1].to_i
570
- control = control.zero? ? control : 10 - control
651
+ control = 10 - control unless control.zero?
571
652
 
572
653
  %w[A B C D E F G H J U V].include?(organization_type) ? control : letters[control]
573
654
  end
@@ -579,6 +660,19 @@ module Faker
579
660
 
580
661
  result.to_s[0].to_i + result.to_s[1].to_i
581
662
  end
663
+
664
+ def calculate_gst_checksum(state_code, taxpayer_number, registration_number)
665
+ gst_base = "#{state_code}#{taxpayer_number}#{registration_number}"
666
+ chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.chars
667
+ values = gst_base.upcase.chars
668
+ sum = values.map.with_index do |char, index|
669
+ product = chars.index(char) * (index.odd? ? 2 : 1)
670
+ (product / chars.length).floor + (product % chars.length)
671
+ end.reduce(:+)
672
+
673
+ checksum = (chars.length - (sum % chars.length)) % chars.length
674
+ chars[checksum]
675
+ end
582
676
  end
583
677
  end
584
678
  end
@@ -5,6 +5,15 @@ require 'openssl'
5
5
  module Faker
6
6
  class Crypto < Base
7
7
  class << self
8
+ # Setting the lorem character number lower than the default of
9
+ # 255 reduces the time complexity of each hash algorithm while
10
+ # still returning deterministically unique values. See
11
+ # https://github.com/faker-ruby/faker/pull/2938 for more info.
12
+ MD5_MIN_NUMBER_OF_CHARACTERS = 25
13
+ SHA1_MIN_NUMBER_OF_CHARACTERS = 31
14
+ SHA256_MIN_NUMBER_OF_CHARACTERS = 50
15
+ SHA512_MIN_NUMBER_OF_CHARACTERS = 100
16
+
8
17
  ##
9
18
  # Produces an MD5 hash.
10
19
  #
@@ -15,7 +24,7 @@ module Faker
15
24
  #
16
25
  # @faker.version 1.6.4
17
26
  def md5
18
- OpenSSL::Digest::MD5.hexdigest(Lorem.characters)
27
+ OpenSSL::Digest::MD5.hexdigest(Lorem.characters(number: MD5_MIN_NUMBER_OF_CHARACTERS))
19
28
  end
20
29
 
21
30
  ##
@@ -28,7 +37,7 @@ module Faker
28
37
  #
29
38
  # @faker.version 1.6.4
30
39
  def sha1
31
- OpenSSL::Digest::SHA1.hexdigest(Lorem.characters)
40
+ OpenSSL::Digest::SHA1.hexdigest(Lorem.characters(number: SHA1_MIN_NUMBER_OF_CHARACTERS))
32
41
  end
33
42
 
34
43
  ##
@@ -41,7 +50,7 @@ module Faker
41
50
  #
42
51
  # @faker.version 1.6.4
43
52
  def sha256
44
- OpenSSL::Digest::SHA256.hexdigest(Lorem.characters)
53
+ OpenSSL::Digest::SHA256.hexdigest(Lorem.characters(number: SHA256_MIN_NUMBER_OF_CHARACTERS))
45
54
  end
46
55
 
47
56
  ##
@@ -54,7 +63,7 @@ module Faker
54
63
  #
55
64
  # @faker.version next
56
65
  def sha512
57
- OpenSSL::Digest::SHA512.hexdigest(Lorem.characters)
66
+ OpenSSL::Digest::SHA512.hexdigest(Lorem.characters(number: SHA512_MIN_NUMBER_OF_CHARACTERS))
58
67
  end
59
68
  end
60
69
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Faker
4
4
  class Date < Base
5
+ DAYS_OF_WEEK = %i[sunday monday tuesday wednesday thursday friday saturday].freeze
6
+
5
7
  class << self
6
8
  ##
7
9
  # Produce a random date between two dates.
@@ -53,18 +55,26 @@ module Faker
53
55
  ##
54
56
  # Produce a random date in the future (up to N days).
55
57
  #
58
+ # @param from [Integer] The start of the usable forward date range.
56
59
  # @param days [Integer] The maximum number of days to go into the future.
57
60
  # @return [Date]
58
61
  #
59
- # @example
62
+ # @example if used with or without Rails (Active Support)
60
63
  # Faker::Date.forward(days: 23) #=> #<Date: 2014-10-03>
61
64
  #
65
+ # @example if used with Rails (Active Support)
66
+ # Faker::Date.forward(from: Date.current, days: 17) #=> #<Date: 2022-06-22>
67
+ #
68
+ # @example if used with or without Rails (Active Support)
69
+ # Faker::Date.forward(from: '2022-06-03', days: 10) #=> #<Date: 2022-10-13>
70
+ #
62
71
  # @faker.version 1.0.0
63
- def forward(days: 365)
64
- from = ::Date.today + 1
65
- to = ::Date.today + days
72
+ def forward(from: ::Date.today, days: 365)
73
+ start_date = get_date_object(from)
74
+ since = start_date + 1
75
+ to = start_date + days
66
76
 
67
- between(from: from, to: to).to_date
77
+ between(from: since, to: to).to_date
68
78
  end
69
79
 
70
80
  ##
@@ -128,6 +138,52 @@ module Faker
128
138
  between(from: from, to: to).to_date
129
139
  end
130
140
 
141
+ ##
142
+ # Produce a random date at given day(s) of the week between two dates.
143
+ #
144
+ # @param day [Symbol, Array<Symbol>] # The day(s) of the week. See {DAYS_OF_WEEK}.
145
+ # @param from [Date, String] The start of the usable date range.
146
+ # @param to [Date, String] The end of the usable date range.
147
+ # @return [Date]
148
+ #
149
+ # @example if used with or without Rails (Active Support)
150
+ # Faker::Date.on_day_of_week_between(day: :tuesday, from: '2023-01-01', to: '2023-02-01') #=> #<Date: 2032-01-10>
151
+ #
152
+ # @example if used with Rails (Active Support)
153
+ # Faker::Date.on_day_of_week_between(day: [:saturday, :sunday], from: 1.month.ago, to: Date.today) #=> #<Date: 2014-09-24>
154
+ #
155
+ # @faker.version next
156
+ def on_day_of_week_between(day:, from:, to:)
157
+ days = [day].flatten
158
+ raise ArgumentError, 'Day of week cannot be empty' if days.empty?
159
+
160
+ # Convert given days of the week to numbers used by `Date#wday` method
161
+ numeric_weekdays = days.map do |d|
162
+ DAYS_OF_WEEK.index(d.to_sym.downcase) || raise(ArgumentError, "#{d} is not a valid day of the week")
163
+ end
164
+
165
+ from = get_date_object(from)
166
+ to = get_date_object(to)
167
+ date = Faker::Base.rand_in_range(from, to)
168
+
169
+ # If the initial date is not on one of the wanted days of the week...
170
+ unless numeric_weekdays.include? date.wday
171
+ # ...pick a date nearby that is on one of the wanted days of the week instead
172
+ date += sample(numeric_weekdays) - date.wday
173
+
174
+ # Move date 1 week earlier or later if the adjusted date is now outside the date range
175
+ date += 7 if date < from
176
+ date -= 7 if date > to
177
+
178
+ if date > to || date < from
179
+ raise ArgumentError,
180
+ "There is no #{DAYS_OF_WEEK[date.wday].capitalize} between #{from} and #{to}. Increase the from/to date range or choose a different day of the week."
181
+ end
182
+ end
183
+
184
+ date
185
+ end
186
+
131
187
  private
132
188
 
133
189
  def birthday_date(date, age)
@@ -98,17 +98,28 @@ module Faker
98
98
  end
99
99
 
100
100
  def gb_licence_year(dob, gender)
101
- decade = (dob.year / 10) % 10
102
- year = dob.year % 10
103
- month = gender == :female ? dob.month + 50 : dob.month
104
- # Rubocop's preferred formatting is pretty gory
105
- # rubocop:disable Style/FormatString
106
- "#{decade}#{'%02d' % month}#{'%02d' % dob.day}#{year}"
107
- # rubocop:enable Style/FormatString
101
+ generate(:string) do |g|
102
+ g.computed do
103
+ (dob.year / 10) % 10
104
+ end
105
+ g.computed do
106
+ gender_marker = gender == :female ? 50 : 0
107
+ format('%02d', dob.month + gender_marker)
108
+ end
109
+ g.computed do
110
+ format('%02d', dob.day)
111
+ end
112
+ g.computed do
113
+ dob.year % 10
114
+ end
115
+ end
108
116
  end
109
117
 
110
118
  def gb_licence_checksum
111
- regexify(/[0-9][A-Z][A-Z]/)
119
+ generate(:string) do |g|
120
+ g.int
121
+ g.letter(ranges: ['A'..'Z'], length: 2)
122
+ end
112
123
  end
113
124
  end
114
125
  end
@@ -97,11 +97,11 @@ module Faker
97
97
  ##
98
98
  # Returns a random condominium fiscal code.
99
99
  #
100
- # @param country [String] Two capital letter country code to use for the vat number.
100
+ # @param country [String] Two capital letter country code to use for the condominium fiscal code number.
101
101
  # @return [String]
102
102
  #
103
103
  # @example
104
- # Faker::Finance.condominium_fiscal_code #=> "012345678"
104
+ # Faker::Finance.condominium_fiscal_code #=> "01234567890"
105
105
  #
106
106
  # @faker.version next
107
107
  def condominium_fiscal_code(country: 'IT')
@@ -39,10 +39,9 @@ module Faker
39
39
  (supplemental ? translate('faker.lorem.words') : [])
40
40
  )
41
41
  word_list *= ((resolved_num / word_list.length) + 1)
42
+ words = sample(word_list, resolved_num)
43
+ return words if spaces_allowed
42
44
 
43
- return shuffle(word_list)[0, resolved_num] if spaces_allowed
44
-
45
- words = shuffle(word_list)[0, resolved_num]
46
45
  words.each_with_index { |w, i| words[i] = word if w =~ /\s/ }
47
46
  end
48
47