bodhi-slam 0.8.6 → 0.8.7

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: 927cbe7fce05186291e3a60f7d5db8080b76eb78
4
- data.tar.gz: 91d7ae587744677ec6975d09e78d90857e589e14
3
+ metadata.gz: df0ac516bd1d04bc4cd3aa891949ba67998980c2
4
+ data.tar.gz: 9d300e641fd66ca7a460eb02d5a569a5549d3c62
5
5
  SHA512:
6
- metadata.gz: acc7b2b51d96c0846113bef0d4e55db377eb0e6e53e1ea85988a6701ae8903d9013ee20f8138e504bc487feaf4b8dbd83e171919e697829d0463147c1cc588ed
7
- data.tar.gz: fe8081714579f87ee22c8981aa54e958cb2a73e9b3b36dd06fd0985dc5f1db50b43568b0eecb2d43c6332c00d8d17292f2eb79c50a631aae2d668d50fb8a3097
6
+ metadata.gz: 267ee73450c418081f5b14d19f5accbaa2ad30ed1ebae413b11c02c2434182887ce4dc11e8ae17a24bb4ff0de14b47e17c89fdb8e6d941a5ca1f7f7ed06a27b7
7
+ data.tar.gz: bf6d08460651b649e0ca05bad80f07c299a9b62636dc049658f6695fcca88ff9114542748902507dbf936d7458293b298c4ae6fa75566bfd07c04787164ca9fd
data/lib/bodhi-slam.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require "json"
2
2
  require "time"
3
3
  require 'faraday'
4
- require 'SecureRandom'
4
+ require 'securerandom'
5
5
  require 'faraday_middleware'
6
6
  require 'faraday-http-cache'
7
7
  require 'net/http/persistent'
@@ -76,7 +76,7 @@ class BodhiSlam
76
76
  end
77
77
 
78
78
  # Dynamically creates Ruby Classes for each type in the given +context+
79
- #
79
+ #
80
80
  # context = Bodhi::Context.new(valid_params)
81
81
  # BodhiSlam.analyze(context) # => [#<Class:0x007fbff403e808 @name="TestType">, #<Class:0x007fbff403e808 @name="TestType2">, ...]
82
82
  def self.analyze(context)
@@ -95,4 +95,4 @@ class BodhiSlam
95
95
  end
96
96
  end
97
97
  end
98
- end
98
+ end
@@ -1,9 +1,18 @@
1
1
  module Bodhi
2
2
  module Factories
3
3
  module ClassMethods
4
+ # Returns the Classes +Bodhi::Factory+ object
5
+ # @return [Bodhi::Factory]
4
6
  def factory; @factory; end
7
+
8
+ # Define a factory generator with the given +name+ and +options+
9
+ # and append to the Classes Bodhi::Factory
10
+ # @param name [String] the name of the property
11
+ # @param options [Hash] the Bodhi::Properties
12
+ # @return [nil]
5
13
  def generates(name, options)
6
14
  @factory.add_generator(name.to_sym, options)
15
+ return nil
7
16
  end
8
17
  end
9
18
 
@@ -13,18 +22,49 @@ module Bodhi
13
22
  end
14
23
  end
15
24
 
25
+ # Randomize and save records to the cloud.
26
+ #
27
+ # Use the built in {Bodhi::Validator} classes to define constraints for
28
+ # randomizing records. You can also create your own lambda expressions for further
29
+ # fine grain control.
30
+ # @example Define factories
31
+ # factory = Bodhi::Factory.new(Drone)
32
+ # @example Default generators using {Bodhi::Type.properties} options
33
+ # factory.add_generator(:motor_count, type: Integer, min: 1, max: 8 )
34
+ # @example Create custom generators using lambda syntax
35
+ # factory.add_generator(:color, lambda { ["Red", "Green", "Blue", "Black"].sample } )
36
+ # @example Build a new record with randomly generated attributes
37
+ # quad_copter = factory.build(motor_count: 4)
38
+ # quad_copter # => #<Drone:0x007fbff403e808 @motor_count=4 @color="Red" >
39
+ # @example Build an array of random records
40
+ # quad_copters = factory.build_list(10, motor_count: 4)
41
+ # quad_copters # => [#<Drone:0x007fbff403e808 @motor_count=4 @color="Blue" >, ...]
42
+ # @example Build and save a randomly generated record
43
+ # quad_copter = factory.create(bodhi_context: context, motor_count: 4)
44
+ # quad_copter # => #<Drone:0x007fbff403e808 @motor_count=4 @color="Green" >
45
+ # @example Build and save an array of random records
46
+ # quad_copters = factory.create_list(10, bodhi_context: context, motor_count: 4)
47
+ # quad_copters # => [#<Drone:0x007fbff403e808 @motor_count=4 @color="Blue" >, ...]
16
48
  class Factory
49
+ # The class that will be used to generate random instances
17
50
  attr_reader :klass
51
+
52
+ # Hash of property names with lambda's to generate random values
18
53
  attr_accessor :generators
19
54
 
55
+ # Initialize a new Factory using the given base class
56
+ # @param base [Class] the class you want to generate random instances for
20
57
  def initialize(base)
21
58
  @klass = base
22
59
  @generators = Hash.new
23
60
  end
24
61
 
25
- # Returns a new randomly generated resource.
26
- # Accepts an options hash to override specified values.
27
- #
62
+ # Builds a new randomly generated resource
63
+ # and accepts a options hash to override specified properties.
64
+ #
65
+ # @param options [Hash] the properties and values that should +NOT+ be randomized
66
+ # @return [Bodhi::Resource] the randomly generated resource
67
+ # @example
28
68
  # Resource.factory.build # => #<Resource:0x007fbff403e808 @name="2-3lmwp^oef@245">
29
69
  # Resource.factory.build(name: "test") # => #<Resource:0x007fbff403e808 @name="test">
30
70
  def build(options={})
@@ -40,31 +80,43 @@ module Bodhi
40
80
  object
41
81
  end
42
82
 
43
- # Returns an array of randomly generated resources
44
- #
83
+ # Builds an array of randomly generated resources
84
+ # and accepts a options hash to override specified properties.
85
+ #
86
+ # @param size [Integer] the amount of resources to generate
87
+ # @param options [Hash] the properties and values that should +NOT+ be randomized
88
+ # @return [Array<Bodhi::Resource>] An Array of randomly generated resources
89
+ # @example
45
90
  # Resource.factory.build_list(10) # => [#<Resource:0x007fbff403e808 @name="2-3lmwp^oef@245">, #<Resource:0x007fbff403e808 @name="p7:n#$903<u1">, ...]
46
91
  # Resource.factory.build_list(10, name: "test") # => [#<Resource:0x007fbff403e808 @name="test">, #<Resource:0x007fbff403e808 @name="test">, ...]
47
92
  def build_list(size, options={})
48
93
  size.times.collect{ build(options) }
49
94
  end
50
95
 
51
- # Builds and saves a new resource to the given +context+
52
- # Accepts an options hash to override specified values.
53
- #
54
- # context = Bodhi::Context.new
55
- # Resource.factory.create(context) # => #<Resource:0x007fbff403e808 @name="2-3lmwp^oef@245">
56
- # Resource.factory.create(context, name: "test") # => #<Resource:0x007fbff403e808 @name="test">
96
+ # Generates a random resource and saves it to the IoT Platform
97
+ # and accepts a options hash to override specified properties.
98
+ #
99
+ # @param options [Hash] the properties and values that should +NOT+ be randomized
100
+ # @return [Bodhi::Resource] the randomly generated resource
101
+ # @example
102
+ # Resource.factory.create(bodhi_context: context) # => #<Resource:0x007fbff403e808 @name="2-3lmwp^oef@245">
103
+ # Resource.factory.create(bodhi_context: context, name: "test") # => #<Resource:0x007fbff403e808 @name="test">
57
104
  def create(options={})
58
105
  object = build(options)
59
106
  object.save!
60
107
  object
61
108
  end
62
109
 
63
- # Builds and saves a list of resources to the given +context+
64
- # Accepts an options hash to override specified values.
65
- #
66
- # Resource.factory.create_list(10, context) # => [#<Resource:0x007fbff403e808 @name="2-3lmwp^oef@245">, #<Resource:0x007fbff403e808 @name="p7:n#$903<u1">, ...]
67
- # Resource.factory.create_list(10, context, name: "test") # => [#<Resource:0x007fbff403e808 @name="test">, #<Resource:0x007fbff403e808 @name="test">, ...]
110
+ # Generates an array of random resources and saves them to the IoT Platform
111
+ # and accepts a options hash to override specified properties.
112
+ #
113
+ # @param size [Integer] the amount of resources to generate
114
+ # @param options [Hash] the properties and values that should +NOT+ be randomized
115
+ # @return [Array<Bodhi::Resource>] An Array of randomly generated resources
116
+ # @raise [Bodhi::ApiErrors] if any resource failed to be saved
117
+ # @example
118
+ # Resource.factory.create_list(10, bodhi_context: context) # => [#<Resource:0x007fbff403e808 @name="2-3lmwp^oef@245">, #<Resource:0x007fbff403e808 @name="p7:n#$903<u1">, ...]
119
+ # Resource.factory.create_list(10, bodhi_context: context, name: "test") # => [#<Resource:0x007fbff403e808 @name="test">, #<Resource:0x007fbff403e808 @name="test">, ...]
68
120
  def create_list(size, options={})
69
121
  resources = build_list(size, options)
70
122
  resources.each{ |resource| resource.save! }
@@ -72,7 +124,11 @@ module Bodhi
72
124
  end
73
125
 
74
126
  # Adds a new generator to the class with the specified +name+ and +options+
75
- #
127
+ #
128
+ # @param name [String, Symbol] the name of the property
129
+ # @param options [Hash] the Bodhi::Properties options to generate
130
+ # @return [nil]
131
+ # @example
76
132
  # Resource.factory.add_generator("name", type: "String")
77
133
  # Resource.factory.add_generator("test", type: "Integer", multi: true, required: true)
78
134
  def add_generator(name, options)
@@ -81,11 +137,15 @@ module Bodhi
81
137
  else
82
138
  @generators[name.to_sym] = build_default_generator(options)
83
139
  end
140
+
141
+ return nil
84
142
  end
85
143
 
86
144
  private
145
+
146
+ # @todo clean up this nasty abomination of a method!
87
147
  def build_default_generator(options)
88
- options = options.reduce({}) do |memo, (k, v)|
148
+ options = options.reduce({}) do |memo, (k, v)|
89
149
  memo.merge({ Bodhi::Support.underscore(k.to_s).to_sym => v})
90
150
  end
91
151
 
@@ -181,7 +241,7 @@ module Bodhi
181
241
  # define max/min lattitude
182
242
  min_lat = -90.0
183
243
  max_lat = 90.0
184
-
244
+
185
245
  if options[:multi]
186
246
  generator = lambda do
187
247
  [*0..5].sample.times.collect do
@@ -333,4 +393,4 @@ module Bodhi
333
393
  end
334
394
 
335
395
  end
336
- end
396
+ end
@@ -1,118 +1,164 @@
1
1
  module Bodhi
2
+ # This module helps turn a Ruby Object into a Form Object.
3
+ # It manages the objects properties as well as serialization to JSON
4
+ # @example
5
+ # class MyNewClass
6
+ # include Bodhi::properties
7
+ #
8
+ # property :attribute_1, type: String
9
+ # property :attribute_2, type: DateTime
10
+ # ...
11
+ # end
12
+ #
13
+ # object = MyNewClass.new(attribute_1: "Foo", attribute_2: Time.now)
14
+ # object.to_json #=> {"attribute_1":"Foo", "attribute_2": "2016-08-16T13:15:19-07:00"}
2
15
  module Properties
3
16
 
17
+ # Default properties for ALL records on the IoT Platform
4
18
  SYSTEM_PROPERTIES = [:sys_created_at, :sys_version, :sys_modified_at, :sys_modified_by,
5
19
  :sys_namespace, :sys_created_by, :sys_type_version, :sys_id, :sys_embeddedType]
6
20
  attr_accessor *SYSTEM_PROPERTIES
7
21
 
8
22
  module ClassMethods
23
+ # Retuns a Hash of the Classes properties
24
+ # @return [Hash] The classes properties and options
9
25
  def properties; @properties; end
26
+
27
+ # A list of all property names
28
+ # @return [Array<String>]
10
29
  def property_names; @properties.keys; end
30
+
31
+ # Set a new property with the given +name+ and +options+
32
+ # @param name [String, Symbol]
33
+ # @param options [Hash]
34
+ # @return [nil]
35
+ # @example
36
+ # Resource.property("age", type: Integer, required: true, min: 18)
37
+ # Resource.property("birthday", type: DateTime, required: true)
38
+ # Resource.property(:tags, type: String, multi: true)
39
+ # Resource.property(:dogs", type: "Dog", multi: true)
11
40
  def property(name, options)
12
41
  attr_accessor name.to_sym
13
42
  @properties[name.to_sym] = options.reduce({}) do |memo, (k, v)|
14
43
  memo.merge({ Bodhi::Support.reverse_camelize(k.to_s).to_sym => v})
15
44
  end
45
+
46
+ return nil
16
47
  end
17
48
  end
18
49
 
19
- module InstanceMethods
20
- def id; @sys_id; end
21
- def persisted?; !@sys_id.nil?; end
22
- def new_record?; @sys_id.nil?; end
23
- def each; attributes.each{ |k, v| yield(k, v) }; end
24
-
25
- # Initializes a new instance of the class. Accepts a parameter Hash for mass assignment.
26
- # If a parameter does not exist for the class, an UndefinedMethod error is raised.
27
- #
28
- # klass = Class.new do
29
- # include Bodhi::Properties
30
- # property :name, :email
31
- # end
32
- #
33
- # object = klass.new(name: "Bob", email: "some@email.com")
34
- # object.name #=> "Bob"
35
- # object.email #=> "some@email.com"
36
- def initialize(options={})
37
- if options.is_a?(String)
38
- options = JSON.parse(options)
39
- end
50
+ # Wraps the sys_id property into a more Rails friendly attribute
51
+ # @return [String]
52
+ def id; @sys_id; end
40
53
 
41
- # Set properties defined by the +options+ parameter
42
- options = Bodhi::Support.symbolize_keys(options)
43
- options.each do |property, value|
44
- property_options = self.class.properties[property]
45
- if property_options.nil?
46
- send("#{property}=", value)
47
- else
48
- send("#{property}=", Bodhi::Support.coerce(value, property_options))
49
- end
50
- end
54
+ # Returns +true+ if the record has been saved to the IoT Platform
55
+ # @return [Boolean]
56
+ def persisted?; !@sys_id.nil?; end
51
57
 
52
- # Set any default values
53
- self.class.properties.select{ |k,v| !v[:default].nil? }.each do |property, property_options|
54
- send("#{property}=", property_options[:default]) if send("#{property}").nil?
55
- end
58
+ # Returns +true+ if the record has +NOT+ been saved to the IoT Platform
59
+ # @return [Boolean]
60
+ def new_record?; @sys_id.nil?; end
61
+
62
+ # Initializes a new instance of the class. Accepts a parameter Hash for mass assignment.
63
+ #
64
+ # @param options [Hash, JSON String]
65
+ # @example
66
+ # klass = Class.new do
67
+ # include Bodhi::Properties
68
+ # property :name, :email
69
+ # end
70
+ #
71
+ # object = klass.new(name: "Bob", email: "some@email.com")
72
+ # object.name #=> "Bob"
73
+ # object.email #=> "some@email.com"
74
+ def initialize(options={})
75
+ if options.is_a?(String)
76
+ options = JSON.parse(options)
56
77
  end
57
78
 
58
- # Returns a Hash of the class properties and their values.
59
- #
60
- # object = SomeResource.new(foo:"test", bar:12345)
61
- # object.attributes # => { foo: "test", bar: 12345 }
62
- def attributes
63
- attributes = Hash.new
64
-
65
- self.class.property_names.each do |property|
66
- value = send(property)
67
- if value.respond_to?(:attributes)
68
- attributes[property] = value.attributes.delete_if { |k, v| v.nil? }
69
- elsif value.is_a?(Array) && value.first.respond_to?(:attributes)
70
- attributes[property] = value.map(&:attributes).collect{ |item| item.delete_if { |k, v| v.nil? } }
71
- elsif value.is_a?(Time)
72
- attributes[property] = value.iso8601
73
- else
74
- attributes[property] = value
75
- end
79
+ # Set properties defined by the +options+ parameter
80
+ #options = Bodhi::Support.symbolize_keys(options)
81
+ options.each do |property, value|
82
+ property_options = self.class.properties[property.to_sym]
83
+ if property_options.nil?
84
+ send("#{property}=", value)
85
+ else
86
+ send("#{property}=", Bodhi::Support.coerce(value, property_options))
76
87
  end
88
+ end
77
89
 
78
- attributes.delete_if { |k, v| v.nil? }
79
- attributes
90
+ # Set any default values
91
+ self.class.properties.select{ |k,v| !v[:default].nil? }.each do |property, property_options|
92
+ send("#{property}=", property_options[:default]) if send("#{property}").nil?
80
93
  end
94
+ end
95
+
96
+ # Returns a Hash of the class properties and their values.
97
+ #
98
+ # @return [Hash]
99
+ # @example
100
+ # object = SomeResource.new(foo:"test", bar:12345)
101
+ # object.attributes # => { foo: "test", bar: 12345 }
102
+ def attributes
103
+ attributes = Hash.new
81
104
 
82
- # Updates the resource with the given attributes Hash
83
- #
84
- # s = SomeResource.factory.build(foo:"test", bar:12345)
85
- # s.attributes # => { foo: "test", bar: 12345 }
86
- # s.update_attributes(bar: 10)
87
- # s.attributes # => { foo: "test", bar: 10 }
88
- def update_attributes(params)
89
- params.each do |property, value|
90
- property_options = self.class.properties[property.to_sym]
91
- if property_options.nil?
92
- send("#{property}=", value)
93
- else
94
- send("#{property}=", Bodhi::Support.coerce(value, property_options))
95
- end
105
+ self.class.property_names.each do |property|
106
+ value = send(property)
107
+ if value.respond_to?(:attributes)
108
+ attributes[property] = value.attributes.delete_if { |k, v| v.nil? }
109
+ elsif value.is_a?(Array) && value.first.respond_to?(:attributes)
110
+ attributes[property] = value.map(&:attributes).collect{ |item| item.delete_if { |k, v| v.nil? } }
111
+ elsif value.is_a?(Time)
112
+ attributes[property] = value.iso8601
113
+ else
114
+ attributes[property] = value
96
115
  end
97
116
  end
98
117
 
99
- # Returns all the classes properties as JSON.
100
- # It converts any nested objects to JSON if they respond to +to_json+
101
- #
102
- # resource = SomeResource.new(foo:"test", bar:12345)
103
- # embedded_resources = AnotherResource.new( test: resource )
104
- #
105
- # resource.to_json # => "{ 'foo':'test', 'bar':12345 }"
106
- # embedded_resources.to_json # => "{ 'test': { 'foo':'test', 'bar':12345 } }"
107
- def to_json(base=nil)
108
- attributes.to_json
118
+ attributes.delete_if { |k, v| v.nil? }
119
+ attributes
120
+ end
121
+
122
+ # Updates the resource with the given attributes Hash
123
+ #
124
+ # @param properties [Hash] The properties to update
125
+ # @return [nil]
126
+ # @example
127
+ # s = SomeResource.factory.build(foo:"test", bar:12345)
128
+ # s.attributes # => { foo: "test", bar: 12345 }
129
+ # s.update_attributes(bar: 10)
130
+ # s.attributes # => { foo: "test", bar: 10 }
131
+ def update_attributes(properties)
132
+ properties.each do |property, value|
133
+ property_options = self.class.properties[property.to_sym]
134
+ if property_options.nil?
135
+ send("#{property}=", value)
136
+ else
137
+ send("#{property}=", Bodhi::Support.coerce(value, property_options))
138
+ end
109
139
  end
140
+
141
+ return nil
142
+ end
143
+
144
+ # Returns all the classes properties as JSON.
145
+ # It converts any nested objects to JSON if they respond to +to_json+
146
+ #
147
+ # @param options [Hash]
148
+ # @return [String] the JSON for all properties on the object
149
+ # @example
150
+ # resource = SomeResource.new(foo:"test", bar:12345)
151
+ # embedded_resources = AnotherResource.new( test: resource )
152
+ #
153
+ # resource.to_json # => "{ 'foo':'test', 'bar':12345 }"
154
+ # embedded_resources.to_json # => "{ 'test': { 'foo':'test', 'bar':12345 } }"
155
+ def to_json(options=nil)
156
+ attributes.to_json
110
157
  end
111
158
 
112
159
  def self.included(base)
113
160
  base.extend(ClassMethods)
114
- base.include(InstanceMethods, Enumerable)
115
161
  base.instance_variable_set(:@properties, Hash.new)
116
162
  end
117
163
  end
118
- end
164
+ end