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.
@@ -1,12 +1,16 @@
1
1
  ################################################################################
2
- # REFLEKT - By Maedi Prichard.
2
+ # Reflective testing.
3
3
  #
4
- # An Execution is created each time a method is called.
5
- # Many Refections are created per Execution.
6
- # Each Reflection executes on a ShadowStack on cloned data.
7
- # Then flow is returned to the original method and normal execution continues.
4
+ # @author
5
+ # Maedi Prichard
8
6
  #
9
- # Usage:
7
+ # @flow
8
+ # 1. An Execution is created on method call.
9
+ # 2. Many Refections are created per Execution.
10
+ # 3. Each Reflection executes on cloned data.
11
+ # 4. Flow is returned to the original method.
12
+ #
13
+ # @usage
10
14
  # class ExampleClass
11
15
  # prepend Reflekt
12
16
  ################################################################################
@@ -15,11 +19,11 @@ require 'set'
15
19
  require 'erb'
16
20
  require 'rowdb'
17
21
  require 'Accessor'
22
+ require 'Aggregator'
18
23
  require 'Control'
19
24
  require 'Execution'
20
25
  require 'Reflection'
21
26
  require 'Renderer'
22
- require 'Ruler'
23
27
  require 'ShadowStack'
24
28
 
25
29
  module Reflekt
@@ -63,7 +67,7 @@ module Reflekt
63
67
  execution.is_reflecting = true
64
68
 
65
69
  # Create control.
66
- control = Control.new(execution, 1, @@reflekt.ruler)
70
+ control = Control.new(execution, 1, @@reflekt.aggregator)
67
71
  execution.control = control
68
72
 
69
73
  # Execute control.
@@ -76,7 +80,7 @@ module Reflekt
76
80
  execution.reflections.each_with_index do |value, index|
77
81
 
78
82
  # Create reflection.
79
- reflection = Reflection.new(execution, index + 1, @@reflekt.ruler)
83
+ reflection = Reflection.new(execution, index + 1, @@reflekt.aggregator)
80
84
  execution.reflections[index] = reflection
81
85
 
82
86
  # Execute reflection.
@@ -130,16 +134,16 @@ module Reflekt
130
134
  # Receive configuration.
131
135
  $ENV ||= {}
132
136
  $ENV[:reflekt] ||= $ENV[:reflekt] = {}
137
+ $ENV[:reflekt][:output_directory] = "reflections"
133
138
 
134
139
  # Set configuration.
135
140
  @@reflekt.path = File.dirname(File.realpath(__FILE__))
136
141
 
137
- # Get reflections directory path from config.
142
+ # Get reflections directory path from config or current execution path.
138
143
  if $ENV[:reflekt][:output_path]
139
- @@reflekt.output_path = File.join($ENV[:reflekt][:output_path], 'reflections')
140
- # Get reflections directory path from current execution path.
144
+ @@reflekt.output_path = File.join($ENV[:reflekt][:output_path], $ENV[:reflekt][:output_directory])
141
145
  else
142
- @@reflekt.output_path = File.join(Dir.pwd, 'reflections')
146
+ @@reflekt.output_path = File.join(Dir.pwd, $ENV[:reflekt][:output_directory])
143
147
  end
144
148
 
145
149
  # Create reflections directory.
@@ -150,30 +154,15 @@ module Reflekt
150
154
  # Create database.
151
155
  @@reflekt.db = Rowdb.new(@@reflekt.output_path + '/db.js')
152
156
  @@reflekt.db.defaults({ :reflekt => { :api_version => 1 }})
157
+ # @TODO Fix Rowdb.get(path) not returning values at path after Rowdb.push()
158
+ db = @@reflekt.db.value()
153
159
 
154
- # Create shadow execution stack.
160
+ # Create shadow stack.
155
161
  @@reflekt.stack = ShadowStack.new()
156
162
 
157
- # Create rules.
158
- @@reflekt.ruler = Ruler.new()
159
- # TODO: Fix Rowdb.get(path) not returning values at path after Rowdb.push()?
160
- values = @@reflekt.db.value()
161
- values.each do |klass, class_values|
162
-
163
- class_values.each do |method_name, method_items|
164
- next if method_items.nil?
165
- next unless method_items.class == Hash
166
- if method_items.key? "controls"
167
-
168
- method = method_name.to_sym
169
-
170
- @@reflekt.ruler.load(klass, method, method_items['controls'])
171
- @@reflekt.ruler.train(klass, method)
172
-
173
- end
174
- end
175
-
176
- end
163
+ # Create aggregated rule sets.
164
+ @@reflekt.aggregator = Aggregator.new()
165
+ @@reflekt.aggregator.train(db[:controls])
177
166
 
178
167
  # The amount of reflections to create per method call.
179
168
  @@reflekt.reflect_amount = 2
@@ -186,16 +175,17 @@ module Reflekt
186
175
  @@reflekt.renderer = Renderer.new(@@reflekt.path, @@reflekt.output_path)
187
176
 
188
177
  return true
178
+
189
179
  end
190
180
 
191
181
  module SingletonClassMethods
192
182
 
193
- @@reflekt_skipped_methods = Set.new
183
+ @@reflekt_skipped_methods = Set.new()
194
184
 
195
185
  ##
196
186
  # Skip a method.
197
187
  #
198
- # @param method - A symbol representing the method name.
188
+ # @param method [Symbol] The method name.
199
189
  ##
200
190
  def reflekt_skip(method)
201
191
  @@reflekt_skipped_methods.add(method)
@@ -28,6 +28,11 @@ class Renderer
28
28
  end
29
29
  end
30
30
 
31
+ file = File.read(File.join(@path, "web", "gitignore.txt"))
32
+ File.open(File.join(@output_path, ".gitignore"), 'w+') do |f|
33
+ f.write file
34
+ end
35
+
31
36
  end
32
37
 
33
38
 
@@ -1,32 +1,36 @@
1
1
  ################################################################################
2
- # RULES
2
+ # All rules behave the same.
3
3
  #
4
- # Abstract class.
5
- # See lib/rules for rules.
4
+ # @pattern Abstract class.
5
+ # @see lib/rules for rules.
6
6
  ################################################################################
7
7
 
8
- require 'set'
9
-
10
8
  class Rule
11
9
 
12
- # Each rule intitalises itself.
13
- def initialize()
14
- @values = []
10
+ ##
11
+ # Each rule trains on metadata to determine its boundaries.
12
+ #
13
+ # @param meta [Meta]
14
+ ##
15
+ def train(meta)
15
16
  end
16
17
 
17
- # Each rule loads up an array of values.
18
- def load(value)
19
- @values << value
18
+ ##
19
+ # Each rule validates a value with its boundaries.
20
+ #
21
+ # @param value [Dynamic]
22
+ # @return [Boolean] Whether the value passes or fails.
23
+ ##
24
+ def test(value)
20
25
  end
21
26
 
22
- # Each rule trains on values to determine its boundaries.
23
- def train()
24
-
25
- end
26
-
27
- # Each rule compares the values it's given with its boundaries.
28
- def validate(value)
29
-
27
+ ##
28
+ # Each rule provides metadata.
29
+ #
30
+ # @return [Hash]
31
+ ##
32
+ def result()
33
+ {}
30
34
  end
31
35
 
32
36
  end
@@ -1,34 +1,64 @@
1
1
  ################################################################################
2
- # RULE POOL
3
- #
4
- # A collection of unique rules that validate an argument.
2
+ # A collection of rules that validate a value.
5
3
  ################################################################################
6
4
 
7
5
  require 'set'
8
- require 'rules/FloatRule'
9
- require 'rules/IntegerRule'
10
- require 'rules/StringRule'
11
6
 
12
7
  class RuleSet
13
8
 
14
- attr_accessor :types
15
9
  attr_accessor :rules
16
10
 
17
11
  def initialize()
18
12
 
19
- @types = Set.new
20
13
  @rules = {}
14
+ @types = Set.new()
21
15
 
22
16
  end
23
17
 
24
- def load(type, value)
18
+ def self.create_sets(args)
19
+
20
+ rule_sets = []
21
+
22
+ args.each do |arg|
23
+ rule_sets << self.create_set(arg)
24
+ end
25
+
26
+ rule_sets
27
+ end
28
+
29
+ def self.create_set(value)
30
+
31
+ rule_set = RuleSet.new()
32
+ value_type = value.class.to_s
33
+
34
+ # Creates values for matching data type.
35
+ case value_type
36
+ when "Integer"
37
+ rule = IntegerRule.new()
38
+ rule.train(arg)
39
+ rule_set.rules[IntegerRule] = rule
40
+ when "String"
41
+ rule = StringRule.new()
42
+ rule.train(arg)
43
+ rule_set.rules[StringRule] = rule
44
+ end
45
+
46
+ rule_set
47
+ end
48
+
49
+ ##
50
+ # Train rule set on metadata.
51
+ #
52
+ # @param meta [Meta] The metadata to train on.
53
+ ##
54
+ def train(meta)
25
55
 
26
56
  # Track data type.
27
- @types << type
57
+ @types << meta.class
58
+ type = meta.class.to_s
28
59
 
29
60
  # Get rule for this data type.
30
61
  rule = nil
31
-
32
62
  case type
33
63
  when "Integer"
34
64
  unless @rules.key? IntegerRule
@@ -46,34 +76,30 @@ class RuleSet
46
76
  end
47
77
  end
48
78
 
49
- # Add value to rule.
79
+ # Train rule.
50
80
  unless rule.nil?
51
- rule.load(value)
81
+ rule.train(meta)
52
82
  end
53
83
 
54
84
  return self
55
85
 
56
86
  end
57
87
 
58
- def train()
88
+ ##
89
+ # Get the results of the rules.
90
+ #
91
+ # @return [Array] The rules.
92
+ ##
93
+ def result()
59
94
 
60
- @rules.each do |klass, rule|
61
- rule.train()
62
- end
95
+ rules = {}
63
96
 
64
- end
65
-
66
- def validate_rule(value)
67
- result = true
68
-
69
- @rules.each do |klass, rule|
70
-
71
- unless rule.validate(value)
72
- result = false
73
- end
97
+ @rules.each do |key, rule|
98
+ rules[rule.class] = rule.result()
74
99
  end
75
100
 
76
- return result
101
+ return rules
102
+
77
103
  end
78
104
 
79
105
  end
@@ -1,7 +1,5 @@
1
1
  ################################################################################
2
- # SHADOW STACK
3
- #
4
- # Track the executions in a call stack.
2
+ # Track the executions in a shadow call stack.
5
3
  ################################################################################
6
4
 
7
5
  class ShadowStack
@@ -20,24 +18,23 @@ class ShadowStack
20
18
  end
21
19
 
22
20
  ##
23
- # Push Execution.
21
+ # Place Execution at the top of stack.
24
22
  #
25
- # @param object - The object being executed.
26
- # @param args - The arguments being executed.
27
- #
28
- # @return Execution - The new execution.
23
+ # @param execution [Execution] The execution to place.
24
+ # @return [Execution] The placed execution.
29
25
  ##
30
26
  def push(execution)
31
27
 
32
- # Reference previous execution.
28
+ # Place first execution at bottom of stack.
33
29
  if @bottom.nil?
34
30
  @bottom = execution
31
+ # Connect subsequent executions to each other.
35
32
  else
36
- execution.child = @top
37
33
  @top.parent = execution
34
+ execution.child = @top
38
35
  end
39
36
 
40
- # Place new execution at the top of the stack.
37
+ # Place execution at top of stack.
41
38
  @top = execution
42
39
 
43
40
  end
@@ -0,0 +1,27 @@
1
+ require 'Meta'
2
+
3
+ class IntegerMeta < Meta
4
+
5
+ def initialize()
6
+
7
+ @value = nil
8
+
9
+ end
10
+
11
+ ##
12
+ # @param value [Integer]
13
+ ##
14
+ def load(value)
15
+
16
+ @value = value
17
+
18
+ end
19
+
20
+ def result()
21
+ {
22
+ :type => :int,
23
+ :value => @value
24
+ }
25
+ end
26
+
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'Meta'
2
+
3
+ class StringMeta < Meta
4
+
5
+ def initialize()
6
+
7
+ @length = nil
8
+
9
+ end
10
+
11
+ ##
12
+ # @param value [Integer]
13
+ ##
14
+ def load(value)
15
+
16
+ @length = value.length
17
+
18
+ end
19
+
20
+ def result()
21
+ {
22
+ :type => :string,
23
+ :length => @length
24
+ }
25
+ end
26
+
27
+ end
@@ -3,24 +3,37 @@ require 'Rule'
3
3
  class IntegerRule < Rule
4
4
 
5
5
  def initialize()
6
+
6
7
  @min = nil
7
8
  @max = nil
8
9
 
9
- super
10
10
  end
11
11
 
12
- def load(value)
13
- @values << value.to_i
14
- end
12
+ ##
13
+ # @param meta [IntegerMeta]
14
+ ##
15
+ def train(meta)
16
+
17
+ value = meta[:value]
18
+
19
+ if @min.nil?
20
+ @min = value
21
+ else
22
+ @min = value if value < @min
23
+ end
24
+
25
+ if @max.nil?
26
+ @max = value
27
+ else
28
+ @max = value if value > @max
29
+ end
15
30
 
16
- def train()
17
- numbers = @values.select {|num| num.class == Integer }
18
- numbers.sort!
19
- @min = numbers.first
20
- @max = numbers.last
21
31
  end
22
32
 
23
- def validate(value)
33
+ ##
34
+ # @param value [Integer]
35
+ ##
36
+ def test(value)
24
37
 
25
38
  return false if value < @min
26
39
  return false if value > @max
@@ -28,4 +41,11 @@ class IntegerRule < Rule
28
41
  true
29
42
  end
30
43
 
44
+ def result()
45
+ {
46
+ :type => :int,
47
+ :value => @min # Min/max are the same.
48
+ }
49
+ end
50
+
31
51
  end