faker 3.2.0 → 3.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -0
  3. data/README.md +5 -3
  4. data/lib/faker/default/chile_rut.rb +23 -17
  5. data/lib/faker/default/code.rb +60 -18
  6. data/lib/faker/default/company.rb +99 -5
  7. data/lib/faker/default/date.rb +61 -5
  8. data/lib/faker/default/driving_licence.rb +19 -8
  9. data/lib/faker/default/html.rb +230 -0
  10. data/lib/faker/default/id_number.rb +17 -3
  11. data/lib/faker/default/internet.rb +12 -11
  12. data/lib/faker/default/lorem.rb +5 -2
  13. data/lib/faker/default/types.rb +3 -2
  14. data/lib/faker/default/vehicle.rb +19 -8
  15. data/lib/faker/games/final_fantasy_xiv.rb +73 -0
  16. data/lib/faker/music/smashing_pumpkins.rb +64 -0
  17. data/lib/faker/travel/airport.rb +2 -2
  18. data/lib/faker/travel/train_station.rb +54 -0
  19. data/lib/faker/tv_shows/archer.rb +51 -0
  20. data/lib/faker/tv_shows/south_park.rb +15 -0
  21. data/lib/faker/version.rb +1 -1
  22. data/lib/faker.rb +13 -5
  23. data/lib/helpers/positional_generator.rb +480 -0
  24. data/lib/locales/README.md +18 -2
  25. data/lib/locales/da-DK.yml +2 -0
  26. data/lib/locales/de-CH.yml +4336 -12
  27. data/lib/locales/en/archer.yml +75 -0
  28. data/lib/locales/en/final_fantasy_xiv.yml +754 -0
  29. data/lib/locales/en/minecraft.yml +4 -4
  30. data/lib/locales/en/opera.yml +1 -1
  31. data/lib/locales/en/smashing_pumpkins.yml +382 -0
  32. data/lib/locales/en/south_park.yml +360 -2
  33. data/lib/locales/en/train_station.yml +280 -0
  34. data/lib/locales/fr/name.yml +2 -1
  35. data/lib/locales/ja/sport.yml +130 -0
  36. data/lib/locales/ja/touhou.yml +466 -0
  37. data/lib/locales/uk.yml +2 -0
  38. data/lib/locales/zh-CN/bank.yml +17 -0
  39. metadata +16 -143
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96ec3715aa40eae20241ea0235f17234c691cbd808a5a5f523e2600979bc1c18
4
- data.tar.gz: e57effe991fbdbc74562d35066f8db66f46be5d3d441e7b650c720a072c23a94
3
+ metadata.gz: a39a95efd06da2c5f87dfd84f6c251e7731ece3edffc9c9d52a6f95a5ec0751e
4
+ data.tar.gz: a881cedce22c1ca2c8bd7d1cc8789371e99829f354872e325ebeada4460de382
5
5
  SHA512:
6
- metadata.gz: 9a12b535d55c2e3d5559228f6b9eafd98a383692165670c7a80f4a986d1c3b23637d59faa69fcc2b06142ee2445e88ce4b8057bdf72f71eafd0c86baeb9147ed
7
- data.tar.gz: 844caa61e4c4be1975f0fc8355302627ff9ead7cf7d423dd78313a4876190482fcb471a95fb43509e0e761d0bac671484851edbaf3cf98325d7864c591b83e6e
6
+ metadata.gz: ed6d8dfc1d75c7639f26ff617755cd421f7bff7152277aa999c26af5991d94c8efe9bb9abfdaadf1349bfd93d2b3ddb16d5c36783680fa463cf86f5836698b39
7
+ data.tar.gz: 6d2f16a39cca245bfc2e28cd55f4a76f5066787719bb371b3ee4edb53fbf59c31098c7c0997e32ad6af280e3b1e742762dbbd6d6a569fba91665427775c4925d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,77 @@
1
1
  # Changelog
2
2
 
3
+ ## [v3.2.1](https://github.com/faker-ruby/faker/tree/v3.2.1) (2023-08-11)
4
+
5
+ Happy August with a new Faker release! 🎉
6
+
7
+ This version:
8
+
9
+ - adds generators
10
+ - fixes bugs
11
+ - updates dev dependencies
12
+
13
+ This version fixes a bug with setting the locale in multi-threaded environments. It's now possible to set the locale per thread. For more details, see [How to set the default locale for in threaded server environments](https://github.com/faker-ruby/faker/blob/main/lib/locales/README.md#how-to-set-the-default-locale-for-in-threaded-server-environments).
14
+
15
+ Other changes included in this version:
16
+
17
+ ## Features
18
+ * Add Final Fantasy XIV by @old-dead-account in https://github.com/faker-ruby/faker/pull/2742
19
+ * Add the Ukrainian country calling code by @kyrylo in https://github.com/faker-ruby/faker/pull/2758
20
+ * Add `exclude_words` filter to `Faker::Lorem.word` generator by @geophilusd in https://github.com/faker-ruby/faker/pull/2761
21
+ * Add Japanese translations for Sports category. by @yamat47 in https://github.com/faker-ruby/faker/pull/2770
22
+ * Add type support for Faker::Types.rb_array by @ruban-thilak in https://github.com/faker-ruby/faker/pull/2771
23
+ * Added Archer into tv category. by @lepari23 in https://github.com/faker-ruby/faker/pull/2750
24
+ * Add train station generator by @AngusDSR in https://github.com/faker-ruby/faker/pull/2755
25
+ * Add custom start date for `Faker::Date.forward` by @luciagirasoles in https://github.com/faker-ruby/faker/pull/2791
26
+ * Add `max_rut` option to `Faker::ChileRut.rut` by @hacktivista in https://github.com/faker-ruby/faker/pull/2778
27
+ * Add Faker::Date.day_of_week_between by @aramvisser in https://github.com/faker-ruby/faker/pull/2713
28
+ * Html generator for Faker by @ruban-thilak in https://github.com/faker-ruby/faker/pull/2769
29
+
30
+ ## Bug fixes
31
+ * Fix locale setting by @mateusdeap in https://github.com/faker-ruby/faker/pull/2734
32
+ * add tests for password and fix an edge case by @DeepakRaj228 in https://github.com/faker-ruby/faker/pull/2741
33
+ * Remove broken chars from minecraft.yml by @ujihisa in https://github.com/faker-ruby/faker/pull/2765
34
+ * Fix flaky specs for `name` and `id` by @ruban-thilak in https://github.com/faker-ruby/faker/pull/2782
35
+ * Fixes `Faker::Music::Opera.saint_saens` issue by @devashishTaneja in https://github.com/faker-ruby/faker/pull/2792
36
+ * Fix flaky specs for dota `test_player` by @ruban-thilak in https://github.com/faker-ruby/faker/pull/2798
37
+ * Add prefixes to french name locale (`Faker::Name.name`) by @thdaraujo in https://github.com/faker-ruby/faker/pull/2800
38
+
39
+ ## What's Changed
40
+ * Introduce PositionalGenerator by @mike-burns in https://github.com/faker-ruby/faker/pull/2710
41
+ * Update South Park by @IvanReyesO7 in https://github.com/faker-ruby/faker/pull/2744
42
+ * Speed up Internet::Password generation using constants by @MicBruz in https://github.com/faker-ruby/faker/pull/2725
43
+ * Improve de-CH locale with new formats and content by @stefnnn in https://github.com/faker-ruby/faker/pull/2768
44
+
45
+ ## Update local dependencies
46
+ * Bump rubocop from 1.55.1 to 1.56.0 by @dependabot in https://github.com/faker-ruby/faker/pull/2807
47
+ * Update test-unit requirement from = 3.5.9 to = 3.6.1 by @dependabot in https://github.com/faker-ruby/faker/pull/2788
48
+ * Bump i18n from 1.12.0 to 1.13.0 by @dependabot in https://github.com/faker-ruby/faker/pull/2756
49
+ * Update rubocop-minitest requirement from = 0.30.0 to = 0.31.0 by @dependabot in https://github.com/faker-ruby/faker/pull/2759
50
+ * Bump minitest from 5.18.1 to 5.19.0 by @dependabot in https://github.com/faker-ruby/faker/pull/2804
51
+
52
+ ## New Contributors
53
+ * @old-dead-account made their first contribution in https://github.com/faker-ruby/faker/pull/2742
54
+ * @IvanReyesO7 made their first contribution in https://github.com/faker-ruby/faker/pull/2744
55
+ * @DeepakRaj228 made their first contribution in https://github.com/faker-ruby/faker/pull/2741
56
+ * @MicBruz made their first contribution in https://github.com/faker-ruby/faker/pull/2725
57
+ * @kyrylo made their first contribution in https://github.com/faker-ruby/faker/pull/2758
58
+ * @ujihisa made their first contribution in https://github.com/faker-ruby/faker/pull/2765
59
+ * @geophilusd made their first contribution in https://github.com/faker-ruby/faker/pull/2761
60
+ * @stefnnn made their first contribution in https://github.com/faker-ruby/faker/pull/2768
61
+ * @yamat47 made their first contribution in https://github.com/faker-ruby/faker/pull/2770
62
+ * @ruban-thilak made their first contribution in https://github.com/faker-ruby/faker/pull/2782
63
+ * @lepari23 made their first contribution in https://github.com/faker-ruby/faker/pull/2750
64
+ * @AngusDSR made their first contribution in https://github.com/faker-ruby/faker/pull/2755
65
+ * @devashishTaneja made their first contribution in https://github.com/faker-ruby/faker/pull/2792
66
+ * @mike-burns made their first contribution in https://github.com/faker-ruby/faker/pull/2710
67
+ * @hacktivista made their first contribution in https://github.com/faker-ruby/faker/pull/2778
68
+ * @mateusdeap made their first contribution in https://github.com/faker-ruby/faker/pull/2734
69
+ * @aramvisser made their first contribution in https://github.com/faker-ruby/faker/pull/2713
70
+
71
+ **Full Changelog**: https://github.com/faker-ruby/faker/compare/v3.2.0...v3.2.1
72
+
73
+ -------------------------
74
+
3
75
  ## [v3.2.0](https://github.com/faker-ruby/faker/tree/v3.2.0) (2023-04-14)
4
76
 
5
77
  Happy Spring with a new Faker release! 🌼
data/README.md CHANGED
@@ -169,9 +169,7 @@ Faker::Config.locale = 'es'
169
169
  Faker::Config.locale = :es
170
170
  ```
171
171
 
172
- Note: Overriding the default locale might not be thread-safe. See [Locale setting can be ignored #2563](https://github.com/faker-ruby/faker/issues/2563) for more details.
173
-
174
- To override Faker's locales,
172
+ To override Faker's locales, and set it on threaded server environments
175
173
  check out the [locales README](lib/locales/README.md).
176
174
 
177
175
  ### Minitest and Faker >= 2.22
@@ -325,6 +323,7 @@ gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'main
325
323
  <summary>Travel</summary>
326
324
 
327
325
  - [Faker:Travel::Airport](doc/travel/airport.md)
326
+ - [Faker:Travel::TrainStation](doc/travel/train_station.md)
328
327
  </details>
329
328
 
330
329
  <details>
@@ -346,6 +345,7 @@ gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'main
346
345
  - [Faker::Games::Dota](doc/games/dota.md)
347
346
  - [Faker::Games::ElderScrolls](doc/games/elder_scrolls.md)
348
347
  - [Faker::Games::Fallout](doc/games/fallout.md)
348
+ - [Faker::Games::FinalFantasyXIV](doc/games/final_fantasy_xiv.md)
349
349
  - [Faker::Games::HalfLife](doc/games/half_life.md)
350
350
  - [Faker::Games::Heroes](doc/games/heroes.md)
351
351
  - [Faker::Games::HeroesOfTheStorm](doc/games/heroes_of_the_storm.md)
@@ -411,6 +411,7 @@ gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'main
411
411
  - [Faker::Music::Prince](doc/music/prince.md)
412
412
  - [Faker::Music::RockBand](doc/music/rock_band.md)
413
413
  - [Faker::Music::Rush](doc/music/rush.md)
414
+ - [Faker::Music::SmashingPumpkins](doc/music/smashing_pumpkins.md)
414
415
  - [Faker::Music::UmphreysMcgee](doc/music/umphreys_mcgee.md)
415
416
  </details>
416
417
 
@@ -438,6 +439,7 @@ gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'main
438
439
  <summary>Tv Shows</summary>
439
440
 
440
441
  - [Faker::TvShows::AquaTeenHungerForce](doc/tv_shows/aqua_teen_hunger_force.md)
442
+ - [Faker::TvShows::Archer](doc/tv_shows/archer.md)
441
443
  - [Faker::TvShows::BigBangTheory](doc/tv_shows/big_bang_theory.md)
442
444
  - [Faker::TvShows::BojackHorseman](doc/tv_shows/bojack_horseman.md)
443
445
  - [Faker::TvShows::BreakingBad](doc/tv_shows/breaking_bad.md)
@@ -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
  ##
@@ -197,15 +209,29 @@ module Faker
197
209
  end
198
210
 
199
211
  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}"
212
+ generate(:string) do |g|
213
+ g.int(name: :values, length: 9)
214
+ g.lit('-')
215
+ g.computed(name: :checksum, deps: [:values]) do |values|
216
+ remainder = sum(values.to_s) { |value, offset| (offset + 1) * value.to_i } % 11
217
+ if remainder == 10
218
+ 'X'
219
+ else
220
+ remainder.to_s
221
+ end
222
+ end
223
+ end
203
224
  end
204
225
 
205
226
  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}"
227
+ generate(:string) do |g|
228
+ g.int(name: :values, length: 12)
229
+ g.lit('-')
230
+ g.computed(name: :checksum, deps: [:values]) do |values|
231
+ remainder = sum(values.to_s) { |value, offset| offset.even? ? value.to_i : value.to_i * 3 } % 10
232
+ (10 - remainder) % 10
233
+ end
234
+ end
209
235
  end
210
236
 
211
237
  def sum(values)
@@ -215,15 +241,31 @@ module Faker
215
241
  end
216
242
 
217
243
  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
244
+ generate(:string) do |g|
245
+ g.int(name: :values, length: 7)
246
+ g.computed(name: :checksum, deps: [:values]) do |values|
247
+ check_digit = 10 - values.to_s.chars.each_with_index.inject(0) { |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT8[i] } % 10
248
+ if check_digit == 10
249
+ 0
250
+ else
251
+ check_digit
252
+ end
253
+ end
254
+ end
221
255
  end
222
256
 
223
257
  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
258
+ generate(:string) do |g|
259
+ g.int(name: :values, length: 12)
260
+ g.computed(name: :checksum, deps: [:values]) do |values|
261
+ check_digit = 10 - values.to_s.chars.each_with_index.inject(0) { |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT13[i] } % 10
262
+ if check_digit == 10
263
+ 0
264
+ else
265
+ check_digit
266
+ end
267
+ end
268
+ end
227
269
  end
228
270
 
229
271
  EAN_CHECK_DIGIT8 = [3, 1, 3, 1, 3, 1, 3].freeze
@@ -231,7 +273,7 @@ module Faker
231
273
 
232
274
  def rut_verificator_digit(rut)
233
275
  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')
276
+ (11 - total % 11).to_s.gsub('10', 'k').gsub('11', '0')
235
277
  end
236
278
 
237
279
  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]].to_a)
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
@@ -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