reflekt 0.9.8 → 1.0.3

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: c5b9e88d60fea03ebe06c430b489cb1295b8d56ec76f30982721a709a406f0af
4
- data.tar.gz: 948f53a8b72f5befda3e175029edfdb017d98b3b8fd41998ab95b5f6b0a6b95e
3
+ metadata.gz: d09b97f103669d2806a5c6e32da41e978fecff763c558d5aa8fb0739bf8e984a
4
+ data.tar.gz: 5f40bbfaa6444d452a0f91c1371d0d9aa75a5cd7edd5da8e36ac81d7f0c7532d
5
5
  SHA512:
6
- metadata.gz: e70f287d10e70e3ac8ab3e01881ed6d8bb79f881c9af5530f39c7dd29997021ddf246d1129467503cfb3c6efb0589604648876c64bda917e8b970cb278a79fb3
7
- data.tar.gz: ef005f855d7c3d1002eb059a73ecf742645841d4d3d0bd416a84b549e2e7d5b63a8bc216e8fe1404bf20c383a8e0a10c54740458e40382fa9591f9c67f3a075c
6
+ metadata.gz: c7198d5f60ee546e1becc9e7e75141705b0f4a01214e70bba2ba597872b2ff7dbd0cd60deb877a18fde3b4c25ba48ce94bede291bd9ddc089c3d195710dd5728
7
+ data.tar.gz: 23b79441dfa54881f1a537d259f686b8528f950aa1caac960c43403d7f5f24301a903ba99cc84d7bf1e743f6f6e16001141cff40a8c70139bf55032f38193131
@@ -2,14 +2,15 @@
2
2
  # Access variables via one object to avoid polluting the caller class scope.
3
3
  #
4
4
  # @pattern Singleton
5
+ #
5
6
  # @note Some variables are not accessed via Accessor:
6
7
  # - @reflekt_counts on the instance
7
- # - @reflekt_enabled on the instance
8
8
  # - @@reflekt_skipped_methods on the instance's singleton class
9
9
  ################################################################################
10
10
 
11
11
  class Accessor
12
12
 
13
+ attr_accessor :config
13
14
  attr_accessor :setup
14
15
  attr_accessor :db
15
16
  attr_accessor :stack
@@ -17,11 +18,11 @@ class Accessor
17
18
  attr_accessor :renderer
18
19
  attr_accessor :path
19
20
  attr_accessor :output_path
20
- attr_accessor :reflect_amount
21
- attr_accessor :reflect_limit
21
+ attr_accessor :error
22
22
 
23
23
  def initialize()
24
24
 
25
+ @config = nil
25
26
  @setup = nil
26
27
  @db = nil
27
28
  @stack = nil
@@ -29,8 +30,7 @@ class Accessor
29
30
  @renderer = nil
30
31
  @path = nil
31
32
  @output_path = nil
32
- @reflect_amount = nil
33
- @reflect_limit = nil
33
+ @error = false
34
34
 
35
35
  end
36
36
 
@@ -1,11 +1,11 @@
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
  #
7
7
  # @hierachy
8
- # 1. Aggregator
8
+ # 1. Aggregator <- YOU ARE HERE
9
9
  # 2. RuleSet
10
10
  # 3. Rule
11
11
  ################################################################################
@@ -14,102 +14,47 @@ require 'RuleSet'
14
14
 
15
15
  class Aggregator
16
16
 
17
- def initialize()
18
-
19
- # Key rule sets by class and method.
20
- @rule_sets = {}
21
-
22
- end
23
-
24
- ##
25
- # Get aggregated RuleSets for all inputs.
26
- #
27
- # @param klass [Symbol]
28
- # @param method [Symbol]
29
- # @return [Array]
30
- ##
31
- def get_input_rule_sets(klass, method)
32
- return @rule_sets.dig(klass, method, :inputs)
33
- end
34
-
35
- ##
36
- # Get an aggregated RuleSet for an input.
37
- #
38
- # @param klass [Symbol]
39
- # @param method [Symbol]
40
- # @return [RuleSet]
41
17
  ##
42
- def get_input_rule_set(klass, method, arg_num)
43
- @rule_sets.dig(klass, method, :inputs, arg_num)
44
- end
45
-
18
+ # @param meta_map [Hash] The rules that apply to each meta type.
46
19
  ##
47
- # Get an aggregated RuleSet for an output.
48
- #
49
- # @param klass [Symbol]
50
- # @param method [Symbol]
51
- # @return [RuleSet]
52
- ##
53
- def get_output_rule_set(klass, method)
54
- @rule_sets.dig(klass, method, :output)
55
- end
20
+ def initialize(meta_map)
56
21
 
57
- ##
58
- # Set an aggregated RuleSet for an input.
59
- #
60
- # @param klass [Symbol]
61
- # @param method [Symbol]
62
- ##
63
- def set_input_rule_set(klass, method, arg_num, rule_set)
64
- # Set defaults.
65
- @rule_sets[klass] = {} unless @rule_sets.key? klass
66
- @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
67
- @rule_sets[klass][method][:inputs] = [] unless @rule_sets[klass][method].key? :inputs
68
- # Set value.
69
- @rule_sets[klass][method][:inputs][arg_num] = rule_set
70
- end
22
+ @meta_map = meta_map
23
+ # Key rule sets by class and method.
24
+ @rule_sets = {}
71
25
 
72
- ##
73
- # Set an aggregated RuleSet for an output.
74
- #
75
- # @param klass [Symbol]
76
- # @param method [Symbol]
77
- # @param rule_set [RuleSet]
78
- ##
79
- def set_output_rule_set(klass, method, rule_set)
80
- # Set defaults.
81
- @rule_sets[klass] = {} unless @rule_sets.key? klass
82
- @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
83
- # Set value.
84
- @rule_sets[klass][method][:output] = rule_set
85
26
  end
86
27
 
87
28
  ##
88
- # Create aggregated rule sets from reflection metadata.
29
+ # Create aggregated rule sets from control metadata.
89
30
  #
90
- # @param reflections [Array] Controls with metadata.
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.
91
34
  ##
92
- def train(reflections)
35
+ def train(controls)
93
36
 
94
- # On first use there are no previous reflections.
95
- return if reflections.nil?
37
+ # On first use there are no previous controls.
38
+ return if controls.nil?
96
39
 
97
- reflections.each do |reflection|
40
+ controls.each do |control|
98
41
 
99
- klass = reflection[:class]
100
- method = reflection[:method]
42
+ klass = control["class"].to_sym
43
+ method = control["method"].to_sym
101
44
 
102
45
  ##
103
46
  # INPUT
104
47
  ##
105
48
 
106
- unless reflection[:inputs].nil?
107
- 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
+ meta = Meta.deserialize(meta)
108
53
 
109
54
  # Get rule set.
110
55
  rule_set = get_input_rule_set(klass, method, arg_num)
111
56
  if rule_set.nil?
112
- rule_set = RuleSet.new()
57
+ rule_set = RuleSet.new(@meta_map)
113
58
  set_input_rule_set(klass, method, arg_num, rule_set)
114
59
  end
115
60
 
@@ -126,12 +71,12 @@ class Aggregator
126
71
  # Get rule set.
127
72
  output_rule_set = get_output_rule_set(klass, method)
128
73
  if output_rule_set.nil?
129
- output_rule_set = RuleSet.new()
74
+ output_rule_set = RuleSet.new(@meta_map)
130
75
  set_output_rule_set(klass, method, output_rule_set)
131
76
  end
132
77
 
133
78
  # Train on metadata.
134
- output_rule_set.train(reflection[:output])
79
+ output_rule_set.train(Meta.deserialize(control["output"]))
135
80
 
136
81
  end
137
82
 
@@ -140,22 +85,23 @@ class Aggregator
140
85
  ##
141
86
  # Validate inputs.
142
87
  #
88
+ # @stage Called when validating a reflection.
143
89
  # @param inputs [Array] The method's arguments.
144
90
  # @param input_rule_sets [Array] The RuleSets to validate each input with.
145
91
  ##
146
- def validate_inputs(inputs, input_rule_sets)
92
+ def test_inputs(inputs, input_rule_sets)
147
93
 
148
- # Default to a PASS result.
94
+ # Default result to PASS.
149
95
  result = true
150
96
 
151
- # Validate each argument against each RuleSet for that argument.
97
+ # Validate each argument against each rule set for that argument.
152
98
  inputs.each_with_index do |input, arg_num|
153
99
 
154
100
  unless input_rule_sets[arg_num].nil?
155
101
 
156
102
  rule_set = input_rule_sets[arg_num]
157
103
 
158
- unless rule_set.validate_rule(input)
104
+ unless rule_set.test(input)
159
105
  result = false
160
106
  end
161
107
 
@@ -169,10 +115,11 @@ class Aggregator
169
115
  ##
170
116
  # Validate output.
171
117
  #
118
+ # @stage Called when validating a reflection.
172
119
  # @param output [Dynamic] The method's return value.
173
120
  # @param output_rule_set [RuleSet] The RuleSet to validate the output with.
174
121
  ##
175
- def validate_output(output, output_rule_set)
122
+ def test_output(output, output_rule_set)
176
123
 
177
124
  # Default to a PASS result.
178
125
  result = true
@@ -180,7 +127,7 @@ class Aggregator
180
127
  unless output_rule_set.nil?
181
128
 
182
129
  # Validate output RuleSet for that argument.
183
- unless output_rule_set.validate_rule(output)
130
+ unless output_rule_set.test(output)
184
131
  result = false
185
132
  end
186
133
 
@@ -190,4 +137,115 @@ class Aggregator
190
137
 
191
138
  end
192
139
 
140
+ ##
141
+ # Get aggregated RuleSets for all inputs.
142
+ #
143
+ # @stage Called when building a reflection.
144
+ # @param klass [Symbol]
145
+ # @param method [Symbol]
146
+ # @return [Array]
147
+ ##
148
+ def get_input_rule_sets(klass, method)
149
+ @rule_sets.dig(klass, method, :inputs)
150
+ end
151
+
152
+ ##
153
+ # Get an aggregated RuleSet for an output.
154
+ #
155
+ # @stage Called when building a reflection.
156
+ # @param klass [Symbol]
157
+ # @param method [Symbol]
158
+ # @return [RuleSet]
159
+ ##
160
+ def get_output_rule_set(klass, method)
161
+ @rule_sets.dig(klass, method, :output)
162
+ end
163
+
164
+ ##
165
+ # Get the base rule type for a data type.
166
+ ##
167
+ def self.value_to_rule_type(value)
168
+
169
+ data_type = value.class
170
+
171
+ rule_types = {
172
+ Array => ArrayRule,
173
+ TrueClass => BooleanRule,
174
+ FalseClass => BooleanRule,
175
+ Float => FloatRule,
176
+ Integer => IntegerRule,
177
+ NilClass => NullRule,
178
+ String => StringRule
179
+ }
180
+
181
+ return rule_types[data_type]
182
+
183
+ end
184
+
185
+ def self.testable?(args, input_rule_sets)
186
+
187
+ args.each_with_index do |arg, arg_num|
188
+
189
+ rule_type = value_to_rule_type(arg)
190
+ if input_rule_sets[arg_num].rules[rule_type].nil?
191
+ return false
192
+ end
193
+
194
+ end
195
+
196
+ return true
197
+
198
+ end
199
+
200
+ ##############################################################################
201
+ # HELPERS
202
+ ##############################################################################
203
+
204
+ private
205
+
206
+ ##
207
+ # Get an aggregated RuleSet for an input.
208
+ #
209
+ # @param klass [Symbol]
210
+ # @param method [Symbol]
211
+ # @return [RuleSet]
212
+ ##
213
+ def get_input_rule_set(klass, method, arg_num)
214
+ @rule_sets.dig(klass, method, :inputs, arg_num)
215
+ end
216
+
217
+ ##
218
+ # Set an aggregated RuleSet for an input.
219
+ #
220
+ # @param klass [Symbol]
221
+ # @param method [Symbol]
222
+ ##
223
+ def set_input_rule_set(klass, method, arg_num, rule_set)
224
+
225
+ # Set defaults.
226
+ @rule_sets[klass] = {} unless @rule_sets.key? klass
227
+ @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
228
+ @rule_sets[klass][method][:inputs] = [] unless @rule_sets[klass][method].key? :inputs
229
+ # Set value.
230
+ @rule_sets[klass][method][:inputs][arg_num] = rule_set
231
+
232
+ end
233
+
234
+ ##
235
+ # Set an aggregated RuleSet for an output.
236
+ #
237
+ # @param klass [Symbol]
238
+ # @param method [Symbol]
239
+ # @param rule_set [RuleSet]
240
+ ##
241
+ def set_output_rule_set(klass, method, rule_set)
242
+
243
+ # Set defaults.
244
+ @rule_sets[klass] = {} unless @rule_sets.key? klass
245
+ @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
246
+ # Set value.
247
+ @rule_sets[klass][method][:output] = rule_set
248
+
249
+ end
250
+
193
251
  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
@@ -0,0 +1,42 @@
1
+ class Config
2
+
3
+ attr_accessor :enabled
4
+ attr_accessor :reflect_amount
5
+ attr_accessor :reflect_limit
6
+ attr_accessor :meta_map
7
+ attr_accessor :output_path
8
+ attr_accessor :output_directory
9
+
10
+ def initialize()
11
+
12
+ # Reflekt is enabled by default and should be disabled on production.
13
+ @enabled = true
14
+
15
+ # The amount of reflections to create per method call.
16
+ # A control reflection is created in addition to this.
17
+ @reflect_amount = 5
18
+
19
+ # The maximum amount of reflections that can be created per instance/method.
20
+ # A method called thousands of times doesn't need that many reflections.
21
+ @reflect_limit = 10
22
+
23
+ # The rules that apply to meta types.
24
+ @meta_map = {
25
+ :array => [ArrayRule],
26
+ :bool => [BooleanRule],
27
+ :int => [IntegerRule],
28
+ :float => [FloatRule],
29
+ :null => [NullRule],
30
+ :string => [StringRule]
31
+ }
32
+
33
+ # An absolute path to the directory that contains the output directory.
34
+ # Defaults to current execution path.
35
+ @output_path = nil
36
+
37
+ # Name of output directory.
38
+ @output_directory = "reflections"
39
+
40
+ end
41
+
42
+ end
@@ -1,10 +1,21 @@
1
1
  ################################################################################
2
2
  # A shapshot of real data.
3
3
  #
4
+ # @note
5
+ # A control's @number property will always be zero.
6
+ #
7
+ # @nomenclature
8
+ # args, inputs/output and meta represent different stages of a value.
9
+ #
4
10
  # @hierachy
5
11
  # 1. Execution
6
- # 2. Control
7
- # 3. RuleSet
12
+ # 2. Control <- YOU ARE HERE
13
+ # 3. Meta
14
+ #
15
+ # @status
16
+ # - :pass [Symbol] The reflection passes the rules.
17
+ # - :fail [Symbol] The reflection fails the rules or produces a system error.
18
+ # - :error [Symbol] The control reflection produces a system error.
8
19
  ################################################################################
9
20
 
10
21
  require 'Reflection'
@@ -15,27 +26,54 @@ class Control < Reflection
15
26
  ##
16
27
  # Reflect on a method.
17
28
  #
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.
29
+ # Creates a shadow execution.
30
+ # @param *args [Dynamic] The method's arguments.
23
31
  ##
24
32
  def reflect(*args)
25
33
 
26
- # Create metadata for each argument.
27
- @inputs = MetaBuilder.create_many(args)
34
+ # Get aggregated rule sets.
35
+ input_rule_sets = @aggregator.get_input_rule_sets(@klass, @method)
36
+ output_rule_set = @aggregator.get_output_rule_set(@klass, @method)
37
+
38
+ # When arguments exist.
39
+ unless args.size == 0
40
+
41
+ # When aggregated rule sets exist.
42
+ unless input_rule_sets.nil?
43
+
44
+ # Validate arguments against aggregated rule sets.
45
+ unless @aggregator.test_inputs(args, input_rule_sets)
46
+ @status = :fail
47
+ end
48
+
49
+ end
28
50
 
29
- # Action method with new arguments.
51
+ # Create metadata for each argument.
52
+ # TODO: Create metadata for other inputs such as properties on the instance.
53
+ @inputs = MetaBuilder.create_many(args)
54
+
55
+ end
56
+
57
+ # Action method with new/old arguments.
30
58
  begin
59
+
60
+ # Run reflection.
31
61
  output = @clone.send(@method, *args)
32
- # When fail.
62
+ @output = MetaBuilder.create(output)
63
+
64
+ # Validate output with aggregated control rule sets.
65
+ unless output_rule_set.nil?
66
+ unless @aggregator.test_output(output, output_rule_set)
67
+ @status = :fail
68
+ end
69
+ end
70
+
71
+ # When a system error occurs.
33
72
  rescue StandardError => message
34
- @status = :fail
73
+
74
+ @status = :error
35
75
  @message = message
36
- # When pass.
37
- else
38
- @status = :pass
76
+
39
77
  end
40
78
 
41
79
  end