Repository: joke2k/faker
Pull request #1499 (2021-08-20 04:35:16)

Added non-geographic phone numbers and added services phones formats in pt_BR
What does this changes
 - Added non-geographic phone numbers ([source](https://pt.wikipedia.org/wiki/N%C3%BAmeros_de_telefone_no_Brasil#N%C3%A3o_Geogr%C3%A1ficos))
 - Added services phones formats ([source](https://pt.wikipedia.org/wiki/N%C3%BAmeros_de_telefone_no_Brasil#C%C3%B3digo_de_Acesso_a_Servi%C3%A7os_de_Utilidade_P%C3%BAblica_e_de_Apoio_ao_STFC))

What was wrong
 - Non-geographic phone number did not exist in valid pt_BR formats and services phones formats did not exist.

How this fixes it
 - Added non-geographic phone numbers in formats and change regex tests for this.
 - Added a new method called _`service_phone_number`_ in providers and added _`test_service_phone`_ test case for this.


Patch:
diff --git a/faker/providers/currency/pt_BR/__init__.py b/faker/providers/currency/pt_BR/__init__.py
new file mode 100644
index 00000000..17ee8e3f
--- /dev/null
+++ b/faker/providers/currency/pt_BR/__init__.py
@@ -0,0 +1,9 @@
+from .. import Provider as CurrencyProvider
+
+
+class Provider(CurrencyProvider):
+
+    price_formats = ["#,##", "%#,##", "%##,##", "%.###,##", "%#.###,##"]
+
+    def pricetag(self):
+        return ("R$" + self.numerify(self.random_element(self.price_formats)))
diff --git a/faker/providers/date_time/pt_BR/__init__.py b/faker/providers/date_time/pt_BR/__init__.py
new file mode 100644
index 00000000..e853211f
--- /dev/null
+++ b/faker/providers/date_time/pt_BR/__init__.py
@@ -0,0 +1,37 @@
+from .. import Provider as DateTimeProvider
+
+
+class Provider(DateTimeProvider):
+
+    DAY_NAMES = {
+        "0": "domingo",
+        "1": "segunda-feira",
+        "2": "terça-feira",
+        "3": "quarta-feira",
+        "4": "quinta-feira",
+        "5": "sexta-feira",
+        "6": "sábado",
+    }
+
+    MONTH_NAMES = {
+        "01": "janeiro",
+        "02": "fevereiro",
+        "03": "março",
+        "04": "abril",
+        "05": "maio",
+        "06": "junho",
+        "07": "julho",
+        "08": "agosto",
+        "09": "setembro",
+        "10": "outubro",
+        "11": "novembro",
+        "12": "dezembro",
+    }
+
+    def day_of_week(self):
+        day = self.date("%w")
+        return self.DAY_NAMES[day]
+
+    def month_name(self):
+        month = self.month()
+        return self.MONTH_NAMES[month]
diff --git a/faker/providers/phone_number/pt_BR/__init__.py b/faker/providers/phone_number/pt_BR/__init__.py
index 46b1fb0b..2097f2ff 100644
--- a/faker/providers/phone_number/pt_BR/__init__.py
+++ b/faker/providers/phone_number/pt_BR/__init__.py
@@ -75,6 +75,14 @@ class Provider(PhoneNumberProvider):
         '71 ####-####',
         '81 ####-####',
         '84 ####-####',
+        '0300 ### ####',
+        '0500 ### ####',
+        '0800 ### ####',
+        '0900 ### ####',
+        '0300-###-####',
+        '0500-###-####',
+        '0800-###-####',
+        '0900-###-####',
     )
 
     msisdn_formats = (
@@ -102,6 +110,31 @@ class Provider(PhoneNumberProvider):
         '+55 (##) 9 ####-####',
     )
 
+    services_phones_formats = (
+        '100',
+        '128',
+        '151',
+        '152',
+        '153',
+        '156',
+        '180',
+        '181',
+        '185',
+        '188',
+        '190',
+        '191',
+        '192',
+        '193',
+        '194',
+        '197',
+        '198',
+        '199',
+    )
+
     def cellphone_number(self):
         pattern = self.random_element(self.cellphone_formats)
         return self.numerify(self.generator.parse(pattern))
+
+    def service_phone_number(self):
+        pattern = self.random_element(self.services_phones_formats)
+        return self.numerify(self.generator.parse(pattern))


Test patch:
diff --git a/tests/providers/test_currency.py b/tests/providers/test_currency.py
index 60703517..d63a8a38 100644
--- a/tests/providers/test_currency.py
+++ b/tests/providers/test_currency.py
@@ -346,3 +346,19 @@ class TestRoRo:
         for _ in range(num_samples):
             pricetag = faker.pricetag()
             assert isinstance(pricetag, str)
+
+
+class TestPtBr:
+    """Test pt_BR currency provider"""
+
+    num_samples = 100
+
+    @classmethod
+    def setup_class(cls):
+        from faker.providers.currency.pt_BR import Provider as PtBrCurrencyProvider
+        cls.provider = PtBrCurrencyProvider
+
+    def test_pricetag(self, faker, num_samples):
+        for _ in range(num_samples):
+            pricetag = faker.pricetag()
+            assert isinstance(pricetag, str)
diff --git a/tests/providers/test_date_time.py b/tests/providers/test_date_time.py
index 38195d8e..33c4f16a 100644
--- a/tests/providers/test_date_time.py
+++ b/tests/providers/test_date_time.py
@@ -25,6 +25,7 @@ from faker.providers.date_time.es_ES import Provider as EsEsProvider
 from faker.providers.date_time.hy_AM import Provider as HyAmProvider
 from faker.providers.date_time.it_IT import Provider as ItItProvider
 from faker.providers.date_time.pl_PL import Provider as PlProvider
+from faker.providers.date_time.pt_BR import Provider as PtBrProvider
 from faker.providers.date_time.pt_PT import Provider as PtPtProvider
 from faker.providers.date_time.ro_RO import Provider as RoRoProvider
 from faker.providers.date_time.ru_RU import Provider as RuProvider
@@ -1103,6 +1104,21 @@ class TestTrTr(unittest.TestCase):
         assert month in TrTrProvider.MONTH_NAMES.values()
 
 
+class TestPtBr(unittest.TestCase):
+
+    def setUp(self):
+        self.fake = Faker('pt_BR')
+        Faker.seed(0)
+
+    def test_day(self):
+        day = self.fake.day_of_week()
+        assert day in PtBrProvider.DAY_NAMES.values()
+
+    def test_month(self):
+        month = self.fake.month_name()
+        assert month in PtBrProvider.MONTH_NAMES.values()
+
+
 class TestPtPt(unittest.TestCase):
 
     def setUp(self):
diff --git a/tests/providers/test_phone_number.py b/tests/providers/test_phone_number.py
index 04668374..287cfae5 100644
--- a/tests/providers/test_phone_number.py
+++ b/tests/providers/test_phone_number.py
@@ -37,7 +37,8 @@ class TestPtBr:
         pattern = re.compile(
             r'(?:\+55 )?'
             r'(?:[1-8]1|84|\((?:0[1-8]1|084)\))'
-            r' \d{4}[ -]\d{4}',
+            r' \d{4}[ -]\d{4}|'
+            r'\d{4}?[ -]\d{3}[ -]\d{4}',
         )
         for _ in range(num_samples):
             phone_number = faker.phone_number()
@@ -59,6 +60,12 @@ class TestPtBr:
             cellphone = faker.cellphone_number()
             assert pattern.fullmatch(cellphone)
 
+    def test_service_phone(self, faker, num_samples):
+        pattern = re.compile(r'1(?:0|2|5|8|9)?(?:[0-9])')
+        for _ in range(num_samples):
+            service = faker.service_phone_number()
+            assert pattern.fullmatch(service)
+
 
 class TestHuHu:
     """Test hu_HU phone number provider methods"""