bodhi-slam 0.1.0 → 0.2.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: 9ca91de0d49a0aa3ff8e084024cdc6114444814e
4
- data.tar.gz: a7d550040d2b4e705ab10c7a0a6a8929aff7b967
3
+ metadata.gz: bb30e21e9283a1c741cb4fb387a671f7f274e0f5
4
+ data.tar.gz: 56da1e71e1010ec141edb8b7583c0cdde33da72d
5
5
  SHA512:
6
- metadata.gz: 8e9231701b099974ee34f0708740e3882743677861153b82a0c996e218b9be6b66fbb638248af82a204abc1b2ffd7bbaa1a8b7055c78b62dc208203f2d8fe058
7
- data.tar.gz: a4cc9b671833cf91bb0524d5bc4bd608a33d276f8f7aaa5e93eb00c86f853595675bfd366380704bb59f80a195829358458e7e9a482924d1aed6c7d6fc7be420
6
+ metadata.gz: adccca58ce46682c5efe48312bcee45f5c94312f10e0b46ea692dbb62df89e11e26f66134f56ab60a41e4413bcdca9f56aad9ab5253c74088d849432294c9492
7
+ data.tar.gz: e7c7b9b8fe73e71a1b18916cd59764b66be0944d705265e4b61acc5a589f1565b97fa677e4455849435e29071c44cc29e28854a064d784e0d89be1d820af68c0
data/lib/bodhi-slam.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require "faraday"
2
2
  require 'net/http/persistent'
3
- require "factory_girl"
4
3
  require "json"
5
4
  require "time"
6
5
 
@@ -10,6 +9,7 @@ require 'bodhi-slam/resource'
10
9
  require 'bodhi-slam/types'
11
10
  require 'bodhi-slam/validations'
12
11
  require 'bodhi-slam/enumerations'
12
+ require 'bodhi-slam/factory'
13
13
 
14
14
  class BodhiSlam
15
15
  def self.context(params, &block)
@@ -23,16 +23,9 @@ class BodhiSlam
23
23
 
24
24
  def self.analyze(context)
25
25
  raise context.errors unless context.valid?
26
-
26
+
27
27
  all_types = Bodhi::Type.find_all(context)
28
28
  all_enums = Bodhi::Enumeration.find_all(context)
29
- klasses = all_types.collect{ |type| Bodhi::Type.create_class_with(type) }
30
-
31
- embedded_types = all_types.select{ |type| type.embedded }
32
- normal_types = all_types.select{ |type| !type.embedded }
33
-
34
- embedded_factories = embedded_types.each{ |type| Bodhi::Type.create_factory_with(type) }
35
- normal_factories = normal_types.each{ |type| Bodhi::Type.create_factory_with(type) }
36
- klasses
29
+ all_types.collect{ |type| Bodhi::Type.create_class_with(type) }
37
30
  end
38
31
  end
@@ -10,8 +10,6 @@ module Bodhi
10
10
  validates :namespace, required: true, is_not_blank: true
11
11
 
12
12
  def initialize(params)
13
- params.symbolize_keys!
14
-
15
13
  @connection = Faraday.new(url: params[:server]) do |faraday|
16
14
  faraday.request :url_encoded # form-encode POST params
17
15
  #faraday.response :logger # log requests to STDOUT
@@ -2,12 +2,26 @@ module Bodhi
2
2
  class Enumeration
3
3
  attr_reader :name, :values
4
4
 
5
- def initialize(params={})
6
- params.symbolize_keys!
7
-
5
+ def initialize(params)
6
+ # same as symbolize_keys!
7
+ params = params.reduce({}) do |memo, (k, v)|
8
+ memo.merge({ k.to_sym => v})
9
+ end
10
+
8
11
  @name = params[:name]
9
12
  @values = params[:values]
10
13
  self.class.cache[@name.to_sym] = self
14
+
15
+ @values = @values.map do |value|
16
+ if value.is_a? Hash
17
+ # same as symbolize_keys!
18
+ value = value.reduce({}) do |memo, (k, v)|
19
+ memo.merge({ k.to_sym => v})
20
+ end
21
+ else
22
+ value
23
+ end
24
+ end
11
25
  end
12
26
 
13
27
  def self.find_all(context)
@@ -0,0 +1,169 @@
1
+ module Bodhi
2
+ class Factory
3
+ attr_reader :klass
4
+ attr_accessor :generators
5
+
6
+ def initialize(base)
7
+ @klass = base
8
+ @generators = Hash.new
9
+ end
10
+
11
+ def build(*args)
12
+ if args.last.is_a?(Hash)
13
+ params = args.last.reduce({}) do |memo, (k, v)|
14
+ memo.merge({ k.to_sym => v})
15
+ end
16
+ else
17
+ params = Hash.new
18
+ end
19
+
20
+ object = klass.new
21
+ @generators.each_pair do |attribute, generator|
22
+ if params[attribute]
23
+ object.send("#{attribute}=", params[attribute])
24
+ else
25
+ object.send("#{attribute}=", generator.call)
26
+ end
27
+ end
28
+ object
29
+ end
30
+
31
+ def build_list(size, *args)
32
+ size.times.collect{ build(*args) }
33
+ end
34
+
35
+ def create(context, params={})
36
+ if context.invalid?
37
+ raise context.errors
38
+ end
39
+
40
+ object = build(params)
41
+ object.bodhi_context = context
42
+ object.save!
43
+ object
44
+ end
45
+
46
+ def create_list(size, context, params={})
47
+ if context.invalid?
48
+ raise context.errors
49
+ end
50
+
51
+ resources = build_list(size, params)
52
+ result = context.connection.post do |request|
53
+ request.url "/#{context.namespace}/resources/#{klass}"
54
+ request.headers['Content-Type'] = 'application/json'
55
+ request.headers[context.credentials_header] = context.credentials
56
+ request.body = resources.to_json
57
+ end
58
+
59
+ #puts "\033[33mResult Body\033[0m: \033[36m#{result.body}\033[0m"
60
+
61
+ if result.status != 200
62
+ errors = JSON.parse result.body
63
+ errors.each{|error| error['status'] = result.status } if errors.is_a? Array
64
+ errors["status"] = result.status if errors.is_a? Hash
65
+ raise errors.to_s
66
+ end
67
+
68
+ #puts "\033[33mRecords\033[0m: \033[36m#{records.map(&:attributes)}\033[0m"
69
+
70
+ resources
71
+ end
72
+
73
+ def add_generator(name, options)
74
+ case options[:type]
75
+ when "String"
76
+ characters = [('a'..'z'), ('A'..'Z'), ('0'..'9')].map { |i| i.to_a }.flatten
77
+ "~!@#$%^&*()_+-=:;<>?,./ ".each_char{ |c| characters.push(c) }
78
+
79
+ generator = lambda do
80
+ if options[:multi]
81
+ [*0..5].sample.times.collect{ [*0..50].sample.times.map{ characters[rand(characters.length)] }.join }
82
+ else
83
+ [*0..50].sample.times.map{ characters[rand(characters.length)] }.join
84
+ end
85
+ end
86
+
87
+ when "DateTime"
88
+ if options[:multi]
89
+ generator = lambda { [*0..5].sample.times.collect{ Time.at(rand * Time.now.to_i).iso8601 } }
90
+ else
91
+ generator = lambda { Time.at(rand * Time.now.to_i).iso8601 }
92
+ end
93
+
94
+ when "Integer"
95
+ options[:min].nil? ? min = -2147483647 : min = options[:min]
96
+ options[:max].nil? ? max = 2147483647 : max = options[:max]
97
+
98
+ if options[:multi]
99
+ generator = lambda { [*0..5].sample.times.collect{ rand(min..max) } }
100
+ else
101
+ generator = lambda { rand(min..max) }
102
+ end
103
+
104
+ when "Real"
105
+ if options[:multi]
106
+ generator = lambda { [*0..5].sample.times.collect{ SecureRandom.random_number*[-1,1,1,1].sample*[10,100,1000,10000].sample } }
107
+ else
108
+ generator = lambda { SecureRandom.random_number*[-1,1,1,1].sample*[10,100,1000,10000].sample }
109
+ end
110
+
111
+ when "Boolean"
112
+ if options[:multi]
113
+ generator = lambda { [*0..5].sample.times.collect{ [true, false].sample } }
114
+ else
115
+ generator = lambda { [true, false].sample }
116
+ end
117
+
118
+ when "GeoJSON"
119
+ if options[:multi]
120
+ generator = lambda { [*0..5].sample.times.collect{ {type: "Point", coordinates: [10,20]} } }
121
+ else
122
+ generator = lambda { {type: "Point", coordinates: [10,20]} }
123
+ end
124
+
125
+ when "Object"
126
+ if options[:multi]
127
+ generator = lambda { [*0..5].sample.times.collect{ {SecureRandom.hex => SecureRandom.hex} } }
128
+ else
129
+ generator = lambda { {SecureRandom.hex => SecureRandom.hex} }
130
+ end
131
+
132
+ when "Enumerated"
133
+ generator = lambda do
134
+ ref = options[:ref].split('.')
135
+ name = ref[0]
136
+ field = ref[1]
137
+
138
+ if options[:multi]
139
+ if field.nil?
140
+ [*0..5].sample.times.collect{ Bodhi::Enumeration.cache[name.to_sym].values.sample }
141
+ else
142
+ [*0..5].sample.times.collect{ Bodhi::Enumeration.cache[name.to_sym].values.sample[field.to_sym] }
143
+ end
144
+ else
145
+ if field.nil?
146
+ Bodhi::Enumeration.cache[name.to_sym].values.sample
147
+ else
148
+ Bodhi::Enumeration.cache[name.to_sym].values.sample[field.to_sym]
149
+ end
150
+ end
151
+ end
152
+
153
+ else
154
+ generator = lambda do
155
+ embedded_klass = Object.const_get(options[:type])
156
+
157
+ if options[:multi]
158
+ [*0..5].sample.times.collect{ embedded_klass.factory.build }
159
+ else
160
+ embedded_klass.factory.build
161
+ end
162
+ end
163
+ end
164
+
165
+ @generators[name.to_sym] = generator
166
+ end
167
+
168
+ end
169
+ end
@@ -1,48 +1,11 @@
1
1
  module Bodhi
2
2
  module Resource
3
3
  SYSTEM_ATTRIBUTES = [:bodhi_context, :sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
4
- :sys_namespace, :sys_created_by, :sys_type_version, :sys_id]
4
+ :sys_namespace, :sys_created_by, :sys_type_version, :sys_id, :sys_embeddedType]
5
5
  attr_accessor *SYSTEM_ATTRIBUTES
6
6
 
7
7
  module ClassMethods
8
- def build(context, params={})
9
- params.merge!({bodhi_context: context})
10
- FactoryGirl.build(name, params)
11
- end
12
-
13
- def build_list(context, amount, params={})
14
- params.merge!({bodhi_context: context})
15
- FactoryGirl.build_list(name, amount, params)
16
- end
17
-
18
- def create(context, params={})
19
- params.merge!({bodhi_context: context})
20
- FactoryGirl.create(name, params)
21
- end
22
-
23
- def create_list(context, amount, params={})
24
- params.merge!({bodhi_context: context})
25
- records = FactoryGirl.build_list(name, amount, params)
26
- result = context.connection.post do |request|
27
- request.url "/#{context.namespace}/resources/#{name}"
28
- request.headers['Content-Type'] = 'application/json'
29
- request.headers[context.credentials_header] = context.credentials
30
- request.body = records.to_json
31
- end
32
-
33
- #puts "\033[33mResult Body\033[0m: \033[36m#{result.body}\033[0m"
34
-
35
- if result.status != 200
36
- errors = JSON.parse result.body
37
- errors.each{|error| error['status'] = result.status } if errors.is_a? Array
38
- errors["status"] = result.status if errors.is_a? Hash
39
- raise errors.to_s
40
- end
41
-
42
- #puts "\033[33mRecords\033[0m: \033[36m#{records.map(&:attributes)}\033[0m"
43
-
44
- records
45
- end
8
+ def factory; @factory; end
46
9
 
47
10
  def find(context, id)
48
11
  raise context.errors unless context.valid?
@@ -64,7 +27,7 @@ module Bodhi
64
27
  end
65
28
 
66
29
  resource_attributes = JSON.parse(result.body)
67
- self.build(context, resource_attributes)
30
+ factory.build(context, resource_attributes)
68
31
  end
69
32
 
70
33
  def aggregate(context, pipeline)
@@ -109,7 +72,7 @@ module Bodhi
109
72
  end
110
73
 
111
74
  resources = JSON.parse(result.body)
112
- resources.map{ |attributes| self.build(context, attributes) }
75
+ resources.map{ |attributes| factory.build(context, attributes) }
113
76
  end
114
77
 
115
78
  def delete_all(context)
@@ -207,6 +170,7 @@ module Bodhi
207
170
  def self.included(base)
208
171
  base.extend(ClassMethods)
209
172
  base.include(InstanceMethods, Bodhi::Validations)
173
+ base.instance_variable_set(:@factory, Bodhi::Factory.new(base))
210
174
  end
211
175
  end
212
176
  end
@@ -1,191 +1,102 @@
1
1
  module Bodhi
2
2
  class Type
3
3
  include Bodhi::Validations
4
-
4
+
5
5
  BODHI_SYSTEM_ATTRIBUTES = [:sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
6
- :sys_namespace, :sys_created_by, :sys_type_version, :sys_id]
6
+ :sys_namespace, :sys_created_by, :sys_type_version, :sys_id, :sys_embeddedType]
7
7
  BODHI_TYPE_ATTRIBUTES = [:name, :namespace, :package, :embedded, :properties]
8
-
8
+
9
9
  attr_accessor *BODHI_TYPE_ATTRIBUTES
10
10
  attr_reader *BODHI_SYSTEM_ATTRIBUTES
11
11
  attr_reader :validations
12
-
12
+
13
13
  validates :name, required: true, is_not_blank: true
14
14
  validates :namespace, required: true
15
15
  validates :properties, required: true
16
-
16
+
17
17
  def initialize(params={})
18
- params.symbolize_keys!
19
-
18
+ # same as symbolize_keys!
19
+ params = params.reduce({}) do |memo, (k, v)|
20
+ memo.merge({ k.to_sym => v})
21
+ end
22
+
23
+ # set attributes
20
24
  BODHI_TYPE_ATTRIBUTES.each do |attribute|
21
25
  send("#{attribute}=", params[attribute])
22
26
  end
23
-
27
+
28
+ if !name.nil? && name[0] == name[0].downcase
29
+ name.capitalize!
30
+ end
31
+
32
+ # build validator objects
24
33
  @validations = {}
25
34
  if properties
26
- properties.symbolize_keys!
27
35
  properties.each_pair do |attr_name, attr_properties|
28
- attr_properties.symbolize_keys!
29
- @validations[attr_name] = []
36
+ @validations[attr_name.to_sym] = []
30
37
  attr_properties.each_pair do |option, value|
31
38
  underscored_name = option.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase.to_sym
32
- unless [:system, :trim, :ref, :unique, :default, :is_current_user].include? underscored_name
39
+ unless [:system, :trim, :ref, :unique, :default, :is_current_user, :to_lower].include? underscored_name
33
40
  klass = Bodhi::Validator.constantize(underscored_name)
34
- if option == :type && value == "Enumerated"
35
- if attr_properties[:ref].nil?
41
+ if option.to_s == "type" && value == "Enumerated"
42
+ if attr_properties["ref"].nil?
36
43
  raise RuntimeError.new("No reference property found! Cannot build enumeration validator for #{name}.#{attr_name}")
37
44
  end
38
-
39
- @validations[attr_name] << klass.new(value, attr_properties[:ref])
45
+ @validations[attr_name.to_sym] << klass.new(value, attr_properties["ref"])
40
46
  else
41
- @validations[attr_name] << klass.new(value)
47
+ @validations[attr_name.to_sym] << klass.new(value)
42
48
  end
43
49
  end
44
50
  end
45
51
  end
46
52
  end
47
53
  end
48
-
54
+
49
55
  def self.find_all(context)
50
56
  raise context.errors unless context.valid?
51
-
52
- result = context.connection.get do |request|
53
- request.url "/#{context.namespace}/types"
54
- request.headers[context.credentials_header] = context.credentials
55
- end
56
-
57
- if result.status != 200
58
- errors = JSON.parse result.body
59
- errors.each{|error| error['status'] = result.status } if errors.is_a? Array
60
- errors["status"] = result.status if errors.is_a? Hash
61
- raise errors.to_s
62
- end
63
-
64
- JSON.parse(result.body).collect{ |type| Bodhi::Type.new(type) }
57
+ page = 1
58
+ all_records = []
59
+
60
+ begin
61
+ result = context.connection.get do |request|
62
+ request.url "/#{context.namespace}/types?paging=page:#{page}"
63
+ request.headers[context.credentials_header] = context.credentials
64
+ end
65
+
66
+ if result.status != 200
67
+ errors = JSON.parse result.body
68
+ errors.each{|error| error['status'] = result.status } if errors.is_a? Array
69
+ errors["status"] = result.status if errors.is_a? Hash
70
+ raise errors.to_s
71
+ end
72
+
73
+ page += 1
74
+ records = JSON.parse(result.body)
75
+ all_records << records
76
+ end while records.size == 100
77
+
78
+ all_records.flatten.collect{ |type| Bodhi::Type.new(type) }
65
79
  end
66
-
80
+
67
81
  def self.create_class_with(type)
68
82
  unless type.is_a? Bodhi::Type
69
83
  raise ArgumentError.new("Expected #{type.class} to be a Bodhi::Type")
70
84
  end
71
-
85
+
72
86
  klass = Object.const_set(type.name, Class.new {
73
87
  include Bodhi::Resource
74
88
  attr_accessor *type.properties.keys
75
89
  })
76
-
90
+
77
91
  type.validations.each_pair do |attribute, validations|
78
92
  attr_options = Hash.new
79
93
  validations.each{ |validation| attr_options.merge!(validation.to_options) }
80
94
  klass.validates(attribute, attr_options)
95
+ klass.factory.add_generator(attribute, attr_options)
81
96
  end
82
-
97
+
83
98
  klass
84
99
  end
85
-
86
- def self.create_factory_with(type)
87
- unless type.is_a? Bodhi::Type
88
- raise ArgumentError.new("Expected #{type.class} to be a Bodhi::Type")
89
- end
90
-
91
- FactoryGirl.define do
92
- factory type.name.to_sym do
93
- type.properties.each_pair do |attribute, options|
94
- unless options[:system]
95
-
96
- case options[:type]
97
- when "GeoJSON"
98
- if options[:multi].nil?
99
- send(attribute) { {type: "Point", coordinates: [10,20]} }
100
- else
101
- send(attribute) { [*0..5].sample.times.collect{ {type: "Point", coordinates: [10,20]} } }
102
- end
103
-
104
- when "Boolean"
105
- if options[:multi].nil?
106
- send(attribute) { [true, false].sample }
107
- else
108
- send(attribute) { [*0..5].sample.times.collect{ [true, false].sample } }
109
- end
110
-
111
- when "Enumerated"
112
- reference = options[:ref].split('.')
113
- name = reference[0]
114
- field = reference[1]
115
-
116
- if options[:multi].nil?
117
- if field.nil?
118
- send(attribute) { Bodhi::Enumeration.cache[name.to_sym].values.sample }
119
- else
120
- Bodhi::Enumeration.cache[name.to_sym].values.map!{ |value| value.symbolize_keys! }
121
- send(attribute) { Bodhi::Enumeration.cache[name.to_sym].values.sample[field.to_sym] }
122
- end
123
- else
124
- if field.nil?
125
- send(attribute) { [*0..5].sample.times.collect{ Bodhi::Enumeration.cache[name.to_sym].values.sample } }
126
- else
127
- send(attribute) { [*0..5].sample.times.collect{ Bodhi::Enumeration.cache[name.to_sym].values.sample[field.to_sym] } }
128
- end
129
- end
130
-
131
- when "Object"
132
- if options[:multi].nil?
133
- send(attribute) { {SecureRandom.hex => SecureRandom.hex} }
134
- else
135
- send(attribute) { [*0..5].sample.times.collect{ {SecureRandom.hex => SecureRandom.hex} } }
136
- end
137
100
 
138
- when "String"
139
- if options[:multi].nil?
140
- send(attribute) { SecureRandom.hex }
141
- else
142
- send(attribute) { [*0..5].sample.times.collect{ SecureRandom.hex } }
143
- end
144
-
145
- when "DateTime"
146
- if options[:multi].nil?
147
- send(attribute) { Time.at(rand * Time.now.to_i).iso8601 }
148
- else
149
- send(attribute) { [*0..5].sample.times.collect{ Time.at(rand * Time.now.to_i).iso8601 } }
150
- end
151
-
152
- when "Integer"
153
- min = -10000
154
- max = 10000
155
- if options[:min]
156
- min = options[:min]
157
- end
158
-
159
- if options[:max]
160
- max = options[:max]
161
- end
162
-
163
- if options[:multi].nil?
164
- send(attribute) { rand(min..max) }
165
- else
166
- send(attribute) { [*0..5].sample.times.collect{ rand(min..max) } }
167
- end
168
-
169
- when "Real"
170
- if options[:multi].nil?
171
- send(attribute) { SecureRandom.random_number*[-1,1,1,1].sample*[10,100,1000,10000].sample }
172
- else
173
- send(attribute) { [*0..5].sample.times.collect{ SecureRandom.random_number*[-1,1,1,1].sample*[10,100,1000,10000].sample } }
174
- end
175
-
176
- else # Its an embedded type
177
- if options[:multi].nil?
178
- send(attribute) { FactoryGirl.build(options[:type]) }
179
- else
180
- send(attribute) { [*0..5].sample.times.collect{ FactoryGirl.build(options[:type]) } }
181
- end
182
- end
183
-
184
- end
185
- end
186
- end
187
- end
188
-
189
- end
190
101
  end
191
102
  end
@@ -0,0 +1,27 @@
1
+ module Bodhi
2
+ class LengthValidator < Validator
3
+ attr_reader :value
4
+
5
+ def initialize(value)
6
+ @value = value
7
+ end
8
+
9
+ def validate(record, attribute, value)
10
+ unless value.nil?
11
+
12
+ if value.is_a?(Array)
13
+ unless value.empty?
14
+ record.errors.add(attribute, "must all be #{value} characters long") unless value.select{ |item| !item.length == @value }.empty?
15
+ end
16
+ else
17
+ record.errors.add(attribute, "must be #{value} characters long") unless value.length == @value
18
+ end
19
+
20
+ end
21
+ end
22
+
23
+ def to_options
24
+ {self.to_sym => @value}
25
+ end
26
+ end
27
+ end
@@ -19,7 +19,7 @@ module Bodhi
19
19
 
20
20
  end
21
21
  end
22
-
22
+
23
23
  def to_options
24
24
  {self.to_sym => @value}
25
25
  end
@@ -19,7 +19,7 @@ module Bodhi
19
19
 
20
20
  end
21
21
  end
22
-
22
+
23
23
  def to_options
24
24
  {self.to_sym => @value}
25
25
  end
@@ -6,7 +6,7 @@ module Bodhi
6
6
  def validate(record, attribute, value)
7
7
  record.errors.add(attribute, "must be an array") unless value.is_a? Array
8
8
  end
9
-
9
+
10
10
  def to_options
11
11
  {self.to_sym => true}
12
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bodhi-slam
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - willdavis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-23 00:00:00.000000000 Z
11
+ date: 2015-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-http-persistent
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.9'
27
- - !ruby/object:Gem::Dependency
28
- name: factory_girl
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '4.5'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '4.5'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: faraday
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +94,7 @@ dependencies:
108
94
  - - ">="
109
95
  - !ruby/object:Gem::Version
110
96
  version: '0'
111
- description: BodhiSlam is an ORM for the Bodhi API and helps with randomly generating.
97
+ description:
112
98
  email: will.davis@hotschedules.com
113
99
  executables: []
114
100
  extensions: []
@@ -118,12 +104,14 @@ files:
118
104
  - lib/bodhi-slam/context.rb
119
105
  - lib/bodhi-slam/enumerations.rb
120
106
  - lib/bodhi-slam/errors.rb
107
+ - lib/bodhi-slam/factory.rb
121
108
  - lib/bodhi-slam/resource.rb
122
109
  - lib/bodhi-slam/types.rb
123
110
  - lib/bodhi-slam/validations.rb
124
111
  - lib/bodhi-slam/validators.rb
125
112
  - lib/bodhi-slam/validators/blank.rb
126
113
  - lib/bodhi-slam/validators/email.rb
114
+ - lib/bodhi-slam/validators/length.rb
127
115
  - lib/bodhi-slam/validators/matches.rb
128
116
  - lib/bodhi-slam/validators/max.rb
129
117
  - lib/bodhi-slam/validators/min.rb
@@ -152,8 +140,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
140
  version: '0'
153
141
  requirements: []
154
142
  rubyforge_project:
155
- rubygems_version: 2.2.2
143
+ rubygems_version: 2.4.5
156
144
  signing_key:
157
145
  specification_version: 4
158
- summary: Ruby bindings for the Bodhi API
146
+ summary: Ruby bindings for the Bodhi API + factories for random data generation
159
147
  test_files: []