miasma 0.2.22 → 0.2.24
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/miasma.rb +2 -0
- data/lib/miasma/utils/animal_strings.rb +1 -19
- data/lib/miasma/utils/lazy.rb +1 -228
- data/lib/miasma/utils/memoization.rb +1 -48
- data/lib/miasma/utils/smash.rb +1 -147
- data/lib/miasma/version.rb +1 -1
- data/miasma.gemspec +2 -2
- metadata +15 -18
- data/test/spec.rb +0 -20
- data/test/specs/miasma_spec.rb +0 -33
- data/test/specs/models/compute_abstract.rb +0 -118
- data/test/specs/models/load_balancer_abstract.rb +0 -88
- data/test/specs/models/orchestration_abstract.rb +0 -123
- data/test/specs/models/storage_abstract.rb +0 -120
- data/test/specs/utils/animal_strings_spec.rb +0 -15
- data/test/specs/utils/memoization_spec.rb +0 -83
- data/test/specs/utils/smash_spec.rb +0 -107
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ad1bada860e09a472096990620ec270dbb3e61c
|
4
|
+
data.tar.gz: 4ff7b4e6f102527bada9c77eff33b04bf3926ebc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6d497bf68b667171a443bfab973856aa2fc9b87a48f13e8ab8ae9b26ca43e414f8aa07b5297e86a2060a96a381cba4a17ab398d61ac3e1de0caaced53bc3ea0
|
7
|
+
data.tar.gz: d90757a5e25193d975313e72226a0266e210aa615e20dc867a02b44c8d7c7e895bc6a25834f4898487b4e363f4908de7457d508388a5d9312640c14d59b43d3a
|
data/CHANGELOG.md
CHANGED
data/lib/miasma.rb
CHANGED
@@ -4,25 +4,7 @@ module Miasma
|
|
4
4
|
|
5
5
|
module Utils
|
6
6
|
# Animal stylings on strings
|
7
|
-
|
8
|
-
|
9
|
-
# Camel case string
|
10
|
-
# @param string [String]
|
11
|
-
# @return [String]
|
12
|
-
def camel(string)
|
13
|
-
string.to_s.split('_').map{|k| "#{k.slice(0,1).upcase}#{k.slice(1,k.length)}"}.join
|
14
|
-
end
|
15
|
-
|
16
|
-
# Snake case (underscore) string
|
17
|
-
#
|
18
|
-
# @param string [String]
|
19
|
-
# @return [String]
|
20
|
-
def snake(string)
|
21
|
-
string.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').gsub('-', '_').downcase
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
7
|
+
AnimalStrings = Bogo::AnimalStrings
|
26
8
|
extend AnimalStrings
|
27
9
|
end
|
28
10
|
|
data/lib/miasma/utils/lazy.rb
CHANGED
@@ -4,233 +4,6 @@ require 'digest/sha2'
|
|
4
4
|
module Miasma
|
5
5
|
module Utils
|
6
6
|
# Adds functionality to facilitate laziness
|
7
|
-
|
8
|
-
|
9
|
-
# Instance methods for laziness
|
10
|
-
module InstanceMethods
|
11
|
-
|
12
|
-
# @return [Smash] argument hash
|
13
|
-
def data
|
14
|
-
unless(@data)
|
15
|
-
@data = Smash.new
|
16
|
-
end
|
17
|
-
@data
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [Smash] updated data
|
21
|
-
def dirty
|
22
|
-
unless(@dirty)
|
23
|
-
@dirty = Smash.new
|
24
|
-
end
|
25
|
-
@dirty
|
26
|
-
end
|
27
|
-
|
28
|
-
# @return [Smash] current data state
|
29
|
-
def attributes
|
30
|
-
data.merge(dirty)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Create new instance
|
34
|
-
#
|
35
|
-
# @param args [Hash]
|
36
|
-
# @return [self]
|
37
|
-
def load_data(args={})
|
38
|
-
args = args.to_smash
|
39
|
-
@data = Smash.new
|
40
|
-
self.class.attributes.each do |name, options|
|
41
|
-
val = args[name]
|
42
|
-
if(options[:required] && !args.has_key?(name) && !options.has_key?(:default))
|
43
|
-
raise ArgumentError.new("Missing required option: `#{name}`")
|
44
|
-
end
|
45
|
-
if(val.nil? && !args.has_key?(name) && options[:default])
|
46
|
-
if(options[:default])
|
47
|
-
val = options[:default].respond_to?(:call) ? options[:default].call : options[:default]
|
48
|
-
end
|
49
|
-
end
|
50
|
-
if(args.has_key?(name) || val)
|
51
|
-
self.send("#{name}=", val)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
self
|
55
|
-
end
|
56
|
-
|
57
|
-
# Identifies valid state and automatically
|
58
|
-
# merges dirty attributes into data, clears
|
59
|
-
# dirty attributes
|
60
|
-
#
|
61
|
-
# @return [self]
|
62
|
-
def valid_state
|
63
|
-
data.merge!(dirty)
|
64
|
-
dirty.clear
|
65
|
-
@_checksum = Digest::SHA256.hexdigest(MultiJson.dump(data))
|
66
|
-
self
|
67
|
-
end
|
68
|
-
|
69
|
-
# Model is dirty or specific attribute is dirty
|
70
|
-
#
|
71
|
-
# @param attr [String, Symbol] name of attribute
|
72
|
-
# @return [TrueClass, FalseClass] model or attribute is dirty
|
73
|
-
def dirty?(attr=nil)
|
74
|
-
if(attr)
|
75
|
-
dirty.has_key?(attr)
|
76
|
-
else
|
77
|
-
if(@_checksum)
|
78
|
-
!dirty.empty? ||
|
79
|
-
@_checksum != Digest::SHA256.hexdigest(MultiJson.dump(data))
|
80
|
-
else
|
81
|
-
true
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# @return [String]
|
87
|
-
def to_s
|
88
|
-
"<#{self.class.name}:#{object_id}>"
|
89
|
-
end
|
90
|
-
|
91
|
-
# @return [String]
|
92
|
-
def inspect
|
93
|
-
"<#{self.class.name}:#{object_id} [#{data.inspect}]>"
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
# Class methods for laziness
|
99
|
-
module ClassMethods
|
100
|
-
|
101
|
-
# Add new attributes to class
|
102
|
-
#
|
103
|
-
# @param name [String]
|
104
|
-
# @param type [Class, Array<Class>]
|
105
|
-
# @param options [Hash]
|
106
|
-
# @option options [TrueClass, FalseClass] :required must be provided on initialization
|
107
|
-
# @option options [Object, Proc] :default default value
|
108
|
-
# @option options [Proc] :coerce
|
109
|
-
# @return [nil]
|
110
|
-
def attribute(name, type, options={})
|
111
|
-
name = name.to_sym
|
112
|
-
options = options.to_smash
|
113
|
-
attributes[name] = Smash.new(:type => type).merge(options)
|
114
|
-
coerce = attributes[name][:coerce]
|
115
|
-
valid_types = [attributes[name][:type], NilClass].flatten.compact
|
116
|
-
allowed_values = attributes[name][:allowed]
|
117
|
-
multiple_values = attributes[name][:multiple]
|
118
|
-
depends_on = attributes[name][:depends]
|
119
|
-
define_method(name) do
|
120
|
-
send(depends_on) if depends_on
|
121
|
-
self.class.on_missing(self) unless data.has_key?(name) || dirty.has_key?(name)
|
122
|
-
dirty[name] || data[name] || self.class.attributes[name][:default]
|
123
|
-
end
|
124
|
-
define_method("#{name}=") do |val|
|
125
|
-
values = multiple_values && val.is_a?(Array) ? val : [val]
|
126
|
-
values.map! do |item|
|
127
|
-
valid_type = valid_types.detect do |klass|
|
128
|
-
item.is_a?(klass)
|
129
|
-
end
|
130
|
-
if(coerce && !valid_type)
|
131
|
-
item = coerce.arity == 2 ? coerce.call(item, self) : coerce.call(item)
|
132
|
-
end
|
133
|
-
valid_type = valid_types.detect do |klass|
|
134
|
-
item.is_a?(klass)
|
135
|
-
end
|
136
|
-
unless(valid_type)
|
137
|
-
raise TypeError.new("Invalid type for `#{name}` (#{item} <#{item.class}>). Valid - #{valid_types.map(&:to_s).join(',')}")
|
138
|
-
end
|
139
|
-
if(allowed_values)
|
140
|
-
unless(allowed_values.include?(item))
|
141
|
-
raise ArgumentError.new("Invalid value provided for `#{name}` (#{item.inspect}). Allowed - #{allowed_values.map(&:inspect).join(', ')}")
|
142
|
-
end
|
143
|
-
end
|
144
|
-
item
|
145
|
-
end
|
146
|
-
if(!multiple_values && !val.is_a?(Array))
|
147
|
-
dirty[name] = values.first
|
148
|
-
else
|
149
|
-
dirty[name] = values
|
150
|
-
end
|
151
|
-
end
|
152
|
-
define_method("#{name}?") do
|
153
|
-
send(depends_on) if depends_on
|
154
|
-
self.class.on_missing(self) unless data.has_key?(name)
|
155
|
-
!!data[name]
|
156
|
-
end
|
157
|
-
nil
|
158
|
-
end
|
159
|
-
|
160
|
-
# Return attributes
|
161
|
-
#
|
162
|
-
# @param args [Symbol] :required or :optional
|
163
|
-
# @return [Array<Hash>]
|
164
|
-
def attributes(*args)
|
165
|
-
@attributes ||= Smash.new
|
166
|
-
if(args.include?(:required))
|
167
|
-
Smash[@attributes.find_all{|k,v| v[:required]}]
|
168
|
-
elsif(args.include?(:optional))
|
169
|
-
Smash[@attributes.find_all{|k,v| !v[:required]}]
|
170
|
-
else
|
171
|
-
@attributes
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
# Instance method to call on missing attribute or
|
176
|
-
# object to call method on if set
|
177
|
-
#
|
178
|
-
# @param param [Symbol, Object]
|
179
|
-
# @return [Symbol]
|
180
|
-
def on_missing(param=nil)
|
181
|
-
if(param)
|
182
|
-
if(param.is_a?(Symbol))
|
183
|
-
@missing_method = param
|
184
|
-
else
|
185
|
-
if(@missing_method && !@calling_on_missing)
|
186
|
-
@calling_on_missing = true
|
187
|
-
begin
|
188
|
-
param.send(@missing_method)
|
189
|
-
ensure
|
190
|
-
@calling_on_missing = false
|
191
|
-
end
|
192
|
-
end
|
193
|
-
@missing_method
|
194
|
-
end
|
195
|
-
else
|
196
|
-
@missing_method
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
# Directly set attribute hash
|
201
|
-
#
|
202
|
-
# @param attrs [Hash]
|
203
|
-
# @return [TrueClass]
|
204
|
-
# @todo need deep dup here
|
205
|
-
def set_attributes(attrs)
|
206
|
-
@attributes = attrs.to_smash
|
207
|
-
true
|
208
|
-
end
|
209
|
-
|
210
|
-
end
|
211
|
-
|
212
|
-
class << self
|
213
|
-
|
214
|
-
# Injects laziness into class
|
215
|
-
#
|
216
|
-
# @param klass [Class]
|
217
|
-
def included(klass)
|
218
|
-
klass.class_eval do
|
219
|
-
include InstanceMethods
|
220
|
-
extend ClassMethods
|
221
|
-
|
222
|
-
class << self
|
223
|
-
|
224
|
-
def inherited(klass)
|
225
|
-
klass.set_attributes(self.attributes.to_smash)
|
226
|
-
end
|
227
|
-
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
end
|
233
|
-
|
234
|
-
end
|
7
|
+
Lazy = Bogo::Lazy
|
235
8
|
end
|
236
9
|
end
|
@@ -3,53 +3,6 @@ require 'miasma'
|
|
3
3
|
module Miasma
|
4
4
|
module Utils
|
5
5
|
# Memoization helpers
|
6
|
-
|
7
|
-
|
8
|
-
# Memoize data
|
9
|
-
#
|
10
|
-
# @param key [String, Symbol] identifier for data
|
11
|
-
# @param direct [Truthy, Falsey] direct skips key prepend of object id
|
12
|
-
# @yield block to create data
|
13
|
-
# @yieldreturn data to memoize
|
14
|
-
# @return [Object] data
|
15
|
-
def memoize(key, direct=false)
|
16
|
-
unless(direct)
|
17
|
-
key = "#{self.object_id}_#{key}"
|
18
|
-
end
|
19
|
-
unless(_memo.has_key?(key))
|
20
|
-
_memo[key] = yield
|
21
|
-
end
|
22
|
-
_memo[key]
|
23
|
-
end
|
24
|
-
|
25
|
-
def _memo
|
26
|
-
Thread.current[:miasma_memoization] ||= Smash.new
|
27
|
-
end
|
28
|
-
|
29
|
-
# Remove memoized value
|
30
|
-
#
|
31
|
-
# @param key [String, Symbol] identifier for data
|
32
|
-
# @param direct [Truthy, Falsey] direct skips key prepend of object id
|
33
|
-
# @return [NilClass]
|
34
|
-
def unmemoize(key, direct=false)
|
35
|
-
unless(direct)
|
36
|
-
key = "#{self.object_id}_#{key}"
|
37
|
-
end
|
38
|
-
_memo.delete(key)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Remove all memoized values
|
42
|
-
#
|
43
|
-
# @return [TrueClass]
|
44
|
-
def clear_memoizations!
|
45
|
-
_memo.keys.find_all do |key|
|
46
|
-
key.to_s.start_with?("#{self.object_id}_")
|
47
|
-
end.each do |key|
|
48
|
-
_memo.delete(key)
|
49
|
-
end
|
50
|
-
true
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
6
|
+
Memoization = Bogo::Memoization
|
54
7
|
end
|
55
8
|
end
|
data/lib/miasma/utils/smash.rb
CHANGED
@@ -1,154 +1,8 @@
|
|
1
|
-
require 'hashie'
|
2
|
-
require 'digest/sha2'
|
3
1
|
require 'miasma'
|
4
2
|
|
5
3
|
module Miasma
|
6
4
|
module Utils
|
7
|
-
|
8
5
|
# Customized Hash
|
9
|
-
|
10
|
-
include Hashie::Extensions::IndifferentAccess
|
11
|
-
include Hashie::Extensions::MergeInitializer
|
12
|
-
include Hashie::Extensions::DeepMerge
|
13
|
-
include Hashie::Extensions::Coercion
|
14
|
-
|
15
|
-
coerce_value Hash, Smash
|
16
|
-
|
17
|
-
# Create new instance
|
18
|
-
#
|
19
|
-
# @param args [Object] argument list
|
20
|
-
def initialize(*args)
|
21
|
-
base = nil
|
22
|
-
if(args.first.is_a?(::Hash))
|
23
|
-
base = args.shift
|
24
|
-
end
|
25
|
-
super *args
|
26
|
-
if(base)
|
27
|
-
self.replace(base.to_smash)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def merge!(hash)
|
32
|
-
hash = hash.to_smash
|
33
|
-
super(hash)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Get value at given path
|
37
|
-
#
|
38
|
-
# @param args [String, Symbol] key path to walk
|
39
|
-
# @return [Object, NilClass]
|
40
|
-
def retrieve(*args)
|
41
|
-
args.inject(self) do |memo, key|
|
42
|
-
if(memo.is_a?(Hash))
|
43
|
-
memo.to_smash[key]
|
44
|
-
else
|
45
|
-
nil
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
alias_method :get, :retrieve
|
50
|
-
|
51
|
-
# Fetch value at given path or return a default value
|
52
|
-
#
|
53
|
-
# @param args [String, Symbol, Object] key path to walk. last value default to return
|
54
|
-
# @return [Object] value at key or default value
|
55
|
-
def fetch(*args)
|
56
|
-
default_value = args.pop
|
57
|
-
retrieve(*args) || default_value
|
58
|
-
end
|
59
|
-
|
60
|
-
# Set value at given path
|
61
|
-
#
|
62
|
-
# @param args [String, Symbol, Object] key path to walk. set last value to given path
|
63
|
-
# @return [Object] value set
|
64
|
-
def set(*args)
|
65
|
-
unless(args.size > 1)
|
66
|
-
raise ArgumentError.new 'Set requires at least one key and a value'
|
67
|
-
end
|
68
|
-
value = args.pop
|
69
|
-
set_key = args.pop
|
70
|
-
leaf = args.inject(self) do |memo, key|
|
71
|
-
unless(memo[key].is_a?(Hash))
|
72
|
-
memo[key] = Smash.new
|
73
|
-
end
|
74
|
-
memo[key]
|
75
|
-
end
|
76
|
-
leaf[set_key] = value
|
77
|
-
value
|
78
|
-
end
|
79
|
-
|
80
|
-
# Convert to Hash
|
81
|
-
#
|
82
|
-
# @return [Hash]
|
83
|
-
def to_hash(*args)
|
84
|
-
self.to_type_converter(::Hash, :to_hash, *args)
|
85
|
-
end
|
86
|
-
|
87
|
-
# Calculate checksum of hash (sha256)
|
88
|
-
#
|
89
|
-
# @return [String] checksum
|
90
|
-
def checksum
|
91
|
-
Digest::SHA256.hexdigest(self.to_smash(:sorted).to_s)
|
92
|
-
end
|
93
|
-
|
94
|
-
end
|
6
|
+
Smash = Bogo::Smash
|
95
7
|
end
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
# Hook helper into toplevel `Hash`
|
100
|
-
class Hash
|
101
|
-
|
102
|
-
# Convert to Smash
|
103
|
-
#
|
104
|
-
# @return [Smash]
|
105
|
-
def to_smash(*args)
|
106
|
-
self.to_type_converter(::Smash, :to_smash, *args)
|
107
|
-
end
|
108
|
-
alias_method :hulk_smash, :to_smash
|
109
|
-
|
110
|
-
protected
|
111
|
-
|
112
|
-
# Convert to type
|
113
|
-
#
|
114
|
-
# @param type [Class] hash type
|
115
|
-
# @param convert_call [Symbol] builtin hash convert
|
116
|
-
# @return [Smash]
|
117
|
-
def to_type_converter(type, convert_call, *args)
|
118
|
-
type.new.tap do |smash|
|
119
|
-
if(args.include?(:sorted))
|
120
|
-
process = self.sort_by do |entry|
|
121
|
-
entry.first.to_s
|
122
|
-
end
|
123
|
-
else
|
124
|
-
process = self
|
125
|
-
end
|
126
|
-
process.each do |k,v|
|
127
|
-
smash[k.is_a?(Symbol) ? k.to_s : k] = smash_conversion(v, convert_call, *args)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
# Convert object to smash if applicable
|
133
|
-
#
|
134
|
-
# @param obj [Object]
|
135
|
-
# @param convert_call [Symbol] builtin hash convert
|
136
|
-
# @return [Smash, Object]
|
137
|
-
def smash_conversion(obj, convert_call, *args)
|
138
|
-
case obj
|
139
|
-
when Hash
|
140
|
-
obj.send(convert_call, *args)
|
141
|
-
when Array
|
142
|
-
obj.map do |i|
|
143
|
-
smash_conversion(i, convert_call, *args)
|
144
|
-
end
|
145
|
-
else
|
146
|
-
obj
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
end
|
151
|
-
|
152
|
-
unless(defined?(Smash))
|
153
|
-
Smash = Miasma::Utils::Smash
|
154
8
|
end
|
data/lib/miasma/version.rb
CHANGED
data/miasma.gemspec
CHANGED
@@ -10,11 +10,11 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.description = 'Smoggy API'
|
11
11
|
s.license = 'Apache 2.0'
|
12
12
|
s.require_path = 'lib'
|
13
|
-
s.add_runtime_dependency 'hashie'
|
14
13
|
s.add_runtime_dependency 'http'
|
15
14
|
s.add_runtime_dependency 'multi_json'
|
16
15
|
s.add_runtime_dependency 'multi_xml'
|
17
16
|
s.add_runtime_dependency 'xml-simple'
|
17
|
+
s.add_runtime_dependency 'bogo', '>= 0.1.20', '< 1.0'
|
18
18
|
# Include provider libs that do not have outside deps
|
19
19
|
s.add_runtime_dependency 'miasma-aws'
|
20
20
|
s.add_runtime_dependency 'miasma-open-stack'
|
@@ -25,5 +25,5 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.add_development_dependency 'minitest'
|
26
26
|
s.add_development_dependency 'vcr'
|
27
27
|
s.add_development_dependency 'webmock'
|
28
|
-
s.files = Dir['{bin,lib
|
28
|
+
s.files = Dir['{bin,lib}/**/*'] + %w(miasma.gemspec README.md CHANGELOG.md LICENSE)
|
29
29
|
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miasma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.24
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: http
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: multi_json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: multi_xml
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: xml-simple
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,19 +67,25 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: bogo
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 0.1.20
|
76
|
+
- - "<"
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '1.0'
|
76
79
|
type: :runtime
|
77
80
|
prerelease: false
|
78
81
|
version_requirements: !ruby/object:Gem::Requirement
|
79
82
|
requirements:
|
80
83
|
- - ">="
|
81
84
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
85
|
+
version: 0.1.20
|
86
|
+
- - "<"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.0'
|
83
89
|
- !ruby/object:Gem::Dependency
|
84
90
|
name: miasma-aws
|
85
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -231,15 +237,6 @@ files:
|
|
231
237
|
- lib/miasma/utils/smash.rb
|
232
238
|
- lib/miasma/version.rb
|
233
239
|
- miasma.gemspec
|
234
|
-
- test/spec.rb
|
235
|
-
- test/specs/miasma_spec.rb
|
236
|
-
- test/specs/models/compute_abstract.rb
|
237
|
-
- test/specs/models/load_balancer_abstract.rb
|
238
|
-
- test/specs/models/orchestration_abstract.rb
|
239
|
-
- test/specs/models/storage_abstract.rb
|
240
|
-
- test/specs/utils/animal_strings_spec.rb
|
241
|
-
- test/specs/utils/memoization_spec.rb
|
242
|
-
- test/specs/utils/smash_spec.rb
|
243
240
|
homepage: https://github.com/miasma-rb/miasma
|
244
241
|
licenses:
|
245
242
|
- Apache 2.0
|
data/test/spec.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'vcr'
|
2
|
-
require 'webmock/minitest'
|
3
|
-
require 'minitest/autorun'
|
4
|
-
|
5
|
-
require 'miasma'
|
6
|
-
|
7
|
-
spec_dir = File.join(File.dirname(__FILE__), 'specs')
|
8
|
-
|
9
|
-
Dir.glob(File.join(spec_dir, 'models', '*.rb')).each do |path|
|
10
|
-
require File.expand_path(path)
|
11
|
-
end
|
12
|
-
|
13
|
-
Dir.glob(File.join(spec_dir, '**/**/*_spec.rb')).each do |path|
|
14
|
-
require File.expand_path(path)
|
15
|
-
end
|
16
|
-
|
17
|
-
VCR.configure do |c|
|
18
|
-
c.cassette_library_dir = File.join(spec_dir, 'cassettes')
|
19
|
-
c.hook_into :webmock
|
20
|
-
end
|
data/test/specs/miasma_spec.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
describe Miasma do
|
2
|
-
it 'should provide an #api entry method' do
|
3
|
-
Miasma.respond_to?(:api).must_equal true
|
4
|
-
end
|
5
|
-
|
6
|
-
describe 'Miasma.api' do
|
7
|
-
|
8
|
-
it 'should require `:type` argument' do
|
9
|
-
lambda do
|
10
|
-
Miasma.api(:provider => '', :credentials => {})
|
11
|
-
end.must_raise ArgumentError
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'should require `:provider` argument' do
|
15
|
-
lambda do
|
16
|
-
Miasma.api(:type => '', :credentials => {})
|
17
|
-
end.must_raise ArgumentError
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should require `:credentials` argument' do
|
21
|
-
lambda do
|
22
|
-
Miasma.api(:provider => '', :type => '')
|
23
|
-
end.must_raise ArgumentError
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'should fail to load unknown provider' do
|
27
|
-
lambda do
|
28
|
-
Miasma.api(:provider => :unknown, :type => :compute, :credentials => {})
|
29
|
-
end.must_raise Miasma::Error
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
@@ -1,118 +0,0 @@
|
|
1
|
-
MIASMA_COMPUTE_ABSTRACT = ->{
|
2
|
-
|
3
|
-
# Required `let`s:
|
4
|
-
# * compute: compute API
|
5
|
-
# * build_args: server build arguments [Smash]
|
6
|
-
# * cassette_prefix: cassette file prefix [String]
|
7
|
-
|
8
|
-
describe Miasma::Models::Compute do
|
9
|
-
|
10
|
-
it 'should provide #servers collection' do
|
11
|
-
compute.servers.must_be_kind_of Miasma::Models::Compute::Servers
|
12
|
-
end
|
13
|
-
|
14
|
-
describe Miasma::Models::Compute::Servers do
|
15
|
-
|
16
|
-
it 'should provide instance class used within collection' do
|
17
|
-
compute.servers.model.must_equal Miasma::Models::Compute::Server
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should build new instance for collection' do
|
21
|
-
instance = compute.servers.build(:name => 'test')
|
22
|
-
instance.must_be_kind_of Miasma::Models::Compute::Server
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should provide #all servers' do
|
26
|
-
VCR.use_cassette("#{cassette_prefix}_servers_all") do
|
27
|
-
compute.servers.all.must_be_kind_of Array
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
describe Miasma::Models::Compute::Server do
|
34
|
-
|
35
|
-
before do
|
36
|
-
@instance = compute.servers.build(build_args)
|
37
|
-
VCR.use_cassette("#{cassette_prefix}_server_before_create") do |obj|
|
38
|
-
@instance.save
|
39
|
-
until(@instance.state == :running)
|
40
|
-
sleep(obj.recording? ? 60 : 0.01)
|
41
|
-
@instance.reload
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
after do
|
47
|
-
VCR.use_cassette("#{cassette_prefix}_server_after_destroy") do
|
48
|
-
@instance.destroy
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
let(:instance){ @instance }
|
53
|
-
|
54
|
-
describe 'instance methods' do
|
55
|
-
|
56
|
-
it 'should have a name' do
|
57
|
-
instance.name.must_equal build_args[:name]
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'should have an image_id' do
|
61
|
-
instance.image_id.must_equal build_args[:image_id]
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'should have a flavor_id' do
|
65
|
-
instance.flavor_id.must_equal build_args[:flavor_id]
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'should have an address' do
|
69
|
-
instance.addresses.detect do |addr|
|
70
|
-
addr.version == 4
|
71
|
-
end.address.must_match /^(\d+)+\.(\d+)\.(\d+)\.(\d+)$/
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'should have a status' do
|
75
|
-
instance.status.wont_be_nil
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'should be in :running state' do
|
79
|
-
instance.state.must_equal :running
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
describe 'instance lifecycle' do
|
87
|
-
it 'should create new server, reload details and destroy server' do
|
88
|
-
VCR.use_cassette("#{cassette_prefix}_servers_create") do |obj|
|
89
|
-
instance = compute.servers.build(build_args)
|
90
|
-
instance.save
|
91
|
-
instance.id.wont_be_nil
|
92
|
-
instance.state.must_equal :pending
|
93
|
-
compute.servers.reload.get(instance.id).wont_be_nil
|
94
|
-
until(instance.state == :running)
|
95
|
-
sleep(obj.recording? ? 60 : 0.01)
|
96
|
-
instance.reload
|
97
|
-
end
|
98
|
-
instance.state.must_equal :running
|
99
|
-
instance.destroy
|
100
|
-
while(instance.state == :running)
|
101
|
-
sleep(obj.recording? ? 10 : 0.01)
|
102
|
-
instance.reload
|
103
|
-
end
|
104
|
-
[:pending, :terminated].must_include instance.state
|
105
|
-
if(instance.state == :pending)
|
106
|
-
until(instance.state == :terminated)
|
107
|
-
sleep(obj.recording? ? 60 : 0.01)
|
108
|
-
instance.reload
|
109
|
-
end
|
110
|
-
instance.state.must_equal :terminated
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
|
-
}
|
@@ -1,88 +0,0 @@
|
|
1
|
-
MIASMA_LOAD_BALANCER_ABSTRACT = ->{
|
2
|
-
|
3
|
-
# Required `let`s:
|
4
|
-
# * load_balancer: load balancer API
|
5
|
-
# * build_args: load balancer build arguments [Smash]
|
6
|
-
# * cassette_prefix: cassette file prefix [String]
|
7
|
-
|
8
|
-
describe Miasma::Models::LoadBalancer do
|
9
|
-
|
10
|
-
it 'should provide #balancers collection' do
|
11
|
-
load_balancer.balancers.must_be_kind_of Miasma::Models::LoadBalancer::Balancers
|
12
|
-
end
|
13
|
-
|
14
|
-
describe Miasma::Models::LoadBalancer::Balancers do
|
15
|
-
|
16
|
-
it 'should provide instance class used within collection' do
|
17
|
-
load_balancer.balancers.model.must_equal Miasma::Models::LoadBalancer::Balancer
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should build new instance for collection' do
|
21
|
-
instance = load_balancer.balancers.build
|
22
|
-
instance.must_be_kind_of Miasma::Models::LoadBalancer::Balancer
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should provide #all balancers' do
|
26
|
-
VCR.use_cassette("#{cassette_prefix}_balancers_all") do
|
27
|
-
load_balancer.balancers.all.must_be_kind_of Array
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
describe Miasma::Models::LoadBalancer::Balancer do
|
34
|
-
|
35
|
-
before do
|
36
|
-
@balancer = load_balancer.balancers.build(build_args)
|
37
|
-
VCR.use_cassette("#{cassette_prefix}_balancer_before_create") do |obj|
|
38
|
-
@balancer.save
|
39
|
-
until(@balancer.state == :active)
|
40
|
-
sleep(obj.recording? ? 60 : 0.01)
|
41
|
-
@balancer.reload
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
after do
|
47
|
-
VCR.use_cassette("#{cassette_prefix}_balancer_after_destroy") do
|
48
|
-
@balancer.destroy
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
let(:balancer){ @balancer }
|
53
|
-
|
54
|
-
describe 'collection' do
|
55
|
-
|
56
|
-
it 'should include balancer' do
|
57
|
-
VCR.use_cassette("#{cassette_prefix}_balancer_direct_fetch") do
|
58
|
-
load_balancer.balancers.reload.get(balancer.id).wont_be_nil
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
describe 'balancer methods' do
|
65
|
-
|
66
|
-
it 'should have a name' do
|
67
|
-
balancer.name.must_equal build_args[:name]
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'should be in :active state' do
|
71
|
-
balancer.state.must_equal :active
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'should have a status' do
|
75
|
-
balancer.status.wont_be_nil
|
76
|
-
balancer.status.must_be_kind_of String
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'should have a public address' do
|
80
|
-
balancer.public_addresses.wont_be :empty?
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
}
|
@@ -1,123 +0,0 @@
|
|
1
|
-
MIASMA_ORCHESTRATION_ABSTRACT = ->{
|
2
|
-
|
3
|
-
# Required `let`s:
|
4
|
-
# * orchestration: orchestration API
|
5
|
-
# * build_args: stack build arguments [Smash]
|
6
|
-
# * cassette_prefix: cassette file prefix [String]
|
7
|
-
|
8
|
-
describe Miasma::Models::Orchestration do
|
9
|
-
|
10
|
-
it 'should provide #stacks collection' do
|
11
|
-
orchestration.stacks.must_be_kind_of Miasma::Models::Orchestration::Stacks
|
12
|
-
end
|
13
|
-
|
14
|
-
describe Miasma::Models::Orchestration::Stacks do
|
15
|
-
|
16
|
-
it 'should provide instance class used within collection' do
|
17
|
-
orchestration.stacks.model.must_equal Miasma::Models::Orchestration::Stack
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should build new instance for collection' do
|
21
|
-
instance = orchestration.stacks.build
|
22
|
-
instance.must_be_kind_of Miasma::Models::Orchestration::Stack
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should provide #all stacks' do
|
26
|
-
VCR.use_cassette("#{cassette_prefix}_stacks_all") do
|
27
|
-
orchestration.stacks.all.must_be_kind_of Array
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
describe Miasma::Models::Orchestration::Stacks do
|
34
|
-
|
35
|
-
before do
|
36
|
-
@stack = orchestration.stacks.build(build_args)
|
37
|
-
VCR.use_cassette("#{cassette_prefix}_stacks_before_create") do |obj|
|
38
|
-
@stack.save
|
39
|
-
until(@stack.state == :create_complete)
|
40
|
-
sleep(obj.recording? ? 60 : 0.01)
|
41
|
-
@stack.reload
|
42
|
-
end
|
43
|
-
@stack.template
|
44
|
-
orchestration.stacks.reload
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
after do
|
49
|
-
VCR.use_cassette("#{cassette_prefix}_stacks_after_destroy") do
|
50
|
-
@stack.destroy
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
let(:stack){ @stack }
|
55
|
-
|
56
|
-
describe 'collection' do
|
57
|
-
|
58
|
-
it 'should include stack' do
|
59
|
-
VCR.use_cassette("#{cassette_prefix}_stacks_direct_fetch") do
|
60
|
-
orchestration.stacks.all.detect{|s| s.id == stack.id}.wont_be_nil
|
61
|
-
orchestration.stacks.get(stack.id).wont_be_nil
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
describe 'instance methods' do
|
68
|
-
|
69
|
-
it 'should have a name' do
|
70
|
-
stack.name.must_equal build_args[:name]
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should be in :create_complete state' do
|
74
|
-
stack.state.must_equal :create_complete
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'should have a status' do
|
78
|
-
stack.status.must_be_kind_of String
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'should have a creation time' do
|
82
|
-
stack.created.must_be_kind_of Time
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'should have parameters used for creation' do
|
86
|
-
stack.parameters.to_smash.must_equal build_args[:parameters].to_smash
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'should include the templated used for creation' do
|
90
|
-
stack.template.to_smash.must_equal build_args[:template].to_smash
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
|
97
|
-
describe 'instance lifecycle' do
|
98
|
-
it 'should create new stack, reload details and destroy stack' do
|
99
|
-
VCR.use_cassette("#{cassette_prefix}_stack_create") do |obj|
|
100
|
-
stack = orchestration.stacks.build(build_args.merge(:name => 'miasma-test-stack-2'))
|
101
|
-
stack.save
|
102
|
-
stack.id.wont_be_nil
|
103
|
-
stack.state.must_equal :create_in_progress
|
104
|
-
orchestration.stacks.reload.get(stack.id).wont_be_nil
|
105
|
-
until(stack.state == :create_complete)
|
106
|
-
sleep(obj.recording? ? 60 : 0.01)
|
107
|
-
stack.reload
|
108
|
-
end
|
109
|
-
stack.state.must_equal :create_complete
|
110
|
-
stack.destroy
|
111
|
-
[:delete_in_progress, :delete_complete].must_include stack.state
|
112
|
-
until(stack.state == :delete_complete)
|
113
|
-
sleep(obj.recording? ? 60 : 0.01)
|
114
|
-
stack.reload
|
115
|
-
end
|
116
|
-
stack.state.must_equal :delete_complete
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
123
|
-
}
|
@@ -1,120 +0,0 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
|
3
|
-
MIASMA_STORAGE_ABSTRACT = ->{
|
4
|
-
|
5
|
-
# Required `let`s:
|
6
|
-
# * storage: storage API
|
7
|
-
# * cassette_prefix: cassette file prefix [String]
|
8
|
-
|
9
|
-
describe Miasma::Models::Storage do
|
10
|
-
|
11
|
-
it 'should provide #buckets collection' do
|
12
|
-
storage.buckets.must_be_kind_of Miasma::Models::Storage::Buckets
|
13
|
-
end
|
14
|
-
|
15
|
-
describe Miasma::Models::Storage::Buckets do
|
16
|
-
|
17
|
-
it 'should provide instance class used within collection' do
|
18
|
-
storage.buckets.model.must_equal Miasma::Models::Storage::Bucket
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'should build new instance for collection' do
|
22
|
-
storage.buckets.build.must_be_kind_of Miasma::Models::Storage::Bucket
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should provide #all buckets' do
|
26
|
-
VCR.use_cassette("#{cassette_prefix}_buckets_all") do
|
27
|
-
storage.buckets.all.must_be_kind_of Array
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
describe Miasma::Models::Storage::Bucket do
|
34
|
-
|
35
|
-
it 'should act like a bucket' do
|
36
|
-
bucket = storage.buckets.build(:name => 'miasma-test-bucket-010')
|
37
|
-
VCR.use_cassette("#{cassette_prefix}_storage_bucket") do |obj|
|
38
|
-
bucket.save
|
39
|
-
bucket.reload
|
40
|
-
|
41
|
-
# should include the bucket
|
42
|
-
storage.buckets.reload.get('miasma-test-bucket-010').wont_be_nil
|
43
|
-
# should have a name
|
44
|
-
bucket.name.must_equal 'miasma-test-bucket-010'
|
45
|
-
# should have a #files collection
|
46
|
-
bucket.files.must_be_kind_of Miasma::Models::Storage::Files
|
47
|
-
#should provide #all files
|
48
|
-
bucket.files.all.must_be_kind_of Array
|
49
|
-
# should include reference to containing bucket
|
50
|
-
bucket.files.bucket.must_equal bucket
|
51
|
-
# should build new instance for collection
|
52
|
-
bucket.files.build.must_be_kind_of Miasma::Models::Storage::File
|
53
|
-
|
54
|
-
file_content = 'blahblahblah'
|
55
|
-
file = bucket.files.build
|
56
|
-
file.name = 'miasma-test-file'
|
57
|
-
file.body = file_content
|
58
|
-
file.save
|
59
|
-
file.reload
|
60
|
-
|
61
|
-
# should have a name
|
62
|
-
file.name.must_equal 'miasma-test-file'
|
63
|
-
# should have a size
|
64
|
-
file.size.must_equal file_content.size
|
65
|
-
# should have an updated timestamp
|
66
|
-
file.updated.must_be_kind_of Time
|
67
|
-
# should create a valid url
|
68
|
-
open(file.url).read.must_equal file_content
|
69
|
-
# should have a body
|
70
|
-
file.body.must_respond_to :readpartial
|
71
|
-
file.body.readpartial(Miasma::Models::Storage::READ_BODY_CHUNK_SIZE).must_equal file_content
|
72
|
-
file.destroy
|
73
|
-
|
74
|
-
big_file_content = '*' * Miasma::Models::Storage::MAX_BODY_SIZE_FOR_STRINGIFY
|
75
|
-
big_file = bucket.files.build
|
76
|
-
big_file.name = 'miasma-test-file-big'
|
77
|
-
big_file.body = big_file_content
|
78
|
-
big_file.save
|
79
|
-
big_file.reload
|
80
|
-
|
81
|
-
# should be the correct size
|
82
|
-
big_file.size.must_equal big_file.size
|
83
|
-
# should provide streaming body
|
84
|
-
big_file.body.must_respond_to :readpartial
|
85
|
-
content = big_file.body.readpartial(big_file.size)
|
86
|
-
content.must_equal big_file_content
|
87
|
-
big_file.destroy
|
88
|
-
|
89
|
-
require 'tempfile'
|
90
|
-
local_io_file = Tempfile.new('miasma-storage-test')
|
91
|
-
big_io_content = '*' * (Miasma::Models::Storage::MAX_BODY_SIZE_FOR_STRINGIFY * 2)
|
92
|
-
local_io_file.write big_io_content
|
93
|
-
local_io_file.flush
|
94
|
-
local_io_file.rewind
|
95
|
-
remote_file = bucket.files.build
|
96
|
-
remote_file.name = 'miasma-test-io-object-010'
|
97
|
-
remote_file.body = local_io_file
|
98
|
-
remote_file.save
|
99
|
-
remote_file.reload
|
100
|
-
|
101
|
-
# should be the correct size
|
102
|
-
remote_file.size.must_equal local_io_file.size
|
103
|
-
# should provide streaming body
|
104
|
-
remote_file.body.must_respond_to :readpartial
|
105
|
-
content = ''
|
106
|
-
while(chunk = remote_file.body.readpartial(1024))
|
107
|
-
content << chunk
|
108
|
-
end
|
109
|
-
content.must_equal big_io_content
|
110
|
-
remote_file.destroy
|
111
|
-
bucket.destroy
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
}
|
@@ -1,15 +0,0 @@
|
|
1
|
-
describe Miasma::Utils::AnimalStrings do
|
2
|
-
|
3
|
-
it 'should camel case strings' do
|
4
|
-
Miasma::Utils.camel('fubar_foobar_fuobar').must_equal 'FubarFoobarFuobar'
|
5
|
-
end
|
6
|
-
|
7
|
-
it 'should camel case symbols' do
|
8
|
-
Miasma::Utils.camel(:fubar_foobar_fuobar).must_equal 'FubarFoobarFuobar'
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'should snake case strings' do
|
12
|
-
Miasma::Utils.snake('FubarFoobarFuobar').must_equal 'fubar_foobar_fuobar'
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
describe Miasma::Utils::Memoization do
|
2
|
-
|
3
|
-
before do
|
4
|
-
@memo = Object.new
|
5
|
-
@memo.extend Miasma::Utils::Memoization
|
6
|
-
end
|
7
|
-
|
8
|
-
after do
|
9
|
-
Thread.current[:miasma_memoization] = nil
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:memo){ @memo }
|
13
|
-
|
14
|
-
it 'should #memoize the value returned by block' do
|
15
|
-
value = Kernel.rand
|
16
|
-
memo.memoize(:test) do
|
17
|
-
value
|
18
|
-
end.must_equal value
|
19
|
-
memo.memoize(:test){ Kernel.rand }.must_equal value
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should not return #memoize value from other instance' do
|
23
|
-
memo2 = Object.new
|
24
|
-
memo2.extend Miasma::Utils::Memoization
|
25
|
-
value = Kernel.rand
|
26
|
-
memo.memoize(:test) do
|
27
|
-
value
|
28
|
-
end.must_equal value
|
29
|
-
memo.memoize(:test){ Kernel.rand }.must_equal value
|
30
|
-
memo2.memoize(:test){ Kernel.rand }.wont_equal value
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should #unmemoize a memoized value' do
|
34
|
-
value = Kernel.rand
|
35
|
-
value2 = Kernel.rand
|
36
|
-
memo.memoize(:test) do
|
37
|
-
value
|
38
|
-
end.must_equal value
|
39
|
-
memo.unmemoize(:test)
|
40
|
-
memo.memoize(:test) do
|
41
|
-
value2
|
42
|
-
end.must_equal value2
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'should allow direct #memoize not restricted to object' do
|
46
|
-
memo2 = Object.new
|
47
|
-
memo2.extend Miasma::Utils::Memoization
|
48
|
-
value = Kernel.rand
|
49
|
-
memo.memoize(:test, true) do
|
50
|
-
value
|
51
|
-
end.must_equal value
|
52
|
-
memo.memoize(:test, true){ Kernel.rand }.must_equal value
|
53
|
-
memo2.memoize(:test, true){ Kernal.rand }.must_equal value
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'should clear all non-direct memoizations with #clear_memoizations!' do
|
57
|
-
memo2 = Object.new
|
58
|
-
memo2.extend Miasma::Utils::Memoization
|
59
|
-
value = Kernel.rand
|
60
|
-
memo.memoize(:test, true) do
|
61
|
-
value
|
62
|
-
end.must_equal value
|
63
|
-
memo.memoize(:test){ value }.must_equal value
|
64
|
-
memo2.memoize(:test){ value }.must_equal value
|
65
|
-
|
66
|
-
memo.memoize(:test, true){ Kernel.rand }.must_equal value
|
67
|
-
memo2.memoize(:test, true){ Kernel.rand }.must_equal value
|
68
|
-
memo.memoize(:test){ Kernel.rand }.must_equal value
|
69
|
-
memo2.memoize(:test){ Kernel.rand }.must_equal value
|
70
|
-
|
71
|
-
memo.clear_memoizations!
|
72
|
-
memo.memoize(:test){ Kernel.rand }.wont_equal value
|
73
|
-
memo2.memoize(:test){ Kernel.rand }.must_equal value
|
74
|
-
|
75
|
-
memo2.clear_memoizations!
|
76
|
-
memo.memoize(:test){ Kernel.rand }.wont_equal value
|
77
|
-
memo2.memoize(:test){ Kernel.rand }.wont_equal value
|
78
|
-
|
79
|
-
memo.memoize(:test, true){ Kernel.rand }.must_equal value
|
80
|
-
memo2.memoize(:test, true){ Kernel.rand }.must_equal value
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
@@ -1,107 +0,0 @@
|
|
1
|
-
describe Miasma::Utils::Smash do
|
2
|
-
|
3
|
-
it 'should provide top level constant' do
|
4
|
-
defined?(::Smash).wont_be_nil
|
5
|
-
end
|
6
|
-
|
7
|
-
it 'should provide #to_smash on Hash' do
|
8
|
-
Hash.instance_methods.must_include :to_smash
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'should convert Hash to Smash' do
|
12
|
-
{:a => 1}.to_smash.must_equal Smash.new(:a => 1)
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should sort keys when converting' do
|
16
|
-
hash = {:z => 1, :d => 3, :m => 1}
|
17
|
-
smash = Smash.new(:d => 3, :m => 1, :z => 1)
|
18
|
-
hash.to_smash.must_equal smash
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'should convert deep nested Hashes to Smashes' do
|
22
|
-
hash = {
|
23
|
-
:a => 1,
|
24
|
-
:b => [
|
25
|
-
{:c => 2},
|
26
|
-
{:d => 3}
|
27
|
-
]
|
28
|
-
}
|
29
|
-
smash = Smash.new(
|
30
|
-
:a => 1,
|
31
|
-
:b => [
|
32
|
-
Smash.new(:c => 2),
|
33
|
-
Smash.new(:d => 3)
|
34
|
-
]
|
35
|
-
)
|
36
|
-
hash.to_smash.must_equal smash
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'should #get deeply nested value' do
|
40
|
-
smash = {
|
41
|
-
:a => {
|
42
|
-
:b => {
|
43
|
-
:c => {
|
44
|
-
:d => 1
|
45
|
-
}
|
46
|
-
}
|
47
|
-
}
|
48
|
-
}.to_smash
|
49
|
-
smash.get(:a, :b, :c, :d).must_equal 1
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'should #get nil on missing deeply nested value' do
|
53
|
-
smash = {
|
54
|
-
:a => {
|
55
|
-
:b => {
|
56
|
-
:c => {
|
57
|
-
:d => 1
|
58
|
-
}
|
59
|
-
}
|
60
|
-
}
|
61
|
-
}.to_smash
|
62
|
-
smash.get(:a, :b, :c, :x).must_be_nil
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'should #set deeply nested value' do
|
66
|
-
smash = Smash.new
|
67
|
-
smash.set(:a, :b, :c, 1)
|
68
|
-
smash.get(:a, :b, :c).must_equal 1
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'should #fetch default value on missing' do
|
72
|
-
smash = {
|
73
|
-
:a => {
|
74
|
-
:b => {
|
75
|
-
:c => {
|
76
|
-
:d => 1
|
77
|
-
}
|
78
|
-
}
|
79
|
-
}
|
80
|
-
}.to_smash
|
81
|
-
smash.fetch(:a, :b, :c, :x, 1).must_equal 1
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'should #fetch value when availble' do
|
85
|
-
smash = {
|
86
|
-
:a => {
|
87
|
-
:b => {
|
88
|
-
:c => {
|
89
|
-
:d => 1
|
90
|
-
}
|
91
|
-
}
|
92
|
-
}
|
93
|
-
}.to_smash
|
94
|
-
smash.fetch(:a, :b, :c, :d, 0).must_equal 1
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'should generate a #checksum' do
|
98
|
-
Smash.new(:a => 1).checksum.must_be_kind_of String
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'should generate equal #checksum' do
|
102
|
-
hash = {:z => 1, :d => 3}
|
103
|
-
smash = Smash.new(:d => 3, :z => 1)
|
104
|
-
hash.to_smash.checksum.must_equal smash.checksum
|
105
|
-
end
|
106
|
-
|
107
|
-
end
|