sps_king 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +3 -3
- data/CHANGELOG.md +9 -0
- data/README.md +17 -14
- data/gemfiles/{Gemfile-activemodel-6.1.x → Gemfile-activemodel-7.2.x} +1 -1
- data/gemfiles/{Gemfile-activemodel-7.0.x → Gemfile-activemodel-8.0.x} +1 -1
- data/lib/sps_king/account/address.rb +55 -0
- data/lib/sps_king/account/creditor_account.rb +3 -0
- data/lib/sps_king/account/creditor_address.rb +2 -34
- data/lib/sps_king/account/debtor_account.rb +1 -0
- data/lib/sps_king/account/debtor_address.rb +2 -31
- data/lib/sps_king/account.rb +3 -0
- data/lib/sps_king/converter.rb +14 -10
- data/lib/sps_king/message/credit_transfer.rb +114 -111
- data/lib/sps_king/message/direct_debit.rb +121 -118
- data/lib/sps_king/message.rb +54 -48
- data/lib/sps_king/structured_remittance_information.rb +2 -0
- data/lib/sps_king/transaction/credit_transfer_transaction.rb +3 -0
- data/lib/sps_king/transaction/direct_debit_transaction.rb +9 -6
- data/lib/sps_king/transaction.rb +10 -7
- data/lib/sps_king/validator.rb +9 -0
- data/lib/sps_king/version.rb +3 -1
- data/lib/sps_king.rb +1 -0
- data/spec/lib/sps_king/account/address_spec.rb +85 -0
- data/spec/lib/sps_king/account/creditor_account_spec.rb +14 -13
- data/spec/lib/sps_king/account/debtor_account_spec.rb +1 -0
- data/spec/lib/sps_king/account_spec.rb +12 -2
- data/spec/lib/sps_king/converter_spec.rb +25 -5
- data/spec/lib/sps_king/message/credit_transfer_spec.rb +184 -45
- data/spec/lib/sps_king/message/direct_debit_spec.rb +218 -102
- data/spec/lib/sps_king/message_spec.rb +23 -8
- data/spec/lib/sps_king/structured_remittance_information_spec.rb +7 -2
- data/spec/lib/sps_king/transaction/credit_transfer_transaction_spec.rb +14 -2
- data/spec/lib/sps_king/transaction/direct_debit_transaction_spec.rb +8 -7
- data/spec/lib/sps_king/transaction_spec.rb +62 -27
- data/spec/lib/sps_king/validator_spec.rb +38 -9
- data/spec/spec_helper.rb +8 -4
- data/spec/support/active_model.rb +3 -1
- data/spec/support/factories.rb +11 -10
- data/spec/support/validations.rb +2 -0
- data/sps_king.gemspec +1 -0
- metadata +8 -12
- data/spec/lib/sps_king/account/creditor_address_spec.rb +0 -14
- data/spec/lib/sps_king/account/debtor_address_spec.rb +0 -14
data/lib/sps_king/message.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module SPS
|
4
|
+
|
4
5
|
PAIN_008_001_02_CH_03 = 'pain.008.001.02.ch.03'
|
5
6
|
PAIN_001_001_03_CH_02 = 'pain.001.001.03.ch.02'
|
6
7
|
|
7
8
|
class Message
|
9
|
+
|
8
10
|
include ActiveModel::Validations
|
9
11
|
|
10
12
|
attr_reader :account, :grouped_transactions
|
@@ -16,7 +18,7 @@ module SPS
|
|
16
18
|
|
17
19
|
class_attribute :account_class, :transaction_class, :xml_main_tag, :known_schemas
|
18
20
|
|
19
|
-
def initialize(account_options={})
|
21
|
+
def initialize(account_options = {})
|
20
22
|
@grouped_transactions = {}
|
21
23
|
@account = account_class.new(account_options)
|
22
24
|
end
|
@@ -24,6 +26,7 @@ module SPS
|
|
24
26
|
def add_transaction(options)
|
25
27
|
transaction = transaction_class.new(options)
|
26
28
|
raise ArgumentError.new(transaction.errors.full_messages.join("\n")) unless transaction.valid?
|
29
|
+
|
27
30
|
@grouped_transactions[transaction_group(transaction)] ||= []
|
28
31
|
@grouped_transactions[transaction_group(transaction)] << transaction
|
29
32
|
end
|
@@ -33,11 +36,11 @@ module SPS
|
|
33
36
|
end
|
34
37
|
|
35
38
|
# @return [String] xml
|
36
|
-
def to_xml(schema_name=self.known_schemas.first)
|
39
|
+
def to_xml(schema_name = self.known_schemas.first, encoding = 'UTF-8')
|
37
40
|
raise SPS::Error.new(errors.full_messages.join("\n")) unless valid?
|
38
41
|
raise SPS::Error.new("Incompatible with schema #{schema_name}!") unless schema_compatible?(schema_name)
|
39
42
|
|
40
|
-
builder = Nokogiri::XML::Builder.new do |builder|
|
43
|
+
builder = Nokogiri::XML::Builder.new(encoding: encoding) do |builder|
|
41
44
|
builder.Document(xml_schema(schema_name)) do
|
42
45
|
builder.__send__(xml_main_tag) do
|
43
46
|
build_group_header(builder)
|
@@ -50,7 +53,7 @@ module SPS
|
|
50
53
|
builder.to_xml
|
51
54
|
end
|
52
55
|
|
53
|
-
def amount_total(selected_transactions=transactions)
|
56
|
+
def amount_total(selected_transactions = transactions)
|
54
57
|
selected_transactions.inject(0) { |sum, t| sum + t.amount }
|
55
58
|
end
|
56
59
|
|
@@ -58,10 +61,10 @@ module SPS
|
|
58
61
|
raise ArgumentError.new("Schema #{schema_name} is unknown!") unless self.known_schemas.include?(schema_name)
|
59
62
|
|
60
63
|
case schema_name
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
64
|
+
when PAIN_001_001_03_CH_02
|
65
|
+
transactions.all? { |t| t.schema_compatible?(schema_name) }
|
66
|
+
when PAIN_008_001_02_CH_03
|
67
|
+
transactions.all? { |t| t.schema_compatible?(schema_name) } &&
|
65
68
|
!account.iban.to_s.match(/^(CH|LI)/).nil? # Only allowed for switzerland or liechtenstein
|
66
69
|
end
|
67
70
|
end
|
@@ -111,53 +114,56 @@ module SPS
|
|
111
114
|
grouped_transactions.keys.collect { |group| payment_information_identification(group) }
|
112
115
|
end
|
113
116
|
|
114
|
-
|
115
|
-
# @return {Hash<Symbol=>String>} xml schema information used in output xml
|
116
|
-
def xml_schema(schema_name)
|
117
|
-
{
|
118
|
-
:xmlns => "http://www.six-interbank-clearing.com/de/#{schema_name}.xsd",
|
119
|
-
:'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
120
|
-
:'xsi:schemaLocation' => "http://www.six-interbank-clearing.com/de/#{schema_name}.xsd #{schema_name}.xsd"
|
121
|
-
}
|
122
|
-
end
|
117
|
+
private
|
123
118
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
119
|
+
# @return {Hash<Symbol=>String>} xml schema information used in output xml
|
120
|
+
def xml_schema(schema_name)
|
121
|
+
{
|
122
|
+
:xmlns => "http://www.six-interbank-clearing.com/de/#{schema_name}.xsd",
|
123
|
+
:'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
124
|
+
:'xsi:schemaLocation' => "http://www.six-interbank-clearing.com/de/#{schema_name}.xsd #{schema_name}.xsd"
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
def build_group_header(builder)
|
129
|
+
builder.GrpHdr do
|
130
|
+
builder.MsgId(message_identification)
|
131
|
+
builder.CreDtTm(creation_date_time)
|
132
|
+
builder.NbOfTxs(transactions.length)
|
133
|
+
builder.CtrlSum('%.2f' % amount_total)
|
134
|
+
builder.InitgPty do
|
135
|
+
builder.Nm(account.name)
|
136
|
+
builder.Id do
|
137
|
+
builder.OrgId do
|
138
|
+
builder.Othr do
|
139
|
+
builder.Id(account.creditor_identifier)
|
140
|
+
end
|
136
141
|
end
|
137
|
-
end
|
138
|
-
end
|
142
|
+
end if account.respond_to? :creditor_identifier
|
143
|
+
end
|
139
144
|
end
|
140
145
|
end
|
141
|
-
end
|
142
146
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
+
# Unique and consecutive identifier (used for the <PmntInf> blocks)
|
148
|
+
def payment_information_identification(group)
|
149
|
+
"#{message_identification}/#{grouped_transactions.keys.index(group) + 1}"
|
150
|
+
end
|
147
151
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
+
# Returns a key to determine the group to which the transaction belongs
|
153
|
+
def transaction_group(transaction)
|
154
|
+
transaction
|
155
|
+
end
|
152
156
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
+
def validate_final_document!(document, schema_name)
|
158
|
+
xsd = Nokogiri::XML::Schema(
|
159
|
+
File.read(
|
160
|
+
File.expand_path("../../../lib/schema/#{schema_name}.xsd", __FILE__)
|
161
|
+
)
|
157
162
|
)
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
163
|
+
errors = xsd.validate(document).map { |error| error.message }
|
164
|
+
raise SPS::Error.new("Incompatible with schema #{schema_name}: #{errors.join(', ')}") if errors.any?
|
165
|
+
end
|
166
|
+
|
162
167
|
end
|
168
|
+
|
163
169
|
end
|
@@ -1,6 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module SPS
|
3
4
|
class DirectDebitTransaction < Transaction
|
5
|
+
|
6
|
+
attr_accessor :service_level,
|
7
|
+
:local_instrument,
|
8
|
+
:creditor_account,
|
9
|
+
:debtor_address
|
10
|
+
|
4
11
|
SERVICE_LEVELS = %w(CHDD CHTA)
|
5
12
|
|
6
13
|
LOCAL_INSTRUMENTS_FOR_SERVICE_LEVELS = {
|
@@ -8,11 +15,6 @@ module SPS
|
|
8
15
|
'CHTA' => %w(LSV+ BDD)
|
9
16
|
}
|
10
17
|
|
11
|
-
attr_accessor :service_level,
|
12
|
-
:local_instrument,
|
13
|
-
:creditor_account,
|
14
|
-
:debtor_address
|
15
|
-
|
16
18
|
validates_format_of :iban, with: /\A(CH|LI)/
|
17
19
|
|
18
20
|
validates_presence_of :instruction,
|
@@ -38,7 +40,7 @@ module SPS
|
|
38
40
|
case schema_name
|
39
41
|
when PAIN_008_001_02_CH_03
|
40
42
|
self.structured_remittance_information.present? &&
|
41
|
-
|
43
|
+
self.structured_remittance_information.valid?
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
@@ -54,5 +56,6 @@ module SPS
|
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
59
|
+
|
57
60
|
end
|
58
61
|
end
|
data/lib/sps_king/transaction.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module SPS
|
3
4
|
class Transaction
|
5
|
+
|
4
6
|
include ActiveModel::Validations
|
5
7
|
extend Converter
|
6
8
|
|
7
|
-
DEFAULT_REQUESTED_DATE = Date.new(1999, 1, 1).freeze
|
8
|
-
|
9
9
|
attr_accessor :name,
|
10
10
|
:iban,
|
11
11
|
:bic,
|
@@ -20,6 +20,8 @@ module SPS
|
|
20
20
|
:debtor_address,
|
21
21
|
:creditor_address
|
22
22
|
|
23
|
+
DEFAULT_REQUESTED_DATE = Date.new(1999, 1, 1).freeze
|
24
|
+
|
23
25
|
convert :name, :instruction, :reference, :remittance_information, to: :text
|
24
26
|
convert :amount, to: :decimal
|
25
27
|
|
@@ -48,12 +50,13 @@ module SPS
|
|
48
50
|
|
49
51
|
protected
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
+
def validate_requested_date_after(min_requested_date)
|
54
|
+
return unless requested_date.is_a?(Date)
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
+
if requested_date != DEFAULT_REQUESTED_DATE && requested_date < min_requested_date
|
57
|
+
errors.add(:requested_date, "must be greater or equal to #{min_requested_date}, or nil")
|
58
|
+
end
|
56
59
|
end
|
57
|
-
|
60
|
+
|
58
61
|
end
|
59
62
|
end
|
data/lib/sps_king/validator.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module SPS
|
4
|
+
|
3
5
|
class IBANValidator < ActiveModel::Validator
|
6
|
+
|
4
7
|
# IBAN2007Identifier (taken from schema)
|
5
8
|
REGEX = /\A[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}\z/
|
6
9
|
|
@@ -12,9 +15,11 @@ module SPS
|
|
12
15
|
record.errors.add(field_name, :invalid, message: options[:message])
|
13
16
|
end
|
14
17
|
end
|
18
|
+
|
15
19
|
end
|
16
20
|
|
17
21
|
class BICValidator < ActiveModel::Validator
|
22
|
+
|
18
23
|
# AnyBICIdentifier (taken from schema)
|
19
24
|
REGEX = /\A[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}\z/
|
20
25
|
|
@@ -28,9 +33,11 @@ module SPS
|
|
28
33
|
end
|
29
34
|
end
|
30
35
|
end
|
36
|
+
|
31
37
|
end
|
32
38
|
|
33
39
|
class CreditorIdentifierValidator < ActiveModel::Validator
|
40
|
+
|
34
41
|
REGEX = /\A[a-zA-Z]{2,2}[0-9]{2,2}([A-Za-z0-9]|[\+|\?|\/|\-|\:|\(|\)|\.|,|']){3,3}([A-Za-z0-9]|[\+|\?|\/|\-|:|\(|\)|\.|,|']){1,28}\z|\A[A-Z0-9]{5,5}\z/
|
35
42
|
|
36
43
|
def validate(record)
|
@@ -51,5 +58,7 @@ module SPS
|
|
51
58
|
end
|
52
59
|
ok
|
53
60
|
end
|
61
|
+
|
54
62
|
end
|
63
|
+
|
55
64
|
end
|
data/lib/sps_king/version.rb
CHANGED
data/lib/sps_king.rb
CHANGED
@@ -9,6 +9,7 @@ require 'sps_king/converter'
|
|
9
9
|
require 'sps_king/validator'
|
10
10
|
require 'sps_king/version'
|
11
11
|
require 'sps_king/account'
|
12
|
+
require 'sps_king/account/address'
|
12
13
|
require 'sps_king/account/debtor_account'
|
13
14
|
require 'sps_king/account/debtor_address'
|
14
15
|
require 'sps_king/account/creditor_account'
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe SPS::Address do
|
6
|
+
let(:country_code) { 'CH' }
|
7
|
+
let(:street_name) { 'Mustergasse' }
|
8
|
+
let(:building_number) { '123' }
|
9
|
+
let(:post_code) { '12345' }
|
10
|
+
let(:town_name) { 'Musterstadt' }
|
11
|
+
let(:address_line1) { "#{street_name} #{building_number}" }
|
12
|
+
let(:address_line2) { "#{post_code} #{town_name}" }
|
13
|
+
let(:subject_valid) do
|
14
|
+
described_class.new(
|
15
|
+
country_code:,
|
16
|
+
address_line2:
|
17
|
+
)
|
18
|
+
end
|
19
|
+
let(:subject_too_long) do
|
20
|
+
described_class.new(
|
21
|
+
country_code:,
|
22
|
+
address_line1: 'X' * 71,
|
23
|
+
address_line2: 'X' * 71,
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should validate country_code format' do
|
28
|
+
subject_valid.country_code = 'ch'
|
29
|
+
expect(subject_valid).not_to be_valid
|
30
|
+
expect(subject_valid.errors.details).to include(
|
31
|
+
country_code: [
|
32
|
+
{
|
33
|
+
error: :invalid,
|
34
|
+
value: "ch"
|
35
|
+
}
|
36
|
+
]
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when using address_line1 and address_line2' do
|
41
|
+
it 'should initialize a new address in line mode' do
|
42
|
+
expect(subject_valid).to be_valid
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'validates address_line1 and address_line2 length' do
|
46
|
+
expect(subject_too_long).not_to be_valid
|
47
|
+
expect(subject_too_long.errors.details).to include(
|
48
|
+
address_line1: [{ error: :too_long, count: 70 }],
|
49
|
+
address_line2: [{ error: :too_long, count: 70 }]
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when using separate attributes' do
|
55
|
+
let(:subject_valid) do
|
56
|
+
described_class.new(
|
57
|
+
country_code:,
|
58
|
+
town_name:
|
59
|
+
)
|
60
|
+
end
|
61
|
+
let(:subject_too_long) do
|
62
|
+
described_class.new(
|
63
|
+
country_code:,
|
64
|
+
street_name: 'X' * 71,
|
65
|
+
building_number: 'X' * 17,
|
66
|
+
post_code: 'X' * 17,
|
67
|
+
town_name: 'X' * 36,
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should initialize a new address in separate mode' do
|
72
|
+
expect(subject_valid).to be_valid
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'validates street_name, building_number, post_code, and town_name length' do
|
76
|
+
expect(subject_too_long).not_to be_valid
|
77
|
+
expect(subject_too_long.errors.details)
|
78
|
+
.to include(
|
79
|
+
street_name: [{ error: :too_long, count: 70 }],
|
80
|
+
post_code: [{ error: :too_long, count: 16 }],
|
81
|
+
town_name: [{ error: :too_long, count: 35 }]
|
82
|
+
)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
require 'spec_helper'
|
3
4
|
|
4
5
|
describe SPS::CreditorAccount do
|
@@ -17,24 +18,24 @@ describe SPS::CreditorAccount do
|
|
17
18
|
it 'should accept valid value' do
|
18
19
|
expect(SPS::CreditorAccount)
|
19
20
|
.to accept(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
'DE98ZZZ09999999999',
|
22
|
+
'AT12ZZZ00000000001',
|
23
|
+
'IT97ZZZA1B2C3D4E5F6G7H8',
|
24
|
+
'NL97ZZZ123456780001',
|
25
|
+
'FR12ZZZ123456',
|
26
|
+
for: :creditor_identifier
|
27
|
+
)
|
27
28
|
end
|
28
29
|
|
29
30
|
it 'should not accept invalid value' do
|
30
31
|
expect(SPS::CreditorAccount)
|
31
32
|
.not_to accept(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
'',
|
34
|
+
'invalid',
|
35
|
+
'DE98ZZZ099999999990',
|
36
|
+
'DEAAAAAAAAAAAAAAAA',
|
37
|
+
for: :creditor_identifier
|
38
|
+
)
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
require 'spec_helper'
|
3
4
|
|
4
5
|
describe SPS::Account do
|
@@ -12,7 +13,12 @@ describe SPS::Account do
|
|
12
13
|
|
13
14
|
describe :name do
|
14
15
|
it 'should accept valid value' do
|
15
|
-
expect(SPS::Account).to accept(
|
16
|
+
expect(SPS::Account).to accept(
|
17
|
+
'Gläubiger GmbH',
|
18
|
+
'Zahlemann & Söhne GbR',
|
19
|
+
'X' * 70,
|
20
|
+
for: :name
|
21
|
+
)
|
16
22
|
end
|
17
23
|
|
18
24
|
it 'should not accept invalid value' do
|
@@ -22,7 +28,11 @@ describe SPS::Account do
|
|
22
28
|
|
23
29
|
describe :iban do
|
24
30
|
it 'should accept valid value' do
|
25
|
-
expect(SPS::Account).to accept(
|
31
|
+
expect(SPS::Account).to accept(
|
32
|
+
'DE21500500009876543210',
|
33
|
+
'PL61109010140000071219812874',
|
34
|
+
for: :iban
|
35
|
+
)
|
26
36
|
end
|
27
37
|
|
28
38
|
it 'should not accept invalid value' do
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
require 'spec_helper'
|
3
4
|
|
4
5
|
describe SPS::Converter do
|
@@ -8,7 +9,9 @@ describe SPS::Converter do
|
|
8
9
|
context 'when the conversion method does not exist' do
|
9
10
|
it 'raises an ArgumentError' do
|
10
11
|
class DummyForConverter
|
12
|
+
|
11
13
|
extend SPS::Converter
|
14
|
+
|
12
15
|
end
|
13
16
|
|
14
17
|
expect {
|
@@ -31,10 +34,10 @@ describe SPS::Converter do
|
|
31
34
|
end
|
32
35
|
|
33
36
|
it 'should convert line breaks' do
|
34
|
-
expect(convert_text("one\ntwo"))
|
35
|
-
expect(convert_text("one\ntwo\n"))
|
37
|
+
expect(convert_text("one\ntwo")).to eq('one two')
|
38
|
+
expect(convert_text("one\ntwo\n")).to eq('one two')
|
36
39
|
expect(convert_text("\none\ntwo\n")).to eq('one two')
|
37
|
-
expect(convert_text("one\n\ntwo"))
|
40
|
+
expect(convert_text("one\n\ntwo")).to eq('one two')
|
38
41
|
end
|
39
42
|
|
40
43
|
it 'should convert number' do
|
@@ -63,6 +66,14 @@ describe SPS::Converter do
|
|
63
66
|
expect(convert_decimal(42.12)).to eq(BigDecimal('42.12'))
|
64
67
|
end
|
65
68
|
|
69
|
+
it "should convert numeric string to BigDecimal" do
|
70
|
+
expect(convert_decimal('35.21')).to eq(BigDecimal('35.21'))
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should keep BigDecimal" do
|
74
|
+
expect(convert_decimal(BigDecimal('55.01'))).to eq(BigDecimal('55.01'))
|
75
|
+
end
|
76
|
+
|
66
77
|
it 'should round' do
|
67
78
|
expect(convert_decimal(1.345)).to eq(BigDecimal('1.35'))
|
68
79
|
end
|
@@ -81,8 +92,17 @@ describe SPS::Converter do
|
|
81
92
|
|
82
93
|
it 'should not convert invalid value' do
|
83
94
|
expect(convert_decimal('xyz')).to eq(nil)
|
84
|
-
expect(convert_decimal(
|
85
|
-
expect(convert_decimal('
|
95
|
+
expect(convert_decimal([12.2])).to eq(nil)
|
96
|
+
expect(convert_decimal({ value: '1.1' })).to eq(nil)
|
97
|
+
expect(convert_decimal(Date.new(2025))).to eq(nil)
|
98
|
+
expect(convert_decimal(1..10)).to eq(nil)
|
99
|
+
expect(convert_decimal(Float::INFINITY)).to eq(nil)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should not convert NaN value" do
|
103
|
+
nan_value = 0.0 / 0
|
104
|
+
expect(nan_value).to be_nan
|
105
|
+
expect(convert_decimal(nan_value)).to eq(nil)
|
86
106
|
end
|
87
107
|
end
|
88
108
|
end
|