joyent-cloud-pricing 1.0.10 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ffe763f26373c4c9dd19d269cabb8d34be18204b
4
- data.tar.gz: e1454babed191bb8e3ddd4f3a6d0f768396a5c76
3
+ metadata.gz: 2111e58865d22fde24d32147061b876f61abd621
4
+ data.tar.gz: 8fc86f5970562d9758afe1638f58095022cc5ffb
5
5
  SHA512:
6
- metadata.gz: 8ee3d92c075e5bd7bd352b59b6e16bf1e6fcd57b5312888b9ae8d802d63bd206138ae8c36c8a95226c56546bae3fd4125fbab1e75d16d53c3a13a207ef0007fb
7
- data.tar.gz: a37d969d4682497eb6380875b9fa7380190145b1d6b3946de4b15d1885f638e2b416c3f51647a47c4a6480058d4d692d223c40cbaac4ca088e56182fdf3859fe
6
+ metadata.gz: d9f9cf9eefc2c6f429830316b550ee2705441b5697a58bbffe2f47caa0bfb5304ae758748c1c120e1e55b1c50225b3ad3807282534d896ea9c889a6e7313aa5f
7
+ data.tar.gz: 4dbe5bc3c410a42f14f722fc8057a6088c27db829101d1ebfa4169141d11caa4d499bf4b338d761391fc45e74a66743165dacf08bae637d05ded22f030e5eac3
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
2
  --format progress
3
+ --require rspec/legacy_formatters
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_development_dependency 'rspec'
30
30
  spec.add_development_dependency 'rspec-mocks'
31
+ spec.add_development_dependency 'rspec-legacy_formatters'
31
32
  end
@@ -23,3 +23,4 @@ require 'pricing/formatter'
23
23
  require 'pricing/commit'
24
24
  require 'pricing/analyzer'
25
25
  require 'pricing/reporter'
26
+ require 'pricing/discount'
@@ -10,7 +10,7 @@ module Joyent::Cloud::Pricing
10
10
  @zone_counts = count_dupes(flavors).symbolize_keys
11
11
  end
12
12
 
13
- # Zones that are not on commit
13
+ # Zones that are not on commit, i.e on demand
14
14
  def excess_zone_counts
15
15
  h = {}
16
16
  zone_counts.each_pair { |flavor, count| diff = count - quantity_for(flavor); h[flavor] = diff if diff > 0 }
@@ -75,7 +75,7 @@ module Joyent::Cloud::Pricing
75
75
 
76
76
  def monthly_full_price_for zones
77
77
  count_for_all zones do |flavor|
78
- pricing.monthly(flavor)
78
+ (commit.discount.nil?) ? pricing.monthly(flavor) : commit.discount.apply(pricing.monthly(flavor))
79
79
  end
80
80
  end
81
81
 
@@ -6,14 +6,14 @@ module Joyent::Cloud::Pricing
6
6
  class << self
7
7
  def from_yaml(filename = COMMIT_FILENAME)
8
8
  hash = YAML.load(File.read(filename))
9
- new(hash['reserved'] || {}, hash['custom'])
9
+ new(hash['reserved'] || {}, hash['custom'], hash['discount'])
10
10
  end
11
11
  end
12
12
 
13
13
  # map of image names to prices
14
- attr_accessor :reserves, :custom
14
+ attr_accessor :reserves, :custom, :discount
15
15
 
16
- def initialize(hash = {}, custom = nil)
16
+ def initialize(hash = {}, custom = nil, discount = nil)
17
17
  @config = hash.symbolize_keys
18
18
  self.reserves = {}
19
19
  @config.each_pair do |flavor, config|
@@ -22,6 +22,10 @@ module Joyent::Cloud::Pricing
22
22
  if custom
23
23
  Joyent::Cloud::Pricing::Configuration.instance.merge(custom)
24
24
  end
25
+ if discount
26
+ discount = discount.symbolize_keys
27
+ self.discount = Joyent::Cloud::Pricing::Discount.type(discount[:type], discount[:value])
28
+ end
25
29
  end
26
30
 
27
31
  def reserve_for flavor
@@ -0,0 +1,34 @@
1
+ module Joyent::Cloud::Pricing
2
+ class Discount
3
+ def apply(amount)
4
+ raise 'Abstract method'
5
+ end
6
+
7
+ end
8
+
9
+ class PercentDiscount < Discount
10
+ attr_accessor :value
11
+ def initialize(value)
12
+ @value = value
13
+ raise 'Discount value must be between 0% and 100%' unless self.value <= 100 && self.value >= 0
14
+ end
15
+
16
+ def apply(amount)
17
+ amount - 0.01 * value * amount
18
+ end
19
+
20
+ def to_s
21
+ "#{value}%"
22
+ end
23
+ end
24
+
25
+ class Discount
26
+ CALCULATORS = { percent: PercentDiscount }
27
+ def self.type(type_name, *args)
28
+ calc = CALCULATORS[type_name]
29
+ raise "Type #{type_name} is unknown!" unless calc.is_a?(Class)
30
+ calc.new *args
31
+ end
32
+ end
33
+
34
+ end
@@ -31,6 +31,9 @@ ZONE COUNTS:
31
31
  <%= separator %>
32
32
 
33
33
  MONTHLY COSTS:
34
+ <%- if commit.discount %>
35
+ NOTE: additional discount of <%= commit.discount.to_s.green %> applies to all on-demand instances
36
+ <%- end %>
34
37
  <%- if print_zone_list -%>
35
38
  List of on-demand flavors by price <%= have_commit_pricing? ? "(in excess of reserve)" : "" %>
36
39
 
@@ -1,7 +1,7 @@
1
1
  module Joyent
2
2
  module Cloud
3
3
  module Pricing
4
- VERSION = '1.0.10'
4
+ VERSION = '1.1.0'
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,27 @@
1
+ defaults: &defaults
2
+ years: 1
3
+
4
+ discount:
5
+ type: :percent
6
+ value: 30
7
+
8
+ reserved:
9
+ "g3-highcpu-32-smartos-cc":
10
+ <<: *defaults
11
+ prepay: 8000.00
12
+ monthly: 500
13
+ quantity: 10
14
+ "g3-highmemory-17.125-smartos":
15
+ <<: *defaults
16
+ prepay: 800.00
17
+ monthly: 60
18
+ quantity: 12
19
+ "g3-highio-60.5-smartos":
20
+ <<: *defaults
21
+ prepay: 1800.00
22
+ monthly: 600
23
+ quantity: 5
24
+
25
+ custom:
26
+ :some-instance:
27
+ :cost: 2.451
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Joyent::Cloud::Pricing::Analyzer' do
3
+ RSpec.describe 'Joyent::Cloud::Pricing::Analyzer' do
4
4
 
5
5
  FLAVORS = %w(
6
6
  g3-highcpu-16-smartos
@@ -113,4 +113,21 @@ describe 'Joyent::Cloud::Pricing::Analyzer' do
113
113
  end
114
114
  end
115
115
 
116
+ context 'for commit with discount' do
117
+ let(:commit) { Joyent::Cloud::Pricing::Commit.from_yaml 'spec/fixtures/commit_with_discount.yml' }
118
+ let(:discount) { 0.7 }
119
+
120
+ context 'should apply discount only to on demand instances' do
121
+ it '#monthly_full_price' do
122
+ expect(analyzer.monthly_full_price).to be_within(0.01).of(35496.0 * discount)
123
+ end
124
+
125
+ it '#monthly_overages_price' do
126
+ expect(analyzer.monthly_overages_price).to be_within(0.01).of(6432.48 * discount)
127
+ end
128
+
129
+ end
130
+
131
+ end
132
+
116
133
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Joyent::Cloud::Pricing::Commit' do
3
+ RSpec.describe 'Joyent::Cloud::Pricing::Commit' do
4
4
 
5
5
  context 'when some reserve pricing is defined' do
6
6
  let(:commit) { Joyent::Cloud::Pricing::Commit.from_yaml 'spec/fixtures/commit.yml' }
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Joyent::Cloud::Pricing::Configuration' do
3
+ RSpec.describe 'Joyent::Cloud::Pricing::Configuration' do
4
4
  expected_prices = {
5
5
  'g3-standard-48-smartos' => 1.536,
6
6
  'g3-standard-0.625-smartos' => 0.02,
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Joyent::Cloud::Pricing::Discount' do
4
+ let(:pricing) { Joyent::Cloud::Pricing::Configuration.from_yaml }
5
+ let(:discount) { Joyent::Cloud::Pricing::Discount.type(:percent, 30) }
6
+ let(:commit) { Joyent::Cloud::Pricing::Commit.from_yaml 'spec/fixtures/commit_with_discount.yml' }
7
+
8
+ it "should apply percent discount correctly" do
9
+ expect(discount.apply(10)).to eql(7.0)
10
+ end
11
+
12
+ it "should read discount from yaml correctly" do
13
+ expect(commit.discount.value).to eq(discount.value)
14
+ end
15
+
16
+
17
+
18
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe' Joyent::Cloud::Pricing::Formatter' do
3
+ RSpec.describe' Joyent::Cloud::Pricing::Formatter' do
4
4
 
5
5
  let(:config) { Joyent::Cloud::Pricing::Configuration.new(
6
6
  {'g3-standard-48-smartos' => {cost: 1.536},
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Joyent::Cloud::Pricing::Reporter' do
3
+ RSpec.describe 'Joyent::Cloud::Pricing::Reporter' do
4
4
 
5
5
  let(:flavors) { %w(
6
6
  g3-highcpu-16-smartos
@@ -39,7 +39,7 @@ describe 'Joyent::Cloud::Pricing::Reporter' do
39
39
  some-fake-flavor-without-pricing
40
40
  some-fake-flavor-again
41
41
  ) }
42
- let(:commit) { Joyent::Cloud::Pricing::Commit.from_yaml 'spec/fixtures/commit.yml' }
42
+ let(:commit) { Joyent::Cloud::Pricing::Commit.from_yaml 'spec/fixtures/commit_with_discount.yml' }
43
43
  let(:reporter) { Joyent::Cloud::Pricing::Reporter.new(commit, flavors) }
44
44
 
45
45
  before do
@@ -62,6 +62,7 @@ describe 'Joyent::Cloud::Pricing::Reporter' do
62
62
  expect(output).to_not be_nil
63
63
  expect(output).to include('MONTHLY COSTS')
64
64
  expect(output).to include('YEARLY RESERVE SAVINGS')
65
+ expect(output).to include('NOTE: additional discount of')
65
66
  end
66
67
  end
67
68
 
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Joyent::Cloud::Pricing::Reserve' do
3
+ RSpec.describe 'Joyent::Cloud::Pricing::Reserve' do
4
4
  let(:pricing) { Joyent::Cloud::Pricing::Configuration.from_yaml }
5
5
  let(:flavor) { "g3-highcpu-32-smartos-cc" }
6
6
  let(:reserve) {
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Joyent::Cloud::Pricing::Scraper' do
3
+ RSpec.describe 'Joyent::Cloud::Pricing::Scraper' do
4
4
  context 'scraping from URL'
5
5
  let(:scraper) { Joyent::Cloud::Pricing::Scraper.new }
6
6
 
@@ -19,6 +19,7 @@ RSpec.configure do |config|
19
19
  # the filtering metadata and `run_all_when_everything_filtered = true` then
20
20
  # all specs will run.
21
21
  #config.filter_run :focus
22
+ config.disable_monkey_patching!
22
23
 
23
24
  # Run all specs when none match the provided filter. This works well in
24
25
  # conjunction with `config.filter_run :focus`, as it will run the entire
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joyent-cloud-pricing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.10
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Gredeskoul
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-10 00:00:00.000000000 Z
11
+ date: 2014-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec-legacy_formatters
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Various set of tools and helpers to calculate infrastructure footprint
112
126
  and cost on Joyent Cloud. Supports commit discounts.
113
127
  email:
@@ -132,6 +146,7 @@ files:
132
146
  - lib/pricing/analyzer.rb
133
147
  - lib/pricing/commit.rb
134
148
  - lib/pricing/configuration.rb
149
+ - lib/pricing/discount.rb
135
150
  - lib/pricing/flavor.rb
136
151
  - lib/pricing/formatter.rb
137
152
  - lib/pricing/helpers.rb
@@ -144,10 +159,12 @@ files:
144
159
  - lib/tasks/update.rake
145
160
  - spec/fixtures/commit.yml
146
161
  - spec/fixtures/commit_noreserve.yml
162
+ - spec/fixtures/commit_with_discount.yml
147
163
  - spec/fixtures/pricing.yml
148
164
  - spec/pricing/analyzer_spec.rb
149
165
  - spec/pricing/commit_spec.rb
150
166
  - spec/pricing/configuration_spec.rb
167
+ - spec/pricing/discount_spec.rb
151
168
  - spec/pricing/formatter_spec.rb
152
169
  - spec/pricing/reporter_spec.rb
153
170
  - spec/pricing/reserve_spec.rb
@@ -181,10 +198,12 @@ summary: Tools for calculating monthly and yearly price of infrastructure hosted
181
198
  test_files:
182
199
  - spec/fixtures/commit.yml
183
200
  - spec/fixtures/commit_noreserve.yml
201
+ - spec/fixtures/commit_with_discount.yml
184
202
  - spec/fixtures/pricing.yml
185
203
  - spec/pricing/analyzer_spec.rb
186
204
  - spec/pricing/commit_spec.rb
187
205
  - spec/pricing/configuration_spec.rb
206
+ - spec/pricing/discount_spec.rb
188
207
  - spec/pricing/formatter_spec.rb
189
208
  - spec/pricing/reporter_spec.rb
190
209
  - spec/pricing/reserve_spec.rb