reflekt 0.9.9 → 1.0.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
  SHA256:
3
- metadata.gz: f04cedc3780f61776191bf7ae72822aae50eba606c76c61c176f5c252462fa22
4
- data.tar.gz: 2ca6aa88016bfcab50460048d338a45f3855ee623f1b1bb5edc5e36323418eca
3
+ metadata.gz: e94e86e6d558012df59e1aebfdbbb7c2bf70a2e849e9a186795a3e4d5cb648f0
4
+ data.tar.gz: 9db428f6c518c06fbddb83e0abd9920b9dc30344846827b5c9505c3f2bc111c9
5
5
  SHA512:
6
- metadata.gz: 88024a7b33ba0ac0fca948b1b0808ad1a7094e958ae3b5d48f378b2c9256fcb29735b4635880322f5c2ee62e0034a265263997c3074d90d6756aef5408e5a2cb
7
- data.tar.gz: b2700bb56c2cf3915676c797381ad7913cb3091ffe576e7f276c9e97dcde488be602e01defbd812c3886f26a2cdde4090bd207312bad14f3d1ab20e55e3541e6
6
+ metadata.gz: e2a7ecf3adb9e06f7f3a09d507265c035bf3c641193711c64fea512b03973696c8ef9278d59eedf43ee83dd03a0f5f552026f0b2f6ba6182c6361bb35a211bf7
7
+ data.tar.gz: f002c69e490b63dd065e5f0ba0b40e9dcbbe980f71e7df66da01b1bc37b2dfe1081c9e58a3024b388b96628cc98422875a5b90f1e9227327f3241bc5d61450b0
@@ -18,6 +18,7 @@ class Accessor
18
18
  attr_accessor :renderer
19
19
  attr_accessor :path
20
20
  attr_accessor :output_path
21
+ attr_accessor :error
21
22
 
22
23
  def initialize()
23
24
 
@@ -29,6 +30,7 @@ class Accessor
29
30
  @renderer = nil
30
31
  @path = nil
31
32
  @output_path = nil
33
+ @error = false
32
34
 
33
35
  end
34
36
 
@@ -1,6 +1,6 @@
1
1
  ################################################################################
2
- # Aggregate reflection metadata into rule sets.
3
- # Validate reflection arguments against aggregates.
2
+ # Aggregate control metadata into rule sets.
3
+ # Validate reflections against aggregated controls.
4
4
  #
5
5
  # @pattern Singleton
6
6
  #
@@ -26,89 +26,33 @@ class Aggregator
26
26
  end
27
27
 
28
28
  ##
29
- # Get aggregated RuleSets for all inputs.
30
- #
31
- # @param klass [Symbol]
32
- # @param method [Symbol]
33
- # @return [Array]
34
- ##
35
- def get_input_rule_sets(klass, method)
36
- return @rule_sets.dig(klass, method, :inputs)
37
- end
38
-
39
- ##
40
- # Get an aggregated RuleSet for an input.
41
- #
42
- # @param klass [Symbol]
43
- # @param method [Symbol]
44
- # @return [RuleSet]
45
- ##
46
- def get_input_rule_set(klass, method, arg_num)
47
- @rule_sets.dig(klass, method, :inputs, arg_num)
48
- end
49
-
50
- ##
51
- # Get an aggregated RuleSet for an output.
52
- #
53
- # @param klass [Symbol]
54
- # @param method [Symbol]
55
- # @return [RuleSet]
56
- ##
57
- def get_output_rule_set(klass, method)
58
- @rule_sets.dig(klass, method, :output)
59
- end
60
-
61
- ##
62
- # Set an aggregated RuleSet for an input.
63
- #
64
- # @param klass [Symbol]
65
- # @param method [Symbol]
66
- ##
67
- def set_input_rule_set(klass, method, arg_num, rule_set)
68
- # Set defaults.
69
- @rule_sets[klass] = {} unless @rule_sets.key? klass
70
- @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
71
- @rule_sets[klass][method][:inputs] = [] unless @rule_sets[klass][method].key? :inputs
72
- # Set value.
73
- @rule_sets[klass][method][:inputs][arg_num] = rule_set
74
- end
75
-
76
- ##
77
- # Set an aggregated RuleSet for an output.
29
+ # Create aggregated rule sets from control metadata.
78
30
  #
79
- # @param klass [Symbol]
80
- # @param method [Symbol]
81
- # @param rule_set [RuleSet]
31
+ # @stage Called on setup.
32
+ # @param controls [Array] Controls with metadata.
33
+ # @TODO Revert string keys to symbols once "Fix Rowdb.get(path)" bug fixed.
82
34
  ##
83
- def set_output_rule_set(klass, method, rule_set)
84
- # Set defaults.
85
- @rule_sets[klass] = {} unless @rule_sets.key? klass
86
- @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
87
- # Set value.
88
- @rule_sets[klass][method][:output] = rule_set
89
- end
90
-
91
- ##
92
- # Create aggregated rule sets from reflection metadata.
93
- #
94
- # @param reflections [Array] Controls with metadata.
95
- ##
96
- def train(reflections)
35
+ def train(controls)
97
36
 
98
- # On first use there are no previous reflections.
99
- return if reflections.nil?
37
+ # On first use there are no previous controls.
38
+ return if controls.nil?
100
39
 
101
- reflections.each do |reflection|
40
+ controls.each do |control|
102
41
 
103
- klass = reflection[:class]
104
- method = reflection[:method]
42
+ klass = control["class"].to_sym
43
+ method = control["method"].to_sym
105
44
 
106
45
  ##
107
46
  # INPUT
108
47
  ##
109
48
 
110
- unless reflection[:inputs].nil?
111
- reflection[:inputs].each_with_index do |meta, arg_num|
49
+ unless control["inputs"].nil?
50
+ control["inputs"].each_with_index do |meta, arg_num|
51
+
52
+ # TODO: Remove once "Fix Rowdb.get(path)" bug fixed.
53
+ meta = meta.transform_keys(&:to_sym)
54
+ # Deserialize meta type to symbol.
55
+ meta[:type] = meta[:type].to_sym
112
56
 
113
57
  # Get rule set.
114
58
  rule_set = get_input_rule_set(klass, method, arg_num)
@@ -135,7 +79,7 @@ class Aggregator
135
79
  end
136
80
 
137
81
  # Train on metadata.
138
- output_rule_set.train(reflection[:output])
82
+ output_rule_set.train(control["output"])
139
83
 
140
84
  end
141
85
 
@@ -144,22 +88,23 @@ class Aggregator
144
88
  ##
145
89
  # Validate inputs.
146
90
  #
91
+ # @stage Called when validating a reflection.
147
92
  # @param inputs [Array] The method's arguments.
148
93
  # @param input_rule_sets [Array] The RuleSets to validate each input with.
149
94
  ##
150
- def validate_inputs(inputs, input_rule_sets)
95
+ def test_inputs(inputs, input_rule_sets)
151
96
 
152
- # Default to a PASS result.
97
+ # Default result to PASS.
153
98
  result = true
154
99
 
155
- # Validate each argument against each RuleSet for that argument.
100
+ # Validate each argument against each rule set for that argument.
156
101
  inputs.each_with_index do |input, arg_num|
157
102
 
158
103
  unless input_rule_sets[arg_num].nil?
159
104
 
160
105
  rule_set = input_rule_sets[arg_num]
161
106
 
162
- unless rule_set.validate_rule(input)
107
+ unless rule_set.test(input)
163
108
  result = false
164
109
  end
165
110
 
@@ -173,10 +118,11 @@ class Aggregator
173
118
  ##
174
119
  # Validate output.
175
120
  #
121
+ # @stage Called when validating a reflection.
176
122
  # @param output [Dynamic] The method's return value.
177
123
  # @param output_rule_set [RuleSet] The RuleSet to validate the output with.
178
124
  ##
179
- def validate_output(output, output_rule_set)
125
+ def test_output(output, output_rule_set)
180
126
 
181
127
  # Default to a PASS result.
182
128
  result = true
@@ -184,7 +130,7 @@ class Aggregator
184
130
  unless output_rule_set.nil?
185
131
 
186
132
  # Validate output RuleSet for that argument.
187
- unless output_rule_set.validate_rule(output)
133
+ unless output_rule_set.test(output)
188
134
  result = false
189
135
  end
190
136
 
@@ -194,4 +140,99 @@ class Aggregator
194
140
 
195
141
  end
196
142
 
143
+ ##
144
+ # Get aggregated RuleSets for all inputs.
145
+ #
146
+ # @stage Called when building a reflection.
147
+ # @param klass [Symbol]
148
+ # @param method [Symbol]
149
+ # @return [Array]
150
+ ##
151
+ def get_input_rule_sets(klass, method)
152
+ @rule_sets.dig(klass, method, :inputs)
153
+ end
154
+
155
+ ##
156
+ # Get an aggregated RuleSet for an output.
157
+ #
158
+ # @stage Called when building a reflection.
159
+ # @param klass [Symbol]
160
+ # @param method [Symbol]
161
+ # @return [RuleSet]
162
+ ##
163
+ def get_output_rule_set(klass, method)
164
+ @rule_sets.dig(klass, method, :output)
165
+ end
166
+
167
+ ##
168
+ # Get the base rule type for a data type.
169
+ ##
170
+ def self.value_to_rule_type(value)
171
+
172
+ data_type = value.class
173
+
174
+ rule_types = {
175
+ Array => ArrayRule,
176
+ TrueClass => BooleanRule,
177
+ FalseClass => BooleanRule,
178
+ Float => FloatRule,
179
+ Integer => IntegerRule,
180
+ String => StringRule
181
+ }
182
+
183
+ return rule_types[data_type]
184
+
185
+ end
186
+
187
+ ##############################################################################
188
+ # HELPERS
189
+ ##############################################################################
190
+
191
+ private
192
+
193
+ ##
194
+ # Get an aggregated RuleSet for an input.
195
+ #
196
+ # @param klass [Symbol]
197
+ # @param method [Symbol]
198
+ # @return [RuleSet]
199
+ ##
200
+ def get_input_rule_set(klass, method, arg_num)
201
+ @rule_sets.dig(klass, method, :inputs, arg_num)
202
+ end
203
+
204
+ ##
205
+ # Set an aggregated RuleSet for an input.
206
+ #
207
+ # @param klass [Symbol]
208
+ # @param method [Symbol]
209
+ ##
210
+ def set_input_rule_set(klass, method, arg_num, rule_set)
211
+
212
+ # Set defaults.
213
+ @rule_sets[klass] = {} unless @rule_sets.key? klass
214
+ @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
215
+ @rule_sets[klass][method][:inputs] = [] unless @rule_sets[klass][method].key? :inputs
216
+ # Set value.
217
+ @rule_sets[klass][method][:inputs][arg_num] = rule_set
218
+
219
+ end
220
+
221
+ ##
222
+ # Set an aggregated RuleSet for an output.
223
+ #
224
+ # @param klass [Symbol]
225
+ # @param method [Symbol]
226
+ # @param rule_set [RuleSet]
227
+ ##
228
+ def set_output_rule_set(klass, method, rule_set)
229
+
230
+ # Set defaults.
231
+ @rule_sets[klass] = {} unless @rule_sets.key? klass
232
+ @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
233
+ # Set value.
234
+ @rule_sets[klass][method][:output] = rule_set
235
+
236
+ end
237
+
197
238
  end
@@ -0,0 +1,31 @@
1
+ ################################################################################
2
+ # A clone of the instance that a reflection calls methods on,
3
+ # as well as any other instances that those methods may lead to.
4
+ #
5
+ # @note
6
+ # Not currently in use due to bug where "send" needs to be called directly
7
+ # on object, not indirectly through clone which results in "undefined method".
8
+ #
9
+ # @hierachy
10
+ # 1. Execution
11
+ # 2. Reflection
12
+ # 3. Clone <- YOU ARE HERE
13
+ ################################################################################
14
+
15
+ class Clone
16
+
17
+ def initialize(execution)
18
+
19
+ # Clone the execution's calling object.
20
+ @caller_object_clone = execution.caller_object.clone
21
+
22
+ # TODO: Clone any other instances that this clone references.
23
+ # TODO: Replace clone's references to these new instances.
24
+
25
+ end
26
+
27
+ def action(method, *new_args)
28
+ @caller_object_clone.send(method, *new_args)
29
+ end
30
+
31
+ end
@@ -1,5 +1,6 @@
1
1
  class Config
2
2
 
3
+ attr_accessor :enabled
3
4
  attr_accessor :reflect_amount
4
5
  attr_accessor :reflect_limit
5
6
  attr_accessor :meta_map
@@ -8,8 +9,12 @@ class Config
8
9
 
9
10
  def initialize()
10
11
 
12
+ # Reflekt is enabled by default and should be disabled on production.
13
+ @enabled = true
14
+
11
15
  # The amount of reflections to create per method call.
12
- @reflect_amount = 2
16
+ # A control reflection is created in addition to this.
17
+ @reflect_amount = 5
13
18
 
14
19
  # The maximum amount of reflections that can be created per instance/method.
15
20
  # A method called thousands of times doesn't need that many reflections.
@@ -20,6 +25,7 @@ class Config
20
25
  :array => [ArrayRule],
21
26
  :bool => [BooleanRule],
22
27
  :int => [IntegerRule],
28
+ :float => [FloatRule],
23
29
  :string => [StringRule]
24
30
  }
25
31
 
@@ -1,10 +1,12 @@
1
1
  ################################################################################
2
2
  # A shapshot of real data.
3
3
  #
4
+ # A control's @number property will always be zero.
5
+ #
4
6
  # @hierachy
5
7
  # 1. Execution
6
- # 2. Control
7
- # 3. RuleSet
8
+ # 2. Control <- YOU ARE HERE
9
+ # 3. Meta
8
10
  ################################################################################
9
11
 
10
12
  require 'Reflection'
@@ -15,27 +17,54 @@ class Control < Reflection
15
17
  ##
16
18
  # Reflect on a method.
17
19
  #
18
- # Creates a shadow execution stack.
19
- #
20
- # @param method [Symbol] The name of the method.
21
- # @param *args [Args] The method arguments.
22
- # @return [Hash] A reflection hash.
20
+ # Creates a shadow execution.
21
+ # @param *args [Dynamic] The method's arguments.
23
22
  ##
24
23
  def reflect(*args)
25
24
 
26
- # Create metadata for each argument.
27
- @inputs = MetaBuilder.create_many(args)
25
+ # Get aggregated rule sets.
26
+ input_rule_sets = @aggregator.get_input_rule_sets(@klass, @method)
27
+ output_rule_set = @aggregator.get_output_rule_set(@klass, @method)
28
+
29
+ # When arguments exist.
30
+ unless args.size == 0
31
+
32
+ # When aggregated rule sets exist.
33
+ unless input_rule_sets.nil?
34
+
35
+ # Validate arguments against aggregated rule sets.
36
+ unless @aggregator.test_inputs(args, input_rule_sets)
37
+ @status = :fail
38
+ end
39
+
40
+ end
41
+
42
+ # Create metadata for each argument.
43
+ # TODO: Create metadata for other inputs such as properties on the instance.
44
+ @inputs = MetaBuilder.create_many(args)
28
45
 
29
- # Action method with new arguments.
46
+ end
47
+
48
+ # Action method with new/old arguments.
30
49
  begin
50
+
51
+ # Run reflection.
31
52
  output = @clone.send(@method, *args)
32
- # When fail.
53
+ @output = MetaBuilder.create(output)
54
+
55
+ # Validate output with aggregated control rule sets.
56
+ unless output_rule_set.nil?
57
+ unless @aggregator.test_output(output, output_rule_set)
58
+ @status = :fail
59
+ end
60
+ end
61
+
62
+ # When a system error occurs.
33
63
  rescue StandardError => message
34
- @status = :fail
64
+
65
+ @status = :error
35
66
  @message = message
36
- # When pass.
37
- else
38
- @status = :pass
67
+
39
68
  end
40
69
 
41
70
  end
@@ -1,3 +1,12 @@
1
+ ################################################################################
2
+ # A shadow execution.
3
+ #
4
+ # @hierachy
5
+ # 1. Execution <- YOU ARE HERE
6
+ # 2. Reflection
7
+ # 3. Meta
8
+ ################################################################################
9
+
1
10
  class Execution
2
11
 
3
12
  attr_accessor :unique_id
@@ -19,10 +28,10 @@ class Execution
19
28
  #
20
29
  # @param object [Object] The calling object.
21
30
  # @param method [Symbol] The calling method.
22
- # @param number [Integer] The number of reflections to create per execution.
31
+ # @param reflect_amount [Integer] The number of reflections to create per execution.
23
32
  # @param stack [ShadowStack] The shadow execution call stack.
24
33
  ##
25
- def initialize(caller_object, method, number, stack)
34
+ def initialize(caller_object, method, reflect_amount, stack)
26
35
 
27
36
  @time = Time.now.to_i
28
37
  @unique_id = @time + rand(1..99999)
@@ -42,7 +51,7 @@ class Execution
42
51
 
43
52
  # Reflections.
44
53
  @control = nil
45
- @reflections = Array.new(number)
54
+ @reflections = Array.new(reflect_amount)
46
55
 
47
56
  # State.
48
57
  if @stack.peek() == nil