bodhi-slam 0.8.6 → 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
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