fog-core 1.22.0 → 1.23.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YTNmYzY5ZmZiYjA4OTVkZWU2MTA0OTQ3ZmVmZmYxM2M0Y2UxY2ZkMA==
4
+ ODU0ZTJhZDcwMGI0NzRiNmY1ODdjM2NmMDc2ZDMzYWM5NTk1ZjcwYw==
5
5
  data.tar.gz: !binary |-
6
- MGJmMDEwODNmZjRiYjA5MTYzMmNkZjA3OTY4NTAzNzAzZGJkZjE0ZQ==
6
+ MzExN2UxODJlZDg5ZGQzZDIxNjM3YzUzMzc1MDI1MmZmMmJlNzg4Yg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NTNmYzVjYzdjMmJiN2NjMjU3ZmFmYTYxZGJiYTA1MTEzZjBmNWFmMWY3Zjg0
10
- NDU0YTcxYWY5ZTU0ODViMGIwMTYyN2IzMWI4YWFlOTVhZjgyYjM5ODU0MTcx
11
- ZTY2MGZkZTVmYmFlMDI4NmVlZGFkNWMxMmY1YTcyOWZhNjJlYTc=
9
+ MTIyZTRhZDg0ZWVjYWY3OTQyNTZhZmY4Y2YzYTBjMDYxYTZhZTQ5N2RiMGRh
10
+ OTMxODUyOGIxYTIwZmYyZGM3NWU4MTc0NTU0OTU4NjI2MzJkODVjYmYzOThl
11
+ OTI2N2MxZjdmOTJiN2IzOTVjZDUwODE5NmEyY2FiOGJmNWEwMGU=
12
12
  data.tar.gz: !binary |-
13
- YTgyMTQ0MWQzOWI5NWM5OWYwNjcxZTE3NWExNWNhZmM1ODU0Y2RlNTNmMDlm
14
- NGFjOThlNDNkNDNmMjA4YTlkNTU4NmU0YjRjNmE4Mzk0ZTExODYyODQzMzg4
15
- OWVlZmQxNDRlM2U2YzViY2ZhOTA0MGY2YzUwOTFjNjFiZWQ2OWI=
13
+ NmQ3NDdjZTM4OGY1ZTI1MTc0M2FiNWQ5YmRmM2FlYjlhNDE3MWNhYjEwMmY3
14
+ NDE0MDNhZDQ5ZTQyYmJhMTliMTI2NzhmZDUyYmVkZThlMDFhMDg0MDA1NTBi
15
+ OWRkMzNlMDUxNTYyYjM4ZDczNTljZWZmZmY5NDE5YTgwNDEzOTM=
@@ -2,6 +2,7 @@ source "https://rubygems.org"
2
2
 
3
3
  gem 'nokogiri', '~>1.5.11'
4
4
  gem 'mime-types', '~>1.16'
5
+ gem 'rest-client', '~> 1.6.7'
5
6
 
6
7
  group :development, :test do
7
8
  gem 'rake', '~> 10.1.0'
data/Rakefile CHANGED
@@ -24,7 +24,7 @@ end
24
24
  #require "tasks/changelog_task"
25
25
  #Fog::Rake::ChangelogTask.new
26
26
  task :coveralls_push_workaround do
27
- use_coveralls = (Gem::Version.new(RUBY_VERSION) > Gem::Version.new('1.9.2'))
27
+ use_coveralls = (Gem::Version.new(RUBY_VERSION.dup) > Gem::Version.new('1.9.2'))
28
28
  if (ENV['COVERAGE'] != 'false') && use_coveralls
29
29
  require 'coveralls/rake/task'
30
30
  Coveralls::RakeTask.new
@@ -1,3 +1,40 @@
1
+ 1.23.0 07/16/2014
2
+ ==========================================================
3
+
4
+ attribute whitelisting
5
+ abstract out stringify for possible reuse
6
+ more specific naming
7
+ reorg
8
+ add path_prefix
9
+ fix time conversion to work with XMLRPC
10
+ add more specific per-type attribute tests
11
+ lock down rest-client for 1.8.7
12
+ allow namespace flipflop for dns
13
+ fix identity lookup
14
+ better default attribute value setting
15
+ bump excon
16
+
17
+ 1.22.0 04/17/2014 1c086852e40e4c1ad7ed138834e4a1505ddb1416
18
+ ==========================================================
19
+
20
+ attribute whitelisting
21
+ abstract out stringify for possible reuse
22
+ more specific naming
23
+ reorg
24
+ add path_prefix
25
+ fix time conversion to work with XMLRPC
26
+ add more specific per-type attribute tests
27
+ lock down rest-client for 1.8.7
28
+ allow namespace flipflop for dns
29
+ fix identity lookup
30
+ better default attribute value setting
31
+ bump excon
32
+
33
+ 1.22.0 04/17/2014 1c086852e40e4c1ad7ed138834e4a1505ddb1416
34
+ ==========================================================
35
+
36
+ tests/cleanup/fixes
37
+
1
38
  1.21.1 03/18/2014 3a803405ba60ded421f4bd14677cd3c76cb7e6ab
2
39
  ==========================================================
3
40
 
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency('builder')
22
- spec.add_dependency('excon', '~>0.33')
22
+ spec.add_dependency('excon', '~>0.38')
23
23
  spec.add_dependency('formatador', '~>0.2')
24
24
  spec.add_dependency('mime-types')
25
25
  spec.add_dependency('net-scp', '~>1.1')
@@ -13,6 +13,14 @@ require 'ipaddr'
13
13
  # internal core dependencies
14
14
  require "fog/version"
15
15
  require 'fog/core/attributes'
16
+ require 'fog/core/attributes/default'
17
+ require 'fog/core/attributes/boolean'
18
+ require 'fog/core/attributes/float'
19
+ require 'fog/core/attributes/integer'
20
+ require 'fog/core/attributes/string'
21
+ require 'fog/core/attributes/time'
22
+ require 'fog/core/attributes/timestamp'
23
+ require 'fog/core/attributes/array'
16
24
  require 'fog/core/collection'
17
25
  require 'fog/core/connection'
18
26
  require 'fog/core/credentials'
@@ -32,6 +40,8 @@ require 'fog/core/utils'
32
40
  require 'fog/core/wait_for'
33
41
  require 'fog/core/wait_for_defaults'
34
42
  require 'fog/core/uuid'
43
+ require 'fog/core/stringify_keys'
44
+ require 'fog/core/whitelist_keys'
35
45
 
36
46
  # service wrappers
37
47
  require 'fog/account'
@@ -14,92 +14,17 @@ module Fog
14
14
  @attributes ||= []
15
15
  end
16
16
 
17
+ def default_values
18
+ @default_values ||= {}
19
+ end
20
+
17
21
  def attribute(name, options = {})
18
- class_eval <<-EOS, __FILE__, __LINE__
19
- def #{name}
20
- attributes[:#{name}]
21
- end
22
- EOS
23
- case options[:type]
24
- when :boolean
25
- class_eval <<-EOS, __FILE__, __LINE__
26
- def #{name}=(new_#{name})
27
- attributes[:#{name}] = case new_#{name}
28
- when true,'true'
29
- true
30
- when false,'false'
31
- false
32
- end
33
- end
34
- EOS
35
- when :float
36
- class_eval <<-EOS, __FILE__, __LINE__
37
- def #{name}=(new_#{name})
38
- attributes[:#{name}] = new_#{name}.to_f
39
- end
40
- EOS
41
- when :integer
42
- class_eval <<-EOS, __FILE__, __LINE__
43
- def #{name}=(new_#{name})
44
- attributes[:#{name}] = new_#{name}.to_i
45
- end
46
- EOS
47
- when :string
48
- class_eval <<-EOS, __FILE__, __LINE__
49
- def #{name}=(new_#{name})
50
- attributes[:#{name}] = new_#{name}.to_s
51
- end
52
- EOS
53
- when :time
54
- class_eval <<-EOS, __FILE__, __LINE__
55
- def #{name}=(new_#{name})
56
- attributes[:#{name}] = if new_#{name}.nil? || new_#{name} == "" || new_#{name}.is_a?(Time)
57
- new_#{name}
58
- else
59
- Time.parse(new_#{name})
60
- end
61
- end
62
- EOS
63
- when :timestamp
64
- class_eval <<-EOS, __FILE__, __LINE__
65
- def #{name}=(new_#{name})
66
- attributes[:#{name}] = Time.at(new_#{name}.to_i)
67
- end
68
- EOS
69
- when :array
70
- class_eval <<-EOS, __FILE__, __LINE__
71
- def #{name}=(new_#{name})
72
- attributes[:#{name}] = [*new_#{name}]
73
- end
74
- EOS
75
- else
76
- if squash = options[:squash]
77
- class_eval <<-EOS, __FILE__, __LINE__
78
- def #{name}=(new_data)
79
- if new_data.is_a?(Hash)
80
- if new_data.has_key?(:'#{squash}')
81
- attributes[:#{name}] = new_data[:'#{squash}']
82
- elsif new_data.has_key?("#{squash}")
83
- attributes[:#{name}] = new_data["#{squash}"]
84
- else
85
- attributes[:#{name}] = [ new_data ]
86
- end
87
- else
88
- attributes[:#{name}] = new_data
89
- end
90
- end
91
- EOS
92
- else
93
- class_eval <<-EOS, __FILE__, __LINE__
94
- def #{name}=(new_#{name})
95
- attributes[:#{name}] = new_#{name}
96
- end
97
- EOS
98
- end
99
- end
100
- @attributes ||= []
101
- @attributes |= [name]
102
- for new_alias in [*options[:aliases]]
22
+ type = options.fetch(:type, 'default').to_s.capitalize
23
+ default = options.fetch(:default, false)
24
+ Fog::Attributes::const_get(type).new(self, name, options).create
25
+ attributes << name
26
+ default_values[name] = default if default
27
+ Array(options[:aliases]).each do |new_alias|
103
28
  aliases[new_alias] = name
104
29
  end
105
30
  end
@@ -0,0 +1,13 @@
1
+ module Fog
2
+ module Attributes
3
+ class Array < Default
4
+ def create_setter
5
+ model.class_eval <<-EOS, __FILE__, __LINE__
6
+ def #{name}=(new_#{name})
7
+ attributes[:#{name}] = [*new_#{name}]
8
+ end
9
+ EOS
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ module Fog
2
+ module Attributes
3
+ class Boolean < Default
4
+ def create_setter
5
+ model.class_eval <<-EOS, __FILE__, __LINE__
6
+ def #{name}=(new_#{name})
7
+ attributes[:#{name}] = case new_#{name}
8
+ when true,'true'
9
+ true
10
+ when false,'false'
11
+ false
12
+ end
13
+ end
14
+ EOS
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,55 @@
1
+ module Fog
2
+ module Attributes
3
+ class Default
4
+ attr_reader :model, :name, :squash
5
+
6
+ def initialize(model, name, options)
7
+ @model = model
8
+ @name = name
9
+ @squash = options.fetch(:squash, false)
10
+ end
11
+
12
+ def create
13
+ create_setter
14
+ create_getter
15
+ end
16
+
17
+ def create_setter
18
+ if squash
19
+ model.class_eval <<-EOS, __FILE__, __LINE__
20
+ def #{name}=(new_data)
21
+ if new_data.is_a?(Hash)
22
+ if new_data.has_key?(:'#{squash}')
23
+ attributes[:#{name}] = new_data[:'#{squash}']
24
+ elsif new_data.has_key?("#{squash}")
25
+ attributes[:#{name}] = new_data["#{squash}"]
26
+ else
27
+ attributes[:#{name}] = [ new_data ]
28
+ end
29
+ else
30
+ attributes[:#{name}] = new_data
31
+ end
32
+ end
33
+ EOS
34
+ else
35
+ model.class_eval <<-EOS, __FILE__, __LINE__
36
+ def #{name}=(new_#{name})
37
+ attributes[:#{name}] = new_#{name}
38
+ end
39
+ EOS
40
+ end
41
+ end
42
+
43
+ def create_getter
44
+ model.class_eval <<-EOS, __FILE__, __LINE__
45
+ def #{name}
46
+ if self.class.default_values[:#{name}] && !persisted?
47
+ return self.class.default_values[:#{name}]
48
+ end
49
+ attributes[:#{name}]
50
+ end
51
+ EOS
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,13 @@
1
+ module Fog
2
+ module Attributes
3
+ class Float < Default
4
+ def create_setter
5
+ model.class_eval <<-EOS, __FILE__, __LINE__
6
+ def #{name}=(new_#{name})
7
+ attributes[:#{name}] = new_#{name}.to_f
8
+ end
9
+ EOS
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Fog
2
+ module Attributes
3
+ class Integer < Default
4
+ def create_setter
5
+ model.class_eval <<-EOS, __FILE__, __LINE__
6
+ def #{name}=(new_#{name})
7
+ attributes[:#{name}] = new_#{name}.to_i
8
+ end
9
+ EOS
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module Fog
2
+ module Attributes
3
+ class String < Default
4
+ def create_setter
5
+ model.class_eval <<-EOS, __FILE__, __LINE__
6
+ def #{name}=(new_#{name})
7
+ attributes[:#{name}] = new_#{name}.to_s
8
+ end
9
+ EOS
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module Fog
2
+ module Attributes
3
+ class Time < Default
4
+ def create_setter
5
+ model.class_eval <<-EOS, __FILE__, __LINE__
6
+ def #{name}=(new_#{name})
7
+ attributes[:#{name}] = if new_#{name}.nil? || new_#{name} == "" || new_#{name}.is_a?(::Time)
8
+ new_#{name}
9
+ elsif new_#{name}.respond_to?(:to_time)
10
+ new_#{name}.to_time
11
+ else
12
+ ::Time.parse(new_#{name})
13
+ end
14
+ end
15
+ EOS
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module Fog
2
+ module Attributes
3
+ class Timestamp < Default
4
+ def create_setter
5
+ model.class_eval <<-EOS, __FILE__, __LINE__
6
+ def #{name}=(new_#{name})
7
+ if new_#{name}.respond_to?(:to_i)
8
+ attributes[:#{name}] = Fog::Time.at(new_#{name}.to_i)
9
+ else
10
+ attributes[:#{name}] = Fog::Time.parse(new_#{name}.to_s)
11
+ end
12
+ end
13
+ EOS
14
+ end
15
+ end
16
+ end
17
+ end
@@ -16,6 +16,7 @@ module Fog
16
16
  # @option params [Hash<Symbol, String>] :headers The default headers to supply in a request. Only used if params[:headers] is not supplied to Connection#request
17
17
  # @option params [String] :host The destination host's reachable DNS name or IP, in the form of a String
18
18
  # @option params [String] :path Default path; appears after 'scheme://host:port/'. Only used if params[:path] is not supplied to Connection#request
19
+ # @option params [String] :path_prefix Sticky version of the "path" arg. :XSpath_prefix => "foo/bar" with a request with :path => "blech" sends a request to path "foo/bar/blech"
19
20
  # @option params [Fixnum] :port The port on which to connect, to the destination host
20
21
  # @option params [Hash] :query Default query; appended to the 'scheme://host:port/path/' in the form of '?key=value'. Will only be used if params[:query] is not supplied to Connection#request
21
22
  # @option params [String] :scheme The protocol; 'https' causes OpenSSL to be used
@@ -23,8 +24,15 @@ module Fog
23
24
  # @option params [Fixnum] :retry_limit Set how many times we'll retry a failed request. (Default 4)
24
25
  # @option params [Class] :instrumentor Responds to #instrument as in ActiveSupport::Notifications
25
26
  # @option params [String] :instrumentor_name Name prefix for #instrument events. Defaults to 'excon'
26
- #
27
27
  def initialize(url, persistent=false, params={})
28
+ if params[:path_prefix]
29
+ if params[:path]
30
+ raise ArgumentError, "optional arg 'path' is invalid when 'path_prefix' is provided"
31
+ end
32
+
33
+ @path_prefix = params.delete(:path_prefix)
34
+ end
35
+
28
36
  unless params.has_key?(:debug_response)
29
37
  params[:debug_response] = true
30
38
  end
@@ -53,7 +61,7 @@ module Fog
53
61
  # @raise [Excon::Errors::SocketError]
54
62
  #
55
63
  def request(params, &block)
56
- @excon.request(params, &block)
64
+ @excon.request(handle_path_prefix_for(params), &block)
57
65
  end
58
66
 
59
67
  # Make {#request} available even when it has been overidden by a subclass
@@ -67,6 +75,16 @@ module Fog
67
75
  def reset
68
76
  @excon.reset
69
77
  end
78
+
79
+ private
80
+
81
+ def handle_path_prefix_for(params)
82
+ return params unless @path_prefix
83
+
84
+ params[:path] = params[:path].sub(/^\//, "")
85
+ params[:path] = "#{@path_prefix}/#{params[:path]}"
86
+ params
87
+ end
70
88
  end
71
89
  end
72
90
  end
@@ -0,0 +1,27 @@
1
+ module Fog
2
+ module StringifyKeys
3
+
4
+ # Returns a new hash with all keys converted to strings.
5
+ def self.stringify(hash)
6
+ self.transform_hash(hash) {|hash, key, value|
7
+ hash[key.to_s] = value
8
+ }
9
+ end
10
+
11
+ private
12
+
13
+ # http://devblog.avdi.org/2009/11/20/hash-transforms-in-ruby/
14
+ def self.transform_hash(original, options={}, &block)
15
+ original.inject({}){|result, (key,value)|
16
+ value = if (options[:deep] && Hash === value)
17
+ transform_hash(value, options, &block)
18
+ else
19
+ value
20
+ end
21
+ block.call(result,key,value)
22
+ result
23
+ }
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,8 @@
1
+ module Fog
2
+ module WhitelistKeys
3
+ def self.whitelist(hash, valid_keys)
4
+ valid_hash = StringifyKeys.stringify(hash)
5
+ valid_hash.select {|k,v| valid_keys.include?(k)}
6
+ end
7
+ end
8
+ end
@@ -14,10 +14,14 @@ module Fog
14
14
  else
15
15
  if self.providers.include?(provider)
16
16
  require "fog/#{provider}/dns"
17
- return Fog::DNS.const_get(Fog.providers[provider]).new(attributes)
17
+ begin
18
+ Fog::DNS.const_get(Fog.providers[provider])
19
+ rescue
20
+ Fog::const_get(Fog.providers[provider])::DNS
21
+ end.new(attributes)
22
+ else
23
+ raise ArgumentError.new("#{provider} is not a recognized dns provider")
18
24
  end
19
-
20
- raise ArgumentError.new("#{provider} is not a recognized dns provider")
21
25
  end
22
26
  end
23
27
 
@@ -17,7 +17,7 @@ module Fog
17
17
  begin
18
18
  Fog::Identity.const_get(Fog.providers[provider]).new(attributes)
19
19
  rescue
20
- Fog::const_get(Fog.providers[provider]).const_get("Identity").new(attributes)
20
+ Fog::const_get(Fog.providers[provider])::Identity.new(attributes)
21
21
  end
22
22
  end
23
23
 
@@ -1,3 +1,3 @@
1
1
  module Fog
2
- VERSION = "1.22.0"
2
+ VERSION = "1.23.0"
3
3
  end
@@ -30,4 +30,71 @@ describe Fog::Core::Connection do
30
30
  }
31
31
  Fog::Core::Connection.new("http://example.com", true, options)
32
32
  end
33
+
34
+ describe ":path_prefix" do
35
+ it "does not emit a warning when provided this argument in the initializer" do
36
+ $stderr = StringIO.new
37
+
38
+ Fog::Core::Connection.new("http://example.com", false, :path_prefix => "foo")
39
+
40
+ assert_empty($stderr.string)
41
+ end
42
+
43
+ it "raises when the 'path' arg is present and this arg is supplied" do
44
+ assert_raises(ArgumentError) do
45
+ Fog::Core::Connection.new("http://example.com", false, :path_prefix => "foo", :path => "bar")
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#request" do
51
+ describe "default behavior" do
52
+ it "supplies the 'path' arg directly to Excon" do
53
+ spy = Object.new
54
+ spy.instance_eval do
55
+ def params
56
+ @params
57
+ end
58
+ def new(_, params)
59
+ @params = params
60
+ end
61
+ end
62
+
63
+ Object.stub_const("Excon", spy) do
64
+ c = Fog::Core::Connection.new("http://example.com", false, :path => "bar")
65
+ assert_equal("bar", spy.params[:path])
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "with path_prefix supplied to the initializer" do
71
+ let(:spy) {
72
+ Object.new.tap { |spy|
73
+ spy.instance_eval do
74
+ def new(*args); self; end
75
+ def params; @params; end
76
+ def request(params)
77
+ @params = params
78
+ end
79
+ end
80
+ }
81
+ }
82
+
83
+ it "uses the initializer-supplied :path_prefix arg with #request :arg to formulate a path to send to Excon.request" do
84
+ Object.stub_const("Excon", spy) do
85
+ c = Fog::Core::Connection.new("http://example.com", false, :path_prefix => "foo")
86
+ c.request(:path => "bar")
87
+ assert_equal("foo/bar", spy.params[:path])
88
+ end
89
+ end
90
+
91
+ it "does not introduce consecutive '/'s into the path if 'path' starts with a '/'" do
92
+ Object.stub_const("Excon", spy) do
93
+ c = Fog::Core::Connection.new("http://example.com", false, :path_prefix => "foo")
94
+ c.request(:path => "/bar")
95
+ assert_equal("foo/bar", spy.params[:path])
96
+ end
97
+ end
98
+ end
99
+ end
33
100
  end
@@ -1,27 +1,39 @@
1
1
  require 'spec_helper'
2
+ require 'xmlrpc/datetime'
2
3
 
3
4
  class FogAttributeTestModel < Fog::Model
5
+ identity :id
4
6
  attribute :key, :aliases => "keys", :squash => "id"
5
7
  attribute :time, :type => :time
6
8
  attribute :bool, :type => :boolean
9
+ attribute :float, :type => :float
10
+ attribute :integer, :type => :integer
11
+ attribute :string, :type => :string
12
+ attribute :timestamp, :type => :timestamp
13
+ attribute :array, :type => :array
14
+ attribute :default, :default => 'default_value'
7
15
  end
8
16
 
9
17
  describe "Fog::Attributes" do
10
-
18
+
11
19
  let(:model) { FogAttributeTestModel.new }
12
20
 
21
+ it "should not create alias for nil" do
22
+ FogAttributeTestModel.aliases.must_equal({ "keys" => :key })
23
+ end
24
+
13
25
  describe "squash 'id'" do
14
26
  it "squashes if the key is a String" do
15
27
  model.merge_attributes("keys" => {:id => "value"})
16
28
  assert_equal"value", model.key
17
29
  end
18
-
30
+
19
31
  it "squashes if the key is a Symbol" do
20
32
  model.merge_attributes("keys" => {"id" => "value"})
21
33
  assert_equal "value", model.key
22
34
  end
23
35
  end
24
-
36
+
25
37
  describe ":type => time" do
26
38
  it "returns nil when provided nil" do
27
39
  model.merge_attributes(:time => nil)
@@ -38,6 +50,12 @@ describe "Fog::Attributes" do
38
50
  model.merge_attributes(:time => now.to_s)
39
51
  assert_equal Time.parse(now.to_s), model.time
40
52
  end
53
+
54
+ it "returns a Time object when passed a XMLRPC::DateTime object" do
55
+ now = XMLRPC::DateTime.new(2000, 7, 8, 10, 20, 34)
56
+ model.merge_attributes(:time => now)
57
+ assert_equal now.to_time, model.time
58
+ end
41
59
  end
42
60
 
43
61
  describe ":type => :boolean" do
@@ -66,4 +84,102 @@ describe "Fog::Attributes" do
66
84
  refute model.bool
67
85
  end
68
86
  end
87
+
88
+ describe ":type => :float" do
89
+ it "returns an integer as float" do
90
+ model.merge_attributes(:float => 1)
91
+ assert_in_delta 1.0, model.float
92
+ end
93
+
94
+ it "returns a string as float" do
95
+ model.merge_attributes(:float => '1')
96
+ assert_in_delta 1.0, model.float
97
+ end
98
+ end
99
+
100
+ describe ":type => :integer" do
101
+ it "returns a float as integer" do
102
+ model.merge_attributes(:integer => 1.5)
103
+ assert_in_delta 1, model.integer
104
+ end
105
+
106
+ it "returns a string as integer" do
107
+ model.merge_attributes(:integer => '1')
108
+ assert_in_delta 1, model.integer
109
+ end
110
+ end
111
+
112
+ describe ":type => :string" do
113
+ it "returns a float as string" do
114
+ model.merge_attributes(:string => 1.5)
115
+ assert_equal '1.5', model.string
116
+ end
117
+
118
+ it "returns a integer as string" do
119
+ model.merge_attributes(:string => 1)
120
+ assert_equal '1', model.string
121
+ end
122
+ end
123
+
124
+ describe ":type => :timestamp" do
125
+ it "returns a date as time" do
126
+ model.merge_attributes(:timestamp => Date.new(2008, 10, 12))
127
+ assert_equal '2008-10-12 00:00', model.timestamp.strftime('%Y-%m-%d %M:%S')
128
+ assert_instance_of Fog::Time, model.timestamp
129
+ end
130
+
131
+ it "returns a time as time" do
132
+ model.merge_attributes(:timestamp => Time.mktime(2007, 11, 1, 15, 25))
133
+ assert_equal '2007-11-01 25:00', model.timestamp.strftime('%Y-%m-%d %M:%S')
134
+ assert_instance_of Fog::Time, model.timestamp
135
+ end
136
+
137
+ it "returns a date_time as time" do
138
+ model.merge_attributes(:timestamp => DateTime.new(2007, 11, 1, 15, 25, 0))
139
+ assert_equal '2007-11-01 25:00', model.timestamp.strftime('%Y-%m-%d %M:%S')
140
+ assert_instance_of Fog::Time, model.timestamp
141
+ end
142
+ end
143
+
144
+ describe ":type => :array" do
145
+ it "returns an empty array as an empty array" do
146
+ model.merge_attributes(:array => [])
147
+ assert_equal [], model.array
148
+ end
149
+
150
+ it "returns a single element as array" do
151
+ model.merge_attributes(:array => 1.5)
152
+ assert_equal [ 1.5 ], model.array
153
+ end
154
+
155
+ it "returns an array as array" do
156
+ model.merge_attributes(:array => [ 1, 2 ])
157
+ assert_equal [ 1, 2 ], model.array
158
+ end
159
+ end
160
+
161
+ describe ":default => 'default_value'" do
162
+ it "should return nil when default is not defined on a new object" do
163
+ assert_equal model.bool, nil
164
+ end
165
+
166
+ it "should return the value of the object when default is not defined" do
167
+ model.merge_attributes({ :bool => false })
168
+ assert_equal model.bool, false
169
+ end
170
+
171
+ it "should return the default value on a new object" do
172
+ assert_equal model.default, 'default_value'
173
+ end
174
+
175
+ it "should return the value of the persisted object" do
176
+ model.merge_attributes({ :id => 'some-crazy-id', :default => 23 })
177
+ assert_equal model.default, 23
178
+ end
179
+
180
+ it "should return nil on a persisted object without a value" do
181
+ model.merge_attributes({ :id => 'some-crazy-id' })
182
+ assert_equal model.default, nil
183
+ end
184
+ end
69
185
  end
@@ -0,0 +1,29 @@
1
+ input_hash = {
2
+ :name => 'test-server',
3
+ :flavor => '123'
4
+ }
5
+
6
+ output_hash = {
7
+ 'name' => 'test-server',
8
+ 'flavor' => '123'
9
+ }
10
+
11
+ Shindo.tests('Fog::StringifyKeys', 'core') do
12
+
13
+ tests('keys') do
14
+
15
+ tests('stringifies symbols') do
16
+ returns(output_hash) {
17
+ Fog::StringifyKeys.stringify(input_hash)
18
+ }
19
+ end
20
+
21
+ tests('skips strings') do
22
+ returns(output_hash) {
23
+ Fog::StringifyKeys.stringify(output_hash)
24
+ }
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,24 @@
1
+ input_hash = {
2
+ :name => 'test-server',
3
+ :flavor => '123',
4
+ :size => '12345'
5
+ }
6
+
7
+ output_hash = {
8
+ 'name' => 'test-server',
9
+ 'flavor' => '123'
10
+ }
11
+
12
+ valid_keys = %w{flavor name}
13
+
14
+ Shindo.tests('Fog::WhitelistKeys', 'core') do
15
+
16
+ tests('whitelist_keys') do
17
+ tests('excludes invalid values') do
18
+ returns(output_hash) {
19
+ Fog::WhitelistKeys.whitelist(input_hash, valid_keys)
20
+ }
21
+ end
22
+ end
23
+
24
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fog-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.22.0
4
+ version: 1.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Light
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-17 00:00:00.000000000 Z
12
+ date: 2014-07-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: builder
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - ~>
33
33
  - !ruby/object:Gem::Version
34
- version: '0.33'
34
+ version: '0.38'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ~>
40
40
  - !ruby/object:Gem::Version
41
- version: '0.33'
41
+ version: '0.38'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: formatador
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -219,6 +219,14 @@ files:
219
219
  - lib/fog/compute/models/server.rb
220
220
  - lib/fog/core.rb
221
221
  - lib/fog/core/attributes.rb
222
+ - lib/fog/core/attributes/array.rb
223
+ - lib/fog/core/attributes/boolean.rb
224
+ - lib/fog/core/attributes/default.rb
225
+ - lib/fog/core/attributes/float.rb
226
+ - lib/fog/core/attributes/integer.rb
227
+ - lib/fog/core/attributes/string.rb
228
+ - lib/fog/core/attributes/time.rb
229
+ - lib/fog/core/attributes/timestamp.rb
222
230
  - lib/fog/core/collection.rb
223
231
  - lib/fog/core/connection.rb
224
232
  - lib/fog/core/credentials.rb
@@ -234,11 +242,13 @@ files:
234
242
  - lib/fog/core/scp.rb
235
243
  - lib/fog/core/service.rb
236
244
  - lib/fog/core/ssh.rb
245
+ - lib/fog/core/stringify_keys.rb
237
246
  - lib/fog/core/time.rb
238
247
  - lib/fog/core/utils.rb
239
248
  - lib/fog/core/uuid.rb
240
249
  - lib/fog/core/wait_for.rb
241
250
  - lib/fog/core/wait_for_defaults.rb
251
+ - lib/fog/core/whitelist_keys.rb
242
252
  - lib/fog/dns.rb
243
253
  - lib/fog/identity.rb
244
254
  - lib/fog/image.rb
@@ -280,6 +290,8 @@ files:
280
290
  - spec/utils_spec.rb
281
291
  - spec/uuid_spec.rb
282
292
  - spec/wait_for_spec.rb
293
+ - tests/core/stringify_keys_tests.rb
294
+ - tests/core/whitelist_keys_tests.rb
283
295
  homepage: https://github.com/fog/fog-core
284
296
  licenses:
285
297
  - MIT
@@ -300,7 +312,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
312
  version: '0'
301
313
  requirements: []
302
314
  rubyforge_project:
303
- rubygems_version: 2.2.2
315
+ rubygems_version: 2.3.0
304
316
  signing_key:
305
317
  specification_version: 4
306
318
  summary: Shared classes and tests for fog providers and services.