pod4 0.9.3 → 0.10.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.
@@ -1,11 +1,12 @@
1
- require 'octothorpe'
1
+ require "octothorpe"
2
+ require "bigdecimal"
2
3
 
3
- require 'pod4'
4
- require 'pod4/typecasting'
5
- require 'pod4/null_interface'
4
+ require "pod4"
5
+ require "pod4/typecasting"
6
+ require "pod4/null_interface"
6
7
 
7
8
 
8
- describe 'ProductModel' do
9
+ describe "ProductModel" do
9
10
 
10
11
  let(:product_model_class) do
11
12
  Class.new Pod4::Model do
@@ -16,33 +17,47 @@ describe 'ProductModel' do
16
17
  end
17
18
  end
18
19
 
19
- let(:records) do
20
+ let(:customer_model_class) do
21
+ Class.new Pod4::Model do
22
+ include Pod4::TypeCasting
23
+ attr_columns :id, :code, :band, :sales, :created, :yrstart, :flag, :foo, :bar
24
+ typecast :band, as: Integer, strict: true
25
+ typecast :sales, as: BigDecimal, ot_as: Float, strict: true
26
+ typecast :created, as: Time
27
+ typecast :yrstart, as: Date
28
+ typecast :flag, as: :boolean
29
+ typecast :foo, use: :mycast, bar: 42
30
+ typecast :bar, as: Float
31
+ set_interface NullInterface.new( :id, :code, :band, :sales, :created, :yrstart,
32
+ :flag, :foo, :bar, [] )
33
+
34
+ def mycast(value, opts); end
35
+ end
36
+ end
37
+
38
+ let(:product_records) do
20
39
  [ {id: 10, code: 'aa1', product: 'beans', price: 1.23},
21
40
  {id: 20, code: 'bb1', product: 'pears', price: 2.34},
22
41
  {id: 30, code: 'cc1', product: 'soap', price: 3.45},
23
42
  {id: 40, code: 'cc2', product: 'matches', price: 4.56} ]
24
43
  end
25
44
 
26
- let(:model) { product_model_class.new(20) }
27
-
28
- let(:model2) do
45
+ let(:product_model) do
29
46
  m = product_model_class.new(30)
30
47
 
31
48
  allow( m.interface ).to receive(:read).
32
- and_return( Octothorpe.new(records[2]) )
49
+ and_return( Octothorpe.new(product_records[2]) )
33
50
 
34
51
  m.read.or_die
35
52
  end
36
53
 
37
- let(:records_as_ot) { records.map{|r| Octothorpe.new(r) } }
38
-
39
54
 
40
- ###
55
+ ########
41
56
 
42
57
 
43
- describe 'Model.force_encoding' do
58
+ describe "Model.force_encoding" do
44
59
 
45
- it 'requires an encoding' do
60
+ it "requires an encoding" do
46
61
  expect( product_model_class ).to respond_to(:force_encoding).with(1).argument
47
62
 
48
63
  expect{ product_model_class.force_encoding('foo') }.to raise_exception Pod4Error
@@ -54,20 +69,91 @@ describe 'ProductModel' do
54
69
 
55
70
  end
56
71
 
57
- it 'sets the encoding to be returned by Model.encoding' do
72
+ it "sets the encoding to be returned by Model.encoding" do
58
73
  expect{ product_model_class.encoding }.not_to raise_exception
59
74
  expect( product_model_class.encoding ).to eq(Encoding::ISO_8859_1)
60
75
  end
61
76
 
62
- end
63
- ##
64
-
77
+ end # of Model.force_encoding
78
+
79
+
80
+ describe "Model.typecast" do
81
+
82
+ let(:customer_model_bad1_class) do
83
+ Class.new Pod4::Model do
84
+ include Pod4::TypeCasting
85
+ attr_columns :id, :foo
86
+ typecast :foo, blarg: Integer
87
+ set_interface NullInterface.new(:id, :foo, [])
88
+ end
89
+ end
90
+
91
+ let(:customer_model_bad2_class) do
92
+ Class.new Pod4::Model do
93
+ include Pod4::TypeCasting
94
+ attr_columns :id, :foo
95
+ typecast :foo, as: Octothorpe
96
+ set_interface NullInterface.new(:id, :foo, [])
97
+ end
98
+ end
99
+
100
+ let(:customer_model_bad3_class) do
101
+ Class.new Pod4::Model do
102
+ include Pod4::TypeCasting
103
+ attr_columns :id, :foo
104
+ typecast :bar, as: Integer
105
+ set_interface NullInterface.new(:id, :foo, [])
106
+ end
107
+ end
108
+
109
+ it "requires either the 'as:' option or the 'use:' option" do
110
+ expect{ customer_model_bad1_class }.to raise_exception Pod4::Pod4Error
111
+ end
112
+
113
+ it "raises an error for an unknown typecast type" do
114
+ expect{ customer_model_bad2_class }.to raise_exception Pod4::Pod4Error
115
+ end
116
+
117
+ it "raises an error for an unknown column" do
118
+ expect{ customer_model_bad3_class }.to raise_exception Pod4::Pod4Error
119
+ end
120
+
121
+ end # of Model.typecast
122
+
123
+
124
+ describe "Model.typecasts" do
125
+
126
+ it "is a hash of hashes" do
127
+ expect( customer_model_class.typecasts ).to be_a Hash
128
+ expect( customer_model_class.typecasts.values ).to all(be_a Hash)
129
+ end
65
130
 
66
- describe '#map_to_model' do
131
+ it "has a key for each column typecast" do
132
+ expect( customer_model_class.typecasts.keys ).
133
+ to match_array(%i|band sales created yrstart flag foo bar|)
67
134
 
68
- it 'forces each string to map to the given encoding' do
135
+ end
136
+
137
+ it "stores the given options of each column as the value" do
138
+ expect( customer_model_class.typecasts[:band] ).to eq(as: Integer, strict: true)
139
+
140
+ expect( customer_model_class.typecasts[:sales] ).
141
+ to eq(as: BigDecimal, ot_as: Float, strict: true)
142
+
143
+ expect( customer_model_class.typecasts[:created] ).to eq(as: Time)
144
+ expect( customer_model_class.typecasts[:yrstart] ).to eq(as: Date)
145
+ expect( customer_model_class.typecasts[:foo] ).to eq(use: :mycast, bar: 42)
146
+ expect( customer_model_class.typecasts[:bar] ).to eq(as: Float)
147
+ end
148
+
149
+ end # of Model.typecasts
150
+
151
+
152
+ describe "#map_to_model" do
153
+
154
+ it "forces each string to map to the given encoding" do
69
155
  # map_to_model has already happened at this point. No matter.
70
- ot = model2.to_ot
156
+ ot = product_model.to_ot
71
157
  expect( ot.>>.id ).to eq 30
72
158
  expect( ot.>>.price ).to eq 3.45
73
159
  expect( ot.>>.code.encoding ).to eq Encoding::ISO_8859_1
@@ -77,6 +163,332 @@ describe 'ProductModel' do
77
163
  end
78
164
 
79
165
 
166
+ describe "#set" do
167
+
168
+ it "typecasts strings to whatever" do
169
+ c = customer_model_class.new
170
+ c.set( id: 77,
171
+ code: "seven",
172
+ band: "7",
173
+ sales: "12.34",
174
+ created: "2018-01-01 12:34",
175
+ yrstart: "2018-01-02",
176
+ flag: "true",
177
+ bar: "34.56" )
178
+
179
+ expect( c.id ).to eq 77
180
+ expect( c.code ).to eq "seven"
181
+ expect( c.band ).to eq 7
182
+ expect( c.sales ).to eq 12.34
183
+ expect( c.created ).to eq Time.parse("2018-01-01 12:34")
184
+ expect( c.yrstart ).to eq Date.parse("2018-01-02")
185
+ expect( c.flag ).to eq true
186
+ expect( c.bar ).to eq 34.56
187
+ end
188
+
189
+ it "allows the attribute to be nil" do
190
+ c = customer_model_class.new
191
+ c.set( id: 11,
192
+ code: "foo",
193
+ band: nil,
194
+ sales: nil,
195
+ created: nil,
196
+ yrstart: nil,
197
+ flag: nil,
198
+ bar: nil )
199
+
200
+ expect( c.code ).to eq "foo"
201
+ expect( c.band ).to eq nil
202
+ expect( c.sales ).to eq nil
203
+ expect( c.created ).to eq nil
204
+ expect( c.yrstart ).to eq nil
205
+ expect( c.flag ).to eq nil
206
+ expect( c.bar ).to eq nil
207
+ end
208
+
209
+ # Note: we cover typecasting more thoroughly in Model#typecast
210
+
211
+ it "leaves the column alone if it can't typecast (with strict off)" do
212
+ c = customer_model_class.new
213
+ c.set( created: "bloob",
214
+ yrstart: "flarg",
215
+ flag: "blobe",
216
+ bar: "xing" )
217
+
218
+ expect( c.created ).to eq "bloob"
219
+ expect( c.yrstart ).to eq "flarg"
220
+ expect( c.flag ).to eq "blobe"
221
+ expect( c.bar ).to eq "xing"
222
+ end
223
+
224
+ it "sets the column to nil if it can't typecast (with strict on)" do
225
+ c = customer_model_class.new
226
+ c.set( band: "bloob",
227
+ sales: "flarg" )
228
+
229
+ expect( c.created ).to eq nil
230
+ expect( c.yrstart ).to eq nil
231
+ end
232
+
233
+ it "calls the use method to get a typecast when the use option is given" do
234
+ c = customer_model_class.new
235
+ expect( c ).to receive(:mycast).with("12345", {use: :mycast, bar: 42} )
236
+
237
+ c.set( foo: "12345" )
238
+ end
239
+
240
+ end # of #set
241
+
242
+
243
+ describe "#map_to_interface" do
244
+
245
+ it "typecasts strings to whatever" do
246
+ c = customer_model_class.new
247
+ c.id = 11
248
+ c.code = "foo"
249
+ c.band = "12"
250
+ c.sales = "98.76"
251
+ c.created = "2018-04-04 11:59"
252
+ c.yrstart = "2018-01-09"
253
+ c.flag = "true"
254
+ c.bar = "87.65"
255
+ c.create
80
256
 
257
+ record = customer_model_class.interface.read(11)
258
+ expect( record.>>.code ).to eq "foo"
259
+ expect( record.>>.band ).to eq 12
260
+ expect( record.>>.sales ).to eq BigDecimal.new("98.76")
261
+ expect( record.>>.created ).to eq Time.parse("2018-04-04 11:59")
262
+ expect( record.>>.yrstart ).to eq Date.parse("2018-01-09")
263
+ expect( record.>>.flag ).to eq true
264
+ expect( record.>>.bar ).to eq 87.65
265
+ end
266
+
267
+ it "allows the attribute to be nil" do
268
+ c = customer_model_class.new
269
+ c.id = 11
270
+ c.code = "foo"
271
+ c.band = nil
272
+ c.sales = nil
273
+ c.created = nil
274
+ c.yrstart = nil
275
+ c.flag = nil
276
+ c.bar = nil
277
+ c.create
278
+
279
+ record = customer_model_class.interface.read(11)
280
+ expect( record.>>.code ).to eq "foo"
281
+ expect( record.>>.band ).to eq nil
282
+ expect( record.>>.sales ).to eq nil
283
+ expect( record.>>.created ).to eq nil
284
+ expect( record.>>.yrstart ).to eq nil
285
+ expect( record.>>.flag ).to eq nil
286
+ expect( record.>>.bar ).to eq nil
287
+ end
288
+
289
+ # Note: we cover typecasting more thoroughly in Model#typecast
290
+
291
+ it "sets the column to nil if it can't typecast" do
292
+ c = customer_model_class.new
293
+ c.id = 22
294
+ c.code = "bar"
295
+ c.band = "bloob"
296
+ c.sales = "flarg"
297
+ c.created = "flam"
298
+ c.yrstart = "glarb"
299
+ c.create
300
+
301
+ record = customer_model_class.interface.read(22)
302
+ expect( record.>>.code ).to eq "bar"
303
+ expect( record.>>.band ).to eq nil
304
+ expect( record.>>.sales ).to eq nil
305
+ expect( record.>>.created ).to eq nil
306
+ expect( record.>>.yrstart ).to eq nil
307
+ end
308
+
309
+ it "calls the use method to get a typecast when the use option is given" do
310
+ c = customer_model_class.new
311
+ # Note that we have gained the strict option automatically since we're in map_to_interface
312
+ expect( c ).to receive(:mycast).with("12345", {use: :mycast, bar: 42, strict: true} )
313
+
314
+ c.id = 33
315
+ c.code = "baz"
316
+ c.foo = "12345"
317
+ c.create
318
+ end
319
+
320
+ end # of #map_to_interface"
321
+
322
+
323
+ describe "#to_ot" do
324
+
325
+ it "casts any columns with the ot_as option as per that option" do
326
+ c1 = customer_model_class.new
327
+ c1.sales = BigDecimal.new("45.67")
328
+ ot = c1.to_ot
329
+ expect( ot.>>.sales ).to be_a Float
330
+ expect( ot.>>.sales ).to eq 45.67
331
+
332
+ c2 = customer_model_class.new
333
+ c2.sales = "67.89"
334
+ ot = c2.to_ot
335
+ expect( ot.>>.sales ).to be_a Float
336
+ expect( ot.>>.sales ).to eq 67.89
337
+ end
338
+
339
+ it "sets guard on any columns with the to_ot option" do
340
+ c = customer_model_class.new
341
+ c.sales = nil
342
+ ot = c.to_ot
343
+
344
+ expect( ot.>>.sales ).to be_a Float
345
+ end
346
+
347
+ end # of #to_ot
348
+
349
+
350
+ describe "#typecast" do
351
+ let(:cmodel) { customer_model_class.new }
352
+
353
+ it "typecasts strings to any type" do
354
+ expect( cmodel.typecast(Integer, "123") ).to eq 123
355
+ expect( cmodel.typecast(Float, "23.45") ).to eq 23.45
356
+ expect( cmodel.typecast(BigDecimal, "34.56") ).to eq BigDecimal.new("34.56")
357
+ expect( cmodel.typecast(Date, "2018-01-01") ).to eq Date.parse("2018-01-01")
358
+ expect( cmodel.typecast(Time, "2018-02-02 14:56") ).to eq Time.parse("2018-02-02 14:56")
359
+ expect( cmodel.typecast(:boolean, "true") ).to eq true
360
+ expect( cmodel.typecast(:boolean, "false") ).to eq false
361
+ end
362
+
363
+ it "typecasts Integer and BigDecimal to Float" do
364
+ expect( cmodel.typecast(Float, 12) ).to be_a Float
365
+ expect( cmodel.typecast(Float, 12) ).to eq 12.0
366
+
367
+ expect( cmodel.typecast(Float, BigDecimal.new("12.34")) ).to be_a Float
368
+ expect( cmodel.typecast(Float, BigDecimal.new("12.34")) ).to eq 12.34
369
+ end
370
+
371
+ it "typecasts Integer and Float to BigDecimal" do
372
+ expect( cmodel.typecast(BigDecimal, 12) ).to be_a BigDecimal
373
+ expect( cmodel.typecast(BigDecimal, 12) ).to eq BigDecimal.new("12.0")
374
+
375
+ expect( cmodel.typecast(BigDecimal, 12.34) ).to be_a BigDecimal
376
+ expect( cmodel.typecast(BigDecimal, 12.34) ).to eq BigDecimal.new("12.34")
377
+ end
378
+
379
+
380
+ it "typecasts reasonably true values to true" do
381
+ %w|true TRUE t T on ON yes YES 1|.each do |x|
382
+ expect( cmodel.typecast(:boolean, x) ).to eq true
383
+ end
384
+ end
385
+
386
+ it "typecasts reasonably false values to false" do
387
+ %w|false FALSE f F off OFF no NO 0|.each do |x|
388
+ expect( cmodel.typecast(:boolean, x) ).to eq false
389
+ end
390
+ end
391
+
392
+ it "typecasts date to time" do
393
+ expect( cmodel.typecast(Time, Date.parse("2018-01-01")) ).to eq Time.parse("2018-01-01 00:00")
394
+ end
395
+
396
+ it "returns the original value if the value is bad and strict is not set" do
397
+ expect( cmodel.typecast(Integer, 12.34) ).to eq 12.34
398
+ expect( cmodel.typecast(Float, "blarg") ).to eq "blarg"
399
+ expect( cmodel.typecast(BigDecimal, "floob") ).to eq "floob"
400
+ expect( cmodel.typecast(Date, "2018-99-01") ).to eq "2018-99-01"
401
+ expect( cmodel.typecast(Time, "2018-02-02 98:76") ).to eq "2018-02-02 98:76"
402
+ expect( cmodel.typecast(:boolean, "maybe") ).to eq "maybe"
403
+ end
404
+
405
+ it "returns nil if the value is bad and strict is set" do
406
+ expect( cmodel.typecast(Integer, 12.34, strict: true) ).to be_nil
407
+ expect( cmodel.typecast(Float, "blarg", strict: true) ).to be_nil
408
+ expect( cmodel.typecast(BigDecimal, "floob", strict: true) ).to be_nil
409
+ expect( cmodel.typecast(Date, "2018-99-01", strict: true) ).to be_nil
410
+ expect( cmodel.typecast(Time, "2018-02-02 98:76", strict: true) ).to be_nil
411
+ expect( cmodel.typecast(:boolean, "maybe", strict: true) ).to be_nil
412
+ end
413
+
414
+ it "will not cast a float or a BigDecimal to an Integer" do
415
+ expect( cmodel.typecast(Integer, 12.34, strict: true) ).to eq nil
416
+ expect( cmodel.typecast(Integer, BigDecimal.new("12.34"), strict: true) ).to eq nil
417
+ end
418
+
419
+ it "will not cast a Time to a Date" do
420
+ expect( cmodel.typecast(Date, Time.now, strict: true) ).to eq nil
421
+ end
422
+
423
+ end # of #typecast
424
+
425
+
426
+ describe "#typecast?" do
427
+ let(:cmodel) { customer_model_class.new }
428
+
429
+ it "returns true if the value can be cast to the type" do
430
+ expect( cmodel.typecast?(:band, 123) ).to eq true
431
+ expect( cmodel.typecast?(:bar, 23.45) ).to eq true
432
+ expect( cmodel.typecast?(:sales, BigDecimal.new("34.56")) ).to eq true
433
+ expect( cmodel.typecast?(:created, Time.parse("2018-02-02 14:56")) ).to eq true
434
+ expect( cmodel.typecast?(:yrstart, Date.parse("2018-01-01")) ).to eq true
435
+ expect( cmodel.typecast?(:flag, true) ).to eq true
436
+ expect( cmodel.typecast?(:flag, false) ).to eq true
437
+ end
438
+
439
+ it "returns false if the value cannot be cast to the type" do
440
+ expect( cmodel.typecast?(:band, 123.45) ).to eq false
441
+ expect( cmodel.typecast?(:bar, "floob") ).to eq false
442
+ expect( cmodel.typecast?(:sales, "glarn") ).to eq false
443
+ expect( cmodel.typecast?(:created, "bloing") ).to eq false
444
+ expect( cmodel.typecast?(:yrstart, Time.parse("2018-02-02")) ).to eq false
445
+ expect( cmodel.typecast?(:flag, "blarg") ).to eq false
446
+ end
447
+
448
+ it "uses the actual value of the attribute if a value is not given" do
449
+ cmodel.set( id: 88,
450
+ band: 123,
451
+ bar: 23.45,
452
+ sales: "34.56",
453
+ created: "2018-01-06",
454
+ yrstart: "2018-01-07 11:59",
455
+ flag: true )
456
+
457
+ expect( cmodel.typecast?(:band) ).to eq true
458
+ expect( cmodel.typecast?(:bar) ).to eq true
459
+ expect( cmodel.typecast?(:sales) ).to eq true
460
+ expect( cmodel.typecast?(:created) ).to eq true
461
+ expect( cmodel.typecast?(:yrstart) ).to eq true
462
+ expect( cmodel.typecast?(:flag) ).to eq true
463
+ end
464
+
465
+ end # of #typecast?
466
+
467
+
468
+ describe "#guard" do
469
+ let(:cmodel) { customer_model_class.new }
470
+
471
+ it "sets a guard clause on the given OT for each typecast 'column'" do
472
+ ot = Octothorpe.new( band: nil,
473
+ sales: nil,
474
+ created: nil,
475
+ yrstart: nil,
476
+ flag: nil,
477
+ bar: nil,
478
+ baz: nil )
479
+
480
+ ot2 = cmodel.guard(ot)
481
+ expect( ot.>>.band ).to be_an Integer
482
+ expect( ot.>>.sales ).to be_a Float # not a BigDecimal, since it has ot_as set
483
+ expect( ot.>>.created ).to be_a Time
484
+ expect( ot.>>.yrstart ).to be_a Date
485
+ expect( ot.>>.flag ).to eq false
486
+ expect( ot.>>.bar ).to be_a Float
487
+ expect( ot.>>.baz ).to be_nil # since it's not a column
488
+ end
489
+
490
+ end # of #guard
491
+
492
+
81
493
  end
82
494
 
metadata CHANGED
@@ -1,38 +1,38 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pod4
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Jones
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-12 00:00:00.000000000 Z
11
+ date: 2018-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: devnull
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
18
  version: '0.1'
20
- type: :runtime
19
+ name: devnull
21
20
  prerelease: false
21
+ type: :runtime
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: octothorpe
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
32
  version: '0.4'
34
- type: :runtime
33
+ name: octothorpe
35
34
  prerelease: false
35
+ type: :runtime
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
@@ -49,6 +49,7 @@ extensions: []
49
49
  extra_rdoc_files:
50
50
  - md/fixme.md
51
51
  - md/roadmap.md
52
+ - md/typecasting.md
52
53
  files:
53
54
  - ".hgignore"
54
55
  - ".hgtags"
@@ -60,6 +61,7 @@ files:
60
61
  - lib/pod4.rb
61
62
  - lib/pod4/alert.rb
62
63
  - lib/pod4/basic_model.rb
64
+ - lib/pod4/encrypting.rb
63
65
  - lib/pod4/errors.rb
64
66
  - lib/pod4/interface.rb
65
67
  - lib/pod4/metaxing.rb
@@ -75,11 +77,13 @@ files:
75
77
  - lib/pod4/version.rb
76
78
  - md/fixme.md
77
79
  - md/roadmap.md
80
+ - md/typecasting.md
78
81
  - pod4.gemspec
79
82
  - spec/README.md
80
83
  - spec/common/alert_spec.rb
81
84
  - spec/common/basic_model_spec.rb
82
85
  - spec/common/model_new_validate_spec.rb
86
+ - spec/common/model_plus_encrypting_spec.rb
83
87
  - spec/common/model_plus_typecasting_spec.rb
84
88
  - spec/common/model_spec.rb
85
89
  - spec/common/nebulous_interface_spec.rb
@@ -103,7 +107,7 @@ homepage: https://bitbucket.org/andy-twosticks/pod4
103
107
  licenses:
104
108
  - MIT
105
109
  metadata: {}
106
- post_install_message:
110
+ post_install_message:
107
111
  rdoc_options: []
108
112
  require_paths:
109
113
  - lib
@@ -118,9 +122,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
122
  - !ruby/object:Gem::Version
119
123
  version: '0'
120
124
  requirements: []
121
- rubyforge_project:
122
- rubygems_version: 2.5.1
123
- signing_key:
125
+ rubyforge_project:
126
+ rubygems_version: 2.6.13
127
+ signing_key:
124
128
  specification_version: 4
125
129
  summary: Totally not an ORM
126
130
  test_files:
@@ -128,6 +132,7 @@ test_files:
128
132
  - spec/common/alert_spec.rb
129
133
  - spec/common/basic_model_spec.rb
130
134
  - spec/common/model_new_validate_spec.rb
135
+ - spec/common/model_plus_encrypting_spec.rb
131
136
  - spec/common/model_plus_typecasting_spec.rb
132
137
  - spec/common/model_spec.rb
133
138
  - spec/common/nebulous_interface_spec.rb