reflekt 0.9.7 → 0.9.8

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