Skip to content

Commit

Permalink
feat: remove virtus dependency (#18)
Browse files Browse the repository at this point in the history
* test: refactor tests to use RSpec verifying doubles

* test: autoload before running tests, allow manual focused testing

* test: add checks to model interfaces

(RED) Tests fail becase they capture a bug in `Document#transaction_date`
that failed with NoMethodError `#date`.

* fix: bug in transaction date for documents

(GREEN) Fixes the bug, but marks the method as to be deprecated

* feat: remove dependency with virtus gem

Because [virtus](https://github.com/solnic/virtus) gem is officially discontinued.

* fix: add .rspec file to make RSpec load spec_helper

* chore: remove virtus gem from gemspec file and uninstall it
  • Loading branch information
esquinas committed Jun 19, 2024
1 parent e4b7971 commit 2fbd32a
Show file tree
Hide file tree
Showing 23 changed files with 363 additions and 110 deletions.
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require spec_helper
18 changes: 0 additions & 18 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,13 @@ PATH
remote: .
specs:
norma43_parser (4.0.0)
virtus (~> 1.0)
zeitwerk (~> 2.0)

GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
axiom-types (0.1.1)
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.5.1)
equalizer (0.0.11)
ice_nine (0.11.2)
json (2.7.2)
json (2.7.2-java)
language_server-protocol (3.17.0.3)
Expand Down Expand Up @@ -66,14 +55,7 @@ GEM
ruby-progressbar (1.13.0)
strscan (3.1.0)
strscan (3.1.0-java)
thread_safe (0.3.6)
thread_safe (0.3.6-java)
unicode-display_width (2.5.0)
virtus (1.0.5)
axiom-types (~> 0.1)
coercible (~> 1.0)
descendants_tracker (~> 0.0, >= 0.0.3)
equalizer (~> 0.0, >= 0.0.9)
zeitwerk (2.6.15)

PLATFORMS
Expand Down
2 changes: 0 additions & 2 deletions lib/norma43/models.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require "virtus"

module Norma43
module Models
DEBIT_CODE = 1
Expand Down
70 changes: 51 additions & 19 deletions lib/norma43/models/account.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,62 @@
# frozen_string_literal: true

require "virtus"

module Norma43
module Models
class Account
include Virtus.model
include Mixins::AttributesAssignment

attr_accessor :bank_code,
:branch_code,
:account_number,
:start_date,
:end_date,
:balance_code,
:balance_amount,
:currency_code,
:information_mode_code,
:abbreviated_name,
:debit_entries,
:debit_amount,
:credit_entries,
:credit_amount,
:transactions

attribute :bank_code
attribute :branch_code
attribute :account_number
attribute :start_date
attribute :end_date
attribute :balance_code
attribute :balance_amount
attribute :currency_code
attribute :information_mode_code
attribute :abbreviated_name
attribute :debit_entries
attribute :debit_amount
attribute :credit_entries
attribute :credit_amount
attribute :transactions, Array[Transaction]
def initialize(attributes = EMPTY_ATTRIBUTES)
@bank_code,
@branch_code,
@account_number,
@start_date,
@end_date,
@balance_code,
@balance_amount,
@currency_code,
@information_mode_code,
@abbreviated_name,
@debit_entries,
@debit_amount,
@credit_entries,
@credit_amount,
transactions = Hash(attributes).values_at(
:bank_code,
:branch_code,
:account_number,
:start_date,
:end_date,
:balance_code,
:balance_amount,
:currency_code,
:information_mode_code,
:abbreviated_name,
:debit_entries,
:debit_amount,
:credit_entries,
:credit_amount,
:transactions)
@transactions = Array(transactions).map { |attrs| Transaction.new(attrs) }
end

def iban
@iban ||= SpanishIban.from_account(self)
SpanishIban.from_account(self)
end
end
end
Expand Down
20 changes: 13 additions & 7 deletions lib/norma43/models/additional_currency.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
# frozen_string_literal: true

require "virtus"

module Norma43
module Models
class AdditionalCurrency
include Virtus.model
include Mixins::AttributesAssignment

attr_accessor :data_code, :currency_code, :amount, :free

attribute :data_code
attribute :currency_code
attribute :amount
attribute :free
def initialize(attributes = EMPTY_ATTRIBUTES)
@data_code,
@currency_code,
@amount,
@free = Hash(attributes).values_at(
:data_code,
:currency_code,
:amount,
:free)
end
end
end
end
17 changes: 11 additions & 6 deletions lib/norma43/models/additional_item.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
# frozen_string_literal: true

require "virtus"

module Norma43
module Models
class AdditionalItem
include Virtus.model
include Mixins::AttributesAssignment

attr_accessor :data_code, :item_1, :item_2

attribute :data_code
attribute :item_1
attribute :item_2
def initialize(attributes = EMPTY_ATTRIBUTES)
@data_code,
@item_1,
@item_2 = Hash(attributes).values_at(
:data_code,
:item_1,
:item_2)
end
end
end
end
41 changes: 30 additions & 11 deletions lib/norma43/models/document.rb
Original file line number Diff line number Diff line change
@@ -1,22 +1,41 @@
# frozen_string_literal: true

require "virtus"

module Norma43
module Models
class Document
include Virtus.model
include Mixins::AttributesAssignment

attr_accessor :id, :created_at, :delivery_number, :file_type, :name, :number_of_lines, :accounts

attribute :id
attribute :created_at
attribute :delivery_number
attribute :file_type
attribute :name
attribute :number_of_lines
attribute :accounts, Array[Account]
def initialize(attributes = EMPTY_ATTRIBUTES)
@id,
@created_at,
@delivery_number,
@file_type,
@name,
@number_of_lines,
accounts = Hash(attributes).values_at(
:id,
:created_at,
:delivery_number,
:file_type,
:name,
:number_of_lines,
:accounts)
@accounts = Array(accounts).map { |account| Account.new(account) }
end

# @deprecated Please ask each transaction inside accounts for their transaction_date instead
def transaction_date
accounts.map(&:date).compact.first
warn "[DEPRECATION] `transaction_date` is deprecated, use `#transaction_date` from transactions in `#accounts` instead"
date = nil

accounts.flat_map(&:transactions).each { |transaction|
date = transaction&.transaction_date
break unless date.nil?
}

date
end
end
end
Expand Down
33 changes: 33 additions & 0 deletions lib/norma43/models/mixins/attributes_assignment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

module Norma43
module Models
module Mixins
module AttributesAssignment
EMPTY_ATTRIBUTES = {}.freeze

def attributes=(new_attributes)
Hash(new_attributes).each do |attr_name, attr_value|
attr_writer_method_name = "#{attr_name}=".to_sym
next unless public_methods(false).include?(attr_writer_method_name)

public_send(attr_writer_method_name, attr_value)
end
end

def attributes
instance_variables.map { |ivar_name|
attr_reader_method_name = ivar_name.to_s.delete_prefix("@").to_sym
next unless public_methods(false).include?(attr_reader_method_name)

attr_value = public_send(attr_reader_method_name)

[attr_reader_method_name, attr_value]
}.compact.to_h
end
alias_method :to_hash, :attributes # Implicit coercion for `Hash(model)`
alias_method :to_h, :attributes # Explicit coercion
end
end
end
end
56 changes: 41 additions & 15 deletions lib/norma43/models/transaction.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,50 @@
# frozen_string_literal: true

require "virtus"

module Norma43
module Models
class Transaction
include Virtus.model
include Mixins::AttributesAssignment

attr_accessor :origin_branch_code,
:transaction_date,
:value_date,
:shared_item,
:own_item,
:amount_code,
:amount,
:document_number,
:reference_1,
:reference_2,
:additional_items,
:additional_currency

def initialize(attributes = EMPTY_ATTRIBUTES)
@origin_branch_code,
@transaction_date,
@value_date,
@shared_item,
@own_item,
@amount_code,
@amount,
@document_number,
@reference_1,
@reference_2,
additional_items,
additional_currency = Hash(attributes).values_at(
:origin_branch_code,
:transaction_date,
:value_date,
:shared_item,
:own_item,
:amount_code,
:amount,
:document_number,
:reference_1,
:reference_2)
@additional_items = Array(additional_items).map { |attrs| AdditionalItem.new(attrs) }
@additional_currency = AdditionalCurrency.new(additional_currency) if additional_currency
end

attribute :origin_branch_code
attribute :transaction_date
attribute :value_date
attribute :shared_item
attribute :own_item
attribute :amount_code
attribute :amount
attribute :document_number
attribute :reference_1
attribute :reference_2
attribute :additional_items, Array[AdditionalItem]
attribute :additional_currency, AdditionalCurrency
def debit?; self.amount_code == DEBIT_CODE end
end
end
Expand Down
1 change: 0 additions & 1 deletion norma43_parser.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]

spec.add_runtime_dependency "virtus", "~> 1.0"
spec.add_runtime_dependency "zeitwerk", "~> 2.0"

spec.add_development_dependency "rake", "~> 13.0"
Expand Down
5 changes: 1 addition & 4 deletions spec/norma43/line_processors/account_end_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
module Norma43
module LineProcessors
RSpec.describe AccountEnd do
let :line do
double "Line", attributes: {}
end

let(:line) { instance_double(LineParsers::AccountEnd, attributes: {}) }
let(:account) { Norma43::Models::Account.new }
let(:contexts) { Norma43::Utils::Contexts.new(
[
Expand Down
6 changes: 3 additions & 3 deletions spec/norma43/line_processors/account_start_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

module Norma43
module LineProcessors
RSpec.describe "AccountStart" do
let(:line) { double "Line", attributes: {} }
RSpec.describe AccountStart do
let(:line) { instance_double(LineParsers::AccountStart, attributes: {}) }
let(:document) { Norma43::Models::Document.new }
let(:contexts) { Norma43::Utils::Contexts.new }

Expand All @@ -20,7 +20,7 @@ module LineProcessors
end

context "when AccountStart is called" do
let(:fake_account) { double "Norma43::Models::Account" }
let(:fake_account) { instance_double(Norma43::Models::Account) }
before do
allow(Norma43::Models::Account).to receive(:new) { fake_account }
end
Expand Down
Loading

0 comments on commit 2fbd32a

Please sign in to comment.