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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 457006f1c0a4fbe9a1ce47684aeeec980852cd966f29d07ac57751161f314d52
4
- data.tar.gz: ca01fd9306ece9e1698aab0dcb4945a848a5a910625f8b9394b4f26aa7819514
3
+ metadata.gz: 3e5af4cf8808efaeb9b41e29c925aee883139afaea6fef303f060a91566a101b
4
+ data.tar.gz: cb877b7821ed829907c52387b5fc04ff3c986f05646170dceb3307cc14a4d648
5
5
  SHA512:
6
- metadata.gz: 1de336f083b2e90230453d3ce07cfb36981998587de2e126c88948da75a618ee57a68b32b9869865fb9353b45e85fadc293d98afc2c4669afe8fadc9761fda93
7
- data.tar.gz: 0b00aa43ef7763bc11e93697446ca0e86114818f3e6238d28711d1038eef0c4bc58dc43b1f1f901ec58a4cdf6c9138493e63572a7d33a0363a591e908b38e751
6
+ metadata.gz: 6200d9280ccdf2cd5cb1788d80e6795813e5dc7ca398ebca75e507aba2fc8e3bf116ec851f3d103c92eaa1e1a79fd0a6c3f14dc1f59cee74117a8a1f74f60e66
7
+ data.tar.gz: 9b28f16baeafa725c606c0ea458742f86d0b87cda0e95180658b66598a8a08a0efa46f706214d8e00e98eecfc766eadfafeeb47697cf297f62beef95e2ed452d
data/lib/accessor.rb ADDED
@@ -0,0 +1,45 @@
1
+ ################################################################################
2
+ # Access variables via one object to avoid polluting the caller's scope.
3
+ #
4
+ # @pattern Singleton
5
+ #
6
+ # @note Variables not accessed via Accessor:
7
+ # - @reflekt_counts on the instance
8
+ # - @@reflekt_skipped_methods on the instance's singleton class
9
+ ################################################################################
10
+
11
+ module Reflekt
12
+ class Accessor
13
+
14
+ attr_accessor :initialized
15
+ attr_accessor :counts
16
+ attr_accessor :error
17
+
18
+ attr_accessor :config
19
+ attr_accessor :db
20
+ attr_accessor :stack
21
+ attr_accessor :aggregator
22
+ attr_accessor :renderer
23
+
24
+ attr_accessor :package_path
25
+ attr_accessor :project_path
26
+ attr_accessor :output_path
27
+
28
+ def initialize()
29
+ @initialized = false
30
+ @counts = {}
31
+ @error = nil
32
+
33
+ @config = nil
34
+ @db = nil
35
+ @stack = nil
36
+ @aggregator = nil
37
+ @renderer = nil
38
+
39
+ @package_path = nil
40
+ @project_path = nil
41
+ @output_path = nil
42
+ end
43
+
44
+ end
45
+ end
data/lib/action.rb ADDED
@@ -0,0 +1,127 @@
1
+ ################################################################################
2
+ # A shadow action.
3
+ #
4
+ # @hierachy
5
+ # 1. Action <- YOU ARE HERE
6
+ # 2. Reflection
7
+ # 3. Meta
8
+ ################################################################################
9
+
10
+ module Reflekt
11
+ class Action
12
+ include LitCLI
13
+
14
+ attr_accessor :unique_id
15
+ attr_accessor :caller_object
16
+ attr_accessor :caller_id
17
+ attr_accessor :caller_class
18
+ attr_accessor :klass
19
+ attr_accessor :method
20
+ attr_accessor :base
21
+ attr_accessor :parent
22
+ attr_accessor :child
23
+ attr_accessor :control
24
+ attr_accessor :experiments
25
+ attr_accessor :is_actioned
26
+ attr_accessor :is_reflecting
27
+ attr_accessor :is_base
28
+
29
+ ##
30
+ # Create Action.
31
+ #
32
+ # @param object [Object] The calling object.
33
+ # @param method [Symbol] The calling method.
34
+ # @param reflect_amount [Integer] The number of experiments to create per action.
35
+ # @param stack [ActionStack] The shadow action call stack.
36
+ ##
37
+ def initialize(caller_object, method, config, db, stack, aggregator)
38
+ @time = Time.now.to_i
39
+ @unique_id = @time + rand(1..99999)
40
+ @base = nil
41
+ @child = nil
42
+ @parent = nil
43
+
44
+ # Dependencies.
45
+ @db = db
46
+ @stack = stack
47
+ @aggregator = aggregator
48
+
49
+ # Caller.
50
+ @caller_object = caller_object
51
+ @caller_class = caller_object.class
52
+ @caller_id = caller_object.object_id
53
+ @klass = @caller_class.to_s.to_sym
54
+ @method = method
55
+
56
+ # Reflections.
57
+ @control = nil
58
+ @experiments = Array.new(config.reflect_amount)
59
+
60
+ # State.
61
+ @is_reflecting = false
62
+ if @stack.peek() == nil
63
+ @is_base = true
64
+ else
65
+ @is_base = false
66
+ @base = @stack.base()
67
+ end
68
+ end
69
+
70
+ def reflect(*args)
71
+
72
+ 🔥"^ Create control for #{@method}()", :info, :control, @klass
73
+ @control = Control.new(self, 0, @aggregator)
74
+
75
+ @control.reflect(*args)
76
+ 🔥"> Reflected control for #{@method}(): #{args}", @control.status, :result, @klass
77
+
78
+ # Stop reflecting when control fails to execute.
79
+ unless @control.status == :error
80
+
81
+ # Save control.
82
+ @db.get("controls").push(@control.serialize())
83
+ @db.get("reflections").push(@control.serialize())
84
+
85
+ # Multiple experiments per action.
86
+ @experiments.each_with_index do |value, index|
87
+
88
+ 🔥"^ Create experiment ##{index + 1} for #{@method}()", :info, :experiment, @klass
89
+ experiment = Experiment.new(self, index + 1, @aggregator)
90
+ @experiments[index] = experiment
91
+
92
+ # Reflect experiment.
93
+ experiment.reflect(*args)
94
+ Reflekt.increase_count(@caller_object, @method)
95
+ 🔥"> Reflected experiment ##{index + 1} for #{@method}()", experiment.status, :result, @klass
96
+
97
+ # Save experiment.
98
+ @db.get("reflections").push(experiment.serialize())
99
+ end
100
+
101
+ # Save results.
102
+ @db.write()
103
+ end
104
+ end
105
+
106
+ def is_actioned?
107
+ @is_actioned
108
+ end
109
+
110
+ # Is the action currently reflecting methods?
111
+ def is_reflecting?
112
+ @is_reflecting
113
+ end
114
+
115
+ def has_empty_experiments?
116
+ @experiments.include? nil
117
+ end
118
+
119
+ def has_finished_loop?
120
+ return false if is_actioned? == false
121
+ return false if is_reflecting?
122
+ return false if has_empty_experiments?
123
+
124
+ true
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,44 @@
1
+ ################################################################################
2
+ # Track the actions in a shadow call stack.
3
+ #
4
+ # @pattern Stack
5
+ ################################################################################
6
+
7
+ module Reflekt
8
+ class ActionStack
9
+
10
+ def initialize()
11
+ @bottom = nil
12
+ @top = nil
13
+ end
14
+
15
+ def peek()
16
+ @top
17
+ end
18
+
19
+ def base()
20
+ @bottom
21
+ end
22
+
23
+ ##
24
+ # Place Action at the top of stack.
25
+ #
26
+ # @param action [Action] The action to place.
27
+ # @return [Action] The placed action.
28
+ ##
29
+ def push(action)
30
+ # First time? Place action at bottom of stack.
31
+ if @bottom.nil?
32
+ @bottom = action
33
+ # Connect subsequent actions to each other.
34
+ else
35
+ @top.parent = action
36
+ action.child = @top
37
+ end
38
+
39
+ # Place action at top of stack.
40
+ @top = action
41
+ end
42
+
43
+ end
44
+ end
@@ -12,20 +12,20 @@
12
12
  # 3. Clone <- YOU ARE HERE
13
13
  ################################################################################
14
14
 
15
- class Clone
15
+ module Reflekt
16
+ class Clone
16
17
 
17
- def initialize(action)
18
+ def initialize(action)
19
+ # Clone the action's calling object.
20
+ @caller_object_clone = action.caller_object.clone
18
21
 
19
- # Clone the action's calling object.
20
- @caller_object_clone = action.caller_object.clone
22
+ # TODO: Clone any other instances that this clone references.
23
+ # TODO: Replace clone's references to these new instances.
24
+ end
21
25
 
22
- # TODO: Clone any other instances that this clone references.
23
- # TODO: Replace clone's references to these new instances.
26
+ def action(method, *new_args)
27
+ @caller_object_clone.send(method, *new_args)
28
+ end
24
29
 
25
30
  end
26
-
27
- def action(method, *new_args)
28
- @caller_object_clone.send(method, *new_args)
29
- end
30
-
31
31
  end
data/lib/config.rb ADDED
@@ -0,0 +1,48 @@
1
+ module Reflekt
2
+ class Config
3
+
4
+ attr_accessor :enabled
5
+ attr_accessor :reflect_amount
6
+ attr_accessor :reflect_limit
7
+ attr_accessor :meta_map
8
+ attr_accessor :project_path
9
+ attr_accessor :output_directory
10
+
11
+ def initialize()
12
+
13
+ # Reflekt is enabled by default and should be disabled on production.
14
+ @enabled = true
15
+
16
+ # Reflekt is untracked in git by default.
17
+ @git_ignore = true
18
+
19
+ # The amount of reflections to create per method call.
20
+ # A control reflection is created in addition to this.
21
+ @reflect_amount = 5
22
+
23
+ # The maximum amount of reflections that can be created per instance per method.
24
+ # A method called thousands of times doesn't need that many reflections.
25
+ @reflect_limit = 10
26
+
27
+ # The rules that apply to meta types.
28
+ @meta_map = {
29
+ :array => [ArrayRule],
30
+ :bool => [BooleanRule],
31
+ :int => [IntegerRule],
32
+ :float => [FloatRule],
33
+ :null => [NullRule],
34
+ :object => [ObjectRule],
35
+ :string => [StringRule]
36
+ }
37
+
38
+ # An absolute path to the project root directory.
39
+ # Defaults to current execution path.
40
+ @project_path = Dir.pwd
41
+
42
+ # Name of output directory.
43
+ @output_directory = "reflections"
44
+
45
+ end
46
+
47
+ end
48
+ end
data/lib/control.rb ADDED
@@ -0,0 +1,81 @@
1
+ ################################################################################
2
+ # A shapshot of real data.
3
+ #
4
+ # @note
5
+ # A control's @number will always be 0.
6
+ #
7
+ # @nomenclature
8
+ # args, inputs/output and meta represent different stages of a value.
9
+ #
10
+ # @hierachy
11
+ # 1. Action
12
+ # 2. Control <- YOU ARE HERE
13
+ # 3. Meta
14
+ #
15
+ # @status
16
+ # - :pass [Symbol] The reflection passes the rules.
17
+ # - :fail [Symbol] The reflection fails the rules or produces a system error.
18
+ # - :error [Symbol] The control reflection produces a system error.
19
+ ################################################################################
20
+
21
+ require_relative 'reflection'
22
+ require_relative 'meta_builder'
23
+
24
+ module Reflekt
25
+ class Control < Reflection
26
+
27
+ ##
28
+ # Reflect on a method.
29
+ #
30
+ # Create a shadow action.
31
+ # @param *args [Dynamic] The method's arguments.
32
+ ##
33
+ def reflect(*args)
34
+ # Get trained rule sets.
35
+ input_rule_sets = @aggregator.get_input_rule_sets(@klass, @method)
36
+ output_rule_set = @aggregator.get_output_rule_set(@klass, @method)
37
+
38
+ # Fail when no trained rule sets.
39
+ if input_rule_sets.nil?
40
+ @status = :fail
41
+ 🔥"> No trained rule sets", :fail, :reflect
42
+ end
43
+
44
+ # When arguments exist.
45
+ unless args.size == 0
46
+ # Validate arguments against trained rule sets.
47
+ unless input_rule_sets.nil?
48
+ unless @aggregator.test_inputs(args, input_rule_sets)
49
+ @status = :fail
50
+ 🔥"> Invalid inputs", @status, :reflect
51
+ end
52
+ end
53
+
54
+ 🔥"> Create meta for #{@method}(): #{args}", :info, :meta, @klass
55
+ # TODO: Create metadata for other inputs such as instance variables.
56
+ @inputs = MetaBuilder.create_many(args)
57
+ end
58
+
59
+ # Action method with real arguments.
60
+ begin
61
+ # Run reflection.
62
+ output = @clone.send(@method, *args)
63
+ @output = MetaBuilder.create(output)
64
+
65
+ # Validate output with aggregated control rule sets.
66
+ unless @aggregator.test_output(output, output_rule_set)
67
+ @status = :fail
68
+ 🔥"> Invalid output", @status, :reflect
69
+ end
70
+
71
+ # When a system error occurs.
72
+ rescue StandardError => message
73
+ @status = :error
74
+ @message = message
75
+
76
+ # TODO: Write log entry to /reflections/errors.txt
77
+ 🔥"#{@method}() not reflected", :error, :control, @klass.class
78
+ end
79
+ end
80
+ end
81
+ end
data/lib/experiment.rb ADDED
@@ -0,0 +1,99 @@
1
+ ################################################################################
2
+ # A snapshot of random data.
3
+ #
4
+ # @note
5
+ # A reflection's random values are generated from aggregated control rule sets.
6
+ #
7
+ # @nomenclature
8
+ # args, inputs/output and meta represent different stages of a value.
9
+ #
10
+ # @hierachy
11
+ # 1. Action
12
+ # 2. Experiment <- YOU ARE HERE
13
+ # 3. Meta
14
+ #
15
+ # @status
16
+ # - :pass [Symbol] The reflection passes the rules.
17
+ # - :fail [Symbol] The reflection fails the rules or produces a system error.
18
+ # - :error [Symbol] The control reflection produces a system error.
19
+ ################################################################################
20
+
21
+ require_relative 'reflection'
22
+ require_relative 'meta_builder'
23
+
24
+ module Reflekt
25
+ class Experiment < Reflection
26
+
27
+ ##
28
+ # Reflect on a method.
29
+ #
30
+ # Create a shadow action.
31
+ # @param *args [Dynamic] The method's arguments.
32
+ ##
33
+ def reflect(*args)
34
+ # Get aggregated rule sets.
35
+ input_rule_sets = @aggregator.get_input_rule_sets(@klass, @method)
36
+ output_rule_set = @aggregator.get_output_rule_set(@klass, @method)
37
+
38
+ # Fail when no trained rule sets.
39
+ if input_rule_sets.nil?
40
+ @status = :fail
41
+ end
42
+
43
+ # When arguments exist.
44
+ unless args.size == 0
45
+ # Create random arguments from aggregated rule sets.
46
+ unless input_rule_sets.nil?
47
+ args = randomize(args, input_rule_sets)
48
+ end
49
+
50
+ # Create metadata for each argument.
51
+ # TODO: Create metadata for other inputs such as instance variables.
52
+ 🔥"> Create meta for #{@method}(): #{args}", :info, :meta, @klass
53
+ @inputs = MetaBuilder.create_many(args)
54
+ end
55
+
56
+ # Action method with random arguments.
57
+ begin
58
+ # Run reflection.
59
+ output = @clone.send(@method, *args)
60
+ @output = MetaBuilder.create(output)
61
+
62
+ # Validate output against aggregated control rule sets.
63
+ unless output_rule_set.nil?
64
+ unless @aggregator.test_output(output, output_rule_set)
65
+ @status = :fail
66
+ end
67
+ end
68
+
69
+ # When a system error occurs.
70
+ rescue StandardError => message
71
+ @status = :fail
72
+ @message = message
73
+ end
74
+ end
75
+
76
+ ##
77
+ # Create random values for each argument from control reflections.
78
+ #
79
+ # @param args [Dynamic] The arguments to mirror random values for.
80
+ # @param input_rule_sets [Array] Aggregated rule sets for each argument.
81
+ #
82
+ # @return [Dynamic] Random arguments.
83
+ ##
84
+ def randomize(args, input_rule_sets)
85
+ random_args = []
86
+
87
+ args.each_with_index do |arg, arg_num|
88
+ # Get a random rule in the rule set.
89
+ rules = input_rule_sets[arg_num].rules
90
+ agg_rule = rules[rules.keys.sample]
91
+
92
+ # Create a random value that follows that rule.
93
+ random_args << agg_rule.random()
94
+ end
95
+
96
+ return random_args
97
+ end
98
+ end
99
+ end