From fdc7d4b47cf9c0b5c463a7021ab36df4892f9328 Mon Sep 17 00:00:00 2001 From: "jamal.mohamed" Date: Tue, 19 Dec 2023 21:36:13 -0600 Subject: [PATCH 1/4] Deprecate IDNumber to IdNumber per issue#2787 --- README.md | 2 +- doc/default/id_number.md | 40 +++++++------- lib/faker/default/id_number.rb | 40 +++++++------- lib/faker/default/south_africa.rb | 6 +-- lib/helpers/deprecated_class.rb | 27 ++++++++++ lib/locales/en-US.yml | 2 +- lib/locales/en/id_number.yml | 2 +- .../default/test_faker_deprecated_class.rb | 27 ++++++++++ test/faker/default/test_faker_id_number.rb | 53 +++++++++++-------- test/faker/default/test_faker_south_africa.rb | 6 +-- test/test_en_locale.rb | 8 +-- test/test_en_us_locale.rb | 8 +-- 12 files changed, 142 insertions(+), 79 deletions(-) create mode 100644 lib/helpers/deprecated_class.rb create mode 100644 test/faker/default/test_faker_deprecated_class.rb diff --git a/README.md b/README.md index 9ba31cc7b1..ce148477fd 100644 --- a/README.md +++ b/README.md @@ -248,7 +248,7 @@ gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'main - [Faker::Hipster](doc/default/hipster.md) - [Faker::Hobby](doc/default/hobby.md) - [Faker::House](doc/default/house.md) - - [Faker::IDNumber](doc/default/id_number.md) + - [Faker::IdNumber](doc/default/id_number.md) - [Faker::IndustrySegments](doc/default/industry_segments.md) - [Faker::Internet](doc/default/internet.md) - [Faker::Invoice](doc/default/invoice.md) diff --git a/doc/default/id_number.md b/doc/default/id_number.md index e5fa858663..89216c0279 100644 --- a/doc/default/id_number.md +++ b/doc/default/id_number.md @@ -1,52 +1,52 @@ -# Faker::IDNumber +# Faker::IdNumber ```ruby # Generate a valid US Social Security number -Faker::IDNumber.valid #=> "552-56-3593" +Faker::IdNumber.valid #=> "552-56-3593" # Generate an invalid US Social Security number -Faker::IDNumber.invalid #=> "311-72-0000" +Faker::IdNumber.invalid #=> "311-72-0000" # Generate a Spanish citizen identifier (DNI) -Faker::IDNumber.spanish_citizen_number #=> "53290236-H" +Faker::IdNumber.spanish_citizen_number #=> "53290236-H" # Generate a Spanish foreign born citizen identifier (NIE) -Faker::IDNumber.spanish_foreign_citizen_number #=> "Z-1600870-Y" +Faker::IdNumber.spanish_foreign_citizen_number #=> "Z-1600870-Y" # Generate a valid South African ID Number -Faker::IDNumber.south_african_id_number #=> "8105128870184" +Faker::IdNumber.south_african_id_number #=> "8105128870184" # or -Faker::IDNumber.valid_south_african_id_number #=> "8105128870184" +Faker::IdNumber.valid_south_african_id_number #=> "8105128870184" # Generate an invalid South African ID Number -Faker::IDNumber.invalid_south_african_id_number #=> "1642972065088" +Faker::IdNumber.invalid_south_african_id_number #=> "1642972065088" # Generate a Brazilian citizen number (CPF) # Keyword arguments: formatted -Faker::IDNumber.brazilian_citizen_number #=> "53540542221" -Faker::IDNumber.brazilian_citizen_number(formatted: true) #=> "535.405.422-21" +Faker::IdNumber.brazilian_citizen_number #=> "53540542221" +Faker::IdNumber.brazilian_citizen_number(formatted: true) #=> "535.405.422-21" # Generate a Brazilian ID Number (RG) # Keyword arguments: formatted -Faker::IDNumber.brazilian_id #=> "493054029" -Faker::IDNumber.brazilian_id(formatted: true) #=> "49.305.402-9" +Faker::IdNumber.brazilian_id #=> "493054029" +Faker::IdNumber.brazilian_id(formatted: true) #=> "49.305.402-9" # Generate a Chilean ID (Rut with 8 digits) # For more advanced cases, please refer to Faker::ChileRut -Faker::IDNumber.chilean_id #=> "15620613-K" +Faker::IdNumber.chilean_id #=> "15620613-K" # Generate a Croatian ID number (OIB) # Keyword arguments: international -Faker::IDNumber.croatian_id #=> "88467617508" -Faker::IDNumber.croatian_id(international: true) #=> "HR88467617508" +Faker::IdNumber.croatian_id #=> "88467617508" +Faker::IdNumber.croatian_id(international: true) #=> "HR88467617508" # Generate a Danish ID number (CPR) # Keyword arguments: formatted, gender, birthday -Faker::IDNumber.danish_id_number #=> "050390-9980" -Faker::IDNumber.danish_id_number(formatted: true) #=> "050390-9980" -Faker::IDNumber.danish_id_number(birthday: Date.new(1990, 3, 5)) #=> "050390-9980" -Faker::IDNumber.danish_id_number(gender: :female) #=> "050390-9980" +Faker::IdNumber.danish_id_number #=> "050390-9980" +Faker::IdNumber.danish_id_number(formatted: true) #=> "050390-9980" +Faker::IdNumber.danish_id_number(birthday: Date.new(1990, 3, 5)) #=> "050390-9980" +Faker::IdNumber.danish_id_number(gender: :female) #=> "050390-9980" # Generate a valid French Social Security number (INSEE number) -Faker::IDNumber.french_insee_number #=> "22510589696868" +Faker::IdNumber.french_insee_number #=> "22510589696868" ``` diff --git a/lib/faker/default/id_number.rb b/lib/faker/default/id_number.rb index 5e08dfbeb9..786034e983 100644 --- a/lib/faker/default/id_number.rb +++ b/lib/faker/default/id_number.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Faker - class IDNumber < Base + class IdNumber < Base CHECKS = 'TRWAGMYFPDXBNJZSQVHLCKE' INVALID_SSN = [ /0{3}-\d{2}-\d{4}/, @@ -25,7 +25,7 @@ class << self # @return [String] # # @example - # Faker::IDNumber.valid #=> "552-56-3593" + # Faker::IdNumber.valid #=> "552-56-3593" # # @faker.version 1.6.0 def valid @@ -38,7 +38,7 @@ def valid # @return [String] # # @example - # Faker::IDNumber.invalid #=> "311-72-0000" + # Faker::IdNumber.invalid #=> "311-72-0000" # # @faker.version 1.6.0 def invalid @@ -71,7 +71,7 @@ def ssn_valid # @return [String] # # @example - # Faker::IDNumber.spanish_citizen_number #=> "53290236-H" + # Faker::IdNumber.spanish_citizen_number #=> "53290236-H" # # @faker.version 1.9.0 def spanish_citizen_number @@ -87,7 +87,7 @@ def spanish_citizen_number # @return [String] # # @example - # Faker::IDNumber.spanish_foreign_citizen_number #=> "Z-1600870-Y" + # Faker::IdNumber.spanish_foreign_citizen_number #=> "Z-1600870-Y" # # @faker.version 1.9.0 def spanish_foreign_citizen_number @@ -106,8 +106,8 @@ def spanish_foreign_citizen_number # @return [String] # # @example - # Faker::IDNumber.south_african_id_number #=> "8105128870184" - # Faker::IDNumber.valid_south_african_id_number #=> "8105128870184" + # Faker::IdNumber.south_african_id_number #=> "8105128870184" + # Faker::IdNumber.valid_south_african_id_number #=> "8105128870184" # # @faker.version 1.9.2 def valid_south_african_id_number @@ -129,7 +129,7 @@ def valid_south_african_id_number # @return [String] # # @example - # Faker::IDNumber.invalid_south_african_id_number #=> "1642972065088" + # Faker::IdNumber.invalid_south_african_id_number #=> "1642972065088" # # @faker.version 1.9.2 def invalid_south_african_id_number @@ -156,8 +156,8 @@ def invalid_south_african_id_number # @return [String] # # @example - # Faker::IDNumber.brazilian_citizen_number #=> "53540542221" - # Faker::IDNumber.brazilian_citizen_number(formatted: true) #=> "535.405.422-21" + # Faker::IdNumber.brazilian_citizen_number #=> "53540542221" + # Faker::IdNumber.brazilian_citizen_number(formatted: true) #=> "535.405.422-21" # # @faker.version 1.9.2 def brazilian_citizen_number(formatted: false) @@ -177,8 +177,8 @@ def brazilian_citizen_number(formatted: false) # @return [String] # # @example - # Faker::IDNumber.brazilian_id #=> "493054029" - # Faker::IDNumber.brazilian_id(formatted: true) #=> "49.305.402-9" + # Faker::IdNumber.brazilian_id #=> "493054029" + # Faker::IdNumber.brazilian_id(formatted: true) #=> "49.305.402-9" # # @faker.version 2.1.2 def brazilian_id(formatted: false) @@ -196,7 +196,7 @@ def brazilian_id(formatted: false) # @return [String] # # @example - # Faker::IDNumber.chilean_id #=> "15620613-K" + # Faker::IdNumber.chilean_id #=> "15620613-K" # # @faker.version 2.1.2 def chilean_id @@ -213,8 +213,8 @@ def chilean_id # @return [String] # # @example - # Faker::IDNumber.croatian_id #=> "88467617508" - # Faker::IDNumber.croatian_id(international: true) #=> "HR88467617508" + # Faker::IdNumber.croatian_id #=> "88467617508" + # Faker::IdNumber.croatian_id(international: true) #=> "HR88467617508" # # @faker.version next def croatian_id(international: false) @@ -238,10 +238,10 @@ def croatian_id(international: false) # @return [String] # # @example - # Faker::IDNumber.danish_id_number #=> "0503909980" - # Faker::IDNumber.danish_id_number(formatted: true) #=> "050390-9980" - # Faker::IDNumber.danish_id_number(birthday: Date.new(1990, 3, 5)) #=> "0503909980" - # Faker::IDNumber.danish_id_number(gender: :female) #=> "0503909980" + # Faker::IdNumber.danish_id_number #=> "0503909980" + # Faker::IdNumber.danish_id_number(formatted: true) #=> "050390-9980" + # Faker::IdNumber.danish_id_number(birthday: Date.new(1990, 3, 5)) #=> "0503909980" + # Faker::IdNumber.danish_id_number(gender: :female) #=> "0503909980" # # @faker.version next def danish_id_number(formatted: false, birthday: Faker::Date.birthday, gender: nil) @@ -275,7 +275,7 @@ def danish_id_number(formatted: false, birthday: Faker::Date.birthday, gender: n # @return [String] # # @example - # Faker::IDNumber.french_insee_number #=> "53290236-H" + # Faker::IdNumber.french_insee_number #=> "53290236-H" # # @faker.version next def french_insee_number diff --git a/lib/faker/default/south_africa.rb b/lib/faker/default/south_africa.rb index 09fdbd8bd5..db8cb3e143 100644 --- a/lib/faker/default/south_africa.rb +++ b/lib/faker/default/south_africa.rb @@ -13,7 +13,7 @@ class << self # # @faker.version 1.9.2 def id_number - Faker::IDNumber.south_african_id_number + Faker::IdNumber.south_african_id_number end ## @@ -26,7 +26,7 @@ def id_number # # @faker.version 1.9.2 def valid_id_number - Faker::IDNumber.valid_south_african_id_number + Faker::IdNumber.valid_south_african_id_number end ## @@ -39,7 +39,7 @@ def valid_id_number # # @faker.version 1.9.2 def invalid_id_number - Faker::IDNumber.invalid_south_african_id_number + Faker::IdNumber.invalid_south_african_id_number end ## diff --git a/lib/helpers/deprecated_class.rb b/lib/helpers/deprecated_class.rb new file mode 100644 index 0000000000..9e509895be --- /dev/null +++ b/lib/helpers/deprecated_class.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Faker + def self.const_missing(const_name) + new_class = DeprecatedClass.names[const_name.to_sym] + super(const_name) unless new_class + warn "DEPRECATION WARNING: the class Faker::#{const_name} is deprecated. Use Faker::#{new_class} instead." + Object.const_get("Faker::#{new_class}") + end + + class Movies + def self.const_missing(const_name) + Faker.const_missing("Movies::#{const_name}") + end + end + + class DeprecatedClass + # rubocop:disable Lint/SymbolConversion + def self.names + { + 'IDNumber': 'IdNumber', + 'Movies::HarryPotterDeprecated': 'Movies::HarryPotter' + } + end + # rubocop:enable Lint/SymbolConversion + end +end diff --git a/lib/locales/en-US.yml b/lib/locales/en-US.yml index a447eb5fef..2fed35282c 100644 --- a/lib/locales/en-US.yml +++ b/lib/locales/en-US.yml @@ -6960,7 +6960,7 @@ en-US: - "#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number}" - "#{PhoneNumber.area_code}.#{PhoneNumber.exchange_code}.#{PhoneNumber.subscriber_number}" id_number: - valid: "#{IDNumber.ssn_valid}" + valid: "#{IdNumber.ssn_valid}" invalid: - 000-##-#### - "###-00-####" diff --git a/lib/locales/en/id_number.yml b/lib/locales/en/id_number.yml index ac1df752ce..597eab1690 100644 --- a/lib/locales/en/id_number.yml +++ b/lib/locales/en/id_number.yml @@ -1,5 +1,5 @@ en: faker: id_number: - valid: "#{IDNumber.ssn_valid}" + valid: "#{IdNumber.ssn_valid}" invalid: ['000-##-####', '###-00-####', '###-##-0000', '666-##-####', '9##-##-####'] diff --git a/test/faker/default/test_faker_deprecated_class.rb b/test/faker/default/test_faker_deprecated_class.rb new file mode 100644 index 0000000000..30591b4cf7 --- /dev/null +++ b/test/faker/default/test_faker_deprecated_class.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require_relative '../../test_helper' + +class TestFakerDeprecatedClass < Test::Unit::TestCase + def setup + @tester = Faker::DeprecatedClass + end + + def test_non_nested_class_with_deprecated_class + actual_stdout, actual_stderr = capture_output do + Faker::IDNumber.valid + end + + assert_empty actual_stdout + assert_match('DEPRECATION WARNING: the class Faker::IDNumber is deprecated. Use Faker::IdNumber instead.', actual_stderr) + end + + def test_nested_class_with_deprecated_class + actual_stdout, actual_stderr = capture_output do + Faker::Movies::HarryPotterDeprecated.character + end + + assert_empty actual_stdout + assert_match('DEPRECATION WARNING: the class Faker::Movies::HarryPotterDeprecated is deprecated. Use Faker::Movies::HarryPotter instead.', actual_stderr) + end +end diff --git a/test/faker/default/test_faker_id_number.rb b/test/faker/default/test_faker_id_number.rb index 21a2389ea9..e1cc8c7962 100644 --- a/test/faker/default/test_faker_id_number.rb +++ b/test/faker/default/test_faker_id_number.rb @@ -4,7 +4,7 @@ class TestFakerIdNumber < Test::Unit::TestCase def setup - @tester = Faker::IDNumber + @tester = Faker::IdNumber end def test_valid_ssn @@ -37,7 +37,7 @@ def test_spanish_dni assert_equal('-', sample[8]) mod = sample[0..7].to_i % 23 - assert_equal Faker::IDNumber::CHECKS[mod], sample[9] + assert_equal Faker::IdNumber::CHECKS[mod], sample[9] end def test_spanish_nie @@ -51,7 +51,7 @@ def test_spanish_nie prefix = 'XYZ'.index(sample[0]).to_s mod = "#{prefix}#{sample[2..8]}".to_i % 23 - assert_equal Faker::IDNumber::CHECKS[mod], sample[10] + assert_equal Faker::IdNumber::CHECKS[mod], sample[10] end def test_south_african_id_number @@ -98,35 +98,35 @@ def test_brazilian_id_formatted def test_brazilian_citizen_number_checksum_digit digits = '128991760' - checksum_digit = Faker::IDNumber.send(:brazilian_citizen_number_checksum_digit, digits) + checksum_digit = Faker::IdNumber.send(:brazilian_citizen_number_checksum_digit, digits) assert_equal('4', checksum_digit) digits = '1289917604' - checksum_digit = Faker::IDNumber.send(:brazilian_citizen_number_checksum_digit, digits) + checksum_digit = Faker::IdNumber.send(:brazilian_citizen_number_checksum_digit, digits) assert_equal('8', checksum_digit) end def test_brazilian_id_checksum_digit digits = '41987080' - checksum_digit = Faker::IDNumber.send(:brazilian_id_checksum_digit, digits) + checksum_digit = Faker::IdNumber.send(:brazilian_id_checksum_digit, digits) assert_equal('5', checksum_digit) end def test_brazilian_document_checksum digits = '123456789' - checksum = Faker::IDNumber.send(:brazilian_document_checksum, digits) + checksum = Faker::IdNumber.send(:brazilian_document_checksum, digits) assert_equal(2100, checksum) end def test_brazilian_document_digit - citizen_number_digit10 = Faker::IDNumber.send(:brazilian_document_digit, 10) - citizen_number_digit_other = Faker::IDNumber.send(:brazilian_document_digit, 9) - id_digit10 = Faker::IDNumber.send(:brazilian_document_digit, 1, id: true) - id_digit11 = Faker::IDNumber.send(:brazilian_document_digit, 0, id: true) - id_digit_other = Faker::IDNumber.send(:brazilian_document_digit, 2, id: true) + citizen_number_digit10 = Faker::IdNumber.send(:brazilian_document_digit, 10) + citizen_number_digit_other = Faker::IdNumber.send(:brazilian_document_digit, 9) + id_digit10 = Faker::IdNumber.send(:brazilian_document_digit, 1, id: true) + id_digit11 = Faker::IdNumber.send(:brazilian_document_digit, 0, id: true) + id_digit_other = Faker::IdNumber.send(:brazilian_document_digit, 2, id: true) assert_equal('0', citizen_number_digit10) assert_equal('9', citizen_number_digit_other) @@ -136,17 +136,17 @@ def test_brazilian_document_digit end def test_brazilian_citizen_number_digit - digit10 = Faker::IDNumber.send(:brazilian_citizen_number_digit, 10) - digit_other = Faker::IDNumber.send(:brazilian_citizen_number_digit, 9) + digit10 = Faker::IdNumber.send(:brazilian_citizen_number_digit, 10) + digit_other = Faker::IdNumber.send(:brazilian_citizen_number_digit, 9) assert_equal('0', digit10) assert_equal('9', digit_other) end def test_brazilian_id_digit - digit10 = Faker::IDNumber.send(:brazilian_id_digit, 1) - digit11 = Faker::IDNumber.send(:brazilian_id_digit, 0) - digit_other = Faker::IDNumber.send(:brazilian_id_digit, 2) + digit10 = Faker::IdNumber.send(:brazilian_id_digit, 1) + digit11 = Faker::IdNumber.send(:brazilian_id_digit, 0) + digit_other = Faker::IdNumber.send(:brazilian_id_digit, 2) assert_equal('X', digit10) assert_equal('0', digit11) @@ -160,13 +160,13 @@ def test_chilean_id end def test_chilean_verification_code_k - verification_code = Faker::IDNumber.send(:chilean_verification_code, 20_680_873) + verification_code = Faker::IdNumber.send(:chilean_verification_code, 20_680_873) assert_equal('K', verification_code) end def test_chilean_verification_code_0 - verification_code = Faker::IDNumber.send(:chilean_verification_code, 13_196_022) + verification_code = Faker::IdNumber.send(:chilean_verification_code, 13_196_022) assert_equal(0, verification_code) end @@ -185,7 +185,7 @@ def test_croatian_id_international def test_croatian_id_checksum_digit digits = '8764670153' - checksum_digit = Faker::IDNumber.send(:croatian_id_checksum_digit, digits) + checksum_digit = Faker::IdNumber.send(:croatian_id_checksum_digit, digits) assert_equal(5, checksum_digit) end @@ -274,6 +274,15 @@ def test_danish_id_number_invalid_gender end end + def test_chilean_id_with_deprecated_class + actual_stdout, actual_stderr = capture_output do + Faker::IDNumber.valid + end + + assert_empty actual_stdout + assert_match('DEPRECATION WARNING: the class Faker::IDNumber is deprecated. Use Faker::IdNumber instead.', actual_stderr) + end + private def south_african_id_number_to_date_of_birth_string(sample) @@ -283,8 +292,8 @@ def south_african_id_number_to_date_of_birth_string(sample) def assert_valid_south_african_id_number(sample) assert_equal 13, sample.length assert_match(/^\d{13}$/, sample) - assert_include Faker::IDNumber::ZA_CITIZENSHIP_DIGITS, sample[10] - assert_equal Faker::IDNumber::ZA_RACE_DIGIT, sample[11] + assert_include Faker::IdNumber::ZA_CITIZENSHIP_DIGITS, sample[10] + assert_equal Faker::IdNumber::ZA_RACE_DIGIT, sample[11] assert Date.parse(south_african_id_number_to_date_of_birth_string(sample)) end end diff --git a/test/faker/default/test_faker_south_africa.rb b/test/faker/default/test_faker_south_africa.rb index 8e7e53e215..608121fbf2 100644 --- a/test/faker/default/test_faker_south_africa.rb +++ b/test/faker/default/test_faker_south_africa.rb @@ -10,7 +10,7 @@ def setup def test_id_number stubbed_id_number = '7201010001081' - Faker::IDNumber.stub :south_african_id_number, stubbed_id_number do + Faker::IdNumber.stub :south_african_id_number, stubbed_id_number do assert_equal stubbed_id_number, @tester.id_number end end @@ -18,7 +18,7 @@ def test_id_number def test_valid_id_number stubbed_id_number = '7201010001081' - Faker::IDNumber.stub :valid_south_african_id_number, stubbed_id_number do + Faker::IdNumber.stub :valid_south_african_id_number, stubbed_id_number do assert_equal stubbed_id_number, @tester.valid_id_number end end @@ -26,7 +26,7 @@ def test_valid_id_number def test_invalid_id_number stubbed_id_number = '9999990001081' - Faker::IDNumber.stub :invalid_south_african_id_number, stubbed_id_number do + Faker::IdNumber.stub :invalid_south_african_id_number, stubbed_id_number do assert_equal stubbed_id_number, @tester.invalid_id_number end end diff --git a/test/test_en_locale.rb b/test/test_en_locale.rb index 3e530aa1bd..d6dec7eed5 100644 --- a/test/test_en_locale.rb +++ b/test/test_en_locale.rb @@ -23,15 +23,15 @@ def test_us_zip_codes end def test_valid_id_number - id_num = Faker::IDNumber.valid + id_num = Faker::IdNumber.valid - assert(Faker::IDNumber::INVALID_SSN.none? { |regex| id_num =~ regex }) + assert(Faker::IdNumber::INVALID_SSN.none? { |regex| id_num =~ regex }) end def test_invalid_id_number - id_num = Faker::IDNumber.invalid + id_num = Faker::IdNumber.invalid - assert(Faker::IDNumber::INVALID_SSN.any? { |regex| id_num =~ regex }) + assert(Faker::IdNumber::INVALID_SSN.any? { |regex| id_num =~ regex }) end def test_values_trimmed diff --git a/test/test_en_us_locale.rb b/test/test_en_us_locale.rb index c7c6a85362..f33a487e2d 100644 --- a/test/test_en_us_locale.rb +++ b/test/test_en_us_locale.rb @@ -85,14 +85,14 @@ def test_en_us_zip_codes_match_state end def test_en_us_valid_id_number - id_num = Faker::IDNumber.valid + id_num = Faker::IdNumber.valid - assert(Faker::IDNumber::INVALID_SSN.none? { |regex| id_num =~ regex }) + assert(Faker::IdNumber::INVALID_SSN.none? { |regex| id_num =~ regex }) end def test_en_us_invalid_id_number - id_num = Faker::IDNumber.invalid + id_num = Faker::IdNumber.invalid - assert(Faker::IDNumber::INVALID_SSN.any? { |regex| id_num =~ regex }) + assert(Faker::IdNumber::INVALID_SSN.any? { |regex| id_num =~ regex }) end end From be1b1195185b29ab84907e3371f58d68d09afb9b Mon Sep 17 00:00:00 2001 From: "jamal.mohamed" Date: Wed, 7 Feb 2024 08:13:23 -0600 Subject: [PATCH 2/4] wip --- lib/faker/default/id_number.rb | 4 +++ lib/helpers/deprecated_class.rb | 27 ---------------- lib/helpers/deprecator.rb | 32 +++++++++++++++++++ ...ated_class.rb => test_faker_deprecator.rb} | 4 +-- 4 files changed, 38 insertions(+), 29 deletions(-) delete mode 100644 lib/helpers/deprecated_class.rb create mode 100644 lib/helpers/deprecator.rb rename test/faker/default/{test_faker_deprecated_class.rb => test_faker_deprecator.rb} (89%) diff --git a/lib/faker/default/id_number.rb b/lib/faker/default/id_number.rb index 786034e983..4b896f47a3 100644 --- a/lib/faker/default/id_number.rb +++ b/lib/faker/default/id_number.rb @@ -19,6 +19,10 @@ class IdNumber < Base CHILEAN_MODULO = 11 class << self + + include Faker::Deprecator::DeprecatorConstantAccessor + deprecated_constant ' Faker::IDNumber', 'Faker::IdNumber' + ## # Produces a random valid US Social Security number. # diff --git a/lib/helpers/deprecated_class.rb b/lib/helpers/deprecated_class.rb deleted file mode 100644 index 9e509895be..0000000000 --- a/lib/helpers/deprecated_class.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -module Faker - def self.const_missing(const_name) - new_class = DeprecatedClass.names[const_name.to_sym] - super(const_name) unless new_class - warn "DEPRECATION WARNING: the class Faker::#{const_name} is deprecated. Use Faker::#{new_class} instead." - Object.const_get("Faker::#{new_class}") - end - - class Movies - def self.const_missing(const_name) - Faker.const_missing("Movies::#{const_name}") - end - end - - class DeprecatedClass - # rubocop:disable Lint/SymbolConversion - def self.names - { - 'IDNumber': 'IdNumber', - 'Movies::HarryPotterDeprecated': 'Movies::HarryPotter' - } - end - # rubocop:enable Lint/SymbolConversion - end -end diff --git a/lib/helpers/deprecator.rb b/lib/helpers/deprecator.rb new file mode 100644 index 0000000000..9132eb61de --- /dev/null +++ b/lib/helpers/deprecator.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Faker + class Deprecator + module DeprecatorConstantAccessor + def self.included(base) + puts base.singleton_class + extension = Module.new do + def const_missing(missing_const_name) + puts "finding missing_const_name: ", missing_const_name.to_s + if class_variable_defined?(:@@_deprecated_constants) + if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s]) + replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", caller_locations) + return Faker::IdNumber + end + end + super + end + + def deprecated_constant(const_name, new_constant, message: nil, deprecator: nil) + puts("Constant being deprecated: ", const_name, '\nconstant replaceing:',new_constant ) + class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants) + class_variable_get(:@@_deprecated_constants)[const_name.to_s] = { new: new_constant, message: message, deprecator: deprecator } + end + end + + base.singleton_class.prepend extension + puts base.ancestors + end + end + end +end diff --git a/test/faker/default/test_faker_deprecated_class.rb b/test/faker/default/test_faker_deprecator.rb similarity index 89% rename from test/faker/default/test_faker_deprecated_class.rb rename to test/faker/default/test_faker_deprecator.rb index 30591b4cf7..174a153563 100644 --- a/test/faker/default/test_faker_deprecated_class.rb +++ b/test/faker/default/test_faker_deprecator.rb @@ -2,9 +2,9 @@ require_relative '../../test_helper' -class TestFakerDeprecatedClass < Test::Unit::TestCase +class TestFakerDeprecated < Test::Unit::TestCase def setup - @tester = Faker::DeprecatedClass + @tester = Faker::Deprecated end def test_non_nested_class_with_deprecated_class From 477fe7103530e1f4e88072818d4e21249b676e87 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Thu, 22 Feb 2024 18:33:46 -0700 Subject: [PATCH 3/4] Add a Faker::Deprecator module Co-authored-by: Thiago Araujo --- lib/faker/default/id_number.rb | 424 +++++++++++++++++++- lib/helpers/deprecator.rb | 38 +- test/faker/default/test_faker_deprecator.rb | 27 -- test/faker/default/test_faker_id_number.rb | 9 - test/test_determinism.rb | 45 ++- test/test_faker_deprecator.rb | 14 + 6 files changed, 497 insertions(+), 60 deletions(-) delete mode 100644 test/faker/default/test_faker_deprecator.rb create mode 100644 test/test_faker_deprecator.rb diff --git a/lib/faker/default/id_number.rb b/lib/faker/default/id_number.rb index 4b896f47a3..54c8399008 100644 --- a/lib/faker/default/id_number.rb +++ b/lib/faker/default/id_number.rb @@ -19,10 +19,430 @@ class IdNumber < Base CHILEAN_MODULO = 11 class << self + ## + # Produces a random valid US Social Security number. + # + # @return [String] + # + # @example + # Faker::IdNumber.valid #=> "552-56-3593" + # + # @faker.version 1.6.0 + def valid + _translate('valid') + end + + ## + # Produces a random invalid US Social Security number. + # + # @return [String] + # + # @example + # Faker::IdNumber.invalid #=> "311-72-0000" + # + # @faker.version 1.6.0 + def invalid + _translate('invalid') + end + + def ssn_valid + generate(:string) do |g| + g.computed(name: :first) do + range = [1..665, 667..899].sample(random: Faker::Config.random) + n = Faker::Base.rand(range) + format('%03d', n) + end + g.lit('-') + g.computed(name: :second) do + n = Faker::Base.rand(1..99) + format('%02d', n) + end + g.lit('-') + g.computed(name: :third) do + n = Faker::Base.rand(1..9999) + format('%04d', n) + end + end + end + + ## + # Produces a random Spanish citizen identifier (DNI). + # + # @return [String] + # + # @example + # Faker::IdNumber.spanish_citizen_number #=> "53290236-H" + # + # @faker.version 1.9.0 + def spanish_citizen_number + num = Faker::Number.number(digits: 8) + mod = num.to_i % 23 + check = CHECKS[mod] + "#{num}-#{check}" + end + + ## + # Produces a random Spanish foreign born citizen identifier (NIE). + # + # @return [String] + # + # @example + # Faker::IdNumber.spanish_foreign_citizen_number #=> "Z-1600870-Y" + # + # @faker.version 1.9.0 + def spanish_foreign_citizen_number + code = 'XYZ' + digits = Faker::Number.number(digits: 7) + prefix = code[rand(code.length)] + prefix_val = 'XYZ'.index(prefix).to_s + mod = "#{prefix_val}#{digits}".to_i % 23 + check = CHECKS[mod] + "#{prefix}-#{digits}-#{check}" + end + + ## + # Produces a random valid South African ID Number. + # + # @return [String] + # + # @example + # Faker::IdNumber.south_african_id_number #=> "8105128870184" + # Faker::IdNumber.valid_south_african_id_number #=> "8105128870184" + # + # @faker.version 1.9.2 + def valid_south_african_id_number + id_number = [ + Faker::Date.birthday.strftime('%y%m%d'), + Faker::Number.number(digits: 4), + ZA_CITIZENSHIP_DIGITS.sample(random: Faker::Config.random), + ZA_RACE_DIGIT + ].join + + [id_number, south_african_id_checksum_digit(id_number)].join + end + + alias south_african_id_number valid_south_african_id_number + + ## + # Produces a random invalid South African ID Number. + # + # @return [String] + # + # @example + # Faker::IdNumber.invalid_south_african_id_number #=> "1642972065088" + # + # @faker.version 1.9.2 + def invalid_south_african_id_number + invalid_date_of_birth = [ + Faker::Number.number(digits: 2), + Faker::Number.between(from: 13, to: 99), + Faker::Number.between(from: 32, to: 99) + ].map(&:to_s).join - include Faker::Deprecator::DeprecatorConstantAccessor - deprecated_constant ' Faker::IDNumber', 'Faker::IdNumber' + id_number = [ + invalid_date_of_birth, + Faker::Number.number(digits: 4), + ZA_CITIZENSHIP_DIGITS.sample(random: Faker::Config.random), + ZA_RACE_DIGIT + ].join + [id_number, south_african_id_checksum_digit(id_number)].join + end + + ## + # Produces a random Brazilian Citizen Number (CPF). + # + # @param formatted [Boolean] Specifies if the number is formatted with dividers. + # @return [String] + # + # @example + # Faker::IdNumber.brazilian_citizen_number #=> "53540542221" + # Faker::IdNumber.brazilian_citizen_number(formatted: true) #=> "535.405.422-21" + # + # @faker.version 1.9.2 + def brazilian_citizen_number(formatted: false) + digits = Faker::Number.leading_zero_number(digits: 9) until digits&.match(/(\d)((?!\1)\d)+/) + first_digit = brazilian_citizen_number_checksum_digit(digits) + second_digit = brazilian_citizen_number_checksum_digit(digits + first_digit) + number = [digits, first_digit, second_digit].join + formatted ? format('%s.%s.%s-%s', *number.scan(/\d{2,3}/).flatten) : number + end + + alias brazilian_cpf brazilian_citizen_number + + ## + # Produces a random Brazilian ID Number (RG). + # + # @param formatted [Boolean] Specifies if the number is formatted with dividers. + # @return [String] + # + # @example + # Faker::IdNumber.brazilian_id #=> "493054029" + # Faker::IdNumber.brazilian_id(formatted: true) #=> "49.305.402-9" + # + # @faker.version 2.1.2 + def brazilian_id(formatted: false) + digits = Faker::Number.between(to: BRAZILIAN_ID_FROM, from: BRAZILIAN_ID_TO).to_s + check_digit = brazilian_id_checksum_digit(digits) + number = [digits, check_digit].join + formatted ? format('%s.%s.%s-%s', *number.scan(BRAZILIAN_ID_FORMAT).flatten) : number + end + + alias brazilian_rg brazilian_id + + ## + # Produces a random Chilean ID (Rut with 8 digits). + # + # @return [String] + # + # @example + # Faker::IdNumber.chilean_id #=> "15620613-K" + # + # @faker.version 2.1.2 + def chilean_id + digits = Faker::Number.number(digits: 8) + verification_code = chilean_verification_code(digits) + + "#{digits}-#{verification_code}" + end + + ## + # Produces a random Croatian ID number (OIB). + # + # @param international [Boolean] Specifies whether to add international prefix. + # @return [String] + # + # @example + # Faker::IdNumber.croatian_id #=> "88467617508" + # Faker::IdNumber.croatian_id(international: true) #=> "HR88467617508" + # + # @faker.version next + def croatian_id(international: false) + prefix = international ? 'HR' : '' + digits = Faker::Number.number(digits: 10).to_s + checksum_digit = croatian_id_checksum_digit(digits) + + "#{prefix}#{digits}#{checksum_digit}" + end + + ## + # Produces a random Danish ID Number (CPR number). + # CPR number is 10 digits. Digit 1-6 is the birthdate (format "DDMMYY"). + # Digit 7-10 is a sequence number. + # Digit 7 digit is a control digit that determines the century of birth. + # Digit 10 reveals the gender: # even is female, odd is male. + # + # @param formatted [Boolean] Specifies if the number is formatted with dividers. + # @param birthday [Date] Specifies the birthday for the id number. + # @param gender [Symbol] Specifies the gender for the id number. Must be one :male or :female if present. + # @return [String] + # + # @example + # Faker::IdNumber.danish_id_number #=> "0503909980" + # Faker::IdNumber.danish_id_number(formatted: true) #=> "050390-9980" + # Faker::IdNumber.danish_id_number(birthday: Date.new(1990, 3, 5)) #=> "0503909980" + # Faker::IdNumber.danish_id_number(gender: :female) #=> "0503909980" + # + # @faker.version next + def danish_id_number(formatted: false, birthday: Faker::Date.birthday, gender: nil) + valid_control_digits = danish_control_digits(birthday) + control_digit = sample(valid_control_digits) + digits = (0..9).to_a + gender = gender.to_sym if gender.respond_to?(:to_sym) + gender_digit = case gender + when nil + sample(digits) + when :male + sample(digits.select(&:odd?)) + when :female + sample(digits.select(&:even?)) + else + raise ArgumentError, "Invalid gender #{gender}. Must be one of male, female, or be omitted." + end + + [ + birthday.strftime('%d%m%y'), + formatted ? '-' : '', + control_digit, + Faker::Number.number(digits: 2), + gender_digit + ].join + end + + ## + # Produces a random French social security number (INSEE number). + # + # @return [String] + # + # @example + # Faker::IdNumber.french_insee_number #=> "53290236-H" + # + # @faker.version next + def french_insee_number + num = [ + [1, 2].sample(random: Faker::Config.random), # gender + Faker::Number.between(from: 0, to: 99).to_s.rjust(2, '0'), # year of birth + Faker::Number.between(from: 1, to: 12).to_s.rjust(2, '0'), # month of birth + Faker::Number.number(digits: 5), # place of birth + Faker::Number.number(digits: 3) # order number + ].join + mod = num.to_i % 97 + check = (97 - mod).to_s.rjust(2, '0') + "#{num}#{check}" + end + + private + + def croatian_id_checksum_digit(digits) + control_sum = 10 + + digits.chars.map(&:to_i).each do |digit| + control_sum += digit + control_sum %= 10 + control_sum = 10 if control_sum.zero? + control_sum *= 2 + control_sum %= 11 + end + + control_sum = 11 - control_sum + control_sum % 10 + end + + def chilean_verification_code(digits) + # First digit is multiplied by 3, second by 2, and so on + multiplication_rule = [3, 2, 7, 6, 5, 4, 3, 2] + digits_splitted = digits.to_s.chars.map(&:to_i) + + sum = digits_splitted.map.with_index { |digit, index| digit * multiplication_rule[index] }.reduce(:+) + + modulo = sum.modulo(CHILEAN_MODULO) + difference = CHILEAN_MODULO - modulo + + case difference + when 0..9 + difference + when 10 + 'K' + when 11 + 0 + end + end + + def south_african_id_checksum_digit(id_number) + value_parts = id_number.chars + even_digits = value_parts + .select + .with_index { |_, i| (i + 1).even? } + odd_digits_without_last_character = value_parts[0...-1] + .select + .with_index { |_, i| (i + 1).odd? } + + sum_of_odd_digits = odd_digits_without_last_character.map(&:to_i).reduce(:+) + even_digits_times_two = (even_digits.join.to_i * 2).to_s + sum_of_even_digits = even_digits_times_two.chars.map(&:to_i).reduce(:+) + + total_sum = sum_of_odd_digits + sum_of_even_digits + + ((10 - (total_sum % 10)) % 10).to_s + end + + def brazilian_citizen_number_checksum_digit(digits) + checksum = brazilian_document_checksum(digits) + brazilian_document_digit(checksum) + end + + def brazilian_id_checksum_digit(digits) + checksum = brazilian_document_checksum(digits) + brazilian_document_digit(checksum, id: true) + end + + def brazilian_document_checksum(digits) + digits.chars.each_with_index.inject(0) do |acc, (digit, i)| + acc + digit.to_i * (digits.size + 1 - i) + end * 10 + end + + def brazilian_document_digit(checksum, id: false) + remainder = checksum % 11 + id ? brazilian_id_digit(remainder) : brazilian_citizen_number_digit(remainder) + end + + def brazilian_citizen_number_digit(remainder) + remainder == 10 ? '0' : remainder.to_s + end + + def brazilian_id_digit(remainder) + subtraction = 11 - remainder.to_i + digits = { 10 => 'X', 11 => '0' } + digits.include?(subtraction) ? digits[subtraction] : subtraction.to_s + end + + def danish_control_digits(birthday) + year = birthday.year + century = year.to_s.slice(0, 2).to_i + year_digits = year.to_s.slice(2, 2).to_i + error_message = "Invalid birthday: #{birthday}. Danish CPR numbers are only distributed to persons born between 1858 and 2057." + + case century + when 18 + # If 5, 6, 7 or 8 and the year numbers are greater than or equal to 58, you were born in 18XX. + case year_digits + when 58..99 + [5, 6, 7, 8] + else + raise ArgumentError, error_message + end + when 19 + # If 0, 1, 2 or 3, you are always born in 19XX. + # If 4 or 9, you are born in 19XX if the year digits are greater than 36. + + case year_digits + when 0..36 + [0, 1, 2, 3] + else # 37..99 + [0, 1, 2, 3, 4, 9] + end + else + # If 4, 5, 6, 7, 8 or 9 and the year digits are less than or equal to 36, you were born in 20XX. + # 5, 6, 7 and 8 are not distributed to persons, with year digits from and including 37 to and including 57. + case year_digits + when 0..36 + [4, 5, 6, 7, 8, 9] + when 37..57 + [5, 6, 7, 8] + else + raise ArgumentError, error_message + end + end + end + + def _translate(key) + parse("id_number.#{key}") + end + end + end + + class IDNumber < Base + include Faker::Deprecator + deprecate_generator(IDNumber, IdNumber) + + CHECKS = 'TRWAGMYFPDXBNJZSQVHLCKE' + INVALID_SSN = [ + /0{3}-\d{2}-\d{4}/, + /\d{3}-0{2}-\d{4}/, + /\d{3}-\d{2}-0{4}/, + /666-\d{2}-\d{4}/, + /9\d{2}-\d{2}-\d{4}/ + ].freeze + ZA_RACE_DIGIT = '8' + ZA_CITIZENSHIP_DIGITS = %w[0 1].freeze + BRAZILIAN_ID_FORMAT = /(\d{1,2})(\d{3})(\d{3})([\dX])/.freeze + BRAZILIAN_ID_FROM = 10_000_000 + BRAZILIAN_ID_TO = 99_999_999 + + CHILEAN_MODULO = 11 + + class << self ## # Produces a random valid US Social Security number. # diff --git a/lib/helpers/deprecator.rb b/lib/helpers/deprecator.rb index 9132eb61de..993edd1e8b 100644 --- a/lib/helpers/deprecator.rb +++ b/lib/helpers/deprecator.rb @@ -1,32 +1,28 @@ # frozen_string_literal: true +# rubocop:disable Style/ClassVars module Faker - class Deprecator - module DeprecatorConstantAccessor - def self.included(base) - puts base.singleton_class - extension = Module.new do - def const_missing(missing_const_name) - puts "finding missing_const_name: ", missing_const_name.to_s - if class_variable_defined?(:@@_deprecated_constants) - if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s]) - replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", caller_locations) - return Faker::IdNumber - end - end - super + module Deprecator + def self.included(base) + extension = Module.new do + def const_missing(missing_const_name) + if class_variable_defined?(:@@_deprecated_constants) && (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s]) + return replacement[:new_constant] end - def deprecated_constant(const_name, new_constant, message: nil, deprecator: nil) - puts("Constant being deprecated: ", const_name, '\nconstant replaceing:',new_constant ) - class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants) - class_variable_get(:@@_deprecated_constants)[const_name.to_s] = { new: new_constant, message: message, deprecator: deprecator } - end + super end - base.singleton_class.prepend extension - puts base.ancestors + def deprecate_generator(old_generator_name, new_generator_constant) + class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants) + class_variable_get(:@@_deprecated_constants)[old_generator_name] = { new_constant: new_generator_constant } + + $stdout.puts("DEPRECATION WARNING: #{old_generator_name} is deprecated! Use #{new_generator_constant} instead.") + end end + + base.singleton_class.prepend extension end end end +# rubocop:enable Style/ClassVars diff --git a/test/faker/default/test_faker_deprecator.rb b/test/faker/default/test_faker_deprecator.rb deleted file mode 100644 index 174a153563..0000000000 --- a/test/faker/default/test_faker_deprecator.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../test_helper' - -class TestFakerDeprecated < Test::Unit::TestCase - def setup - @tester = Faker::Deprecated - end - - def test_non_nested_class_with_deprecated_class - actual_stdout, actual_stderr = capture_output do - Faker::IDNumber.valid - end - - assert_empty actual_stdout - assert_match('DEPRECATION WARNING: the class Faker::IDNumber is deprecated. Use Faker::IdNumber instead.', actual_stderr) - end - - def test_nested_class_with_deprecated_class - actual_stdout, actual_stderr = capture_output do - Faker::Movies::HarryPotterDeprecated.character - end - - assert_empty actual_stdout - assert_match('DEPRECATION WARNING: the class Faker::Movies::HarryPotterDeprecated is deprecated. Use Faker::Movies::HarryPotter instead.', actual_stderr) - end -end diff --git a/test/faker/default/test_faker_id_number.rb b/test/faker/default/test_faker_id_number.rb index e1cc8c7962..12ceff83c7 100644 --- a/test/faker/default/test_faker_id_number.rb +++ b/test/faker/default/test_faker_id_number.rb @@ -274,15 +274,6 @@ def test_danish_id_number_invalid_gender end end - def test_chilean_id_with_deprecated_class - actual_stdout, actual_stderr = capture_output do - Faker::IDNumber.valid - end - - assert_empty actual_stdout - assert_match('DEPRECATION WARNING: the class Faker::IDNumber is deprecated. Use Faker::IdNumber instead.', actual_stderr) - end - private def south_african_id_number_to_date_of_birth_string(sample) diff --git a/test/test_determinism.rb b/test/test_determinism.rb index 807852a0bd..71be9d5706 100644 --- a/test/test_determinism.rb +++ b/test/test_determinism.rb @@ -67,7 +67,7 @@ def all_methods def subclasses Faker.constants.delete_if do |subclass| - %i[Base Bank Books Cat Char Base58 ChileRut CLI Config Creature Date Dog DragonBall Dota ElderScrolls Fallout Games GamesHalfLife HeroesOfTheStorm Internet JapaneseMedia LeagueOfLegends Movies Myst Overwatch OnePiece Pokemon Religion Sports SwordArtOnline TvShows Time VERSION Witcher WorldOfWarcraft Zelda].include?(subclass) + skipped_classes.include?(subclass) end.sort end @@ -76,5 +76,48 @@ def subclass_methods(subclass) "Faker::#{subclass}.#{method}" end.sort end + + def skipped_classes + %i[ + Bank + Base + Base58 + Books + Cat + Char + ChileRut + CLI + Config + Creature + Date + Deprecator + Dog + DragonBall + Dota + ElderScrolls + Fallout + Games + GamesHalfLife + HeroesOfTheStorm + IDNumber + Internet + JapaneseMedia + LeagueOfLegends + Movies + Myst + Overwatch + OnePiece + Pokemon + Religion + Sports + SwordArtOnline + TvShows + Time + VERSION + Witcher + WorldOfWarcraft + Zelda + ] + end end # rubocop:enable Security/Eval,Style/EvalWithLocation diff --git a/test/test_faker_deprecator.rb b/test/test_faker_deprecator.rb new file mode 100644 index 0000000000..dee45ac116 --- /dev/null +++ b/test/test_faker_deprecator.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require_relative 'test_helper' + +class TestFakerDeprecation < Test::Unit::TestCase + def test_using_a_deprecated_generator_returns_a_warning_message + actual_stdout, actual_stderr = capture_output do + Faker::IDNumber.valid + end + + assert_match(actual_stdout, 'DEPRECATION WARNING: the class Faker::IDNumber is deprecated. Use Faker::IdNumber instead.') + assert_match(actual_stderr, 'DEPRECATION WARNING: the class Faker::IDNumber is deprecated. Use Faker::IdNumber instead.') + end +end From c3cdb34ab87b6b666c750c3bd11837f2cdc98e55 Mon Sep 17 00:00:00 2001 From: Stefanni Brasil Date: Fri, 23 Feb 2024 16:02:51 -0700 Subject: [PATCH 4/4] Add more specs and improve warning message --- lib/faker/default/id_number.rb | 425 +-------------------- lib/helpers/deprecator.rb | 8 +- test/faker/default/test_faker_id_number.rb | 287 ++++++++++++++ test/test_determinism.rb | 1 - test/test_faker_deprecator.rb | 13 +- 5 files changed, 305 insertions(+), 429 deletions(-) diff --git a/lib/faker/default/id_number.rb b/lib/faker/default/id_number.rb index 54c8399008..b02c17b77e 100644 --- a/lib/faker/default/id_number.rb +++ b/lib/faker/default/id_number.rb @@ -422,427 +422,6 @@ def _translate(key) end end - class IDNumber < Base - include Faker::Deprecator - deprecate_generator(IDNumber, IdNumber) - - CHECKS = 'TRWAGMYFPDXBNJZSQVHLCKE' - INVALID_SSN = [ - /0{3}-\d{2}-\d{4}/, - /\d{3}-0{2}-\d{4}/, - /\d{3}-\d{2}-0{4}/, - /666-\d{2}-\d{4}/, - /9\d{2}-\d{2}-\d{4}/ - ].freeze - ZA_RACE_DIGIT = '8' - ZA_CITIZENSHIP_DIGITS = %w[0 1].freeze - BRAZILIAN_ID_FORMAT = /(\d{1,2})(\d{3})(\d{3})([\dX])/.freeze - BRAZILIAN_ID_FROM = 10_000_000 - BRAZILIAN_ID_TO = 99_999_999 - - CHILEAN_MODULO = 11 - - class << self - ## - # Produces a random valid US Social Security number. - # - # @return [String] - # - # @example - # Faker::IdNumber.valid #=> "552-56-3593" - # - # @faker.version 1.6.0 - def valid - _translate('valid') - end - - ## - # Produces a random invalid US Social Security number. - # - # @return [String] - # - # @example - # Faker::IdNumber.invalid #=> "311-72-0000" - # - # @faker.version 1.6.0 - def invalid - _translate('invalid') - end - - def ssn_valid - generate(:string) do |g| - g.computed(name: :first) do - range = [1..665, 667..899].sample(random: Faker::Config.random) - n = Faker::Base.rand(range) - format('%03d', n) - end - g.lit('-') - g.computed(name: :second) do - n = Faker::Base.rand(1..99) - format('%02d', n) - end - g.lit('-') - g.computed(name: :third) do - n = Faker::Base.rand(1..9999) - format('%04d', n) - end - end - end - - ## - # Produces a random Spanish citizen identifier (DNI). - # - # @return [String] - # - # @example - # Faker::IdNumber.spanish_citizen_number #=> "53290236-H" - # - # @faker.version 1.9.0 - def spanish_citizen_number - num = Faker::Number.number(digits: 8) - mod = num.to_i % 23 - check = CHECKS[mod] - "#{num}-#{check}" - end - - ## - # Produces a random Spanish foreign born citizen identifier (NIE). - # - # @return [String] - # - # @example - # Faker::IdNumber.spanish_foreign_citizen_number #=> "Z-1600870-Y" - # - # @faker.version 1.9.0 - def spanish_foreign_citizen_number - code = 'XYZ' - digits = Faker::Number.number(digits: 7) - prefix = code[rand(code.length)] - prefix_val = 'XYZ'.index(prefix).to_s - mod = "#{prefix_val}#{digits}".to_i % 23 - check = CHECKS[mod] - "#{prefix}-#{digits}-#{check}" - end - - ## - # Produces a random valid South African ID Number. - # - # @return [String] - # - # @example - # Faker::IdNumber.south_african_id_number #=> "8105128870184" - # Faker::IdNumber.valid_south_african_id_number #=> "8105128870184" - # - # @faker.version 1.9.2 - def valid_south_african_id_number - id_number = [ - Faker::Date.birthday.strftime('%y%m%d'), - Faker::Number.number(digits: 4), - ZA_CITIZENSHIP_DIGITS.sample(random: Faker::Config.random), - ZA_RACE_DIGIT - ].join - - [id_number, south_african_id_checksum_digit(id_number)].join - end - - alias south_african_id_number valid_south_african_id_number - - ## - # Produces a random invalid South African ID Number. - # - # @return [String] - # - # @example - # Faker::IdNumber.invalid_south_african_id_number #=> "1642972065088" - # - # @faker.version 1.9.2 - def invalid_south_african_id_number - invalid_date_of_birth = [ - Faker::Number.number(digits: 2), - Faker::Number.between(from: 13, to: 99), - Faker::Number.between(from: 32, to: 99) - ].map(&:to_s).join - - id_number = [ - invalid_date_of_birth, - Faker::Number.number(digits: 4), - ZA_CITIZENSHIP_DIGITS.sample(random: Faker::Config.random), - ZA_RACE_DIGIT - ].join - - [id_number, south_african_id_checksum_digit(id_number)].join - end - - ## - # Produces a random Brazilian Citizen Number (CPF). - # - # @param formatted [Boolean] Specifies if the number is formatted with dividers. - # @return [String] - # - # @example - # Faker::IdNumber.brazilian_citizen_number #=> "53540542221" - # Faker::IdNumber.brazilian_citizen_number(formatted: true) #=> "535.405.422-21" - # - # @faker.version 1.9.2 - def brazilian_citizen_number(formatted: false) - digits = Faker::Number.leading_zero_number(digits: 9) until digits&.match(/(\d)((?!\1)\d)+/) - first_digit = brazilian_citizen_number_checksum_digit(digits) - second_digit = brazilian_citizen_number_checksum_digit(digits + first_digit) - number = [digits, first_digit, second_digit].join - formatted ? format('%s.%s.%s-%s', *number.scan(/\d{2,3}/).flatten) : number - end - - alias brazilian_cpf brazilian_citizen_number - - ## - # Produces a random Brazilian ID Number (RG). - # - # @param formatted [Boolean] Specifies if the number is formatted with dividers. - # @return [String] - # - # @example - # Faker::IdNumber.brazilian_id #=> "493054029" - # Faker::IdNumber.brazilian_id(formatted: true) #=> "49.305.402-9" - # - # @faker.version 2.1.2 - def brazilian_id(formatted: false) - digits = Faker::Number.between(to: BRAZILIAN_ID_FROM, from: BRAZILIAN_ID_TO).to_s - check_digit = brazilian_id_checksum_digit(digits) - number = [digits, check_digit].join - formatted ? format('%s.%s.%s-%s', *number.scan(BRAZILIAN_ID_FORMAT).flatten) : number - end - - alias brazilian_rg brazilian_id - - ## - # Produces a random Chilean ID (Rut with 8 digits). - # - # @return [String] - # - # @example - # Faker::IdNumber.chilean_id #=> "15620613-K" - # - # @faker.version 2.1.2 - def chilean_id - digits = Faker::Number.number(digits: 8) - verification_code = chilean_verification_code(digits) - - "#{digits}-#{verification_code}" - end - - ## - # Produces a random Croatian ID number (OIB). - # - # @param international [Boolean] Specifies whether to add international prefix. - # @return [String] - # - # @example - # Faker::IdNumber.croatian_id #=> "88467617508" - # Faker::IdNumber.croatian_id(international: true) #=> "HR88467617508" - # - # @faker.version next - def croatian_id(international: false) - prefix = international ? 'HR' : '' - digits = Faker::Number.number(digits: 10).to_s - checksum_digit = croatian_id_checksum_digit(digits) - - "#{prefix}#{digits}#{checksum_digit}" - end - - ## - # Produces a random Danish ID Number (CPR number). - # CPR number is 10 digits. Digit 1-6 is the birthdate (format "DDMMYY"). - # Digit 7-10 is a sequence number. - # Digit 7 digit is a control digit that determines the century of birth. - # Digit 10 reveals the gender: # even is female, odd is male. - # - # @param formatted [Boolean] Specifies if the number is formatted with dividers. - # @param birthday [Date] Specifies the birthday for the id number. - # @param gender [Symbol] Specifies the gender for the id number. Must be one :male or :female if present. - # @return [String] - # - # @example - # Faker::IdNumber.danish_id_number #=> "0503909980" - # Faker::IdNumber.danish_id_number(formatted: true) #=> "050390-9980" - # Faker::IdNumber.danish_id_number(birthday: Date.new(1990, 3, 5)) #=> "0503909980" - # Faker::IdNumber.danish_id_number(gender: :female) #=> "0503909980" - # - # @faker.version next - def danish_id_number(formatted: false, birthday: Faker::Date.birthday, gender: nil) - valid_control_digits = danish_control_digits(birthday) - control_digit = sample(valid_control_digits) - digits = (0..9).to_a - gender = gender.to_sym if gender.respond_to?(:to_sym) - gender_digit = case gender - when nil - sample(digits) - when :male - sample(digits.select(&:odd?)) - when :female - sample(digits.select(&:even?)) - else - raise ArgumentError, "Invalid gender #{gender}. Must be one of male, female, or be omitted." - end - - [ - birthday.strftime('%d%m%y'), - formatted ? '-' : '', - control_digit, - Faker::Number.number(digits: 2), - gender_digit - ].join - end - - ## - # Produces a random French social security number (INSEE number). - # - # @return [String] - # - # @example - # Faker::IdNumber.french_insee_number #=> "53290236-H" - # - # @faker.version next - def french_insee_number - num = [ - [1, 2].sample(random: Faker::Config.random), # gender - Faker::Number.between(from: 0, to: 99).to_s.rjust(2, '0'), # year of birth - Faker::Number.between(from: 1, to: 12).to_s.rjust(2, '0'), # month of birth - Faker::Number.number(digits: 5), # place of birth - Faker::Number.number(digits: 3) # order number - ].join - mod = num.to_i % 97 - check = (97 - mod).to_s.rjust(2, '0') - "#{num}#{check}" - end - - private - - def croatian_id_checksum_digit(digits) - control_sum = 10 - - digits.chars.map(&:to_i).each do |digit| - control_sum += digit - control_sum %= 10 - control_sum = 10 if control_sum.zero? - control_sum *= 2 - control_sum %= 11 - end - - control_sum = 11 - control_sum - control_sum % 10 - end - - def chilean_verification_code(digits) - # First digit is multiplied by 3, second by 2, and so on - multiplication_rule = [3, 2, 7, 6, 5, 4, 3, 2] - digits_splitted = digits.to_s.chars.map(&:to_i) - - sum = digits_splitted.map.with_index { |digit, index| digit * multiplication_rule[index] }.reduce(:+) - - modulo = sum.modulo(CHILEAN_MODULO) - difference = CHILEAN_MODULO - modulo - - case difference - when 0..9 - difference - when 10 - 'K' - when 11 - 0 - end - end - - def south_african_id_checksum_digit(id_number) - value_parts = id_number.chars - even_digits = value_parts - .select - .with_index { |_, i| (i + 1).even? } - odd_digits_without_last_character = value_parts[0...-1] - .select - .with_index { |_, i| (i + 1).odd? } - - sum_of_odd_digits = odd_digits_without_last_character.map(&:to_i).reduce(:+) - even_digits_times_two = (even_digits.join.to_i * 2).to_s - sum_of_even_digits = even_digits_times_two.chars.map(&:to_i).reduce(:+) - - total_sum = sum_of_odd_digits + sum_of_even_digits - - ((10 - (total_sum % 10)) % 10).to_s - end - - def brazilian_citizen_number_checksum_digit(digits) - checksum = brazilian_document_checksum(digits) - brazilian_document_digit(checksum) - end - - def brazilian_id_checksum_digit(digits) - checksum = brazilian_document_checksum(digits) - brazilian_document_digit(checksum, id: true) - end - - def brazilian_document_checksum(digits) - digits.chars.each_with_index.inject(0) do |acc, (digit, i)| - acc + digit.to_i * (digits.size + 1 - i) - end * 10 - end - - def brazilian_document_digit(checksum, id: false) - remainder = checksum % 11 - id ? brazilian_id_digit(remainder) : brazilian_citizen_number_digit(remainder) - end - - def brazilian_citizen_number_digit(remainder) - remainder == 10 ? '0' : remainder.to_s - end - - def brazilian_id_digit(remainder) - subtraction = 11 - remainder.to_i - digits = { 10 => 'X', 11 => '0' } - digits.include?(subtraction) ? digits[subtraction] : subtraction.to_s - end - - def danish_control_digits(birthday) - year = birthday.year - century = year.to_s.slice(0, 2).to_i - year_digits = year.to_s.slice(2, 2).to_i - error_message = "Invalid birthday: #{birthday}. Danish CPR numbers are only distributed to persons born between 1858 and 2057." - - case century - when 18 - # If 5, 6, 7 or 8 and the year numbers are greater than or equal to 58, you were born in 18XX. - case year_digits - when 58..99 - [5, 6, 7, 8] - else - raise ArgumentError, error_message - end - when 19 - # If 0, 1, 2 or 3, you are always born in 19XX. - # If 4 or 9, you are born in 19XX if the year digits are greater than 36. - - case year_digits - when 0..36 - [0, 1, 2, 3] - else # 37..99 - [0, 1, 2, 3, 4, 9] - end - else - # If 4, 5, 6, 7, 8 or 9 and the year digits are less than or equal to 36, you were born in 20XX. - # 5, 6, 7 and 8 are not distributed to persons, with year digits from and including 37 to and including 57. - case year_digits - when 0..36 - [4, 5, 6, 7, 8, 9] - when 37..57 - [5, 6, 7, 8] - else - raise ArgumentError, error_message - end - end - end - - def _translate(key) - parse("id_number.#{key}") - end - end - end + include Faker::Deprecator + deprecate_generator('IDNumber', IdNumber) end diff --git a/lib/helpers/deprecator.rb b/lib/helpers/deprecator.rb index 993edd1e8b..e280cf9423 100644 --- a/lib/helpers/deprecator.rb +++ b/lib/helpers/deprecator.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +# Based on Rails ActiveSupport Deprecator +# https://github.com/rails/rails/blob/6f0d1ad14b92b9f5906e44740fce8b4f1c7075dc/activesupport/lib/active_support/deprecation/constant_accessor.rb + # rubocop:disable Style/ClassVars module Faker module Deprecator @@ -7,6 +10,7 @@ def self.included(base) extension = Module.new do def const_missing(missing_const_name) if class_variable_defined?(:@@_deprecated_constants) && (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s]) + $stdout.puts("DEPRECATION WARNING: #{name}::#{replacement[:old_generator]} is deprecated. Use #{replacement[:new_constant]} instead.") return replacement[:new_constant] end @@ -15,9 +19,7 @@ def const_missing(missing_const_name) def deprecate_generator(old_generator_name, new_generator_constant) class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants) - class_variable_get(:@@_deprecated_constants)[old_generator_name] = { new_constant: new_generator_constant } - - $stdout.puts("DEPRECATION WARNING: #{old_generator_name} is deprecated! Use #{new_generator_constant} instead.") + class_variable_get(:@@_deprecated_constants)[old_generator_name] = { new_constant: new_generator_constant, old_generator: old_generator_name } end end diff --git a/test/faker/default/test_faker_id_number.rb b/test/faker/default/test_faker_id_number.rb index 12ceff83c7..3e66178367 100644 --- a/test/faker/default/test_faker_id_number.rb +++ b/test/faker/default/test_faker_id_number.rb @@ -288,3 +288,290 @@ def assert_valid_south_african_id_number(sample) assert Date.parse(south_african_id_number_to_date_of_birth_string(sample)) end end + +class TestFakerIDNumber < Test::Unit::TestCase + def setup + @tester = Faker::IDNumber + end + + def test_valid_ssn + sample = @tester.valid + + assert_equal(11, sample.length) + assert_equal '-', sample[3] + assert_equal '-', sample[6] + assert sample[0..2].split.map { :to_i }.all? { :is_digit? } + assert sample[4..5].split.map { :to_i }.all? { :is_digit? } + assert sample[7..9].split.map { :to_i }.all? { :is_digit? } + end + + def test_invalid_ssn + sample = @tester.invalid + + assert_equal(11, sample.length) + assert_equal '-', sample[3] + assert_equal '-', sample[6] + assert sample[0..2].split.map { :to_i }.all? { :is_digit? } + assert sample[4..5].split.map { :to_i }.all? { :is_digit? } + assert sample[7..9].split.map { :to_i }.all? { :is_digit? } + end + + def test_spanish_dni + sample = @tester.spanish_citizen_number + + assert_equal 10, sample.length + assert sample[0..7].split.map { :to_i }.all? { :is_digit? } + assert_equal('-', sample[8]) + mod = sample[0..7].to_i % 23 + + assert_equal Faker::IdNumber::CHECKS[mod], sample[9] + end + + def test_spanish_nie + sample = @tester.spanish_foreign_citizen_number + + assert_equal 11, sample.length + assert_includes 'XYZ', sample[0] + assert_equal '-', sample[1] + assert sample[2..8].split.map { :to_i }.all? { :is_digit? } + assert_equal '-', sample[9] + prefix = 'XYZ'.index(sample[0]).to_s + mod = "#{prefix}#{sample[2..8]}".to_i % 23 + + assert_equal Faker::IdNumber::CHECKS[mod], sample[10] + end + + def test_south_african_id_number + assert_valid_south_african_id_number(@tester.south_african_id_number) + end + + def test_valid_south_african_id_number + assert_valid_south_african_id_number(@tester.valid_south_african_id_number) + end + + def test_invalid_south_african_id_number + sample = @tester.invalid_south_african_id_number + + assert_raises Date::Error do + Date.parse(south_african_id_number_to_date_of_birth_string(sample)) + end + end + + def test_brazilian_citizen_number + sample = @tester.brazilian_citizen_number + + assert_match(/^\d{11}$/, sample) + assert_match(/(\d)((?!\1)\d)+/, sample) + end + + def test_brazilian_citizen_number_formatted + sample = @tester.brazilian_citizen_number(formatted: true) + + assert_match(/^\d{3}\.\d{3}\.\d{3}-\d{2}$/, sample) + end + + def test_brazilian_id + sample = @tester.brazilian_id + + assert_match(/^\d{8}(X|\d)?$/, sample) + assert_match(/(\d)((?!\1)\d)+/, sample) + end + + def test_brazilian_id_formatted + sample = @tester.brazilian_id(formatted: true) + + assert_match(/^\d{1,2}.\d{3}.\d{3}-[\dX]$/, sample) + end + + def test_brazilian_citizen_number_checksum_digit + digits = '128991760' + checksum_digit = Faker::IdNumber.send(:brazilian_citizen_number_checksum_digit, digits) + + assert_equal('4', checksum_digit) + digits = '1289917604' + checksum_digit = Faker::IdNumber.send(:brazilian_citizen_number_checksum_digit, digits) + + assert_equal('8', checksum_digit) + end + + def test_brazilian_id_checksum_digit + digits = '41987080' + checksum_digit = Faker::IdNumber.send(:brazilian_id_checksum_digit, digits) + + assert_equal('5', checksum_digit) + end + + def test_brazilian_document_checksum + digits = '123456789' + checksum = Faker::IdNumber.send(:brazilian_document_checksum, digits) + + assert_equal(2100, checksum) + end + + def test_brazilian_document_digit + citizen_number_digit10 = Faker::IdNumber.send(:brazilian_document_digit, 10) + citizen_number_digit_other = Faker::IdNumber.send(:brazilian_document_digit, 9) + id_digit10 = Faker::IdNumber.send(:brazilian_document_digit, 1, id: true) + id_digit11 = Faker::IdNumber.send(:brazilian_document_digit, 0, id: true) + id_digit_other = Faker::IdNumber.send(:brazilian_document_digit, 2, id: true) + + assert_equal('0', citizen_number_digit10) + assert_equal('9', citizen_number_digit_other) + assert_equal('X', id_digit10) + assert_equal('0', id_digit11) + assert_equal('9', id_digit_other) + end + + def test_brazilian_citizen_number_digit + digit10 = Faker::IdNumber.send(:brazilian_citizen_number_digit, 10) + digit_other = Faker::IdNumber.send(:brazilian_citizen_number_digit, 9) + + assert_equal('0', digit10) + assert_equal('9', digit_other) + end + + def test_brazilian_id_digit + digit10 = Faker::IdNumber.send(:brazilian_id_digit, 1) + digit11 = Faker::IdNumber.send(:brazilian_id_digit, 0) + digit_other = Faker::IdNumber.send(:brazilian_id_digit, 2) + + assert_equal('X', digit10) + assert_equal('0', digit11) + assert_equal('9', digit_other) + end + + def test_chilean_id + sample = @tester.chilean_id + + assert_match(/^\d{8}-[K\d]$/, sample) + end + + def test_chilean_verification_code_k + verification_code = Faker::IdNumber.send(:chilean_verification_code, 20_680_873) + + assert_equal('K', verification_code) + end + + def test_chilean_verification_code_0 + verification_code = Faker::IdNumber.send(:chilean_verification_code, 13_196_022) + + assert_equal(0, verification_code) + end + + def test_croatian_id + sample = @tester.croatian_id + + assert_match(/^\d{11}$/, sample) + end + + def test_croatian_id_international + sample = @tester.croatian_id(international: true) + + assert_match(/^HR\d{11}$/, sample) + end + + def test_croatian_id_checksum_digit + digits = '8764670153' + checksum_digit = Faker::IdNumber.send(:croatian_id_checksum_digit, digits) + + assert_equal(5, checksum_digit) + end + + def test_danish_id_number + sample = @tester.danish_id_number + + assert_match(/^\d{10}$/, sample) + end + + def test_french_insee_number + sample = @tester.french_insee_number + + assert_match(/^(?\d{1})(?\d{2})(?\d{2})(?\d{1})(?[0-9AB]{1})(?\d{3})(?\d{3})(?\d{2})$/, sample) + end + + def test_danish_id_number_formatted + sample = @tester.danish_id_number(formatted: true) + + assert_match(/^\d{6}-\d{4}$/, sample) + end + + def test_danish_id_number_birthday + sample = @tester.danish_id_number(birthday: Date.new(1995, 1, 2)) + + assert_match(/^020195\d{4}$/, sample) + end + + def test_danish_id_number_birthday_early_1800 + assert_raises ArgumentError do + @tester.danish_id_number(birthday: Date.new(1815, 1, 2)) + end + end + + def test_danish_id_number_birthday_late_1800 + sample = @tester.danish_id_number(birthday: Date.new(1895, 1, 2)) + + assert_match(/^020195[5678]\d{3}$/, sample) + end + + def test_danish_id_number_birthday_early_1900 + sample = @tester.danish_id_number(birthday: Date.new(1915, 1, 2)) + + assert_match(/^020115[0123]\d{3}$/, sample) + end + + def test_danish_id_number_birthday_late_1900 + sample = @tester.danish_id_number(birthday: Date.new(1995, 1, 2)) + + assert_match(/^020195[012349]\d{3}$/, sample) + end + + def test_danish_id_number_birthday_early_2000 + sample = @tester.danish_id_number(birthday: Date.new(2015, 1, 2)) + + assert_match(/^020115[456789]\d{3}$/, sample) + end + + def test_danish_id_number_birthday_mid_2000 + sample = @tester.danish_id_number(birthday: Date.new(2055, 1, 2)) + + assert_match(/^020155[5678]\d{3}$/, sample) + end + + def test_danish_id_number_birthday_late_2000 + assert_raises ArgumentError do + @tester.danish_id_number(birthday: Date.new(2095, 1, 2)) + end + end + + def test_danish_id_number_gender_female + sample = @tester.danish_id_number(gender: :female) + + assert_predicate sample.chars.last.to_i, :even? + end + + def test_danish_id_number_gender_male + sample = @tester.danish_id_number(gender: :male) + + assert_predicate sample.chars.last.to_i, :odd? + end + + def test_danish_id_number_invalid_gender + assert_raises ArgumentError do + @tester.danish_id_number(gender: :invalid) + end + end + + private + + def south_african_id_number_to_date_of_birth_string(sample) + "19#{sample[0..1]}/#{sample[2..3]}/#{sample[4..5]}}" + end + + def assert_valid_south_african_id_number(sample) + assert_equal 13, sample.length + assert_match(/^\d{13}$/, sample) + assert_include Faker::IdNumber::ZA_CITIZENSHIP_DIGITS, sample[10] + assert_equal Faker::IdNumber::ZA_RACE_DIGIT, sample[11] + assert Date.parse(south_african_id_number_to_date_of_birth_string(sample)) + end +end diff --git a/test/test_determinism.rb b/test/test_determinism.rb index 71be9d5706..69ddf28979 100644 --- a/test/test_determinism.rb +++ b/test/test_determinism.rb @@ -99,7 +99,6 @@ def skipped_classes Games GamesHalfLife HeroesOfTheStorm - IDNumber Internet JapaneseMedia LeagueOfLegends diff --git a/test/test_faker_deprecator.rb b/test/test_faker_deprecator.rb index dee45ac116..0083a2203c 100644 --- a/test/test_faker_deprecator.rb +++ b/test/test_faker_deprecator.rb @@ -8,7 +8,16 @@ def test_using_a_deprecated_generator_returns_a_warning_message Faker::IDNumber.valid end - assert_match(actual_stdout, 'DEPRECATION WARNING: the class Faker::IDNumber is deprecated. Use Faker::IdNumber instead.') - assert_match(actual_stderr, 'DEPRECATION WARNING: the class Faker::IDNumber is deprecated. Use Faker::IdNumber instead.') + assert_includes(actual_stdout, 'DEPRECATION WARNING: Faker::IDNumber is deprecated. Use Faker::IdNumber instead') + assert_empty(actual_stderr) + end + + def test_using_a_non_deprecated_generator_does_not_return_a_warning_message + actual_stdout, actual_stderr = capture_output do + Faker::IdNumber.valid + end + + assert_empty(actual_stdout) + assert_empty(actual_stderr) end end