sepa_king 0.0.5 → 0.0.6
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/README.md +33 -14
- data/lib/sepa_king/message.rb +11 -2
- data/lib/sepa_king/message/direct_debit.rb +6 -0
- data/lib/sepa_king/version.rb +1 -1
- data/spec/credit_transfer_spec.rb +17 -0
- data/spec/direct_debit_spec.rb +27 -40
- data/spec/message_spec.rb +8 -0
- data/spec/support/custom_matcher.rb +5 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2314875acf744a2dad9a545b56d75a27672e29e9
|
4
|
+
data.tar.gz: dc3f98095e43274d6eeafab00a46f68abc9f8728
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f1f366521a4884bea53d0e0b9989039af4d94e54936df4889460f4aa3926dc9520e82d4018dcdd88e88c8b76abedf4963880f01320971d818561d89b06206b6
|
7
|
+
data.tar.gz: 720f897af281d19848ef4396cda5b2e1faf9aa17b823226972f9f3d2e5276aeb7bbde2c71c674bd679aeaa36422d9174cbb6177b0d5f45b673e989805c2bbd4a
|
data/README.md
CHANGED
@@ -3,15 +3,25 @@
|
|
3
3
|
[](http://travis-ci.org/salesking/sepa_king)
|
4
4
|
[](https://codeclimate.com/github/salesking/sepa_king)
|
5
5
|
[](https://coveralls.io/r/salesking/sepa_king)
|
6
|
+
[](http://badge.fury.io/rb/sepa_king)
|
7
|
+
[](https://gemnasium.com/salesking/sepa_king)
|
6
8
|
|
7
9
|
We love building payment applications! So after developing the [DTAUS library for Ruby](https://github.com/salesking/king_dtaus) we move on with SEPA.
|
8
10
|
|
9
11
|
|
10
12
|
## Features
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
*
|
14
|
+
This gem implements the following two messages out of the ISO 20022 standard:
|
15
|
+
|
16
|
+
* Credit Transfer Initiation (pain.001.002.03)
|
17
|
+
* Direct Debit Initiation (pain.008.002.02)
|
18
|
+
|
19
|
+
BTW: **pain** is a shortcut for **Pa**yment **In**itiation.
|
20
|
+
|
21
|
+
|
22
|
+
## Requirements
|
23
|
+
|
24
|
+
* Ruby 1.9.3 or 2.0.0
|
15
25
|
|
16
26
|
|
17
27
|
## Installation
|
@@ -45,15 +55,15 @@ sdd = SEPA::DirectDebit.new(
|
|
45
55
|
|
46
56
|
# Second: Add transactions
|
47
57
|
sdd.add_transaction(
|
48
|
-
# Name of the
|
58
|
+
# Name of the debtor, in German: "Zahlungspflichtiger"
|
49
59
|
# String, max. 70 char
|
50
60
|
name: 'Zahlemann & Söhne GbR',
|
51
61
|
|
52
|
-
# Business Identifier Code (SWIFT-Code) of the
|
62
|
+
# Business Identifier Code (SWIFT-Code) of the debtor's account
|
53
63
|
# String, 8 or 11 char
|
54
64
|
bic: 'SPUEDE2UXXX',
|
55
65
|
|
56
|
-
# International Bank Account Number of the
|
66
|
+
# International Bank Account Number of the debtor's account
|
57
67
|
# String, max. 34 chars
|
58
68
|
iban: 'DE21500500009876543210',
|
59
69
|
|
@@ -61,11 +71,11 @@ sdd.add_transaction(
|
|
61
71
|
# Number with two decimal digit
|
62
72
|
amount: 39.99,
|
63
73
|
|
64
|
-
# OPTIONAL: End-To-End-Identification, will be submitted to the
|
74
|
+
# OPTIONAL: End-To-End-Identification, will be submitted to the debtor
|
65
75
|
# String, max. 35 char
|
66
76
|
reference: 'XYZ/2013-08-ABO/6789',
|
67
77
|
|
68
|
-
# OPTIONAL: Unstructured remittance
|
78
|
+
# OPTIONAL: Unstructured remittance information, in German "Verwendungszweck"
|
69
79
|
# String, max. 140 char
|
70
80
|
remittance_information: 'Vielen Dank für Ihren Einkauf!',
|
71
81
|
|
@@ -78,13 +88,13 @@ sdd.add_transaction(
|
|
78
88
|
mandate_date_of_signature: Date.new(2011,1,25),
|
79
89
|
|
80
90
|
# Local instrument, in German "Lastschriftart"
|
81
|
-
# One of
|
91
|
+
# One of these strings:
|
82
92
|
# 'CORE' ("Basis-Lastschrift")
|
83
93
|
# 'B2B' ("Firmen-Lastschrift")
|
84
94
|
local_instrument: 'CORE',
|
85
95
|
|
86
96
|
# Sequence type
|
87
|
-
# One of
|
97
|
+
# One of these strings:
|
88
98
|
# 'FRST' ("Erst-Lastschrift")
|
89
99
|
# 'RCUR' ("Folge-Lastschrift")
|
90
100
|
# 'OOFF' ("Einmalige Lastschrift")
|
@@ -96,6 +106,7 @@ sdd.add_transaction(
|
|
96
106
|
requested_date: Date.new(2013,9,5),
|
97
107
|
|
98
108
|
# OPTIONAL: Enables or disables batch booking, in German "Sammelbuchung / Einzelbuchung"
|
109
|
+
# True or False
|
99
110
|
batch_booking: true
|
100
111
|
)
|
101
112
|
sdd.add_transaction ...
|
@@ -110,15 +121,15 @@ How to create the XML for **Credit Transfer Initiation** (in german: "Überweisu
|
|
110
121
|
```ruby
|
111
122
|
# First: Create the main object
|
112
123
|
sct = SEPA::CreditTransfer.new(
|
113
|
-
# Name of the initiating party and
|
124
|
+
# Name of the initiating party and debtor, in German: "Auftraggeber"
|
114
125
|
# String, max. 70 char
|
115
126
|
name: 'Schuldner GmbH',
|
116
127
|
|
117
|
-
# Business Identifier Code (SWIFT-Code) of the
|
128
|
+
# Business Identifier Code (SWIFT-Code) of the debtor
|
118
129
|
# String, 8 or 11 char
|
119
130
|
bic: 'BANKDEFFXXX',
|
120
131
|
|
121
|
-
# International Bank Account Number of the
|
132
|
+
# International Bank Account Number of the debtor
|
122
133
|
# String, max. 34 chars
|
123
134
|
iban: 'DE87200500001234567890'
|
124
135
|
)
|
@@ -145,9 +156,17 @@ sct.add_transaction(
|
|
145
156
|
# String, max. 35 char
|
146
157
|
reference: 'XYZ-1234/123',
|
147
158
|
|
148
|
-
# OPTIONAL: Unstructured remittance
|
159
|
+
# OPTIONAL: Unstructured remittance information, in German "Verwendungszweck"
|
149
160
|
# String, max. 140 char
|
150
161
|
remittance_information: 'Rechnung vom 22.08.2013'
|
162
|
+
|
163
|
+
# OPTIONAL: Requested execution date, in German "Ausführungstermin"
|
164
|
+
# Date
|
165
|
+
requested_date: Date.new(2013,9,5),
|
166
|
+
|
167
|
+
# OPTIONAL: Enables or disables batch booking, in German "Sammelbuchung / Einzelbuchung"
|
168
|
+
# True or False
|
169
|
+
batch_booking: true
|
151
170
|
)
|
152
171
|
sct.add_transaction ...
|
153
172
|
|
data/lib/sepa_king/message.rb
CHANGED
@@ -2,7 +2,11 @@
|
|
2
2
|
|
3
3
|
module SEPA
|
4
4
|
class Message
|
5
|
+
include ActiveModel::Validations
|
6
|
+
|
5
7
|
attr_reader :account, :transactions
|
8
|
+
validates_presence_of :transactions
|
9
|
+
|
6
10
|
class_attribute :account_class, :transaction_class, :xml_main_tag
|
7
11
|
|
8
12
|
def initialize(account_options={})
|
@@ -19,6 +23,7 @@ module SEPA
|
|
19
23
|
# @return [String] xml
|
20
24
|
def to_xml
|
21
25
|
raise RuntimeError.new(account.errors.full_messages.join("\n")) unless account.valid?
|
26
|
+
raise RuntimeError.new(errors.full_messages.join("\n")) unless valid?
|
22
27
|
|
23
28
|
builder = Builder::XmlMarkup.new indent: 2
|
24
29
|
builder.instruct!
|
@@ -47,12 +52,16 @@ module SEPA
|
|
47
52
|
end
|
48
53
|
end
|
49
54
|
|
55
|
+
# Unique identifer for the whole message
|
50
56
|
def message_identification
|
51
|
-
"SEPA-KING/#{Time.now.
|
57
|
+
@message_identification ||= "SEPA-KING/#{Time.now.to_i}"
|
52
58
|
end
|
53
59
|
|
60
|
+
# Unique and consecutive identifier (used for the <PmntInf> blocks)
|
54
61
|
def payment_information_identification
|
55
|
-
|
62
|
+
@payment_information_counter ||= 0
|
63
|
+
@payment_information_counter += 1
|
64
|
+
"#{message_identification}/#{@payment_information_counter}"
|
56
65
|
end
|
57
66
|
end
|
58
67
|
end
|
@@ -6,6 +6,12 @@ module SEPA
|
|
6
6
|
self.transaction_class = DirectDebitTransaction
|
7
7
|
self.xml_main_tag = 'CstmrDrctDbtInitn'
|
8
8
|
|
9
|
+
validate do |record|
|
10
|
+
if record.transactions.map(&:local_instrument).uniq.size > 1
|
11
|
+
errors.add(:base, 'CORE and B2B must not be mixed in one message!')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
9
15
|
private
|
10
16
|
# @return {Hash<Symbol=>String>} xml schema information used in output xml
|
11
17
|
def xml_schema
|
data/lib/sepa_king/version.rb
CHANGED
@@ -67,6 +67,18 @@ describe SEPA::CreditTransfer do
|
|
67
67
|
expect(subject).to validate_against('pain.001.002.03.xsd')
|
68
68
|
end
|
69
69
|
|
70
|
+
it 'should have message_identification' do
|
71
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/GrpHdr/MsgId', /SEPA-KING\/[0-9]+/)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should contain <PmtInfId>' do
|
75
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/PmtInfId', /SEPA-KING\/[0-9]+\/1/)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should contain <ReqdExctnDt>' do
|
79
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/ReqdExctnDt', Date.today.next.iso8601)
|
80
|
+
end
|
81
|
+
|
70
82
|
it 'should contain <PmtMtd>' do
|
71
83
|
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/PmtMtd', 'TRF')
|
72
84
|
end
|
@@ -143,6 +155,11 @@ describe SEPA::CreditTransfer do
|
|
143
155
|
|
144
156
|
subject.should_not have_xml('//Document/CstmrCdtTrfInitn/PmtInf[3]')
|
145
157
|
end
|
158
|
+
|
159
|
+
it 'should contain two payment_informations with different <PmtInfId>' do
|
160
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[1]/PmtInfId', /SEPA-KING\/[0-9]+\/1/)
|
161
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[2]/PmtInfId', /SEPA-KING\/[0-9]+\/2/)
|
162
|
+
end
|
146
163
|
end
|
147
164
|
|
148
165
|
context 'with different batch_booking given' do
|
data/spec/direct_debit_spec.rb
CHANGED
@@ -72,6 +72,14 @@ describe SEPA::DirectDebit do
|
|
72
72
|
expect(subject).to validate_against('pain.008.002.02.xsd')
|
73
73
|
end
|
74
74
|
|
75
|
+
it 'should have message_identification' do
|
76
|
+
subject.should have_xml('//Document/CstmrDrctDbtInitn/GrpHdr/MsgId', /SEPA-KING\/[0-9]+/)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should contain <PmtInfId>' do
|
80
|
+
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf/PmtInfId', /SEPA-KING\/[0-9]+\/1/)
|
81
|
+
end
|
82
|
+
|
75
83
|
it 'should contain <ReqdColltnDt>' do
|
76
84
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf/ReqdColltnDt', Date.today.next.iso8601)
|
77
85
|
end
|
@@ -166,6 +174,11 @@ describe SEPA::DirectDebit do
|
|
166
174
|
|
167
175
|
subject.should_not have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]')
|
168
176
|
end
|
177
|
+
|
178
|
+
it 'should contain two payment_informations with different <PmtInfId>' do
|
179
|
+
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/PmtInfId', /SEPA-KING\/[0-9]+\/1/)
|
180
|
+
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/PmtInfId', /SEPA-KING\/[0-9]+\/2/)
|
181
|
+
end
|
169
182
|
end
|
170
183
|
|
171
184
|
context 'with different local_instrument given' do
|
@@ -174,16 +187,18 @@ describe SEPA::DirectDebit do
|
|
174
187
|
|
175
188
|
sdd.add_transaction(direct_debt_transaction.merge local_instrument: 'CORE')
|
176
189
|
sdd.add_transaction(direct_debt_transaction.merge local_instrument: 'B2B')
|
177
|
-
sdd.add_transaction(direct_debt_transaction.merge local_instrument: 'B2B')
|
178
190
|
|
179
|
-
sdd
|
191
|
+
sdd
|
180
192
|
end
|
181
193
|
|
182
|
-
it 'should
|
183
|
-
subject.should
|
184
|
-
|
194
|
+
it 'should have errors' do
|
195
|
+
subject.should have(1).error_on(:base)
|
196
|
+
end
|
185
197
|
|
186
|
-
|
198
|
+
it 'should raise error on XML generation' do
|
199
|
+
expect {
|
200
|
+
subject.to_xml
|
201
|
+
}.to raise_error(RuntimeError)
|
187
202
|
end
|
188
203
|
end
|
189
204
|
|
@@ -229,50 +244,26 @@ describe SEPA::DirectDebit do
|
|
229
244
|
subject do
|
230
245
|
sdd = direct_debit
|
231
246
|
|
232
|
-
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 1,
|
233
|
-
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 1,
|
234
|
-
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today +
|
235
|
-
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today +
|
236
|
-
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2, local_instrument: 'CORE', sequence_type: 'OOFF', amount: 16)
|
237
|
-
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2, local_instrument: 'CORE', sequence_type: 'FNAL', amount: 32)
|
238
|
-
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2, local_instrument: 'B2B', sequence_type: 'OOFF', amount: 64)
|
239
|
-
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2, local_instrument: 'B2B', sequence_type: 'FNAL', amount: 128)
|
247
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 1, sequence_type: 'OOFF', amount: 1)
|
248
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 1, sequence_type: 'FNAL', amount: 2)
|
249
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2, sequence_type: 'OOFF', amount: 4)
|
250
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2, sequence_type: 'FNAL', amount: 8)
|
240
251
|
|
241
252
|
sdd.to_xml
|
242
253
|
end
|
243
254
|
|
244
255
|
it 'should contain multiple payment_informations' do
|
245
256
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/ReqdColltnDt', (Date.today + 1).iso8601)
|
246
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/PmtTpInf/LclInstrm/Cd', 'CORE')
|
247
257
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/PmtTpInf/SeqTp', 'OOFF')
|
248
258
|
|
249
259
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/ReqdColltnDt', (Date.today + 1).iso8601)
|
250
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/PmtTpInf/LclInstrm/Cd', 'CORE')
|
251
260
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/PmtTpInf/SeqTp', 'FNAL')
|
252
261
|
|
253
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]/ReqdColltnDt', (Date.today +
|
254
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]/PmtTpInf/LclInstrm/Cd', 'B2B')
|
262
|
+
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]/ReqdColltnDt', (Date.today + 2).iso8601)
|
255
263
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]/PmtTpInf/SeqTp', 'OOFF')
|
256
264
|
|
257
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[4]/ReqdColltnDt', (Date.today +
|
258
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[4]/PmtTpInf/LclInstrm/Cd', 'B2B')
|
265
|
+
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[4]/ReqdColltnDt', (Date.today + 2).iso8601)
|
259
266
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[4]/PmtTpInf/SeqTp', 'FNAL')
|
260
|
-
|
261
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[5]/ReqdColltnDt', (Date.today + 2).iso8601)
|
262
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[5]/PmtTpInf/LclInstrm/Cd', 'CORE')
|
263
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[5]/PmtTpInf/SeqTp', 'OOFF')
|
264
|
-
|
265
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[6]/ReqdColltnDt', (Date.today + 2).iso8601)
|
266
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[6]/PmtTpInf/LclInstrm/Cd', 'CORE')
|
267
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[6]/PmtTpInf/SeqTp', 'FNAL')
|
268
|
-
|
269
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[7]/ReqdColltnDt', (Date.today + 2).iso8601)
|
270
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[7]/PmtTpInf/LclInstrm/Cd', 'B2B')
|
271
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[7]/PmtTpInf/SeqTp', 'OOFF')
|
272
|
-
|
273
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[8]/ReqdColltnDt', (Date.today + 2).iso8601)
|
274
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[8]/PmtTpInf/LclInstrm/Cd', 'B2B')
|
275
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[8]/PmtTpInf/SeqTp', 'FNAL')
|
276
267
|
end
|
277
268
|
|
278
269
|
it 'should have multiple control sums' do
|
@@ -280,10 +271,6 @@ describe SEPA::DirectDebit do
|
|
280
271
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/CtrlSum', '2.00')
|
281
272
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]/CtrlSum', '4.00')
|
282
273
|
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[4]/CtrlSum', '8.00')
|
283
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[5]/CtrlSum', '16.00')
|
284
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[6]/CtrlSum', '32.00')
|
285
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[7]/CtrlSum', '64.00')
|
286
|
-
subject.should have_xml('//Document/CstmrDrctDbtInitn/PmtInf[8]/CtrlSum', '128.00')
|
287
274
|
end
|
288
275
|
end
|
289
276
|
end
|
data/spec/message_spec.rb
CHANGED
@@ -26,4 +26,12 @@ describe SEPA::Message do
|
|
26
26
|
message.amount_total([message.transactions[0]]).should == 1.1
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
describe 'validation' do
|
31
|
+
it 'should fail without transactions' do
|
32
|
+
message = DummyMessage.new
|
33
|
+
message.should_not be_valid
|
34
|
+
message.should have(1).error_on(:transactions)
|
35
|
+
end
|
36
|
+
end
|
29
37
|
end
|
@@ -24,7 +24,11 @@ RSpec::Matchers.define :have_xml do |xpath, text|
|
|
24
24
|
nodes.should_not be_empty
|
25
25
|
if text
|
26
26
|
nodes.each do |node|
|
27
|
-
|
27
|
+
if text.is_a?(Regexp)
|
28
|
+
node.content.should =~ text
|
29
|
+
else
|
30
|
+
node.content.should == text
|
31
|
+
end
|
28
32
|
end
|
29
33
|
end
|
30
34
|
true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sepa_king
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Georg Leciejewski
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-09-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|