Skip to content

[br-utils] Create package to consolidate itilities for CPF - #30

Open
juliolmuller wants to merge 7 commits into
mainfrom
feat/br-utilities
Open

[br-utils] Create package to consolidate itilities for CPF#30
juliolmuller wants to merge 7 commits into
mainfrom
feat/br-utilities

Conversation

@juliolmuller

@juliolmuller juliolmuller commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Implements #12.

Summary by CodeRabbit

  • New Features

    • Added a unified Ruby toolkit for CPF and CNPJ formatting, generation, and validation.
    • Added support for alphanumeric CNPJ values.
    • Added configurable defaults, per-call options, reusable instances, and convenient component access.
    • Added consistent exports and structured errors for invalid inputs or conflicting options.
  • Documentation

    • Added comprehensive English and Portuguese usage documentation, including installation, APIs, configuration, examples, and supported Ruby versions.
    • Added a changelog entry for the 1.0.0 stable release.

juliolmuller and others added 7 commits August 10, 2026 17:29
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
@juliolmuller juliolmuller self-assigned this Aug 10, 2026
@juliolmuller
juliolmuller requested a review from a team as a code owner August 10, 2026 20:45
@juliolmuller juliolmuller added the enhancement New minor or major features. label Aug 10, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR replaces the placeholder gem with a unified, configurable BrUtils façade for CPF and CNPJ utilities. It adds namespace exports, structured errors, extensive RSpec coverage, Ruby and Portuguese documentation, dependency constraints, and a 1.0.0 changelog entry.

Changes

Unified BrUtils façade

Layer / File(s) Summary
Façade configuration and resource access
packages/br-utilities/src/br-utilities.rb, packages/br-utilities/br-utilities.gemspec, packages/br-utilities/Gemfile, packages/br-utilities/src/br-utilities/br_utils.rb, packages/br-utilities/tests/br_utils.spec.rb
BrUtils is now a configurable class with CPF/CNPJ resources, setters, class helpers, and a mutable DEFAULT instance. Dependency versions are constrained.
Exports and API errors
packages/br-utilities/src/br-utilities/errors.rb, packages/br-utilities/src/br-utilities/cpf_*, packages/br-utilities/src/br-utilities/cnpj_*, packages/br-utilities/src/br-utilities/version.rb, packages/br-utilities/tests/br_utils.spec.rb
CPF and CNPJ modules, classes, options, and errors are re-exported under BrUtils. New API misuse errors preserve native Ruby exception ancestry.
CPF and CNPJ operation coverage
packages/br-utilities/tests/br_utils.spec.rb
Tests cover formatting, generation, validation, option forwarding, deterministic generation, formatted inputs, and alphanumeric CNPJ behavior.
Usage and release documentation
README.md, README.pt.md, packages/br-utilities/README.md, packages/br-utilities/README.pt.md, packages/br-utilities/CHANGELOG.md
Documentation covers installation, APIs, configuration, exports, errors, bundled packages, contribution, licensing, and the 1.0.0 release.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Application
  participant BrUtils
  participant CpfUtils
  participant CnpjUtils
  Application->>BrUtils: access cpf or cnpj helper
  BrUtils->>CpfUtils: delegate CPF operation
  BrUtils->>CnpjUtils: delegate CNPJ operation
  CpfUtils-->>Application: return CPF result
  CnpjUtils-->>Application: return CNPJ result
Loading

Possibly related issues

Possibly related PRs

Poem

A rabbit hops through CPF fields,
While CNPJ letters bloom.
BrUtils gathers every tool,
And gives each helper room.
Tests guard the paths with care,
Release notes twitch their nose.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title identifies the new utility package and CPF consolidation, but it omits CNPJ and contains a typo.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/br-utilities

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@juliolmuller juliolmuller linked an issue Aug 10, 2026 that may be closed by this pull request
7 tasks

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/br-utilities/README.md`:
- Around line 607-616: Update packages/br-utilities/README.md lines 607-616 and
packages/br-utilities/README.pt.md lines 600-609 to replace the undefined
BrUtils::DomainError rescue with a real bundled-package DomainError example.
Expand packages/br-utilities/README.md lines 641-652 and
packages/br-utilities/README.pt.md lines 634-645 with every propagated leaf,
including callback-delivered InvalidLengthError, documenting each in the
required order with its full hierarchy, marker, category, trigger, example, and
handling guidance.
- Line 26: Correct the façade wording to describe BrUtils.cpf and BrUtils.cnpj
as delegating to BrUtils::DEFAULT.cpf and BrUtils::DEFAULT.cnpj, not aliasing
the BrUtils::DEFAULT object. Apply the equivalent precise Portuguese wording in
packages/br-utilities/README.pt.md (line 19) and README.pt.md (line 19), and
update the same contract wording in packages/br-utilities/README.md (line 26),
README.md (line 26), and packages/br-utilities/CHANGELOG.md (line 11).

In `@packages/br-utilities/src/br-utilities/errors.rb`:
- Around line 4-8: Update the exposed sibling error marker modules, including
CpfFmt::Error and CnpjFmt::Error, to include BrUtils::Error so their derived
errors are caught by rescue BrUtils::Error. Add a rescue test covering a
propagated domain error such as CpfFmt::OutOfRangeError or
CnpjFmt::ValidationError.

In `@packages/br-utilities/src/br-utilities/version.rb`:
- Around line 3-6: The BrUtils constant is declared with conflicting module and
class kinds. In packages/br-utilities/src/br-utilities/version.rb lines 3-6,
declare BrUtils as a class and update the placeholder comment; keep the class
reopening in packages/br-utilities/src/br-utilities/br_utils.rb lines 37-42, and
align the BrUtils reopenings in
packages/br-utilities/src/br-utilities/cpf_gen.rb line 3, cpf_utils.rb line 3,
and cpf_val.rb line 3 with that class declaration.

In `@packages/br-utilities/tests/br_utils.spec.rb`:
- Around line 605-633: Add examples for the two documented BrUtils#initialize
contracts in the existing settings contexts: verify string-keyed settings are
normalized and adopt the provided CpfUtils/CnpjUtils instances, and verify
matching nested :cpf or :cnpj settings take precedence over flat keyword values.
Use the existing Helpers.normalize_settings behavior and preserve the current
non-Hash error coverage.

In `@README.md`:
- Around line 10-12: Add the blockquote marker to the blank line between callout
paragraphs in README.md lines 10-12, README.pt.md lines 3-5,
packages/br-utilities/README.md lines 10-12, and
packages/br-utilities/README.pt.md lines 3-5, keeping each callout in one
continuous blockquote.
- Line 239: Update repository-root documentation links to use package-relative
paths: in README.md (239-239) point CPF to packages/cpf-utilities/README.md,
(302-302) CNPJ to packages/cnpj-utilities/README.md, (471-471) both
bundled-package links, (643-643) both propagated-package links, (683-684) both
table links, and (703-703) the changelog to packages/br-utilities/CHANGELOG.md;
apply the corresponding README.pt.md paths at 232-232, 295-295, 464-464,
636-636, 670-670, and 676-677, with the changelog at 696-696 pointing to
packages/br-utilities/CHANGELOG.md.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 54e28ace-8710-4a3d-92f7-5bc81a132fdb

📥 Commits

Reviewing files that changed from the base of the PR and between a79000a and a199a1f.

📒 Files selected for processing (21)
  • README.md
  • README.pt.md
  • packages/br-utilities/CHANGELOG.md
  • packages/br-utilities/Gemfile
  • packages/br-utilities/README.md
  • packages/br-utilities/README.pt.md
  • packages/br-utilities/br-utilities.gemspec
  • packages/br-utilities/src/br-utilities.rb
  • packages/br-utilities/src/br-utilities/br_utils.rb
  • packages/br-utilities/src/br-utilities/cnpj_fmt.rb
  • packages/br-utilities/src/br-utilities/cnpj_gen.rb
  • packages/br-utilities/src/br-utilities/cnpj_utils.rb
  • packages/br-utilities/src/br-utilities/cnpj_val.rb
  • packages/br-utilities/src/br-utilities/cpf_fmt.rb
  • packages/br-utilities/src/br-utilities/cpf_gen.rb
  • packages/br-utilities/src/br-utilities/cpf_utils.rb
  • packages/br-utilities/src/br-utilities/cpf_val.rb
  • packages/br-utilities/src/br-utilities/errors.rb
  • packages/br-utilities/src/br-utilities/version.rb
  • packages/br-utilities/tests/br_utilities.spec.rb
  • packages/br-utilities/tests/br_utils.spec.rb
💤 Files with no reviewable changes (2)
  • packages/br-utilities/tests/br_utilities.spec.rb
  • packages/br-utilities/Gemfile


## Features

- ✅ **Unified top-level API**: Class helpers `BrUtils.cpf` / `.cnpj` alias `BrUtils::DEFAULT`; each domain offers `format`, `generate`, and `is_valid`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

issue (blocking): Keep the façade identity contract consistent across the documentation.

The implementation delegates to BrUtils::DEFAULT.cpf and BrUtils::DEFAULT.cnpj. The current wording says that the helpers alias the BrUtils::DEFAULT façade object.

  • packages/br-utilities/README.md#L26-L26: Describe the helpers as delegating to BrUtils::DEFAULT.cpf and .cnpj.
  • packages/br-utilities/README.pt.md#L19-L19: Use the same precise delegation wording in Portuguese.
  • README.md#L26-L26: Correct the root English feature description.
  • README.pt.md#L19-L19: Correct the root Portuguese feature description.
  • packages/br-utilities/CHANGELOG.md#L11-L11: Correct the release-summary wording.

Based on the upstream contract in packages/br-utilities/src/br-utilities/br_utils.rb:242-267.

📍 Affects 5 files
  • packages/br-utilities/README.md#L26-L26 (this comment)
  • packages/br-utilities/README.pt.md#L19-L19
  • README.md#L26-L26
  • README.pt.md#L19-L19
  • packages/br-utilities/CHANGELOG.md#L11-L11
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/br-utilities/README.md` at line 26, Correct the façade wording to
describe BrUtils.cpf and BrUtils.cnpj as delegating to BrUtils::DEFAULT.cpf and
BrUtils::DEFAULT.cnpj, not aliasing the BrUtils::DEFAULT object. Apply the
equivalent precise Portuguese wording in packages/br-utilities/README.pt.md
(line 19) and README.pt.md (line 19), and update the same contract wording in
packages/br-utilities/README.md (line 26), README.md (line 26), and
packages/br-utilities/CHANGELOG.md (line 11).

Comment on lines +607 to +616
```ruby
require 'br-utilities'

# 2) BrUtils::DomainError — not applicable: this gem defines no DomainError
# (and no domain leaves). Domain failures come from bundled packages only.
# begin
# BrUtils.new(cpf: { formatter: { hidden_start: -1 } })
# rescue BrUtils::DomainError # NameError — constant is not defined
# end
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

issue (blocking): Apply the complete public error-documentation contract to both package READMEs.

The current documents omit the required details for propagated errors and do not demonstrate a real DomainError rescue.

  • packages/br-utilities/README.md#L607-L616: Replace the undefined BrUtils::DomainError example with the actual bundled-package DomainError.
  • packages/br-utilities/README.md#L641-L652: Document every propagated leaf, including callback-delivered InvalidLengthError, with its full hierarchy, marker, category, trigger, example, and handling guidance.
  • packages/br-utilities/README.pt.md#L600-L609: Add the equivalent real DomainError rescue example in Portuguese documentation.
  • packages/br-utilities/README.pt.md#L634-L645: Add the equivalent complete propagated-error entries in Portuguese documentation.

As per coding guidelines, every public error must be documented in the required order, and the rescue section must use real library classes.

📍 Affects 2 files
  • packages/br-utilities/README.md#L607-L616 (this comment)
  • packages/br-utilities/README.md#L641-L652
  • packages/br-utilities/README.pt.md#L600-L609
  • packages/br-utilities/README.pt.md#L634-L645
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/br-utilities/README.md` around lines 607 - 616, Update
packages/br-utilities/README.md lines 607-616 and
packages/br-utilities/README.pt.md lines 600-609 to replace the undefined
BrUtils::DomainError rescue with a real bundled-package DomainError example.
Expand packages/br-utilities/README.md lines 641-652 and
packages/br-utilities/README.pt.md lines 634-645 with every propagated leaf,
including callback-delivered InvalidLengthError, documenting each in the
required order with its full hierarchy, marker, category, trigger, example, and
handling guidance.

Source: Coding guidelines

Comment on lines +4 to +8
# Marker module mixed into every custom error raised by this library.
#
# Use +rescue BrUtils::Error+ to catch every library error regardless of
# native ancestry. Domain packages raise their own error hierarchies;
# this gem only defines the misuse errors it raises itself.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

issue (blocking): Include BrUtils::Error in every re-exported error hierarchy.

Line 6 promises that rescue BrUtils::Error catches every library error. The façade can propagate sibling errors such as CpfFmt::OutOfRangeError and CnpjFmt::ValidationError, but those hierarchies only use their sibling-package markers. Include BrUtils::Error in each exposed sibling Error marker, then add a rescue test for a propagated domain error.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/br-utilities/src/br-utilities/errors.rb` around lines 4 - 8, Update
the exposed sibling error marker modules, including CpfFmt::Error and
CnpjFmt::Error, to include BrUtils::Error so their derived errors are caught by
rescue BrUtils::Error. Add a rescue test covering a propagated domain error such
as CpfFmt::OutOfRangeError or CnpjFmt::ValidationError.

Source: Coding guidelines

Comment on lines +3 to 6
# Placeholder module so the gemspec (and any early require of this file) can read
# {BrUtils::VERSION}. The gem entry point promotes +BrUtils+ to a class and
# reopens it for the façade implementation.
module BrUtils

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

issue (blocking): The BrUtils constant is declared as both a module and a class. version.rb loads first and defines module BrUtils; four façade files then reopen it with class BrUtils. Ruby raises TypeError: BrUtils is not a class on the first such reopening, unless the entry point removes the constant first. Pick one kind for the constant across the package.

  • packages/br-utilities/src/br-utilities/version.rb#L3-L6: change module BrUtils to class BrUtils and update the comment, or document the entry-point remove_const sequence and confirm VERSION is re-assigned.
  • packages/br-utilities/src/br-utilities/br_utils.rb#L37-L42: keep class BrUtils only if version.rb declares the same kind.
  • packages/br-utilities/src/br-utilities/cpf_gen.rb#L3-L3: align the reopening kind with the chosen declaration.
  • packages/br-utilities/src/br-utilities/cpf_utils.rb#L3-L3: align the reopening kind with the chosen declaration.
  • packages/br-utilities/src/br-utilities/cpf_val.rb#L3-L3: align the reopening kind with the chosen declaration.
📍 Affects 5 files
  • packages/br-utilities/src/br-utilities/version.rb#L3-L6 (this comment)
  • packages/br-utilities/src/br-utilities/br_utils.rb#L37-L42
  • packages/br-utilities/src/br-utilities/cpf_gen.rb#L3-L3
  • packages/br-utilities/src/br-utilities/cpf_utils.rb#L3-L3
  • packages/br-utilities/src/br-utilities/cpf_val.rb#L3-L3
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/br-utilities/src/br-utilities/version.rb` around lines 3 - 6, The
BrUtils constant is declared with conflicting module and class kinds. In
packages/br-utilities/src/br-utilities/version.rb lines 3-6, declare BrUtils as
a class and update the placeholder comment; keep the class reopening in
packages/br-utilities/src/br-utilities/br_utils.rb lines 37-42, and align the
BrUtils reopenings in packages/br-utilities/src/br-utilities/cpf_gen.rb line 3,
cpf_utils.rb line 3, and cpf_val.rb line 3 with that class declaration.

Comment on lines +605 to +633
context 'when called with a settings Hash' do
it 'adopts nested domain utils from the Hash' do
cpf_utils = CpfUtils.new
cnpj_utils = CnpjUtils.new
utils = described_class.new({ cpf: cpf_utils, cnpj: cnpj_utils })

aggregate_failures do
expect(utils.cpf).to equal(cpf_utils)
expect(utils.cnpj).to equal(cnpj_utils)
end
end
end

context 'when called with a non-Hash settings value' do
it 'raises TypeMismatchError for a string' do
expect { described_class.new('not-a-hash') }
.to raise_error(BrUtils::TypeMismatchError, /settings must be a Hash/)
end

it 'raises TypeMismatchError for false' do
expect { described_class.new(false) }
.to raise_error(BrUtils::TypeMismatchError, /settings must be a Hash/)
end

it 'raises TypeMismatchError for an array' do
expect { described_class.new([]) }
.to raise_error(BrUtils::TypeMismatchError, /settings must be a Hash/)
end
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

suggestion (non-blocking): Add coverage for two documented #initialize contracts.

Two documented behaviors of BrUtils#initialize have no example:

  1. String-keyed settings. Helpers.normalize_settings accepts 'cpf' and 'cnpj' (packages/br-utilities/src/br-utilities/br_utils.rb lines 62-63).
  2. Flat-keyword precedence. Flat keywords are ignored when the matching :cpf or :cnpj keyword is present (documented on lines 129-132 of the same file).

Both are public contracts, so a silent regression would not fail the suite.

💚 Proposed additional examples
     context 'when called with a settings Hash' do
       it 'adopts nested domain utils from the Hash' do
         cpf_utils = CpfUtils.new
         cnpj_utils = CnpjUtils.new
         utils = described_class.new({ cpf: cpf_utils, cnpj: cnpj_utils })
 
         aggregate_failures do
           expect(utils.cpf).to equal(cpf_utils)
           expect(utils.cnpj).to equal(cnpj_utils)
         end
       end
+
+      it 'adopts domain utils from string keys' do
+        cpf_utils = CpfUtils.new
+        cnpj_utils = CnpjUtils.new
+        utils = described_class.new({ 'cpf' => cpf_utils, 'cnpj' => cnpj_utils })
+
+        aggregate_failures do
+          expect(utils.cpf).to equal(cpf_utils)
+          expect(utils.cnpj).to equal(cnpj_utils)
+        end
+      end
+    end
+
+    context 'when a domain keyword and its flat keyword are both given' do
+      it 'ignores the flat keyword' do
+        cpf_utils = CpfUtils.new
+        utils = described_class.new(
+          cpf: cpf_utils,
+          cpf_formatter: CpfFmt::CpfFormatterOptions.new(dash_key: '|')
+        )
+
+        expect(utils.cpf).to equal(cpf_utils)
+      end
     end
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
context 'when called with a settings Hash' do
it 'adopts nested domain utils from the Hash' do
cpf_utils = CpfUtils.new
cnpj_utils = CnpjUtils.new
utils = described_class.new({ cpf: cpf_utils, cnpj: cnpj_utils })
aggregate_failures do
expect(utils.cpf).to equal(cpf_utils)
expect(utils.cnpj).to equal(cnpj_utils)
end
end
end
context 'when called with a non-Hash settings value' do
it 'raises TypeMismatchError for a string' do
expect { described_class.new('not-a-hash') }
.to raise_error(BrUtils::TypeMismatchError, /settings must be a Hash/)
end
it 'raises TypeMismatchError for false' do
expect { described_class.new(false) }
.to raise_error(BrUtils::TypeMismatchError, /settings must be a Hash/)
end
it 'raises TypeMismatchError for an array' do
expect { described_class.new([]) }
.to raise_error(BrUtils::TypeMismatchError, /settings must be a Hash/)
end
end
context 'when called with a settings Hash' do
it 'adopts nested domain utils from the Hash' do
cpf_utils = CpfUtils.new
cnpj_utils = CnpjUtils.new
utils = described_class.new({ cpf: cpf_utils, cnpj: cnpj_utils })
aggregate_failures do
expect(utils.cpf).to equal(cpf_utils)
expect(utils.cnpj).to equal(cnpj_utils)
end
end
it 'adopts domain utils from string keys' do
cpf_utils = CpfUtils.new
cnpj_utils = CnpjUtils.new
utils = described_class.new({ 'cpf' => cpf_utils, 'cnpj' => cnpj_utils })
aggregate_failures do
expect(utils.cpf).to equal(cpf_utils)
expect(utils.cnpj).to equal(cnpj_utils)
end
end
end
context 'when a domain keyword and its flat keyword are both given' do
it 'ignores the flat keyword' do
cpf_utils = CpfUtils.new
utils = described_class.new(
cpf: cpf_utils,
cpf_formatter: CpfFmt::CpfFormatterOptions.new(dash_key: '|')
)
expect(utils.cpf).to equal(cpf_utils)
end
end
context 'when called with a non-Hash settings value' do
it 'raises TypeMismatchError for a string' do
expect { described_class.new('not-a-hash') }
.to raise_error(BrUtils::TypeMismatchError, /settings must be a Hash/)
end
it 'raises TypeMismatchError for false' do
expect { described_class.new(false) }
.to raise_error(BrUtils::TypeMismatchError, /settings must be a Hash/)
end
it 'raises TypeMismatchError for an array' do
expect { described_class.new([]) }
.to raise_error(BrUtils::TypeMismatchError, /settings must be a Hash/)
end
end
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/br-utilities/tests/br_utils.spec.rb` around lines 605 - 633, Add
examples for the two documented BrUtils#initialize contracts in the existing
settings contexts: verify string-keyed settings are normalized and adopt the
provided CpfUtils/CnpjUtils instances, and verify matching nested :cpf or :cnpj
settings take precedence over flat keyword values. Use the existing
Helpers.normalize_settings behavior and preserve the current non-Hash error
coverage.

Comment thread README.md
Comment on lines +10 to +12
> 🚀 **Full support for the [new alphanumeric CNPJ format](https://github.com/user-attachments/files/23937961/calculodvcnpjalfanaumerico.pdf).**

- **Root**: Tooling (Rake, RuboCop), shared config in `config/gems.yml`, no app code.
- **Packages**: Under `packages/` — each is a gem (e.g. `cpf-dv`, `cpf-utilities`, `br-utilities`). Internal dependencies use path in development and version constraints when published.
> 🌎 [Acessar documentação em português](./README.pt.md)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

suggestion (non-blocking): Keep the callout paragraphs in one blockquote.

Each file has a blank line inside the blockquote without a > marker. Add the marker to remove the repeated MD028 warning.

  • README.md#L10-L12: Add > to the blank line.
  • README.pt.md#L3-L5: Add > to the blank line.
  • packages/br-utilities/README.md#L10-L12: Add > to the blank line.
  • packages/br-utilities/README.pt.md#L3-L5: Add > to the blank line.

Based on the markdownlint MD028 warnings in the supplied static-analysis results.

🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 11-11: Blank line inside blockquote

(MD028, no-blanks-blockquote)

📍 Affects 4 files
  • README.md#L10-L12 (this comment)
  • README.pt.md#L3-L5
  • packages/br-utilities/README.md#L10-L12
  • packages/br-utilities/README.pt.md#L3-L5
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 10 - 12, Add the blockquote marker to the blank line
between callout paragraphs in README.md lines 10-12, README.pt.md lines 3-5,
packages/br-utilities/README.md lines 10-12, and
packages/br-utilities/README.pt.md lines 3-5, keeping each callout in one
continuous blockquote.

Source: Linters/SAST tools

Comment thread README.md

### CPF operations

CPF methods are accessed via `BrUtils.cpf`, `utils.cpf`, `CpfUtils`, or the `CpfFmt` / `CpfGen` / `CpfVal` helpers. CPF uses the API from [`cpf-utilities`](../cpf-utilities/README.md).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

issue (blocking): Resolve repository-level documentation links from the repository root.

The root READMEs use paths intended for packages/br-utilities/README.md. Update each package README link and the changelog link for the repository-root location.

  • README.md#L239-L239: Change the CPF package link to packages/cpf-utilities/README.md.
  • README.md#L302-L302: Change the CNPJ package link to packages/cnpj-utilities/README.md.
  • README.md#L471-L471: Correct both bundled-package links.
  • README.md#L643-L643: Correct both propagated-package links.
  • README.md#L683-L684: Correct both table links.
  • README.md#L703-L703: Change the changelog link to packages/br-utilities/CHANGELOG.md.
  • README.pt.md#L232-L232: Change the CPF package link to packages/cpf-utilities/README.pt.md.
  • README.pt.md#L295-L295: Change the CNPJ package link to packages/cnpj-utilities/README.pt.md.
  • README.pt.md#L464-L464: Correct both bundled-package links.
  • README.pt.md#L636-L636: Correct both propagated-package links.
  • README.pt.md#L670-L670: Correct both detailed-package links.
  • README.pt.md#L676-L677: Correct both table links.
  • README.pt.md#L696-L696: Change the changelog link to packages/br-utilities/CHANGELOG.md.

Based on the repository paths in the review context.

🧰 Tools
🪛 LanguageTool

[style] ~239-~239: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...CpfFmt / CpfGen / CpfVal helpers. CPF uses the API from [cpf-utilities](../...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

📍 Affects 2 files
  • README.md#L239-L239 (this comment)
  • README.md#L302-L302
  • README.md#L471-L471
  • README.md#L643-L643
  • README.md#L683-L684
  • README.md#L703-L703
  • README.pt.md#L232-L232
  • README.pt.md#L295-L295
  • README.pt.md#L464-L464
  • README.pt.md#L636-L636
  • README.pt.md#L670-L670
  • README.pt.md#L676-L677
  • README.pt.md#L696-L696
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 239, Update repository-root documentation links to use
package-relative paths: in README.md (239-239) point CPF to
packages/cpf-utilities/README.md, (302-302) CNPJ to
packages/cnpj-utilities/README.md, (471-471) both bundled-package links,
(643-643) both propagated-package links, (683-684) both table links, and
(703-703) the changelog to packages/br-utilities/CHANGELOG.md; apply the
corresponding README.pt.md paths at 232-232, 295-295, 464-464, 636-636, 670-670,
and 676-677, with the changelog at 696-696 pointing to
packages/br-utilities/CHANGELOG.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New minor or major features.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement package br-utilities

1 participant