faker 3.2.0 → 3.2.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 (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