reflekt 0.9.1 → 0.9.2

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: 3589292c5c5cba2f3d7c7d5e1d7e02ee1052afe7339929cfa058b787b89c3158
4
- data.tar.gz: d33c6774d53d4b7a0978fcfc48fa00e22f3684ccd51e5d42676f01831fb84291
3
+ metadata.gz: 21ac72b1a4f8bf9bd182f1d1ae5464d11aa87ab0f38c6fa418c9a3e73ff33a5d
4
+ data.tar.gz: bfd3a381c930d910e3b293e835877712734eecc2a51c7949e7f4747b67377058
5
5
  SHA512:
6
- metadata.gz: 2e3120f544d87057b4783a4e6e76a9689844f17ed1ad602c8b2c5e5ee241285ef83e276b56fbdb33da0d167c68077eca6f851e859a28392718a26ed129ab18e7
7
- data.tar.gz: 47d323198d8d27585ef5fb0d493eca120d0cd2ff532a6578ef3b7490ccbc9e4fc38757bab8fb2ad4ab6c05c0a9fd721b27a5925a90c95503c0de5d4fb7483e12
6
+ metadata.gz: e9b62612aa60d91bf591eae59c9797c97e9b54fdafd58d2785ed4fdfa8c7bc256cd288e13dd9e83d4fd8d11fbdbe043ce0660f6ba82878f8fd5eabb224d691b0
7
+ data.tar.gz: 9a38959ce057bdf3f4e7e2091f0aa6666be940e356b5865952a7e9e7749958d77f8beb68d2fd8f9a252f047bb45bccc756b3f9af793c85e3031a4f0cab541c74
@@ -2,6 +2,32 @@ require 'Reflection'
2
2
 
3
3
  class Control < Reflection
4
4
 
5
- # TODO.
5
+ ##
6
+ # Reflect on a method.
7
+ #
8
+ # Creates a shadow execution stack.
9
+ #
10
+ # @param method - The name of the method.
11
+ # @param *args - The method arguments.
12
+ #
13
+ # @return - A reflection hash.
14
+ ##
15
+ def reflect(*args)
16
+
17
+ @input = *args
18
+
19
+ # Action method with new arguments.
20
+ begin
21
+ @output = @clone.send(@method, *@input)
22
+ # When fail.
23
+ rescue StandardError => message
24
+ @status = FAIL
25
+ @message = message
26
+ # When pass.
27
+ else
28
+ @status = PASS
29
+ end
30
+
31
+ end
6
32
 
7
33
  end
@@ -15,11 +15,11 @@ class Reflection
15
15
 
16
16
  attr_accessor :clone
17
17
 
18
- def initialize(execution, method, is_control)
18
+ def initialize(execution, method, ruler)
19
19
 
20
20
  @execution = execution
21
21
  @method = method
22
- @is_control = is_control
22
+ @ruler = ruler
23
23
 
24
24
  # Clone the execution's object.
25
25
  @clone = execution.object.clone
@@ -28,7 +28,7 @@ class Reflection
28
28
  # Result.
29
29
  @status = nil
30
30
  @time = Time.now.to_i
31
- @input = []
31
+ @inputs = []
32
32
  @output = nil
33
33
 
34
34
  end
@@ -45,30 +45,43 @@ class Reflection
45
45
  ##
46
46
  def reflect(*args)
47
47
 
48
- # Reflect on real world arguments.
49
- if @is_control
50
- @input = *args
51
- # Reflect on deviated arguments.
52
- else
53
- args.each do |arg|
54
- case arg
55
- when Integer
56
- @input << rand(9999)
57
- else
58
- @input << arg
59
- end
48
+ # Create deviated arguments.
49
+ args.each do |arg|
50
+ case arg
51
+ when Integer
52
+ @inputs << rand(999)
53
+ else
54
+ @inputs << arg
60
55
  end
61
56
  end
62
57
 
63
58
  # Action method with new arguments.
64
59
  begin
65
- @output = @clone.send(@method, *@input)
60
+ # Validate input with controls.
61
+ unless @ruler.nil?
62
+ if @ruler.validate_inputs(@execution.caller_class, @method, @inputs)
63
+ @status = PASS
64
+ else
65
+ @status = FAIL
66
+ end
67
+ end
68
+ # Run reflection.
69
+ @output = @clone.send(@method, *@inputs)
66
70
  # When fail.
67
71
  rescue StandardError => message
68
- @status = MESSAGE
72
+ @status = FAIL
69
73
  @message = message
70
74
  # When pass.
71
75
  else
76
+ # Validate output with controls.
77
+ unless @ruler.nil?
78
+ if @ruler.validate_output(@execution.caller_class, @method, @output)
79
+ @status = PASS
80
+ else
81
+ @status = FAIL
82
+ end
83
+ return
84
+ end
72
85
  @status = PASS
73
86
  end
74
87
 
@@ -79,7 +92,7 @@ class Reflection
79
92
  reflection = {
80
93
  TIME => @time,
81
94
  STATUS => @status,
82
- INPUT => normalize_input(@input),
95
+ INPUT => normalize_input(@inputs),
83
96
  OUTPUT => normalize_output(@output),
84
97
  MESSAGE => @message
85
98
  }
@@ -0,0 +1,38 @@
1
+ require 'set'
2
+
3
+ class Rule
4
+
5
+ attr_accessor :type
6
+ attr_accessor :min
7
+ attr_accessor :max
8
+ attr_accessor :length
9
+ attr_accessor :types
10
+ attr_accessor :values
11
+
12
+ def initialize()
13
+
14
+ @types = Set.new
15
+ @values = Set.new
16
+ @min = nil
17
+ @max = nil
18
+ @length = nil
19
+
20
+ end
21
+
22
+ ##
23
+ # A parameter can accept multiple input types.
24
+ # Duplicates will not be added to the set.
25
+ ##
26
+ def add_type(type)
27
+ @types.add(type)
28
+ end
29
+
30
+ def add_value(value)
31
+ @values.add(value)
32
+ end
33
+
34
+ def is_number?
35
+ @types.include? Integer
36
+ end
37
+
38
+ end
@@ -0,0 +1,112 @@
1
+ require 'Rule'
2
+
3
+ class Ruler
4
+
5
+ INPUT = "i"
6
+ OUTPUT = "o"
7
+ TYPE = "T"
8
+ VALUE = "V"
9
+
10
+ def initialize()
11
+
12
+ @controls = nil
13
+
14
+ # Rules.
15
+ @inputs = []
16
+ @output = nil
17
+
18
+ end
19
+
20
+ def load(controls)
21
+
22
+ @controls = controls
23
+ @controls.each_with_index do |control, index|
24
+
25
+ # Multiple inputs.
26
+ control[INPUT].each_with_index do |input, index|
27
+ unless input.nil?
28
+
29
+ # Create rule.
30
+ if @inputs[index].nil?
31
+ rule = Rule.new()
32
+ @inputs[index] = rule
33
+ else
34
+ rule = @inputs[index]
35
+ end
36
+
37
+ # Add rules to rule.
38
+ unless input[TYPE].nil? || input[TYPE].empty?
39
+ rule.add_type(input[TYPE].class)
40
+ end
41
+ unless input[VALUE].nil? || input[VALUE].empty?
42
+ rule.add_value(input[VALUE])
43
+ end
44
+
45
+ index = index + 1
46
+ end
47
+ end
48
+
49
+ # Singular output.
50
+ output = control[OUTPUT]
51
+ unless control[OUTPUT].nil?
52
+
53
+ # Create rule.
54
+ if @output.nil?
55
+ rule = Rule.new()
56
+ @output = rule
57
+ else
58
+ rule = @output
59
+ end
60
+
61
+ ## Add rules to rule.
62
+ unless output[TYPE].nil? || output[TYPE].empty?
63
+ rule.add_type(output[TYPE])
64
+ end
65
+ unless output[VALUE].nil? || output[VALUE].empty?
66
+ rule.add_value(output[VALUE])
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ def train()
76
+
77
+ @inputs.each do |rule|
78
+ # Get min/max.
79
+ if rule.is_number?
80
+ numbers = rule.values.select {|num| num.class == Integer }
81
+ numbers.sort!
82
+ rule.min = numbers.first
83
+ rule.max = numbers.last
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ def validate_inputs(klass, method, inputs)
91
+ result = true
92
+ inputs.each_with_index do |value, index|
93
+ rule = @inputs[index]
94
+ if rule.is_number? && value.class == Integer
95
+ result = false if value < rule.min
96
+ result = false if value > rule.max
97
+ end
98
+ end
99
+ return result
100
+ end
101
+
102
+ def validate_output(klass, method, outputs)
103
+ result = true
104
+ rule = @output
105
+ if rule.is_number? && value.class == Integer
106
+ result = false if value < rule.min
107
+ result = false if value > rule.max
108
+ end
109
+ return result
110
+ end
111
+
112
+ end
@@ -4,6 +4,7 @@ require 'rowdb'
4
4
  require 'Control'
5
5
  require 'Execution'
6
6
  require 'Reflection'
7
+ require 'Ruler'
7
8
  require 'ShadowStack'
8
9
 
9
10
  ################################################################################
@@ -60,6 +61,14 @@ module Reflekt
60
61
 
61
62
  end
62
63
 
64
+ # Get ruler.
65
+ # The method's ruler will not exist the first time the db generated.
66
+ if @@reflekt_rules.key? execution.caller_class.to_s.to_sym
67
+ ruler = @@reflekt_rules[execution.caller_class.to_s.to_sym][method.to_s]
68
+ else
69
+ ruler = nil
70
+ end
71
+
63
72
  # Reflect.
64
73
  # The first method call in the Execution creates a Reflection.
65
74
  # Subsequent method calls are shadow executions on cloned objects.
@@ -70,7 +79,7 @@ module Reflekt
70
79
  method_name = method.to_s
71
80
 
72
81
  # Create control.
73
- control = Control.new(execution, method, true)
82
+ control = Control.new(execution, method, ruler)
74
83
  execution.control = control
75
84
 
76
85
  # Execute control.
@@ -83,11 +92,12 @@ module Reflekt
83
92
  execution.reflections.each_with_index do |value, index|
84
93
 
85
94
  # Create reflection.
86
- reflection = Reflection.new(execution, method, false)
95
+ reflection = Reflection.new(execution, method, ruler)
87
96
  execution.reflections[index] = reflection
88
97
 
89
98
  # Execute reflection.
90
99
  reflection.reflect(*args)
100
+ @reflection_counts[method] = @reflection_counts[method] + 1
91
101
 
92
102
  # Save reflection.
93
103
  @@reflekt_db.get("#{class_name}.#{method_name}.reflections").push(reflection.result())
@@ -105,8 +115,6 @@ module Reflekt
105
115
 
106
116
  end
107
117
 
108
- @reflection_counts[method] = @reflection_counts[method] + 1
109
-
110
118
  # Continue execution / shadow execution.
111
119
  super *args
112
120
 
@@ -167,9 +175,6 @@ module Reflekt
167
175
  # Set configuration.
168
176
  @@reflekt_path = File.dirname(File.realpath(__FILE__))
169
177
 
170
- # Create reflection tree.
171
- @@reflekt_stack = ShadowStack.new()
172
-
173
178
  # Build reflections directory.
174
179
  if $ENV[:reflekt][:output_path]
175
180
  @@reflekt_output_path = File.join($ENV[:reflekt][:output_path], 'reflections')
@@ -184,7 +189,30 @@ module Reflekt
184
189
 
185
190
  # Create database.
186
191
  @@reflekt_db = Rowdb.new(@@reflekt_output_path + '/db.json')
187
- @@reflekt_db.defaults({ :reflekt => { :api_version => 1 }}).write()
192
+ @@reflekt_db.defaults({ :reflekt => { :api_version => 1 }})
193
+
194
+ # Create shadow execution stack.
195
+ @@reflekt_stack = ShadowStack.new()
196
+
197
+ # Define rules.
198
+ # TODO: Fix Rowdb.get(path) not returning data at path after Rowdb.push()?
199
+ @@reflekt_rules = {}
200
+ db = @@reflekt_db.value()
201
+ db.each do |class_name, class_values|
202
+ @@reflekt_rules[class_name] = {}
203
+ class_values.each do |method_name, method_values|
204
+ next if method_values.nil?
205
+ next unless method_values.class == Hash
206
+ if method_values.key? "controls"
207
+
208
+ ruler = Ruler.new()
209
+ ruler.load(method_values['controls'])
210
+ ruler.train()
211
+
212
+ @@reflekt_rules[class_name][method_name] = ruler
213
+ end
214
+ end
215
+ end
188
216
 
189
217
  return true
190
218
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reflekt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maedi Prichard
@@ -33,6 +33,8 @@ files:
33
33
  - lib/Control.rb
34
34
  - lib/Execution.rb
35
35
  - lib/Reflection.rb
36
+ - lib/Rule.rb
37
+ - lib/Ruler.rb
36
38
  - lib/ShadowStack.rb
37
39
  - lib/reflekt.rb
38
40
  - lib/web/script.js