reflekt 1.0.5 → 1.0.10

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/lib/accessor.rb +45 -0
  3. data/lib/action.rb +127 -0
  4. data/lib/action_stack.rb +44 -0
  5. data/lib/{Clone.rb → clone.rb} +11 -11
  6. data/lib/config.rb +48 -0
  7. data/lib/control.rb +81 -0
  8. data/lib/experiment.rb +99 -0
  9. data/lib/meta.rb +75 -0
  10. data/lib/meta/array_meta.rb +32 -0
  11. data/lib/meta/boolean_meta.rb +26 -0
  12. data/lib/meta/float_meta.rb +26 -0
  13. data/lib/meta/integer_meta.rb +26 -0
  14. data/lib/meta/{NullMeta.rb → null_meta.rb} +21 -19
  15. data/lib/meta/object_meta.rb +35 -0
  16. data/lib/meta/string_meta.rb +26 -0
  17. data/lib/meta_builder.rb +100 -0
  18. data/lib/reflection.rb +123 -0
  19. data/lib/reflekt.rb +277 -0
  20. data/lib/renderer.rb +38 -0
  21. data/lib/rule.rb +54 -0
  22. data/lib/rule_set.rb +110 -0
  23. data/lib/rule_set_aggregator.rb +260 -0
  24. data/lib/rules/array_rule.rb +94 -0
  25. data/lib/rules/boolean_rule.rb +43 -0
  26. data/lib/rules/float_rule.rb +55 -0
  27. data/lib/rules/integer_rule.rb +55 -0
  28. data/lib/rules/null_rule.rb +35 -0
  29. data/lib/rules/object_rule.rb +42 -0
  30. data/lib/rules/string_rule.rb +75 -0
  31. data/lib/web/index.html +3 -4
  32. metadata +46 -29
  33. data/lib/Accessor.rb +0 -37
  34. data/lib/Action.rb +0 -88
  35. data/lib/ActionStack.rb +0 -44
  36. data/lib/Aggregator.rb +0 -260
  37. data/lib/Config.rb +0 -42
  38. data/lib/Control.rb +0 -83
  39. data/lib/Meta.rb +0 -71
  40. data/lib/MetaBuilder.rb +0 -84
  41. data/lib/Reflection.rb +0 -195
  42. data/lib/Reflekt.rb +0 -243
  43. data/lib/Renderer.rb +0 -39
  44. data/lib/Rule.rb +0 -52
  45. data/lib/RuleSet.rb +0 -109
  46. data/lib/meta/ArrayMeta.rb +0 -34
  47. data/lib/meta/BooleanMeta.rb +0 -26
  48. data/lib/meta/FloatMeta.rb +0 -26
  49. data/lib/meta/IntegerMeta.rb +0 -26
  50. data/lib/meta/StringMeta.rb +0 -26
  51. data/lib/rules/ArrayRule.rb +0 -88
  52. data/lib/rules/BooleanRule.rb +0 -47
  53. data/lib/rules/FloatRule.rb +0 -57
  54. data/lib/rules/IntegerRule.rb +0 -57
  55. data/lib/rules/NullRule.rb +0 -33
  56. data/lib/rules/StringRule.rb +0 -81
data/lib/ActionStack.rb DELETED
@@ -1,44 +0,0 @@
1
- ################################################################################
2
- # Track the actions in a shadow call stack.
3
- #
4
- # @pattern Stack
5
- ################################################################################
6
-
7
- class ActionStack
8
-
9
- def initialize()
10
- @bottom = nil
11
- @top = nil
12
- end
13
-
14
- def peek()
15
- @top
16
- end
17
-
18
- def base()
19
- @bottom
20
- end
21
-
22
- ##
23
- # Place Action at the top of stack.
24
- #
25
- # @param action [Action] The action to place.
26
- # @return [Action] The placed action.
27
- ##
28
- def push(action)
29
-
30
- # Place first action at bottom of stack.
31
- if @bottom.nil?
32
- @bottom = action
33
- # Connect subsequent actions to each other.
34
- else
35
- @top.parent = action
36
- action.child = @top
37
- end
38
-
39
- # Place action at top of stack.
40
- @top = action
41
-
42
- end
43
-
44
- end
data/lib/Aggregator.rb DELETED
@@ -1,260 +0,0 @@
1
- ################################################################################
2
- # Aggregate control metadata into rule sets.
3
- # Validate reflections against aggregated controls.
4
- #
5
- # @pattern Singleton
6
- #
7
- # @hierachy
8
- # 1. Aggregator <- YOU ARE HERE
9
- # 2. RuleSet
10
- # 3. Rule
11
- ################################################################################
12
-
13
- require 'RuleSet'
14
-
15
- class Aggregator
16
-
17
- ##
18
- # @param meta_map [Hash] The rules that apply to each meta type.
19
- ##
20
- def initialize(meta_map)
21
-
22
- @meta_map = meta_map
23
- # Key rule sets by class and method.
24
- @rule_sets = {}
25
-
26
- end
27
-
28
- ##
29
- # Create aggregated rule sets from control metadata.
30
- #
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.
34
- ##
35
- def train(controls)
36
-
37
- # On first use there are no previous controls.
38
- return if controls.nil?
39
-
40
- controls.each do |control|
41
-
42
- klass = control["class"].to_sym
43
- method = control["method"].to_sym
44
-
45
- ##
46
- # INPUT
47
- ##
48
-
49
- # Singular null input.
50
- if control["inputs"].nil?
51
- train_input(klass, method, nil, 0)
52
- # Multiple inputs.
53
- else
54
- control["inputs"].each_with_index do |meta, arg_num|
55
- train_input(klass, method, meta, arg_num)
56
- end
57
- end
58
-
59
- ##
60
- # OUTPUT
61
- ##
62
-
63
- # Get rule set.
64
- output_rule_set = get_output_rule_set(klass, method)
65
- if output_rule_set.nil?
66
- output_rule_set = RuleSet.new(@meta_map)
67
- set_output_rule_set(klass, method, output_rule_set)
68
- end
69
-
70
- # Train on metadata.
71
- output_rule_set.train(Meta.deserialize(control["output"]))
72
-
73
- end
74
-
75
- end
76
-
77
- def train_input(klass, method, meta, arg_num)
78
-
79
- # Get deserialized meta.
80
- meta = Meta.deserialize(meta)
81
-
82
- # Get rule set.
83
- rule_set = get_input_rule_set(klass, method, arg_num)
84
- if rule_set.nil?
85
- rule_set = RuleSet.new(@meta_map)
86
- set_input_rule_set(klass, method, arg_num, rule_set)
87
- end
88
-
89
- # Train on metadata.
90
- rule_set.train(meta)
91
-
92
- end
93
-
94
- ##
95
- # Validate inputs.
96
- #
97
- # @stage Called when validating a control reflection.
98
- # @param inputs [Array] The method's arguments.
99
- # @param input_rule_sets [Array] The RuleSets to validate each input with.
100
- ##
101
- def test_inputs(inputs, input_rule_sets)
102
-
103
- # Default result to PASS.
104
- result = true
105
-
106
- # Validate each argument against each rule set for that argument.
107
- inputs.each_with_index do |input, arg_num|
108
-
109
- unless input_rule_sets[arg_num].nil?
110
-
111
- rule_set = input_rule_sets[arg_num]
112
-
113
- unless rule_set.test(input)
114
- result = false
115
- end
116
-
117
- end
118
- end
119
-
120
- return result
121
-
122
- end
123
-
124
- ##
125
- # Validate output.
126
- #
127
- # @stage Called when validating a reflection.
128
- # @param output [Dynamic] The method's return value.
129
- # @param output_rule_set [RuleSet] The RuleSet to validate the output with.
130
- ##
131
- def test_output(output, output_rule_set)
132
-
133
- # Default to a PASS result.
134
- result = true
135
-
136
- unless output_rule_set.nil?
137
-
138
- # Validate output RuleSet for that argument.
139
- unless output_rule_set.test(output)
140
- result = false
141
- end
142
-
143
- end
144
-
145
- return result
146
-
147
- end
148
-
149
- ##
150
- # Get aggregated RuleSets for all inputs.
151
- #
152
- # @stage Called when building a reflection.
153
- # @param klass [Symbol]
154
- # @param method [Symbol]
155
- # @return [Array]
156
- ##
157
- def get_input_rule_sets(klass, method)
158
- @rule_sets.dig(klass, method, :inputs)
159
- end
160
-
161
- ##
162
- # Get an aggregated RuleSet for an output.
163
- #
164
- # @stage Called when building a reflection.
165
- # @param klass [Symbol]
166
- # @param method [Symbol]
167
- # @return [RuleSet]
168
- ##
169
- def get_output_rule_set(klass, method)
170
- @rule_sets.dig(klass, method, :output)
171
- end
172
-
173
- ##
174
- # Get the base rule type for a data type.
175
- ##
176
- def self.value_to_rule_type(value)
177
-
178
- data_type = value.class
179
-
180
- rule_types = {
181
- Array => ArrayRule,
182
- TrueClass => BooleanRule,
183
- FalseClass => BooleanRule,
184
- Float => FloatRule,
185
- Integer => IntegerRule,
186
- NilClass => NullRule,
187
- String => StringRule
188
- }
189
-
190
- return rule_types[data_type]
191
-
192
- end
193
-
194
- def self.testable?(args, input_rule_sets)
195
-
196
- args.each_with_index do |arg, arg_num|
197
-
198
- rule_type = value_to_rule_type(arg)
199
- if input_rule_sets[arg_num].rules[rule_type].nil?
200
- return false
201
- end
202
-
203
- end
204
-
205
- return true
206
-
207
- end
208
-
209
- ##############################################################################
210
- # HELPERS
211
- ##############################################################################
212
-
213
- private
214
-
215
- ##
216
- # Get an aggregated RuleSet for an input.
217
- #
218
- # @param klass [Symbol]
219
- # @param method [Symbol]
220
- # @return [RuleSet]
221
- ##
222
- def get_input_rule_set(klass, method, arg_num)
223
- @rule_sets.dig(klass, method, :inputs, arg_num)
224
- end
225
-
226
- ##
227
- # Set an aggregated RuleSet for an input.
228
- #
229
- # @param klass [Symbol]
230
- # @param method [Symbol]
231
- ##
232
- def set_input_rule_set(klass, method, arg_num, rule_set)
233
-
234
- # Set defaults.
235
- @rule_sets[klass] = {} unless @rule_sets.key? klass
236
- @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
237
- @rule_sets[klass][method][:inputs] = [] unless @rule_sets[klass][method].key? :inputs
238
- # Set value.
239
- @rule_sets[klass][method][:inputs][arg_num] = rule_set
240
-
241
- end
242
-
243
- ##
244
- # Set an aggregated RuleSet for an output.
245
- #
246
- # @param klass [Symbol]
247
- # @param method [Symbol]
248
- # @param rule_set [RuleSet]
249
- ##
250
- def set_output_rule_set(klass, method, rule_set)
251
-
252
- # Set defaults.
253
- @rule_sets[klass] = {} unless @rule_sets.key? klass
254
- @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
255
- # Set value.
256
- @rule_sets[klass][method][:output] = rule_set
257
-
258
- end
259
-
260
- end
data/lib/Config.rb DELETED
@@ -1,42 +0,0 @@
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 action path.
35
- @output_path = nil
36
-
37
- # Name of output directory.
38
- @output_directory = "reflections"
39
-
40
- end
41
-
42
- end
data/lib/Control.rb DELETED
@@ -1,83 +0,0 @@
1
- ################################################################################
2
- # A shapshot of real data.
3
- #
4
- # @note
5
- # A control's @number will always be 0.
6
- #
7
- # @nomenclature
8
- # args, inputs/output and meta represent different stages of a value.
9
- #
10
- # @hierachy
11
- # 1. Action
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.
19
- ################################################################################
20
-
21
- require 'Reflection'
22
- require 'MetaBuilder'
23
-
24
- class Control < Reflection
25
-
26
- ##
27
- # Reflect on a method.
28
- #
29
- # Creates a shadow action.
30
- # @param *args [Dynamic] The method's arguments.
31
- ##
32
- def reflect(*args)
33
-
34
- # Get trained 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
- # Fail when no trained rule sets.
39
- if input_rule_sets.nil?
40
- @status = :fail
41
- end
42
-
43
- # When arguments exist.
44
- unless args.size == 0
45
-
46
- # Validate arguments against trained rule sets.
47
- unless input_rule_sets.nil?
48
- unless @aggregator.test_inputs(args, input_rule_sets)
49
- @status = :fail
50
- end
51
- end
52
-
53
- # Create metadata for each argument.
54
- # TODO: Create metadata for other inputs such as instance variables.
55
- @inputs = MetaBuilder.create_many(args)
56
-
57
- end
58
-
59
- # Action method with real arguments.
60
- begin
61
-
62
- # Run reflection.
63
- output = @clone.send(@method, *args)
64
- @output = MetaBuilder.create(output)
65
-
66
- # Validate output with aggregated control rule sets.
67
- unless output_rule_set.nil?
68
- unless @aggregator.test_output(output, output_rule_set)
69
- @status = :fail
70
- end
71
- end
72
-
73
- # When a system error occurs.
74
- rescue StandardError => message
75
-
76
- @status = :error
77
- @message = message
78
-
79
- end
80
-
81
- end
82
-
83
- end
data/lib/Meta.rb DELETED
@@ -1,71 +0,0 @@
1
- ################################################################################
2
- # Metadata for input and output.
3
- #
4
- # @pattern Abstract class
5
- # @see lib/meta for each meta.
6
- #
7
- # @hierachy
8
- # 1. Action
9
- # 2. Reflection
10
- # 3. Meta <- YOU ARE HERE
11
- ################################################################################
12
-
13
- class Meta
14
-
15
- ##
16
- # Each meta defines its type.
17
- ##
18
- def initialize()
19
- @type = :null
20
- end
21
-
22
- ##
23
- # Each meta loads values.
24
- #
25
- # @param value [Dynamic]
26
- ##
27
- def load(value)
28
- end
29
-
30
- ##
31
- # @return [Hash]
32
- ##
33
- def serialize()
34
- {
35
- :type => @type
36
- }
37
- end
38
-
39
- ##############################################################################
40
- # CLASS
41
- ##############################################################################
42
-
43
- ##
44
- # Deserialize metadata.
45
- #
46
- # @todo Deserialize should create a Meta object.
47
- # @todo Require each Meta type to handle its own deserialization.
48
- #
49
- # @param meta [Hash] The metadata to deserialize.
50
- # @param meta [Hash]
51
- ##
52
- def self.deserialize(meta)
53
-
54
- # Convert nil meta into NullMeta.
55
- # Meta is nil when there are no @inputs or @output on the method.
56
- if meta.nil?
57
- return NullMeta.new().serialize()
58
- end
59
-
60
- # Symbolize keys.
61
- # TODO: Remove once "Fix Rowdb.get(path)" bug fixed.
62
- meta = meta.transform_keys(&:to_sym)
63
-
64
- # Symbolize type value.
65
- meta[:type] = meta[:type].to_sym
66
-
67
- return meta
68
-
69
- end
70
-
71
- end