Module: RSpec::Puppet::Yaml::DataHelpers
- Defined in:
- lib/rspec-puppet-yaml/data_helpers.rb
Overview
A collection of static methods that help coerce data into simpler (to digest) forms. This is necessitated primarily because YAML files can be written with either String or Symbol keys for the same value and because Hashes can be explicitly or implicitly named.
Class Method Summary collapse
-
.get_array_of_named_hashes(key, data = {}) ⇒ Array[Hash]
Condenses a collection of named Hashes into an Array-of-Hashes.
-
.get_named_hash(key, data = {}, default = {}) ⇒ Hash
Gets a named Hash child from a supplied Hash parent.
-
.get_named_value(key, data = {}, default = nil) ⇒ Any
Gets a named value from a Hash by its String and Symbol names.
-
.make_hash_name_explicit(transform_hash = {}) ⇒ Object
Takes a Hash, checks it for a name attribute, and ensures that name is a string-named, 'name', attribute.
Class Method Details
.get_array_of_named_hashes(key, data = {}) ⇒ Array[Hash]
Condenses a collection of named Hashes into an Array-of-Hashes.
Accepts Hashes-of-Hashes -- where each key is the entry's :name and -- Arrays-of-Hashes -- where each Hash has a :name element -- returning both forms as an Array-of-Hashes with a guaranteed 'name' element. Any entry without a :name or 'name' generates an exception.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/rspec-puppet-yaml/data_helpers.rb', line 64 def self.get_array_of_named_hashes(key, data = {}) coerced_hashes = [] hashes = RSpec::Puppet::Yaml::DataHelpers.get_named_value( key, data, {} ) return coerced_hashes if hashes.empty? # Supported Cases: # 1. [{'this is a name' => {:key => val}}, {'this is also a name' => {:key => val}}] # 2. {'this is a name' => {:key => value}, 'this is also a name' => {:key => value}} # 3. [{:name => 'the name', :key => value}, {:name => 'another name', :key => value}] # 4. {:name => 'the name', :key => value} if hashes.kind_of?(Array) hashes.each { |hash| coerced_hashes << RSpec::Puppet::Yaml::DataHelpers .make_hash_name_explicit(hash) } elsif hashes.is_a?(Hash) # Supported Case 2 requires that each Hash attribute be a named Hash # when there is no explicit name attribute. if hashes.has_key?('name') || hashes.has_key?(:name) coerced_hashes << RSpec::Puppet::Yaml::DataHelpers .make_hash_name_explicit(hashes) else hashes.each do |k, v| if v.nil? coerced_hashes << { 'name' => k } elsif !v.is_a?(Hash) raise ArgumentError, "#{key} indicates a Hash but at least one of its attributes is neither a Hash nor nil." else coerced_hashes << v .select {|m, n| m != :name} .merge({'name' => k}) end end end else raise ArgumentError, "#{key} is for neither an Array nor a Hash value." end coerced_hashes end |
.get_named_hash(key, data = {}, default = {}) ⇒ Hash
Gets a named Hash child from a supplied Hash parent.
Attempts to get an immediate child Hash from a parent Hash that is named according to a given key. The key may be supplied in either String or Symbol form and both are searched for. When both forms exist in the parent Hash, a shallow merge is attempted, favoring the String form.
122 123 124 125 126 127 128 129 130 |
# File 'lib/rspec-puppet-yaml/data_helpers.rb', line 122 def self.get_named_hash(key, data = {}, default = {}) hash_value = RSpec::Puppet::Yaml::DataHelpers.get_named_value( key, data, default ) if !hash_value.is_a?(Hash) raise NameError, "The value of #{key} is not a Hash." end hash_value end |
.get_named_value(key, data = {}, default = nil) ⇒ Any
Gets a named value from a Hash by its String and Symbol names.
Searches a Hash for a key by both its String and Symbol names. When both are found, they are merged as long as their values are both Hash (shallow) or Array (unique). An exception is raised when the values are scalar or of different data types.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/rspec-puppet-yaml/data_helpers.rb', line 145 def self.get_named_value(key, data = {}, default = nil) return default unless !data.nil? && data.respond_to?(:has_key?) str_key = key.to_s sym_key = key.to_sym has_str_key = data.has_key?(str_key) has_sym_key = data.has_key?(sym_key) if has_str_key && has_sym_key str_value = data[str_key] sym_value = data[sym_key] if str_value.is_a?(Hash) && sym_value.is_a?(Hash) begin sym_value.merge(str_value) rescue raise NameError, "Both symbolic and string forms of '#{str_key}' Hash declarations exist but one cannot be merged into the other. Pick one form or the other or ensure both are Hashes that can be merged." end elsif str_value.kind_of?(Array) && sym_value.kind_of?(Array) str_value | sym_value else raise NameError, "Both symbolic and string forms of '#{str_key}' scalar declarations exist and they cannot be combined. Pick one form or the other." end elsif has_str_key data[str_key] elsif has_sym_key data[sym_key] else default end end |
.make_hash_name_explicit(transform_hash = {}) ⇒ Object
Takes a Hash, checks it for a name attribute, and ensures that name is a string-named, 'name', attribute. If the Hash has no identifyable name, an ArgumentError is raised.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/rspec-puppet-yaml/data_helpers.rb', line 19 def self.make_hash_name_explicit(transform_hash = {}) raise ArgumentError, "Cannot transform non-Hash data." unless transform_hash.is_a?(Hash) transformed_hash = {} hash_name = RSpec::Puppet::Yaml::DataHelpers.get_named_value( 'name', transform_hash ) if hash_name.nil? || hash_name.empty? # Could be an implicit name when { 'implicit' => { 'key' => 'val' } } if 1 == transform_hash.keys.count first_value = transform_hash.values[0] if !first_value.nil? && !first_value.is_a?(Hash) raise ArgumentError, "Cannot transform implicitly named Hash when its value is neither nil nor a Hash." else hash_name = transform_hash.keys.first hash_value = first_value ||= {} transformed_hash = hash_value .select {|k,v| k != :name} .merge({'name' => hash_name}) end else # No explicit or implicit name raise ArgumentError, "Hash has neither an explicit nor implicit name." end else transformed_hash = transform_hash .select {|k,v| k != :name} .merge({'name' => hash_name}) end transformed_hash end |