zillion 0.1.2 → 0.1.3
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 +5 -5
- data/lib/zillion/plan.rb +16 -13
- data/spec/plans_spec.rb +39 -7
- data/zillion.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: aa5e49662e1f608430f15149830de87cf410c8ff6fbcfdfb815b43a58224345c
|
4
|
+
data.tar.gz: d3a5d3476423dcf3c8bd35e7f22aefc6709f0d6134792cb1e6c465fdf97de466
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 698359ad81c9ba5a1af1b450fef3472c6b56bf41890f5a0f8d0c63d73e17d299c9d03b096bf2899e268c57b8735fb8bcf7066e87b90ebe01991207b7ba9c7f68
|
7
|
+
data.tar.gz: 9571b0b84a001b4139cf1566add53fc8847f2d6dd3c263f5d1ed825312c8d566536344dc76febc17ede68a0f2e635d30c93107bdb97cc578404ea2717cc36f20
|
data/lib/zillion/plan.rb
CHANGED
@@ -58,13 +58,13 @@ class Plan
|
|
58
58
|
self.monthly_fee <=> other_plan.monthly_fee
|
59
59
|
end
|
60
60
|
|
61
|
-
def amounts_for(counts)
|
62
|
-
{ monthly_fee: monthly_fee }
|
61
|
+
def amounts_for(counts, custom_monthly_fee: nil, fallback: false)
|
62
|
+
{ monthly_fee: custom_monthly_fee.nil? ? monthly_fee : custom_monthly_fee }
|
63
63
|
end
|
64
64
|
|
65
|
-
def monthly_fee_for(counts)
|
65
|
+
def monthly_fee_for(counts, custom_monthly_fee: nil)
|
66
66
|
ensure_available!(counts)
|
67
|
-
sum(amounts_for(counts))
|
67
|
+
sum(amounts_for(counts, custom_monthly_fee: custom_monthly_fee))
|
68
68
|
end
|
69
69
|
|
70
70
|
def available_for?(counts)
|
@@ -125,7 +125,8 @@ end
|
|
125
125
|
|
126
126
|
class TieredPlan < Plan
|
127
127
|
|
128
|
-
def amounts_for(counts)
|
128
|
+
def amounts_for(counts, custom_monthly_fee: nil, fallback: false)
|
129
|
+
raise "Tiered plans don't have fixed monthly fees! (Use FixedTieredPlan for that)" if custom_monthly_fee
|
129
130
|
tier = matching_tier_for(counts)
|
130
131
|
obj = {}
|
131
132
|
obj[tier.last.to_sym] = tier[1] # tier[1] is monthly cost
|
@@ -181,13 +182,13 @@ class TieredPlan < Plan
|
|
181
182
|
end
|
182
183
|
end
|
183
184
|
|
184
|
-
def matching_tiers_for(counts,
|
185
|
+
def matching_tiers_for(counts, fallback: false)
|
185
186
|
tier_groups.map do |key, tiers|
|
186
187
|
units = counts[key] or raise MissingCountError.new("Unit count required for #{key}")
|
187
188
|
begin
|
188
189
|
find_tier_for(tiers, units.to_i) + [key]
|
189
190
|
rescue TierNotFoundError
|
190
|
-
raise unless
|
191
|
+
raise unless fallback # to highest tier
|
191
192
|
last_existing_tier_for(key)
|
192
193
|
end
|
193
194
|
end.compact
|
@@ -201,9 +202,11 @@ end
|
|
201
202
|
|
202
203
|
class MeteredPlan < TieredPlan
|
203
204
|
|
204
|
-
def amounts_for(counts,
|
205
|
+
def amounts_for(counts, custom_monthly_fee: nil, fallback: false)
|
206
|
+
# raise "Tiered plans don't have fixed monthly fees! (Use FixedTieredPlan for that)" if custom_monthly_fee
|
207
|
+
|
205
208
|
obj = {}
|
206
|
-
matching_tiers_for(counts,
|
209
|
+
matching_tiers_for(counts, fallback: fallback).map do |tier|
|
207
210
|
units = units_for(tier.last, counts)
|
208
211
|
obj[tier.last.to_sym] = units * tier[1] # tier[1] is monthly unit cost
|
209
212
|
end
|
@@ -228,9 +231,9 @@ class FixedMeteredPlan < MeteredPlan
|
|
228
231
|
spec[:monthly_fee] ? spec[:monthly_fee].to_f : 0
|
229
232
|
end
|
230
233
|
|
231
|
-
def amounts_for(counts,
|
234
|
+
def amounts_for(counts, custom_monthly_fee: nil, fallback: false)
|
232
235
|
obj = super
|
233
|
-
obj[:base_fee] = base_fee
|
236
|
+
obj[:base_fee] = custom_monthly_fee.nil? ? base_fee : custom_monthly_fee
|
234
237
|
obj
|
235
238
|
end
|
236
239
|
|
@@ -275,7 +278,7 @@ class FixedMeteredPlan < MeteredPlan
|
|
275
278
|
:monthly_unit_cost
|
276
279
|
end
|
277
280
|
|
278
|
-
def matching_tiers_for(counts,
|
281
|
+
def matching_tiers_for(counts, fallback: false)
|
279
282
|
tier_groups.map do |key, tiers|
|
280
283
|
units = counts[key] or raise MissingCountError.new("Unit count required for #{key}")
|
281
284
|
next if limits[key] and limits[key] >= units.to_i
|
@@ -283,7 +286,7 @@ class FixedMeteredPlan < MeteredPlan
|
|
283
286
|
begin
|
284
287
|
find_tier_for(tiers, units.to_i) + [key]
|
285
288
|
rescue TierNotFoundError
|
286
|
-
raise unless
|
289
|
+
raise unless fallback # to_highest_tier
|
287
290
|
last_existing_tier_for(key)
|
288
291
|
end
|
289
292
|
end.compact
|
data/spec/plans_spec.rb
CHANGED
@@ -138,6 +138,10 @@ describe 'FixedPlan' do
|
|
138
138
|
expect(other.monthly_fee_for({ bananas: 10 })).to eql(10.0)
|
139
139
|
end
|
140
140
|
|
141
|
+
it 'uses custom_monthly_fee if passed' do
|
142
|
+
expect(plan.monthly_fee_for({ apples: 10 }, custom_monthly_fee: 20)).to eql(20)
|
143
|
+
end
|
144
|
+
|
141
145
|
it 'raises if not within limits' do
|
142
146
|
other = FixedPlan.new(monthly_fee: 10, limits: { bananas: 10 })
|
143
147
|
expect { other.monthly_fee_for({ bananas: 11 }) }.to raise_error(Zillion::Plan::OverLimitsError)
|
@@ -212,6 +216,10 @@ describe 'TieredPlan', 'Single tier' do
|
|
212
216
|
expect(plan.monthly_fee_for({ bananas: 5, products: 25 })).to eql(20)
|
213
217
|
end
|
214
218
|
|
219
|
+
it 'raises if custom_monthly_fee passed (because these plans dont have one)' do
|
220
|
+
expect { plan.monthly_fee_for({ bananas: 5, products: 25 }, custom_monthly_fee: 5) }.to raise_error
|
221
|
+
end
|
222
|
+
|
215
223
|
end
|
216
224
|
|
217
225
|
end
|
@@ -279,6 +287,10 @@ describe 'TieredPlan', 'Multiple tiers' do
|
|
279
287
|
expect(plan.monthly_fee_for({ bananas: 1, orders: 5, products: 25 })).to eql(20)
|
280
288
|
end
|
281
289
|
|
290
|
+
it 'raises if custom_monthly_fee passed (because these plans dont have one)' do
|
291
|
+
expect { plan.monthly_fee_for({ bananas: 1, orders: 5, products: 25 }, custom_monthly_fee: 100) }.to raise_error
|
292
|
+
end
|
293
|
+
|
282
294
|
end
|
283
295
|
|
284
296
|
end
|
@@ -342,6 +354,10 @@ describe 'MeteredPlan', 'Single tier' do
|
|
342
354
|
expect(plan.monthly_fee_for({ bananas: 5, products: 25 })).to eql(50)
|
343
355
|
end
|
344
356
|
|
357
|
+
xit 'raises if custom_monthly_fee passed (because these plans dont have one)' do
|
358
|
+
expect { plan.monthly_fee_for({ bananas: 5, products: 25 }, custom_monthly_fee: 100) }.to raise_error
|
359
|
+
end
|
360
|
+
|
345
361
|
end
|
346
362
|
|
347
363
|
describe '#amounts_for(counts)' do
|
@@ -363,14 +379,18 @@ describe 'MeteredPlan', 'Single tier' do
|
|
363
379
|
end
|
364
380
|
|
365
381
|
it 'doesnt raise if not within limits but second arg is true' do
|
366
|
-
expect { plan.amounts_for({ products: 250 }, true) }.not_to raise_error(Zillion::Plan::TierNotFoundError)
|
367
|
-
expect(plan.amounts_for({ products: 250 }, true)).to eql({ products: 375.0 })
|
382
|
+
expect { plan.amounts_for({ products: 250 }, fallback: true) }.not_to raise_error(Zillion::Plan::TierNotFoundError)
|
383
|
+
expect(plan.amounts_for({ products: 250 }, fallback: true)).to eql({ products: 375.0 })
|
368
384
|
end
|
369
385
|
|
370
386
|
it 'returns amounts if within limits' do
|
371
387
|
expect(plan.amounts_for({ bananas: 5, products: 25 })).to eql({ products: 50 })
|
372
388
|
end
|
373
389
|
|
390
|
+
xit 'raises if custom_monthly_fee passed (because these plans dont have one)' do
|
391
|
+
expect { plan.amounts_for({ bananas: 5, products: 25 }, custom_monthly_fee: 100) }.to raise_error
|
392
|
+
end
|
393
|
+
|
374
394
|
end
|
375
395
|
|
376
396
|
end
|
@@ -460,8 +480,8 @@ describe 'MeteredPlan', 'Multiple tiers' do
|
|
460
480
|
end
|
461
481
|
|
462
482
|
it 'doesnt raise if not within limits but second arg is true' do
|
463
|
-
expect { plan.amounts_for({ products: 250, orders: 5 }, true) }.not_to raise_error(Zillion::Plan::TierNotFoundError)
|
464
|
-
expect(plan.amounts_for({ products: 250, orders: 5 }, true)).to eql({ orders: 15, products: 375.0 })
|
483
|
+
expect { plan.amounts_for({ products: 250, orders: 5 }, fallback: true) }.not_to raise_error(Zillion::Plan::TierNotFoundError)
|
484
|
+
expect(plan.amounts_for({ products: 250, orders: 5 }, fallback: true)).to eql({ orders: 15, products: 375.0 })
|
465
485
|
end
|
466
486
|
|
467
487
|
it 'returns amounts if within limits' do
|
@@ -472,6 +492,10 @@ describe 'MeteredPlan', 'Multiple tiers' do
|
|
472
492
|
expect(plan.amounts_for({ bananas: 5, products: 25, orders: 1 })).to eql({ orders: 3, products: 50 })
|
473
493
|
end
|
474
494
|
|
495
|
+
xit 'raises if custom_monthly_fee passed (because these plans dont have one)' do
|
496
|
+
expect { plan.amounts_for({ bananas: 5, products: 25, orders: 1 }, custom_monthly_fee: 100) }.to raise_error
|
497
|
+
end
|
498
|
+
|
475
499
|
end
|
476
500
|
|
477
501
|
end
|
@@ -574,9 +598,13 @@ describe 'FixedMeteredPlan' do
|
|
574
598
|
expect(plan.monthly_fee_for({ bananas: 5, orders: 15, products: 25 })).to eql(55.0)
|
575
599
|
end
|
576
600
|
|
577
|
-
|
601
|
+
it 'uses custom_monthly_fee if passed' do
|
602
|
+
expect(plan.monthly_fee_for({ bananas: 5, orders: 15, products: 25 }, custom_monthly_fee: 100)).to eql(145)
|
603
|
+
end
|
578
604
|
|
579
605
|
|
606
|
+
end
|
607
|
+
|
580
608
|
describe '#amounts_for(counts)' do
|
581
609
|
|
582
610
|
it 'raises if missing unit for tier' do
|
@@ -592,8 +620,8 @@ describe 'FixedMeteredPlan' do
|
|
592
620
|
end
|
593
621
|
|
594
622
|
it 'doest raises if over limits but second arg is true' do
|
595
|
-
expect { plan.amounts_for({ orders: 1000, products: 5 }, true) }.not_to raise_error(Zillion::Plan::TierNotFoundError)
|
596
|
-
expect(plan.amounts_for({ orders: 1000, products: 5 }, true)).to eql({ orders: 990, base_fee: 10.0 })
|
623
|
+
expect { plan.amounts_for({ orders: 1000, products: 5 }, fallback: true) }.not_to raise_error(Zillion::Plan::TierNotFoundError)
|
624
|
+
expect(plan.amounts_for({ orders: 1000, products: 5 }, fallback: true)).to eql({ orders: 990, base_fee: 10.0 })
|
597
625
|
end
|
598
626
|
|
599
627
|
it 'doesnt explode if negative key for tiered count, but under fixed limit' do
|
@@ -616,6 +644,10 @@ describe 'FixedMeteredPlan' do
|
|
616
644
|
expect(plan.amounts_for({ bananas: 5, orders: 15, products: 25 })).to eql({:orders=>15, :products=>30, :base_fee=>10.0})
|
617
645
|
end
|
618
646
|
|
647
|
+
it 'uses custom_monthly_fee if passed' do
|
648
|
+
expect(plan.amounts_for({ bananas: 5, orders: 15, products: 25 }, custom_monthly_fee: 100)).to eql({:orders=>15, :products=>30, :base_fee=>100})
|
649
|
+
end
|
650
|
+
|
619
651
|
end
|
620
652
|
|
621
653
|
end
|
data/zillion.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zillion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomás Pollak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
78
|
version: 1.3.6
|
79
79
|
requirements: []
|
80
80
|
rubyforge_project:
|
81
|
-
rubygems_version: 2.
|
81
|
+
rubygems_version: 2.7.3
|
82
82
|
signing_key:
|
83
83
|
specification_version: 4
|
84
84
|
summary: A model for SaaS plans with fixed, tiered and metered pricing.
|