joyent-cloud-pricing 1.0.10 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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