reflekt 0.9.8 → 0.9.9

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: c5b9e88d60fea03ebe06c430b489cb1295b8d56ec76f30982721a709a406f0af
4
- data.tar.gz: 948f53a8b72f5befda3e175029edfdb017d98b3b8fd41998ab95b5f6b0a6b95e
3
+ metadata.gz: f04cedc3780f61776191bf7ae72822aae50eba606c76c61c176f5c252462fa22
4
+ data.tar.gz: 2ca6aa88016bfcab50460048d338a45f3855ee623f1b1bb5edc5e36323418eca
5
5
  SHA512:
6
- metadata.gz: e70f287d10e70e3ac8ab3e01881ed6d8bb79f881c9af5530f39c7dd29997021ddf246d1129467503cfb3c6efb0589604648876c64bda917e8b970cb278a79fb3
7
- data.tar.gz: ef005f855d7c3d1002eb059a73ecf742645841d4d3d0bd416a84b549e2e7d5b63a8bc216e8fe1404bf20c383a8e0a10c54740458e40382fa9591f9c67f3a075c
6
+ metadata.gz: 88024a7b33ba0ac0fca948b1b0808ad1a7094e958ae3b5d48f378b2c9256fcb29735b4635880322f5c2ee62e0034a265263997c3074d90d6756aef5408e5a2cb
7
+ data.tar.gz: b2700bb56c2cf3915676c797381ad7913cb3091ffe576e7f276c9e97dcde488be602e01defbd812c3886f26a2cdde4090bd207312bad14f3d1ab20e55e3541e6
@@ -2,14 +2,15 @@
2
2
  # Access variables via one object to avoid polluting the caller class scope.
3
3
  #
4
4
  # @pattern Singleton
5
+ #
5
6
  # @note Some variables are not accessed via Accessor:
6
7
  # - @reflekt_counts on the instance
7
- # - @reflekt_enabled on the instance
8
8
  # - @@reflekt_skipped_methods on the instance's singleton class
9
9
  ################################################################################
10
10
 
11
11
  class Accessor
12
12
 
13
+ attr_accessor :config
13
14
  attr_accessor :setup
14
15
  attr_accessor :db
15
16
  attr_accessor :stack
@@ -17,11 +18,10 @@ class Accessor
17
18
  attr_accessor :renderer
18
19
  attr_accessor :path
19
20
  attr_accessor :output_path
20
- attr_accessor :reflect_amount
21
- attr_accessor :reflect_limit
22
21
 
23
22
  def initialize()
24
23
 
24
+ @config = nil
25
25
  @setup = nil
26
26
  @db = nil
27
27
  @stack = nil
@@ -29,8 +29,6 @@ class Accessor
29
29
  @renderer = nil
30
30
  @path = nil
31
31
  @output_path = nil
32
- @reflect_amount = nil
33
- @reflect_limit = nil
34
32
 
35
33
  end
36
34
 
@@ -5,7 +5,7 @@
5
5
  # @pattern Singleton
6
6
  #
7
7
  # @hierachy
8
- # 1. Aggregator
8
+ # 1. Aggregator <- YOU ARE HERE
9
9
  # 2. RuleSet
10
10
  # 3. Rule
11
11
  ################################################################################
@@ -14,8 +14,12 @@ require 'RuleSet'
14
14
 
15
15
  class Aggregator
16
16
 
17
- def initialize()
17
+ ##
18
+ # @param meta_map [Hash] The rules that apply to each meta type.
19
+ ##
20
+ def initialize(meta_map)
18
21
 
22
+ @meta_map = meta_map
19
23
  # Key rule sets by class and method.
20
24
  @rule_sets = {}
21
25
 
@@ -109,7 +113,7 @@ class Aggregator
109
113
  # Get rule set.
110
114
  rule_set = get_input_rule_set(klass, method, arg_num)
111
115
  if rule_set.nil?
112
- rule_set = RuleSet.new()
116
+ rule_set = RuleSet.new(@meta_map)
113
117
  set_input_rule_set(klass, method, arg_num, rule_set)
114
118
  end
115
119
 
@@ -126,7 +130,7 @@ class Aggregator
126
130
  # Get rule set.
127
131
  output_rule_set = get_output_rule_set(klass, method)
128
132
  if output_rule_set.nil?
129
- output_rule_set = RuleSet.new()
133
+ output_rule_set = RuleSet.new(@meta_map)
130
134
  set_output_rule_set(klass, method, output_rule_set)
131
135
  end
132
136
 
@@ -0,0 +1,35 @@
1
+ class Config
2
+
3
+ attr_accessor :reflect_amount
4
+ attr_accessor :reflect_limit
5
+ attr_accessor :meta_map
6
+ attr_accessor :output_path
7
+ attr_accessor :output_directory
8
+
9
+ def initialize()
10
+
11
+ # The amount of reflections to create per method call.
12
+ @reflect_amount = 2
13
+
14
+ # The maximum amount of reflections that can be created per instance/method.
15
+ # A method called thousands of times doesn't need that many reflections.
16
+ @reflect_limit = 10
17
+
18
+ # The rules that apply to meta types.
19
+ @meta_map = {
20
+ :array => [ArrayRule],
21
+ :bool => [BooleanRule],
22
+ :int => [IntegerRule],
23
+ :string => [StringRule]
24
+ }
25
+
26
+ # An absolute path to the directory that contains the output directory.
27
+ # Defaults to current execution path.
28
+ @output_path = nil
29
+
30
+ # Name of output directory.
31
+ @output_directory = "reflections"
32
+
33
+ end
34
+
35
+ end
@@ -17,10 +17,10 @@ class Execution
17
17
  ##
18
18
  # Create Execution.
19
19
  #
20
- # @param Object object - The calling object.
21
- # @param Symbol method - The calling method.
22
- # @param Integer number - The number of reflections to create per execution.
23
- # @param ShadowStack stack - The shadow execution call stack.
20
+ # @param object [Object] The calling object.
21
+ # @param method [Symbol] The calling method.
22
+ # @param number [Integer] The number of reflections to create per execution.
23
+ # @param stack [ShadowStack] The shadow execution call stack.
24
24
  ##
25
25
  def initialize(caller_object, method, number, stack)
26
26
 
@@ -1,7 +1,7 @@
1
1
  ################################################################################
2
- # Meta for input and output. All meta behave the same.
2
+ # Metadata for input and output.
3
3
  #
4
- # @pattern Abstract class.
4
+ # @pattern Abstract class
5
5
  # @see lib/meta for each meta.
6
6
  ################################################################################
7
7
 
@@ -1,7 +1,7 @@
1
1
  ################################################################################
2
- # Create Meta.
2
+ # Create metadata.
3
3
  #
4
- # @pattern Builder.
4
+ # @pattern Builder
5
5
  # @see lib/meta for each meta.
6
6
  ################################################################################
7
7
 
@@ -1,14 +1,15 @@
1
1
  ################################################################################
2
2
  # Reflective testing.
3
3
  #
4
- # @author
5
- # Maedi Prichard
4
+ # @author Maedi Prichard
6
5
  #
7
6
  # @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.
7
+ # 1. Reflekt is prepended to a class and setup.
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.
11
+ # 5. Each Reflection executes on cloned data.
12
+ # 6. Flow is returned to the original method.
12
13
  #
13
14
  # @usage
14
15
  # class ExampleClass
@@ -20,11 +21,14 @@ require 'erb'
20
21
  require 'rowdb'
21
22
  require 'Accessor'
22
23
  require 'Aggregator'
24
+ require 'Config'
23
25
  require 'Control'
24
26
  require 'Execution'
25
27
  require 'Reflection'
26
28
  require 'Renderer'
27
29
  require 'ShadowStack'
30
+ # Require all rules.
31
+ Dir[File.join(__dir__, 'rules', '*.rb')].each { |file| require file }
28
32
 
29
33
  module Reflekt
30
34
 
@@ -32,37 +36,41 @@ module Reflekt
32
36
 
33
37
  @reflekt_counts = {}
34
38
 
35
- # Get instance methods.
36
- # TODO: Include parent methods like "Array.include?".
37
- self.class.instance_methods(false).each do |method|
39
+ # Get child and parent instance methods.
40
+ parent_instance_methods = self.class.superclass.instance_methods(false)
41
+ child_instance_methods = self.class.instance_methods(false)
42
+ instance_methods = parent_instance_methods + child_instance_methods
38
43
 
39
- # Don't process skipped methods.
40
- next if self.class.reflekt_skipped?(method)
44
+ # TODO: Include core methods like "Array.include?".
45
+ instance_methods.each do |method|
41
46
 
42
47
  @reflekt_counts[method] = 0
43
48
 
44
49
  # When method called in flow.
45
50
  self.define_singleton_method(method) do |*args|
46
51
 
47
- # Don't reflect when limit reached.
48
- unless @reflekt_counts[method] >= @@reflekt.reflect_limit
52
+ # Get current execution.
53
+ execution = @@reflekt.stack.peek()
49
54
 
50
- # Get current execution.
51
- execution = @@reflekt.stack.peek()
55
+ # Don't reflect when reflect limit reached or method skipped.
56
+ unless (@reflekt_counts[method] >= @@reflekt.config.reflect_limit) || self.class.reflekt_skipped?(method)
52
57
 
53
58
  # When stack empty or past execution done reflecting.
54
59
  if execution.nil? || execution.has_finished_reflecting?
55
60
 
56
61
  # Create execution.
57
- execution = Execution.new(self, method, @@reflekt.reflect_amount, @@reflekt.stack)
62
+ execution = Execution.new(self, method, @@reflekt.config.reflect_amount, @@reflekt.stack)
58
63
 
59
64
  @@reflekt.stack.push(execution)
60
65
 
61
66
  end
62
67
 
63
- # Reflect.
68
+ ##
69
+ # Reflect the execution.
70
+ #
64
71
  # The first method call in the Execution creates a Reflection.
65
72
  # Subsequent method calls are shadow executions on cloned objects.
73
+ ##
66
74
  if execution.has_empty_reflections? && !execution.is_reflecting?
67
75
  execution.is_reflecting = true
68
76
 
@@ -103,8 +111,13 @@ module Reflekt
103
111
 
104
112
  end
105
113
 
106
- # Continue execution / shadow execution.
107
- super *args
114
+ # Don't execute skipped methods when reflecting.
115
+ unless execution.is_reflecting? && self.class.reflekt_skipped?(method)
116
+
117
+ # Continue execution / shadow execution.
118
+ super *args
119
+
120
+ end
108
121
 
109
122
  end
110
123
 
@@ -115,6 +128,13 @@ module Reflekt
115
128
 
116
129
  end
117
130
 
131
+ ##
132
+ # Provide Config instance to block.
133
+ ##
134
+ def self.configure
135
+ yield(@@reflekt.config)
136
+ end
137
+
118
138
  private
119
139
 
120
140
  def self.prepended(base)
@@ -132,18 +152,16 @@ module Reflekt
132
152
  def self.reflekt_setup_class()
133
153
 
134
154
  # Receive configuration.
135
- $ENV ||= {}
136
- $ENV[:reflekt] ||= $ENV[:reflekt] = {}
137
- $ENV[:reflekt][:output_directory] = "reflections"
155
+ @@reflekt.config = Config.new()
138
156
 
139
157
  # Set configuration.
140
158
  @@reflekt.path = File.dirname(File.realpath(__FILE__))
141
159
 
142
160
  # Get reflections directory path from config or current execution path.
143
- if $ENV[:reflekt][:output_path]
144
- @@reflekt.output_path = File.join($ENV[:reflekt][:output_path], $ENV[:reflekt][:output_directory])
161
+ if @@reflekt.config.output_path
162
+ @@reflekt.output_path = File.join(@@reflekt.config.output_path, @@reflekt.config.output_directory)
145
163
  else
146
- @@reflekt.output_path = File.join(Dir.pwd, $ENV[:reflekt][:output_directory])
164
+ @@reflekt.output_path = File.join(Dir.pwd, @@reflekt.config.output_directory)
147
165
  end
148
166
 
149
167
  # Create reflections directory.
@@ -161,16 +179,9 @@ module Reflekt
161
179
  @@reflekt.stack = ShadowStack.new()
162
180
 
163
181
  # Create aggregated rule sets.
164
- @@reflekt.aggregator = Aggregator.new()
182
+ @@reflekt.aggregator = Aggregator.new(@@reflekt.config.meta_map)
165
183
  @@reflekt.aggregator.train(db[:controls])
166
184
 
167
- # The amount of reflections to create per method call.
168
- @@reflekt.reflect_amount = 2
169
-
170
- # Limit the amount of reflections that can be created per instance method.
171
- # A method called thousands of times doesn't need that many reflections.
172
- @@reflekt.reflect_limit = 10
173
-
174
185
  # Create renderer.
175
186
  @@reflekt.renderer = Renderer.new(@@reflekt.path, @@reflekt.output_path)
176
187
 
@@ -185,6 +196,10 @@ module Reflekt
185
196
  ##
186
197
  # Skip a method.
187
198
  #
199
+ # @note
200
+ # Class variables cascade to child classes.
201
+ # So a reflekt_skip on the parent class will persist to the child class.
202
+ #
188
203
  # @param method [Symbol] The method name.
189
204
  ##
190
205
  def reflekt_skip(method)
@@ -196,9 +211,9 @@ module Reflekt
196
211
  false
197
212
  end
198
213
 
199
- def reflekt_limit(amount)
200
- @@reflekt.reflect_limit = amount
201
- end
214
+ #def reflekt_limit(amount)
215
+ # @@reflekt.reflect_limit = amount
216
+ #end
202
217
 
203
218
  end
204
219
 
@@ -1,7 +1,13 @@
1
1
  ################################################################################
2
- # All rules behave the same.
2
+ # A pattern that metadata follows.
3
+ #
4
+ # @pattern Abstract class
5
+ #
6
+ # @hierachy
7
+ # 1. Aggregator
8
+ # 2. RuleSet
9
+ # 3. Rule <- YOU ARE HERE
3
10
  #
4
- # @pattern Abstract class.
5
11
  # @see lib/rules for rules.
6
12
  ################################################################################
7
13
 
@@ -1,5 +1,14 @@
1
1
  ################################################################################
2
- # A collection of rules that validate a value.
2
+ # A collection of rules that validate metadata.
3
+ #
4
+ # @patterns
5
+ # - Dependency Injection
6
+ # - Builder
7
+ #
8
+ # @hierachy
9
+ # 1. Aggregator
10
+ # 2. RuleSet <- YOU ARE HERE
11
+ # 3. Rule
3
12
  ################################################################################
4
13
 
5
14
  require 'set'
@@ -8,44 +17,17 @@ class RuleSet
8
17
 
9
18
  attr_accessor :rules
10
19
 
11
- def initialize()
20
+ ##
21
+ # @param meta_map [Hash] The rules to apply to each data type.
22
+ ##
23
+ def initialize(meta_map)
12
24
 
25
+ @meta_map = meta_map
13
26
  @rules = {}
14
27
  @types = Set.new()
15
28
 
16
29
  end
17
30
 
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
31
  ##
50
32
  # Train rule set on metadata.
51
33
  #
@@ -53,35 +35,29 @@ class RuleSet
53
35
  ##
54
36
  def train(meta)
55
37
 
56
- # Track data type.
57
- @types << meta.class
58
- type = meta.class.to_s
59
-
60
- # Get rule for this data type.
61
- rule = nil
62
- case type
63
- when "Integer"
64
- unless @rules.key? IntegerRule
65
- rule = IntegerRule.new()
66
- @rules[IntegerRule] = rule
67
- else
68
- rule = @rules[IntegerRule]
69
- end
70
- when "String"
71
- unless @rules.key? StringRule
72
- rule = StringRule.new()
73
- @rules[StringRule] = rule
74
- else
75
- rule = @rules[IntegerRule]
38
+ unless meta.nil? || meta[:type].nil?
39
+
40
+ meta_type = meta[:type]
41
+ @types << meta_type
42
+
43
+ # Get rule types for this meta type.
44
+ if @meta_map.key? meta_type
45
+ @meta_map[meta_type].each do |rule_type|
46
+
47
+ # Ensure rule exists.
48
+ if @rules[rule_type].nil?
49
+ @rules << rule_type.new()
50
+ end
51
+
52
+ # Train rule.
53
+ @rules[rule_type].train(meta)
54
+
55
+ end
76
56
  end
77
- end
78
57
 
79
- # Train rule.
80
- unless rule.nil?
81
- rule.train(meta)
82
- end
58
+ return self
83
59
 
84
- return self
60
+ end
85
61
 
86
62
  end
87
63
 
@@ -1,5 +1,7 @@
1
1
  ################################################################################
2
2
  # Track the executions in a shadow call stack.
3
+ #
4
+ # @pattern Stack
3
5
  ################################################################################
4
6
 
5
7
  class ShadowStack
@@ -0,0 +1,33 @@
1
+ require 'Meta'
2
+
3
+ class ArrayMeta < Meta
4
+
5
+ def initialize()
6
+
7
+ @min = nil
8
+ @max = nil
9
+ @length = nil
10
+
11
+ end
12
+
13
+ ##
14
+ # @param value [Array]
15
+ ##
16
+ def load(value)
17
+
18
+ @min = value.min()
19
+ @max = value.max()
20
+ @length = value.length()
21
+
22
+ end
23
+
24
+ def result()
25
+ {
26
+ :type => :array,
27
+ :max => @max,
28
+ :min => @min,
29
+ :length => @length
30
+ }
31
+ end
32
+
33
+ end
@@ -0,0 +1,23 @@
1
+ require 'Meta'
2
+
3
+ class BooleanMeta < Meta
4
+
5
+ def initialize()
6
+ @value = nil
7
+ end
8
+
9
+ ##
10
+ # @param value [Boolean]
11
+ ##
12
+ def load(value)
13
+ @value = value
14
+ end
15
+
16
+ def result()
17
+ {
18
+ :type => :bool,
19
+ :value => @value
20
+ }
21
+ end
22
+
23
+ end
@@ -3,18 +3,14 @@ require 'Meta'
3
3
  class IntegerMeta < Meta
4
4
 
5
5
  def initialize()
6
-
7
6
  @value = nil
8
-
9
7
  end
10
8
 
11
9
  ##
12
10
  # @param value [Integer]
13
11
  ##
14
12
  def load(value)
15
-
16
13
  @value = value
17
-
18
14
  end
19
15
 
20
16
  def result()
@@ -3,18 +3,14 @@ require 'Meta'
3
3
  class StringMeta < Meta
4
4
 
5
5
  def initialize()
6
-
7
6
  @length = nil
8
-
9
7
  end
10
8
 
11
9
  ##
12
- # @param value [Integer]
10
+ # @param value [String]
13
11
  ##
14
12
  def load(value)
15
-
16
13
  @length = value.length
17
-
18
14
  end
19
15
 
20
16
  def result()
@@ -0,0 +1,75 @@
1
+ require 'Rule'
2
+
3
+ class ArrayRule < Rule
4
+
5
+ def initialize()
6
+
7
+ @min = nil
8
+ @max = nil
9
+ @min_length = nil
10
+ @max_length = nil
11
+
12
+ end
13
+
14
+ ##
15
+ # @param meta [ArrayMeta]
16
+ ##
17
+ def train(meta)
18
+
19
+ # Min value.
20
+ if @min.nil?
21
+ @min = meta[:min]
22
+ else
23
+ @min = meta[:min] if meta[:min] < @min
24
+ end
25
+
26
+ # Max value.
27
+ if @max.nil?
28
+ @max = meta[:max]
29
+ else
30
+ @max = meta[:max] if meta[:max] > @max
31
+ end
32
+
33
+ # Min length.
34
+ if @min_length.nil?
35
+ @min_length = meta[:length]
36
+ else
37
+ @min_length = meta[:length] if meta[:length] < @min_length
38
+ end
39
+
40
+ # Max length.
41
+ if @max_length.nil?
42
+ @max_length = meta[:length]
43
+ else
44
+ @max_length = meta[:length] if meta[:length] > @max_length
45
+ end
46
+
47
+ end
48
+
49
+ ##
50
+ # @param value [Array]
51
+ ##
52
+ def test(value)
53
+
54
+ # Min/max value.
55
+ return false if value.min() < @min
56
+ return false if value.max() > @max
57
+
58
+ # Min/max length.
59
+ return false if value.length < @min_length
60
+ return false if value.length > @max_length
61
+
62
+ true
63
+ end
64
+
65
+ def result()
66
+ {
67
+ :type => :array,
68
+ :min => @min,
69
+ :max => @max,
70
+ :min_length => @min_length,
71
+ :max_length => @max_length
72
+ }
73
+ end
74
+
75
+ end
@@ -0,0 +1,42 @@
1
+ require 'set'
2
+ require 'Rule'
3
+
4
+ class BooleanRule < Rule
5
+
6
+ def initialize()
7
+
8
+ @booleans = Set.new()
9
+
10
+ end
11
+
12
+ ##
13
+ # @param meta [BooleanMeta]
14
+ ##
15
+ def train(meta)
16
+
17
+ value = meta[:value]
18
+
19
+ unless value.nil?
20
+ @booleans << value
21
+ end
22
+
23
+ end
24
+
25
+ ##
26
+ # @param value [Boolean]
27
+ ##
28
+ def test(value)
29
+
30
+ @booleans.include? value
31
+
32
+ end
33
+
34
+ def result()
35
+ {
36
+ :type => :bool,
37
+ :is_true => @booleans.include?,
38
+ :is_false => @booleans.include?
39
+ }
40
+ end
41
+
42
+ end
@@ -44,7 +44,8 @@ class IntegerRule < Rule
44
44
  def result()
45
45
  {
46
46
  :type => :int,
47
- :value => @min # Min/max are the same.
47
+ :min => @min,
48
+ :max => @max
48
49
  }
49
50
  end
50
51
 
@@ -13,7 +13,7 @@ class StringRule < Rule
13
13
  end
14
14
 
15
15
  ##
16
- # @param meta [Meta]
16
+ # @param meta [StringMeta]
17
17
  ##
18
18
  def train(meta)
19
19
 
@@ -1,7 +1,7 @@
1
1
  # Reflections
2
2
 
3
- As you use the application reflections will be added to /reflections/db.js.
4
- They can be viewed by opening reflections/index.html, no server setup required.
3
+ As you use your application, reflections will be added to `/reflections/db.js`.
4
+ They can be viewed by opening `/reflections/index.html` in your browser, no server setup required.
5
5
 
6
6
  If you would like to keep or delete reflections then start the server:
7
7
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reflekt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maedi Prichard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-26 00:00:00.000000000 Z
11
+ date: 2020-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rowdb
@@ -32,6 +32,7 @@ extra_rdoc_files: []
32
32
  files:
33
33
  - lib/Accessor.rb
34
34
  - lib/Aggregator.rb
35
+ - lib/Config.rb
35
36
  - lib/Control.rb
36
37
  - lib/Execution.rb
37
38
  - lib/Meta.rb
@@ -42,8 +43,12 @@ files:
42
43
  - lib/Rule.rb
43
44
  - lib/RuleSet.rb
44
45
  - lib/ShadowStack.rb
46
+ - lib/meta/ArrayMeta.rb
47
+ - lib/meta/BooleanMeta.rb
45
48
  - lib/meta/IntegerMeta.rb
46
49
  - lib/meta/StringMeta.rb
50
+ - lib/rules/ArrayRule.rb
51
+ - lib/rules/BooleanRule.rb
47
52
  - lib/rules/IntegerRule.rb
48
53
  - lib/rules/StringRule.rb
49
54
  - lib/web/README.md