reflekt 1.0.5 → 1.0.10

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,260 @@
1
+ ################################################################################
2
+ # Aggregate control metadata into rule sets.
3
+ # Validate reflections against aggregated controls.
4
+ #
5
+ # @pattern Singleton
6
+ #
7
+ # @hierachy
8
+ # 1. RuleSetAggregator <- YOU ARE HERE
9
+ # 2. RuleSet
10
+ # 3. Rule
11
+ ################################################################################
12
+
13
+ require_relative 'rule_set'
14
+
15
+ module Reflekt
16
+ class RuleSetAggregator
17
+
18
+ ##
19
+ # @param meta_map [Hash] The rules that apply to each meta type.
20
+ ##
21
+ def initialize(meta_map)
22
+ @meta_map = meta_map
23
+ # Key rule sets by class and method.
24
+ @rule_sets = {}
25
+ end
26
+
27
+ ##
28
+ # Create aggregated rule sets from control metadata.
29
+ #
30
+ # @stage Called on setup.
31
+ # @param controls [Array] Controls with metadata.
32
+ # @TODO Revert string keys to symbols once "Fix Rowdb.get(path)" bug fixed.
33
+ ##
34
+ def train(controls)
35
+
36
+ # On first use there are no previous controls.
37
+ return if controls.nil?
38
+
39
+ controls.each do |control|
40
+
41
+ klass = control["class"].to_sym
42
+ method = control["method"].to_sym
43
+
44
+ ##
45
+ # INPUT
46
+ ##
47
+
48
+ # Singular null input.
49
+ if control["inputs"].nil?
50
+ train_input(klass, method, nil, 0)
51
+ # Multiple inputs.
52
+ else
53
+ control["inputs"].each_with_index do |meta, arg_num|
54
+ train_input(klass, method, meta, arg_num)
55
+ end
56
+ end
57
+
58
+ ##
59
+ # OUTPUT
60
+ ##
61
+
62
+ # Get rule set.
63
+ output_rule_set = get_output_rule_set(klass, method)
64
+ if output_rule_set.nil?
65
+ output_rule_set = RuleSet.new(@meta_map)
66
+ set_output_rule_set(klass, method, output_rule_set)
67
+ end
68
+
69
+ # Train on metadata.
70
+ output_rule_set.train(Meta.deserialize(control["output"]))
71
+
72
+ end
73
+
74
+ end
75
+
76
+ def train_input(klass, method, meta, arg_num)
77
+
78
+ # Get deserialized meta.
79
+ meta = Meta.deserialize(meta)
80
+
81
+ # Get rule set.
82
+ rule_set = get_input_rule_set(klass, method, arg_num)
83
+ if rule_set.nil?
84
+ rule_set = RuleSet.new(@meta_map)
85
+ set_input_rule_set(klass, method, arg_num, rule_set)
86
+ end
87
+
88
+ # Train on metadata.
89
+ rule_set.train(meta)
90
+
91
+ end
92
+
93
+ ##
94
+ # Validate inputs.
95
+ #
96
+ # @stage Called when validating a control reflection.
97
+ # @param inputs [Array] The method's arguments.
98
+ # @param input_rule_sets [Array] The RuleSets to validate each input with.
99
+ ##
100
+ def test_inputs(inputs, input_rule_sets)
101
+
102
+ # Default result to PASS.
103
+ result = true
104
+
105
+ # Validate each argument against each rule set for that argument.
106
+ inputs.each_with_index do |input, arg_num|
107
+
108
+ unless input_rule_sets[arg_num].nil?
109
+
110
+ rule_set = input_rule_sets[arg_num]
111
+
112
+ unless rule_set.test(input)
113
+ result = false
114
+ end
115
+
116
+ end
117
+ end
118
+
119
+ return result
120
+
121
+ end
122
+
123
+ ##
124
+ # Validate output.
125
+ #
126
+ # @stage Called when validating a reflection.
127
+ # @param output [Dynamic] The method's return value.
128
+ # @param output_rule_set [RuleSet] The rule set to validate the output with.
129
+ ##
130
+ def test_output(output, output_rule_set)
131
+
132
+ # Default to a PASS result.
133
+ result = true
134
+
135
+ unless output_rule_set.nil?
136
+
137
+ # Validate output rule set for that argument.
138
+ unless output_rule_set.test(output)
139
+ result = false
140
+ end
141
+
142
+ end
143
+
144
+ return result
145
+
146
+ end
147
+
148
+ ##
149
+ # Get aggregated RuleSets for all inputs.
150
+ #
151
+ # @stage Called when building a reflection.
152
+ # @param klass [Symbol]
153
+ # @param method [Symbol]
154
+ # @return [Array]
155
+ ##
156
+ def get_input_rule_sets(klass, method)
157
+ @rule_sets.dig(klass, method, :inputs)
158
+ end
159
+
160
+ ##
161
+ # Get an aggregated RuleSet for an output.
162
+ #
163
+ # @stage Called when building a reflection.
164
+ # @param klass [Symbol]
165
+ # @param method [Symbol]
166
+ # @return [RuleSet]
167
+ ##
168
+ def get_output_rule_set(klass, method)
169
+ @rule_sets.dig(klass, method, :output)
170
+ end
171
+
172
+ ##
173
+ # Get the base rule type for a data type.
174
+ ##
175
+ def self.value_to_rule_type(value)
176
+
177
+ data_type = value.class
178
+
179
+ rule_types = {
180
+ Array => ArrayRule,
181
+ TrueClass => BooleanRule,
182
+ FalseClass => BooleanRule,
183
+ Float => FloatRule,
184
+ Integer => IntegerRule,
185
+ NilClass => NullRule,
186
+ String => StringRule
187
+ }
188
+
189
+ return rule_types[data_type]
190
+
191
+ end
192
+
193
+ def self.testable?(args, input_rule_sets)
194
+
195
+ args.each_with_index do |arg, arg_num|
196
+
197
+ rule_type = value_to_rule_type(arg)
198
+ if input_rule_sets[arg_num].rules[rule_type].nil?
199
+ return false
200
+ end
201
+
202
+ end
203
+
204
+ return true
205
+
206
+ end
207
+
208
+ ##############################################################################
209
+ # HELPERS
210
+ ##############################################################################
211
+
212
+ private
213
+
214
+ ##
215
+ # Get an aggregated RuleSet for an input.
216
+ #
217
+ # @param klass [Symbol]
218
+ # @param method [Symbol]
219
+ # @return [RuleSet]
220
+ ##
221
+ def get_input_rule_set(klass, method, arg_num)
222
+ @rule_sets.dig(klass, method, :inputs, arg_num)
223
+ end
224
+
225
+ ##
226
+ # Set an aggregated RuleSet for an input.
227
+ #
228
+ # @param klass [Symbol]
229
+ # @param method [Symbol]
230
+ ##
231
+ def set_input_rule_set(klass, method, arg_num, rule_set)
232
+
233
+ # Set defaults.
234
+ @rule_sets[klass] = {} unless @rule_sets.key? klass
235
+ @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
236
+ @rule_sets[klass][method][:inputs] = [] unless @rule_sets[klass][method].key? :inputs
237
+ # Set value.
238
+ @rule_sets[klass][method][:inputs][arg_num] = rule_set
239
+
240
+ end
241
+
242
+ ##
243
+ # Set an aggregated RuleSet for an output.
244
+ #
245
+ # @param klass [Symbol]
246
+ # @param method [Symbol]
247
+ # @param rule_set [RuleSet]
248
+ ##
249
+ def set_output_rule_set(klass, method, rule_set)
250
+
251
+ # Set defaults.
252
+ @rule_sets[klass] = {} unless @rule_sets.key? klass
253
+ @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
254
+ # Set value.
255
+ @rule_sets[klass][method][:output] = rule_set
256
+
257
+ end
258
+
259
+ end
260
+ end
@@ -0,0 +1,94 @@
1
+ require_relative '../rule'
2
+
3
+ module Reflekt
4
+ class ArrayRule < Rule
5
+
6
+ def initialize()
7
+ @type = :array
8
+ @min = nil
9
+ @max = nil
10
+ @min_length = nil
11
+ @max_length = nil
12
+ end
13
+
14
+ ##
15
+ # @param meta [ArrayMeta]
16
+ ##
17
+ def train(meta)
18
+ if Meta.numeric? meta[:min]
19
+ # Min value.
20
+ meta_min = meta[:min].to_i
21
+ if @min.nil?
22
+ @min = meta_min
23
+ else
24
+ @min = meta_min if meta_min < @min
25
+ end
26
+
27
+ # Max value.
28
+ meta_max = meta[:max].to_i
29
+ if @max.nil?
30
+ @max = meta_max
31
+ else
32
+ @max = meta_max if meta_max > @max
33
+ end
34
+ end
35
+
36
+ # Min length.
37
+ if @min_length.nil?
38
+ @min_length = meta[:length]
39
+ else
40
+ @min_length = meta[:length] if meta[:length] < @min_length
41
+ end
42
+
43
+ # Max length.
44
+ if @max_length.nil?
45
+ @max_length = meta[:length]
46
+ else
47
+ @max_length = meta[:length] if meta[:length] > @max_length
48
+ end
49
+ end
50
+
51
+ ##
52
+ # @param value [Array]
53
+ ##
54
+ def test(value)
55
+ # Handle empty value.
56
+ return true if value.empty? && @min_length == 0 && @max_length == 0
57
+
58
+ unless value.empty?
59
+ # Numbers only; if the value is a string then there will be no min/max.
60
+ unless @min.nil? || @max.nil?
61
+ return false if value.min() < @min
62
+ return false if value.max() > @max
63
+ end
64
+
65
+ # Min/max length.
66
+ return false if value.length < @min_length
67
+ return false if value.length > @max_length
68
+ end
69
+
70
+ true
71
+ end
72
+
73
+ def result()
74
+ {
75
+ :type => @type,
76
+ :min => @min,
77
+ :max => @max,
78
+ :min_length => @min_length,
79
+ :max_length => @max_length
80
+ }
81
+ end
82
+
83
+ def random()
84
+ array = Array.new(rand(@min_length..@max_length))
85
+
86
+ array.each_with_index do |item, index|
87
+ array[index] = rand(@min..@max)
88
+ end
89
+
90
+ return array
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,43 @@
1
+ require 'set'
2
+ require_relative '../rule'
3
+
4
+ module Reflekt
5
+ class BooleanRule < Rule
6
+
7
+ def initialize()
8
+ @type = :bool
9
+ @booleans = Set.new()
10
+ end
11
+
12
+ ##
13
+ # @param meta [BooleanMeta]
14
+ ##
15
+ def train(meta)
16
+ value = meta[:value]
17
+
18
+ unless value.nil?
19
+ @booleans << value
20
+ end
21
+ end
22
+
23
+ ##
24
+ # @param value [Boolean]
25
+ ##
26
+ def test(value)
27
+ # Booleans are stored as strings.
28
+ @booleans.include? value.to_s
29
+ end
30
+
31
+ def result()
32
+ {
33
+ :type => @type,
34
+ :booleans => @booleans
35
+ }
36
+ end
37
+
38
+ def random()
39
+ @booleans.to_a.sample
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,55 @@
1
+ require_relative '../rule'
2
+
3
+ module Reflekt
4
+ class FloatRule < Rule
5
+
6
+ def initialize()
7
+ @type = :float
8
+ @min = nil
9
+ @max = nil
10
+ end
11
+
12
+ ##
13
+ # @param meta [FloatMeta]
14
+ ##
15
+ def train(meta)
16
+ value = meta[:value]
17
+
18
+ if @min.nil?
19
+ @min = value
20
+ else
21
+ @min = value if value < @min
22
+ end
23
+
24
+ if @max.nil?
25
+ @max = value
26
+ else
27
+ @max = value if value > @max
28
+ end
29
+ end
30
+
31
+ ##
32
+ # @param value [Float]
33
+ ##
34
+ def test(value)
35
+ # Numbers only; if the value is a string then there will be no min/max.
36
+ unless @min.nil? || @max.nil?
37
+ return false if value < @min
38
+ return false if value > @max
39
+ end
40
+ end
41
+
42
+ def result()
43
+ {
44
+ :type => @type,
45
+ :min => @min,
46
+ :max => @max
47
+ }
48
+ end
49
+
50
+ def random()
51
+ rand(@min..@max)
52
+ end
53
+
54
+ end
55
+ end