reflekt 0.9.7 → 0.9.8

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: 6df15da98e45aecc17c3594c000b6234f77afde5ce89541104bc3afe7eb5a221
4
- data.tar.gz: 3f1446eb16bdcd214d3df924d0b2df0017bc26b073c5c94e36d1094849a9b1ef
3
+ metadata.gz: c5b9e88d60fea03ebe06c430b489cb1295b8d56ec76f30982721a709a406f0af
4
+ data.tar.gz: 948f53a8b72f5befda3e175029edfdb017d98b3b8fd41998ab95b5f6b0a6b95e
5
5
  SHA512:
6
- metadata.gz: e84519473c26febf3522119e66b25708abc1f05271c01b498debcb00c69eaf4b8bc244e43374737fef49e946304529c0efc2e6fceade3629c4ccef5503f1d3fa
7
- data.tar.gz: 8faa3f80665504b4e5ffb182b7e9977234bd13e2f17aa5fac41636068b30ea07bfbf5aa580bee6deae2bb8e5fa6ea0ea7dc09505ce0a28bbf8797bb785aea0bb
6
+ metadata.gz: e70f287d10e70e3ac8ab3e01881ed6d8bb79f881c9af5530f39c7dd29997021ddf246d1129467503cfb3c6efb0589604648876c64bda917e8b970cb278a79fb3
7
+ data.tar.gz: ef005f855d7c3d1002eb059a73ecf742645841d4d3d0bd416a84b549e2e7d5b63a8bc216e8fe1404bf20c383a8e0a10c54740458e40382fa9591f9c67f3a075c
@@ -1,9 +1,8 @@
1
1
  ################################################################################
2
- # ACCESSOR
3
- #
4
2
  # Access variables via one object to avoid polluting the caller class scope.
5
3
  #
6
- # Some variables are not accessed via Accessor:
4
+ # @pattern Singleton
5
+ # @note Some variables are not accessed via Accessor:
7
6
  # - @reflekt_counts on the instance
8
7
  # - @reflekt_enabled on the instance
9
8
  # - @@reflekt_skipped_methods on the instance's singleton class
@@ -14,7 +13,7 @@ class Accessor
14
13
  attr_accessor :setup
15
14
  attr_accessor :db
16
15
  attr_accessor :stack
17
- attr_accessor :ruler
16
+ attr_accessor :aggregator
18
17
  attr_accessor :renderer
19
18
  attr_accessor :path
20
19
  attr_accessor :output_path
@@ -26,7 +25,7 @@ class Accessor
26
25
  @setup = nil
27
26
  @db = nil
28
27
  @stack = nil
29
- @ruler = nil
28
+ @aggregator = nil
30
29
  @renderer = nil
31
30
  @path = nil
32
31
  @output_path = nil
@@ -1,60 +1,64 @@
1
1
  ################################################################################
2
- # RULER
2
+ # Aggregate reflection metadata into rule sets.
3
+ # Validate reflection arguments against aggregates.
3
4
  #
4
- # Aggregates input/output from controls.
5
- # Creates and trains RuleSets from aggregated input/output.
6
- # Validates reflection input/output against RuleSets.
5
+ # @pattern Singleton
6
+ #
7
+ # @hierachy
8
+ # 1. Aggregator
9
+ # 2. RuleSet
10
+ # 3. Rule
7
11
  ################################################################################
8
12
 
9
13
  require 'RuleSet'
10
14
 
11
- class Ruler
15
+ class Aggregator
12
16
 
13
17
  def initialize()
18
+
19
+ # Key rule sets by class and method.
14
20
  @rule_sets = {}
21
+
15
22
  end
16
23
 
17
24
  ##
18
- # Get input RuleSets.
25
+ # Get aggregated RuleSets for all inputs.
19
26
  #
20
- # @param Symbol klass
21
- # @param Symbol method
22
- #
23
- # @return Array
27
+ # @param klass [Symbol]
28
+ # @param method [Symbol]
29
+ # @return [Array]
24
30
  ##
25
31
  def get_input_rule_sets(klass, method)
26
32
  return @rule_sets.dig(klass, method, :inputs)
27
33
  end
28
34
 
29
35
  ##
30
- # Get input RuleSet.
31
- #
32
- # @param Symbol klass
33
- # @param Symbol method
36
+ # Get an aggregated RuleSet for an input.
34
37
  #
35
- # @return RuleSet
38
+ # @param klass [Symbol]
39
+ # @param method [Symbol]
40
+ # @return [RuleSet]
36
41
  ##
37
42
  def get_input_rule_set(klass, method, arg_num)
38
43
  @rule_sets.dig(klass, method, :inputs, arg_num)
39
44
  end
40
45
 
41
46
  ##
42
- # Get output RuleSet.
43
- #
44
- # @param Symbol klass
45
- # @param Symbol method
47
+ # Get an aggregated RuleSet for an output.
46
48
  #
47
- # @return RuleSet.
49
+ # @param klass [Symbol]
50
+ # @param method [Symbol]
51
+ # @return [RuleSet]
48
52
  ##
49
53
  def get_output_rule_set(klass, method)
50
54
  @rule_sets.dig(klass, method, :output)
51
55
  end
52
56
 
53
57
  ##
54
- # Set input RuleSet.
58
+ # Set an aggregated RuleSet for an input.
55
59
  #
56
- # @param Symbol klass
57
- # @param Symbol method
60
+ # @param klass [Symbol]
61
+ # @param method [Symbol]
58
62
  ##
59
63
  def set_input_rule_set(klass, method, arg_num, rule_set)
60
64
  # Set defaults.
@@ -66,11 +70,11 @@ class Ruler
66
70
  end
67
71
 
68
72
  ##
69
- # Set output RuleSet.
73
+ # Set an aggregated RuleSet for an output.
70
74
  #
71
- # @param Symbol klass
72
- # @param Symbol method
73
- # @param RuleSet rule_set
75
+ # @param klass [Symbol]
76
+ # @param method [Symbol]
77
+ # @param rule_set [RuleSet]
74
78
  ##
75
79
  def set_output_rule_set(klass, method, rule_set)
76
80
  # Set defaults.
@@ -81,57 +85,54 @@ class Ruler
81
85
  end
82
86
 
83
87
  ##
84
- # Load RuleSets.
88
+ # Create aggregated rule sets from reflection metadata.
85
89
  #
86
- # @param Symbol klass
87
- # @param Symbol method
88
- # @param Array controls
90
+ # @param reflections [Array] Controls with metadata.
89
91
  ##
90
- def load(klass, method, controls)
92
+ def train(reflections)
93
+
94
+ # On first use there are no previous reflections.
95
+ return if reflections.nil?
96
+
97
+ reflections.each do |reflection|
98
+
99
+ klass = reflection[:class]
100
+ method = reflection[:method]
101
+
102
+ ##
103
+ # INPUT
104
+ ##
105
+
106
+ unless reflection[:inputs].nil?
107
+ reflection[:inputs].each_with_index do |meta, arg_num|
108
+
109
+ # Get rule set.
110
+ rule_set = get_input_rule_set(klass, method, arg_num)
111
+ if rule_set.nil?
112
+ rule_set = RuleSet.new()
113
+ set_input_rule_set(klass, method, arg_num, rule_set)
114
+ end
91
115
 
92
- # Create a RuleSet for each control's inputs/output.
93
- controls.each_with_index do |control, index|
116
+ # Train on metadata.
117
+ rule_set.train(meta)
94
118
 
95
- # Process inputs.
96
- control[:inputs].each_with_index do |input, arg_num|
97
- rule_set = get_input_rule_set(klass, method, arg_num)
98
- if rule_set.nil?
99
- rule_set = RuleSet.new()
100
- set_input_rule_set(klass, method, arg_num, rule_set)
101
119
  end
102
- rule_set.load(input[:type], input[:value])
103
120
  end
104
121
 
105
- # Process output.
122
+ ##
123
+ # OUTPUT
124
+ ##
125
+
126
+ # Get rule set.
106
127
  output_rule_set = get_output_rule_set(klass, method)
107
128
  if output_rule_set.nil?
108
129
  output_rule_set = RuleSet.new()
109
130
  set_output_rule_set(klass, method, output_rule_set)
110
131
  end
111
- output_rule_set.load(control[:output][:type], control[:output][:value])
112
-
113
- end
114
-
115
- end
116
-
117
- ##
118
- # Train RuleSets from controls.
119
- #
120
- # @param Symbol klass
121
- # @param Symbol method
122
- ##
123
- def train(klass, method)
124
132
 
125
- input_rule_sets = get_input_rule_sets(klass, method)
126
- unless input_rule_sets.nil?
127
- input_rule_sets.each do |input_rule_set|
128
- input_rule_set.train()
129
- end
130
- end
133
+ # Train on metadata.
134
+ output_rule_set.train(reflection[:output])
131
135
 
132
- output_rule_set = get_output_rule_set(klass, method)
133
- unless output_rule_set.nil?
134
- output_rule_set.train()
135
136
  end
136
137
 
137
138
  end
@@ -139,15 +140,15 @@ class Ruler
139
140
  ##
140
141
  # Validate inputs.
141
142
  #
142
- # @param Array inputs - The method's arguments.
143
- # @param Array input_rule_sets - The RuleSets to validate each input with.
143
+ # @param inputs [Array] The method's arguments.
144
+ # @param input_rule_sets [Array] The RuleSets to validate each input with.
144
145
  ##
145
146
  def validate_inputs(inputs, input_rule_sets)
146
147
 
147
148
  # Default to a PASS result.
148
149
  result = true
149
150
 
150
- # Validate each argument against each rule set for that argument.
151
+ # Validate each argument against each RuleSet for that argument.
151
152
  inputs.each_with_index do |input, arg_num|
152
153
 
153
154
  unless input_rule_sets[arg_num].nil?
@@ -168,8 +169,8 @@ class Ruler
168
169
  ##
169
170
  # Validate output.
170
171
  #
171
- # @param dynamic output - The method's return value.
172
- # @param RuleSet output_rule_set - The RuleSet to validate the output with.
172
+ # @param output [Dynamic] The method's return value.
173
+ # @param output_rule_set [RuleSet] The RuleSet to validate the output with.
173
174
  ##
174
175
  def validate_output(output, output_rule_set)
175
176
 
@@ -1,4 +1,14 @@
1
+ ################################################################################
2
+ # A shapshot of real data.
3
+ #
4
+ # @hierachy
5
+ # 1. Execution
6
+ # 2. Control
7
+ # 3. RuleSet
8
+ ################################################################################
9
+
1
10
  require 'Reflection'
11
+ require 'MetaBuilder'
2
12
 
3
13
  class Control < Reflection
4
14
 
@@ -7,18 +17,18 @@ class Control < Reflection
7
17
  #
8
18
  # Creates a shadow execution stack.
9
19
  #
10
- # @param method - The name of the method.
11
- # @param *args - The method arguments.
12
- #
13
- # @return - A reflection hash.
20
+ # @param method [Symbol] The name of the method.
21
+ # @param *args [Args] The method arguments.
22
+ # @return [Hash] A reflection hash.
14
23
  ##
15
24
  def reflect(*args)
16
25
 
17
- @inputs = *args
26
+ # Create metadata for each argument.
27
+ @inputs = MetaBuilder.create_many(args)
18
28
 
19
29
  # Action method with new arguments.
20
30
  begin
21
- @output = @clone.send(@method, *@inputs)
31
+ output = @clone.send(@method, *args)
22
32
  # When fail.
23
33
  rescue StandardError => message
24
34
  @status = :fail
@@ -0,0 +1,27 @@
1
+ ################################################################################
2
+ # Meta for input and output. All meta behave the same.
3
+ #
4
+ # @pattern Abstract class.
5
+ # @see lib/meta for each meta.
6
+ ################################################################################
7
+
8
+ class Meta
9
+
10
+ ##
11
+ # Each meta loads values.
12
+ #
13
+ # @param value [Dynamic]
14
+ ##
15
+ def load(value)
16
+ end
17
+
18
+ ##
19
+ # Each meta provides metadata.
20
+ #
21
+ # @return [Hash]
22
+ ##
23
+ def result()
24
+ {}
25
+ end
26
+
27
+ end
@@ -0,0 +1,56 @@
1
+ ################################################################################
2
+ # Create Meta.
3
+ #
4
+ # @pattern Builder.
5
+ # @see lib/meta for each meta.
6
+ ################################################################################
7
+
8
+ require 'Meta'
9
+ require_relative './meta/IntegerMeta'
10
+ require_relative './meta/StringMeta'
11
+
12
+ class MetaBuilder
13
+
14
+ ##
15
+ # Create meta.
16
+ #
17
+ # @param value
18
+ ##
19
+ def self.create(value)
20
+
21
+ meta = nil
22
+
23
+ # Creates values for matching data type.
24
+ case value.class.to_s
25
+ when "Integer"
26
+ meta = IntegerMeta.new()
27
+ when "String"
28
+ meta = StringMeta.new()
29
+ end
30
+
31
+ unless meta.nil?
32
+ meta.load(value)
33
+ end
34
+
35
+ return meta
36
+
37
+ end
38
+
39
+ ##
40
+ # Create meta for multiple values.
41
+ #
42
+ # @param values
43
+ ##
44
+ def self.create_many(values)
45
+
46
+ meta = []
47
+
48
+ values.each do |value|
49
+ meta << self.create(value)
50
+ end
51
+
52
+ return meta
53
+
54
+ end
55
+
56
+ end
@@ -1,3 +1,17 @@
1
+ ################################################################################
2
+ # A snapshot of simulated data.
3
+ #
4
+ # @nomenclature
5
+ # args/inputs/values are the same thing but at a different stage of lifecycle.
6
+ #
7
+ # @hierachy
8
+ # 1. Execution
9
+ # 2. Reflection
10
+ # 3. RuleSet
11
+ ################################################################################
12
+
13
+ require 'MetaBuilder'
14
+
1
15
  class Reflection
2
16
 
3
17
  attr_accessor :clone
@@ -5,24 +19,24 @@ class Reflection
5
19
  ##
6
20
  # Create a Reflection.
7
21
  #
8
- # @param Execution execution - The Execution that created this Reflection.
9
- # @param Integer number - Multiple Reflections can be created per Execution.
10
- # @param Ruler ruler - The RuleSets for this class/method.
22
+ # @param execution [Execution] The Execution that created this Reflection.
23
+ # @param number [Integer] Multiple Reflections can be created per Execution.
24
+ # @param aggregator [Aggregator] The aggregated RuleSet for this class/method.
11
25
  ##
12
- def initialize(execution, number, ruler)
26
+ def initialize(execution, number, aggregator)
13
27
 
14
28
  @execution = execution
15
29
  @unique_id = execution.unique_id + number
16
30
  @number = number
17
31
 
18
32
  # Dependency.
19
- @ruler = ruler
33
+ @aggregator = aggregator
20
34
 
21
35
  # Caller.
22
36
  @klass = execution.klass
23
37
  @method = execution.method
24
38
 
25
- # Arguments.
39
+ # Metadata.
26
40
  @inputs = []
27
41
  @output = nil
28
42
 
@@ -40,43 +54,37 @@ class Reflection
40
54
  # Reflect on a method.
41
55
  #
42
56
  # Creates a shadow execution stack.
43
- #
44
- # @param *args - The method's arguments.
45
- #
46
- # @return - A reflection hash.
57
+ # @param *args [Dynamic] The method's arguments.
47
58
  ##
48
59
  def reflect(*args)
49
60
 
50
- # Get RuleSets.
51
- input_rule_sets = @ruler.get_input_rule_sets(@klass, @method)
52
- output_rule_set = @ruler.get_output_rule_set(@klass, @method)
61
+ # Get aggregated RuleSets.
62
+ agg_input_rule_sets = @aggregator.get_input_rule_sets(@klass, @method)
63
+ agg_output_rule_set = @aggregator.get_output_rule_set(@klass, @method)
53
64
 
54
- # Create deviated arguments.
55
- args.each do |arg|
56
- case arg
57
- when Integer
58
- @inputs << rand(999)
59
- else
60
- @inputs << arg
61
- end
62
- end
65
+ # Create random arguments.
66
+ new_args = randomize(args)
67
+
68
+ # Create metadata for each argument.
69
+ @inputs = MetaBuilder.create_many(new_args)
63
70
 
64
71
  # Action method with new arguments.
65
72
  begin
66
73
 
67
- # Validate input with controls.
68
- unless input_rule_sets.nil?
69
- unless @ruler.validate_inputs(@inputs, input_rule_sets)
74
+ # Validate input with aggregated control RuleSets.
75
+ unless agg_input_rule_sets.nil?
76
+ unless @aggregator.validate_inputs(new_args, agg_input_rule_sets)
70
77
  @status = :fail
71
78
  end
72
79
  end
73
80
 
74
81
  # Run reflection.
75
- @output = @clone.send(@method, *@inputs)
82
+ output = @clone.send(@method, *new_args)
83
+ @output = MetaBuilder.create(output)
76
84
 
77
- # Validate output with controls.
78
- unless output_rule_set.nil?
79
- unless @ruler.validate_output(@output, output_rule_set)
85
+ # Validate output with aggregated control RuleSets.
86
+ unless agg_output_rule_set.nil?
87
+ unless @aggregator.validate_output(output, agg_output_rule_set)
80
88
  @status = :fail
81
89
  end
82
90
  end
@@ -89,6 +97,34 @@ class Reflection
89
97
 
90
98
  end
91
99
 
100
+ ##
101
+ # Create random values for each argument.
102
+ #
103
+ # @param args [Dynamic] The arguments to create random values for.
104
+ # @return [Dynamic] Random arguments.
105
+ ##
106
+ def randomize(args)
107
+
108
+ random_args = []
109
+
110
+ args.each do |arg|
111
+ case arg
112
+ when Integer
113
+ random_args << rand(999)
114
+ else
115
+ random_args << arg
116
+ end
117
+ end
118
+
119
+ return random_args
120
+
121
+ end
122
+
123
+ ##
124
+ # Get the results of the reflection.
125
+ #
126
+ # @return [Hash] Reflection metadata.
127
+ ##
92
128
  def result()
93
129
 
94
130
  # The ID of the first execution in the ShadowStack.
@@ -107,66 +143,15 @@ class Reflection
107
143
  :class => @klass,
108
144
  :method => @method,
109
145
  :status => @status,
110
- :input => normalize_input(@inputs),
111
- :output => normalize_output(@output),
112
- :message => @message
146
+ :message => @message,
147
+ :inputs => [],
148
+ :output => @output,
113
149
  }
114
-
115
- return reflection
116
- end
117
-
118
- ##
119
- # Normalize inputs.
120
- #
121
- # @param args - The actual inputs.
122
- # @return - A generic inputs representation.
123
- ##
124
- def normalize_input(args)
125
- inputs = []
126
- args.each do |arg|
127
- input = {
128
- :type => arg.class.to_s
129
- }
130
- if (arg.class == Array)
131
- input[:count] = arg.count
132
- end
133
- inputs << input
150
+ @inputs.each do |meta|
151
+ reflection[:inputs] << meta.result()
134
152
  end
135
- inputs
136
- end
137
153
 
138
- ##
139
- # Normalize output.
140
- #
141
- # @param input - The actual output.
142
- # @return - A generic output representation.
143
- ##
144
- def normalize_output(arg)
145
-
146
- input = {
147
- :type => arg.class.to_s
148
- }
149
-
150
- if (arg.class == Array || arg.class == Hash)
151
- input[:count] = arg.count
152
- elsif (arg.class == TrueClass || arg.class == FalseClass)
153
- input[:type] = :Boolean
154
- end
155
-
156
- return input
157
-
158
- end
159
-
160
- def normalize_value(value)
161
-
162
- unless value.nil?
163
- value = value.to_s.gsub(/\r?\n/, " ").to_s
164
- if value.length >= 30
165
- value = value[0, value.rindex(/\s/,30)].rstrip() + '...'
166
- end
167
- end
168
-
169
- return value
154
+ return reflection
170
155
 
171
156
  end
172
157