reflekt 0.9.9 → 1.0.0

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
  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