reflekt 1.0.1 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/{Accessor.rb → accessor.rb} +0 -0
  3. data/lib/{Execution.rb → action.rb} +12 -12
  4. data/lib/action_stack.rb +44 -0
  5. data/lib/{Clone.rb → clone.rb} +4 -4
  6. data/lib/{Config.rb → config.rb} +2 -1
  7. data/lib/{Control.rb → control.rb} +23 -12
  8. data/lib/experiment.rb +81 -0
  9. data/lib/meta.rb +71 -0
  10. data/lib/meta/{ArrayMeta.rb → array_meta.rb} +2 -2
  11. data/lib/meta/{BooleanMeta.rb → boolean_meta.rb} +2 -2
  12. data/lib/meta/{FloatMeta.rb → float_meta.rb} +2 -2
  13. data/lib/meta/{IntegerMeta.rb → integer_meta.rb} +2 -2
  14. data/lib/meta/null_meta.rb +34 -0
  15. data/lib/meta/{StringMeta.rb → string_meta.rb} +2 -2
  16. data/lib/{MetaBuilder.rb → meta_builder.rb} +3 -2
  17. data/lib/reflection.rb +148 -0
  18. data/lib/{Reflekt.rb → reflekt.rb} +44 -44
  19. data/lib/{Renderer.rb → renderer.rb} +0 -0
  20. data/lib/{Rule.rb → rule.rb} +1 -1
  21. data/lib/{RuleSet.rb → rule_set.rb} +26 -20
  22. data/lib/{Aggregator.rb → rule_set_aggregator.rb} +44 -22
  23. data/lib/rules/{ArrayRule.rb → array_rule.rb} +1 -1
  24. data/lib/rules/{BooleanRule.rb → boolean_rule.rb} +6 -4
  25. data/lib/rules/{FloatRule.rb → float_rule.rb} +1 -1
  26. data/lib/rules/{IntegerRule.rb → integer_rule.rb} +1 -1
  27. data/lib/rules/null_rule.rb +33 -0
  28. data/lib/rules/{StringRule.rb → string_rule.rb} +1 -1
  29. data/lib/web/bundle.js +2 -2
  30. data/lib/web/package-lock.json +3 -3
  31. data/lib/web/package.json +1 -1
  32. data/lib/web/server.js +5 -5
  33. metadata +30 -27
  34. data/lib/Meta.rb +0 -39
  35. data/lib/Reflection.rb +0 -186
  36. data/lib/ShadowStack.rb +0 -44
@@ -0,0 +1,34 @@
1
+ ################################################################################
2
+ # A reprsentation of a null value.
3
+ #
4
+ # @note
5
+ # A "null" value on serialized "inputs" and "output" also becomes a NullMeta.
6
+ #
7
+ # @hierachy
8
+ # 1. Action
9
+ # 2. Reflection
10
+ # 3. Meta <- YOU ARE HERE
11
+ ################################################################################
12
+
13
+ require_relative '../meta'
14
+
15
+ class NullMeta < Meta
16
+
17
+ def initialize()
18
+ @type = :null
19
+ end
20
+
21
+ ##
22
+ # @param value [NilClass]
23
+ ##
24
+ def load(value)
25
+ # No need to load a value for null meta.
26
+ end
27
+
28
+ def serialize()
29
+ {
30
+ :type => @type,
31
+ }
32
+ end
33
+
34
+ end
@@ -1,4 +1,4 @@
1
- require 'Meta'
1
+ require_relative '../meta'
2
2
 
3
3
  class StringMeta < Meta
4
4
 
@@ -16,7 +16,7 @@ class StringMeta < Meta
16
16
  @length = value.length
17
17
  end
18
18
 
19
- def result()
19
+ def serialize()
20
20
  {
21
21
  :type => @type,
22
22
  :length => @length
@@ -5,9 +5,9 @@
5
5
  # @see lib/meta for each meta.
6
6
  ################################################################################
7
7
 
8
- require 'Meta'
8
+ require_relative 'meta'
9
9
  # Require all meta.
10
- Dir[File.join(__dir__, 'meta', '*.rb')].each { |file| require file }
10
+ Dir[File.join(__dir__, 'meta', '*.rb')].each { |file| require_relative file }
11
11
 
12
12
  class MetaBuilder
13
13
 
@@ -73,6 +73,7 @@ class MetaBuilder
73
73
  FalseClass => :bool,
74
74
  Float => :float,
75
75
  Integer => :int,
76
+ NilClass => :null,
76
77
  String => :string
77
78
  }
78
79
 
@@ -0,0 +1,148 @@
1
+ ################################################################################
2
+ # A snapshot of real or random data.
3
+ #
4
+ # @pattern Abstract class
5
+ #
6
+ # @nomenclature
7
+ # args, inputs/output and meta represent different stages of a value.
8
+ #
9
+ # @hierachy
10
+ # 1. Action
11
+ # 2. Reflection <- YOU ARE HERE
12
+ # 3. Meta
13
+ #
14
+ # @status
15
+ # - :pass [Symbol] The reflection passes the rules.
16
+ # - :fail [Symbol] The reflection fails the rules or produces a system error.
17
+ # - :error [Symbol] The control reflection produces a system error.
18
+ ################################################################################
19
+
20
+ require_relative 'clone'
21
+ require_relative 'meta_builder'
22
+
23
+ class Reflection
24
+
25
+ attr_reader :status
26
+
27
+ ##
28
+ # Create a reflection.
29
+ #
30
+ # @param action [Action] The Action that created this Reflection.
31
+ # @param number [Integer] Multiple Reflections can be created per Action.
32
+ # @param aggregator [RuleSetAggregator] The aggregated RuleSet for this class/method.
33
+ ##
34
+ def initialize(action, number, aggregator)
35
+
36
+ @action = action
37
+ @unique_id = action.unique_id + number
38
+ @number = number
39
+
40
+ # Dependency.
41
+ @aggregator = aggregator
42
+
43
+ # Caller.
44
+ @klass = action.klass
45
+ @method = action.method
46
+
47
+ # Metadata.
48
+ @inputs = nil
49
+ @output = nil
50
+
51
+ # Clone the action's calling object.
52
+ # TODO: Abstract away into Clone class.
53
+ @clone = action.caller_object.clone
54
+
55
+ # Result.
56
+ @status = :pass
57
+ @time = Time.now.to_i
58
+ @message = nil
59
+
60
+ end
61
+
62
+ ##
63
+ # Reflect on a method.
64
+ #
65
+ # Create a shadow action.
66
+ # @param *args [Dynamic] The method's arguments.
67
+ ##
68
+ def reflect(*args)
69
+ # Implemented by Control and Experiment.
70
+ end
71
+
72
+ ##
73
+ # Create random values for each argument from control reflections.
74
+ #
75
+ # @param args [Dynamic] The arguments to mirror random values for.
76
+ # @param input_rule_sets [Array] Aggregated rule sets for each argument.
77
+ #
78
+ # @return [Dynamic] Random arguments.
79
+ ##
80
+ def randomize(args, input_rule_sets)
81
+
82
+ random_args = []
83
+
84
+ args.each_with_index do |arg, arg_num|
85
+
86
+ # Get a random rule in the rule set.
87
+ rules = input_rule_sets[arg_num].rules
88
+ agg_rule = rules[rules.keys.sample]
89
+
90
+ # Create a random value that follows that rule.
91
+ random_args << agg_rule.random()
92
+
93
+ end
94
+
95
+ return random_args
96
+
97
+ end
98
+
99
+ ##
100
+ # Get the results of the reflection.
101
+ #
102
+ # @keys
103
+ # - eid [Integer] Execution ID
104
+ # - aid [Integer] Action ID
105
+ # - rid [Integer] Reflection ID
106
+ # - num [Integer] Reflection number
107
+ #
108
+ # @return [Hash] Reflection metadata.
109
+ ##
110
+ def serialize()
111
+
112
+ # Create execution ID from the ID of the first action in the ActionStack.
113
+ execution_id = @action.unique_id
114
+ unless @action.base.nil?
115
+ execution_id = @action.base.unique_id
116
+ end
117
+
118
+ # Build reflection.
119
+ reflection = {
120
+ :eid => execution_id,
121
+ :aid => @action.unique_id,
122
+ :rid => @unique_id,
123
+ :num => @number,
124
+ :time => @time,
125
+ :class => @klass,
126
+ :method => @method,
127
+ :status => @status,
128
+ :message => @message,
129
+ :inputs => nil,
130
+ :output => nil,
131
+ }
132
+
133
+ unless @inputs.nil?
134
+ reflection[:inputs] = []
135
+ @inputs.each do |meta|
136
+ reflection[:inputs] << meta.serialize()
137
+ end
138
+ end
139
+
140
+ unless @output.nil?
141
+ reflection[:output] = @output.serialize()
142
+ end
143
+
144
+ return reflection
145
+
146
+ end
147
+
148
+ end
@@ -6,8 +6,8 @@
6
6
  # @flow
7
7
  # 1. Reflekt is prepended to a class and setup.
8
8
  # 2. When a class insantiates so does Reflekt.
9
- # 3. An Execution is created on method call.
10
- # 4. Many Refections are created per Execution.
9
+ # 3. An Action is created on method call.
10
+ # 4. Many Refections are created per Action.
11
11
  # 5. Each Reflection executes on cloned data.
12
12
  # 6. Flow is returned to the original method.
13
13
  #
@@ -19,16 +19,16 @@
19
19
  require 'set'
20
20
  require 'erb'
21
21
  require 'rowdb'
22
- require 'Accessor'
23
- require 'Aggregator'
24
- require 'Config'
25
- require 'Control'
26
- require 'Execution'
27
- require 'Reflection'
28
- require 'Renderer'
29
- require 'ShadowStack'
22
+ require_relative 'accessor'
23
+ require_relative 'action'
24
+ require_relative 'action_stack'
25
+ require_relative 'config'
26
+ require_relative 'control'
27
+ require_relative 'experiment'
28
+ require_relative 'renderer'
29
+ require_relative 'rule_set_aggregator'
30
30
  # Require all rules.
31
- Dir[File.join(__dir__, 'rules', '*.rb')].each { |file| require file }
31
+ Dir[File.join(__dir__, 'rules', '*.rb')].each { |file| require_relative file }
32
32
 
33
33
  module Reflekt
34
34
 
@@ -53,34 +53,34 @@ module Reflekt
53
53
  # When Reflekt enabled and control reflection has executed without error.
54
54
  if @@reflekt.config.enabled && !@@reflekt.error
55
55
 
56
- # Get current execution.
57
- execution = @@reflekt.stack.peek()
56
+ # Get current action.
57
+ action = @@reflekt.stack.peek()
58
58
 
59
59
  # Don't reflect when reflect limit reached or method skipped.
60
60
  unless (@reflekt_counts[method] >= @@reflekt.config.reflect_limit) || self.class.reflekt_skipped?(method)
61
61
 
62
- # When stack empty or past execution done reflecting.
63
- if execution.nil? || execution.has_finished_reflecting?
62
+ # When stack empty or past action done reflecting.
63
+ if action.nil? || action.has_finished_reflecting?
64
64
 
65
- # Create execution.
66
- execution = Execution.new(self, method, @@reflekt.config.reflect_amount, @@reflekt.stack)
65
+ # Create action.
66
+ action = Action.new(self, method, @@reflekt.config.reflect_amount, @@reflekt.stack)
67
67
 
68
- @@reflekt.stack.push(execution)
68
+ @@reflekt.stack.push(action)
69
69
 
70
70
  end
71
71
 
72
72
  ##
73
- # Reflect the execution.
73
+ # Reflect the action.
74
74
  #
75
- # The first method call in the execution creates a reflection.
76
- # Then method calls are shadow executions which return to the reflection.
75
+ # The first method call in the action creates a reflection.
76
+ # Then method calls are shadow actions which return to the reflection.
77
77
  ##
78
- if execution.has_empty_reflections? && !execution.is_reflecting?
79
- execution.is_reflecting = true
78
+ if action.has_empty_experiments? && !action.is_reflecting?
79
+ action.is_reflecting = true
80
80
 
81
81
  # Create control.
82
- control = Control.new(execution, 0, @@reflekt.aggregator)
83
- execution.control = control
82
+ control = Control.new(action, 0, @@reflekt.aggregator)
83
+ action.control = control
84
84
 
85
85
  # Execute control.
86
86
  control.reflect(*args)
@@ -91,27 +91,27 @@ module Reflekt
91
91
  # Continue reflecting when control executes succesfully.
92
92
  else
93
93
 
94
- # Save control as reflection.
95
- @@reflekt.db.get("reflections").push(control.result())
94
+ # Save control as a reflection.
95
+ @@reflekt.db.get("reflections").push(control.serialize())
96
96
 
97
- # Multiple reflections per execution.
98
- execution.reflections.each_with_index do |value, index|
97
+ # Multiple experiments per action.
98
+ action.experiments.each_with_index do |value, index|
99
99
 
100
- # Create reflection.
101
- reflection = Reflection.new(execution, index + 1, @@reflekt.aggregator)
102
- execution.reflections[index] = reflection
100
+ # Create experiment.
101
+ experiment = Experiment.new(action, index + 1, @@reflekt.aggregator)
102
+ action.experiments[index] = experiment
103
103
 
104
- # Execute reflection.
105
- reflection.reflect(*args)
104
+ # Execute experiment.
105
+ experiment.reflect(*args)
106
106
  @reflekt_counts[method] = @reflekt_counts[method] + 1
107
107
 
108
- # Save reflection.
109
- @@reflekt.db.get("reflections").push(reflection.result())
108
+ # Save experiment.
109
+ @@reflekt.db.get("reflections").push(experiment.serialize())
110
110
 
111
111
  end
112
112
 
113
113
  # Save control.
114
- @@reflekt.db.get("controls").push(control.result())
114
+ @@reflekt.db.get("controls").push(control.serialize())
115
115
 
116
116
  # Save results.
117
117
  @@reflekt.db.write()
@@ -121,15 +121,15 @@ module Reflekt
121
121
 
122
122
  end
123
123
 
124
- execution.is_reflecting = false
124
+ action.is_reflecting = false
125
125
  end
126
126
 
127
127
  end
128
128
 
129
129
  # Don't execute skipped methods when reflecting.
130
- unless execution.is_reflecting? && self.class.reflekt_skipped?(method)
130
+ unless action.is_reflecting? && self.class.reflekt_skipped?(method)
131
131
 
132
- # Continue execution / shadow execution.
132
+ # Continue action / shadow action.
133
133
  super *args
134
134
 
135
135
  end
@@ -137,7 +137,7 @@ module Reflekt
137
137
  # When Reflekt disabled or control reflection failed.
138
138
  else
139
139
 
140
- # Continue execution.
140
+ # Continue action.
141
141
  super *args
142
142
 
143
143
  end
@@ -180,7 +180,7 @@ module Reflekt
180
180
  # Set configuration.
181
181
  @@reflekt.path = File.dirname(File.realpath(__FILE__))
182
182
 
183
- # Get reflections directory path from config or current execution path.
183
+ # Get reflections directory path from config or current action path.
184
184
  if @@reflekt.config.output_path
185
185
  @@reflekt.output_path = File.join(@@reflekt.config.output_path, @@reflekt.config.output_directory)
186
186
  else
@@ -199,10 +199,10 @@ module Reflekt
199
199
  db = @@reflekt.db.value()
200
200
 
201
201
  # Create shadow stack.
202
- @@reflekt.stack = ShadowStack.new()
202
+ @@reflekt.stack = ActionStack.new()
203
203
 
204
204
  # Create aggregated rule sets.
205
- @@reflekt.aggregator = Aggregator.new(@@reflekt.config.meta_map)
205
+ @@reflekt.aggregator = RuleSetAggregator.new(@@reflekt.config.meta_map)
206
206
  @@reflekt.aggregator.train(db[:controls])
207
207
 
208
208
  # Create renderer.
File without changes
@@ -4,7 +4,7 @@
4
4
  # @pattern Abstract class
5
5
  #
6
6
  # @hierachy
7
- # 1. Aggregator
7
+ # 1. RuleSetAggregator
8
8
  # 2. RuleSet
9
9
  # 3. Rule <- YOU ARE HERE
10
10
  #
@@ -6,13 +6,14 @@
6
6
  # - Builder
7
7
  #
8
8
  # @hierachy
9
- # 1. Aggregator
9
+ # 1. RuleSetAggregator
10
10
  # 2. RuleSet <- YOU ARE HERE
11
11
  # 3. Rule
12
12
  ################################################################################
13
13
 
14
14
  require 'set'
15
- require 'MetaBuilder'
15
+ require_relative 'meta_builder'
16
+ require_relative 'meta/null_meta.rb'
16
17
 
17
18
  class RuleSet
18
19
 
@@ -37,40 +38,44 @@ class RuleSet
37
38
  ##
38
39
  # Train rule set on metadata.
39
40
  #
40
- # @param meta [Meta] The metadata to train on.
41
+ # @param meta [Hash] The metadata to train on.
41
42
  ##
42
43
  def train(meta)
43
44
 
44
- unless meta.nil? || meta[:type].nil?
45
+ # Track supported meta types.
46
+ meta_type = meta[:type]
47
+ @meta_types << meta_type
45
48
 
46
- meta_type = meta[:type]
47
- @meta_types << meta_type
49
+ # Get rule types for this meta type.
50
+ if @meta_map.key? meta_type
51
+ @meta_map[meta_type].each do |rule_type|
48
52
 
49
- # Get rule types for this meta type.
50
- if @meta_map.key? meta_type
51
- @meta_map[meta_type].each do |rule_type|
52
-
53
- # Ensure rule exists.
54
- if @rules[rule_type].nil?
55
- @rules[rule_type] = rule_type.new()
56
- end
53
+ # Ensure rule exists.
54
+ if @rules[rule_type].nil?
55
+ @rules[rule_type] = rule_type.new()
56
+ end
57
57
 
58
- # Train rule.
59
- @rules[rule_type].train(meta)
58
+ # Train rule.
59
+ @rules[rule_type].train(meta)
60
60
 
61
- end
62
61
  end
63
-
64
62
  end
65
63
 
66
64
  end
67
65
 
66
+ ##
67
+ # @param value [Dynamic]
68
+ ##
68
69
  def test(value)
69
- result = true
70
70
 
71
- # Only test data type on rule of matching meta type.
71
+ result = true
72
72
  meta_type = MetaBuilder.data_type_to_meta_type(value)
73
73
 
74
+ # Fail if value's meta type not testable by rule set.
75
+ unless @meta_types.include? meta_type
76
+ return false
77
+ end
78
+
74
79
  @rules.each do |klass, rule|
75
80
  if (rule.type == meta_type)
76
81
  unless rule.test(value)
@@ -80,6 +85,7 @@ class RuleSet
80
85
  end
81
86
 
82
87
  return result
88
+
83
89
  end
84
90
 
85
91
  ##