array_logic 0.0.1
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.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +32 -0
- data/Rakefile +19 -0
- data/lib/array_logic.rb +5 -0
- data/lib/array_logic/rule.rb +134 -0
- data/lib/array_logic/thing.rb +17 -0
- data/lib/array_logic/version.rb +3 -0
- data/lib/main.rb +4 -0
- data/test/array_logic/rule_test.rb +214 -0
- data/test/array_logic/test_case.rb +25 -0
- data/test/array_logic/thing_test.rb +14 -0
- metadata +60 -0
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2012 Rob Nichols
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
== array_logic
|
|
2
|
+
|
|
3
|
+
A system that allows me to define the logic for comparing arrays.
|
|
4
|
+
|
|
5
|
+
The logic for an active record model Answer, looks like this:
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
a1 = Answer.find(1)
|
|
9
|
+
a2 = Answer.find(2)
|
|
10
|
+
....
|
|
11
|
+
a5 = Answer.find(5)
|
|
12
|
+
|
|
13
|
+
rule_one.rule = "(a1 and a2) or (a3 and a4)"
|
|
14
|
+
|
|
15
|
+
rule_two.rule = "a1 and not a2"
|
|
16
|
+
|
|
17
|
+
rule_three.rule = "2 in a1 a2 a3"
|
|
18
|
+
|
|
19
|
+
rule_four.rule = "(2 in a1 a2 a3) and (1 in a4 a5)"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
rule_one rule_two rule_three rule_four
|
|
23
|
+
[a1, a2] true false true false
|
|
24
|
+
[a3, a4] true false false false
|
|
25
|
+
[a1, a3, a5] false true true true
|
|
26
|
+
|
|
27
|
+
The *match* and *matches* methods allow arrays to be tested against these rules:
|
|
28
|
+
|
|
29
|
+
rule_two.match([a1, a2]) --> false
|
|
30
|
+
rule_two.matches([a1, a2], [a1]) --> [[a1]]
|
|
31
|
+
|
|
32
|
+
See test/array_logic/rule_test for more examples
|
data/Rakefile
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
require 'rake'
|
|
4
|
+
require 'rake/clean'
|
|
5
|
+
require 'rdoc/task'
|
|
6
|
+
require 'rake/testtask'
|
|
7
|
+
|
|
8
|
+
Rake::RDocTask.new do |rdoc|
|
|
9
|
+
files =['README.rdoc', 'MIT-LICENSE', 'lib/**/*.rb']
|
|
10
|
+
rdoc.rdoc_files.add(files)
|
|
11
|
+
rdoc.main = "README.rdoc" # page to start on
|
|
12
|
+
rdoc.title = "Dibber Docs"
|
|
13
|
+
rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
|
|
14
|
+
rdoc.options << '--line-numbers'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
Rake::TestTask.new do |t|
|
|
18
|
+
t.test_files = FileList['test/**/*.rb']
|
|
19
|
+
end
|
data/lib/array_logic.rb
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
|
|
2
|
+
class Rule
|
|
3
|
+
attr_accessor :rule
|
|
4
|
+
attr_reader :things
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def matches(*array_of_things)
|
|
11
|
+
array_of_things.delete_if{|things| !match(things)}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def match(things)
|
|
15
|
+
rule_valid?
|
|
16
|
+
@things = things
|
|
17
|
+
logic
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def logic
|
|
21
|
+
eval(expression)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def rule_valid?
|
|
25
|
+
check_rule_entered
|
|
26
|
+
check_allowed_characters
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def replace_item(pattern, processor)
|
|
30
|
+
@processed_rule = processed_rule.gsub(pattern) {|x| processor.call(x)}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
def thing_ids
|
|
35
|
+
things.collect(&:id)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def expression
|
|
39
|
+
rule_processing_steps
|
|
40
|
+
return final_processed_rule
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def rule_processing_steps
|
|
46
|
+
add_space_around_puctuation_characters
|
|
47
|
+
make_everything_lower_case
|
|
48
|
+
replace_logic_words_with_operators
|
|
49
|
+
replace_item(thing_id_pattern, true_or_false_for_thing_id_in_thing_ids)
|
|
50
|
+
replace_item(number_in_set_pattern, comparison_of_number_with_true_count)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def number_in_set_pattern
|
|
54
|
+
/\d+\s+in\s+((true|false)[\,\s]*)+/
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def comparison_of_number_with_true_count
|
|
58
|
+
lambda do |string|
|
|
59
|
+
before_in, after_in = string.split(/\s+in\s+/)
|
|
60
|
+
true_count = after_in.split.count('true')
|
|
61
|
+
" ( #{before_in} <= #{true_count} ) "
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# examples: a1, a2, a33, t1
|
|
66
|
+
def thing_id_pattern
|
|
67
|
+
/\w\d+/
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def true_or_false_for_thing_id_in_thing_ids
|
|
71
|
+
lambda {|s| thing_ids.include?(s[/\d+/].to_i)}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def processed_rule
|
|
75
|
+
@processed_rule ||= rule.clone
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def add_space_around_puctuation_characters
|
|
79
|
+
@processed_rule = processed_rule.gsub(/(\)|\)|\,)/, ' \1 ')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def make_everything_lower_case
|
|
83
|
+
@processed_rule = processed_rule.downcase
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def replace_logic_words_with_operators
|
|
87
|
+
{
|
|
88
|
+
'and' => '&&',
|
|
89
|
+
'or' => '||',
|
|
90
|
+
'not' => '!'
|
|
91
|
+
}.each{|word, operator| @processed_rule = processed_rule.gsub(Regexp.new(word), operator)}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def final_processed_rule
|
|
95
|
+
result = processed_rule.clone
|
|
96
|
+
reset_processed_rule_ready_for_next_comparison
|
|
97
|
+
return result
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def reset_processed_rule_ready_for_next_comparison
|
|
101
|
+
@processed_rule = nil
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def check_rule_entered
|
|
105
|
+
raise "You must define a rule before trying to match" unless rule.kind_of? String
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def check_allowed_characters
|
|
109
|
+
raise_invalid_charachers unless allowed_charachers_pattern =~ rule
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def allowed_charachers_pattern
|
|
113
|
+
case_insensitive = true
|
|
114
|
+
Regexp.new("^(#{allowed_characters.join('|')})*$", case_insensitive)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def allowed_characters
|
|
118
|
+
brackets = ['\(', '\)']
|
|
119
|
+
in_pattern = ['\d+\s+in']
|
|
120
|
+
ids = ['\w\d+']
|
|
121
|
+
logic_words = %w{and or not}
|
|
122
|
+
logic_chrs = ['&&', '\|\|', '!']
|
|
123
|
+
commas = ['\,']
|
|
124
|
+
white_space = ['\s']
|
|
125
|
+
|
|
126
|
+
[brackets, in_pattern, ids, logic_words, logic_chrs, commas, white_space].flatten
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def raise_invalid_charachers
|
|
130
|
+
invalid = rule.split.collect{|s| (allowed_charachers_pattern =~ s) ? nil : s }.compact
|
|
131
|
+
raise "The rule '#{rule}' is not valid. The problem is within '#{invalid.join(' ')}'"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module ArrayLogic
|
|
2
|
+
|
|
3
|
+
# Basic object used in testing
|
|
4
|
+
class Thing
|
|
5
|
+
attr_accessor :id
|
|
6
|
+
|
|
7
|
+
def initialize(number)
|
|
8
|
+
@id = number
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.make(number)
|
|
12
|
+
things = Hash.new
|
|
13
|
+
(1..number).each{|n| things[n] = new(n)}
|
|
14
|
+
return things
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/main.rb
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require_relative '../../lib/array_logic'
|
|
3
|
+
require_relative 'test_case'
|
|
4
|
+
|
|
5
|
+
module ArrayLogic
|
|
6
|
+
class RuleTest < TestCase
|
|
7
|
+
|
|
8
|
+
def setup
|
|
9
|
+
@rule = Rule.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_simple_and
|
|
13
|
+
@rule.rule = 't1 and t2'
|
|
14
|
+
assert_thing_match([1, 2], @rule)
|
|
15
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
16
|
+
assert_no_thing_match([2, 3], @rule)
|
|
17
|
+
assert_no_thing_match([3], @rule)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_simple_or
|
|
21
|
+
@rule.rule = 't1 or t2'
|
|
22
|
+
assert_thing_match([1, 2], @rule)
|
|
23
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
24
|
+
assert_thing_match([2, 3], @rule)
|
|
25
|
+
assert_no_thing_match([3], @rule)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_multiple_and
|
|
29
|
+
@rule.rule = 't1 and t2 and t3'
|
|
30
|
+
assert_no_thing_match([1, 2], @rule)
|
|
31
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
32
|
+
assert_no_thing_match([2, 3], @rule)
|
|
33
|
+
assert_no_thing_match([3], @rule)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_multiple_or
|
|
37
|
+
@rule.rule = 't1 or t2 or t3'
|
|
38
|
+
assert_thing_match([1, 2], @rule)
|
|
39
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
40
|
+
assert_thing_match([3], @rule)
|
|
41
|
+
assert_no_thing_match([4], @rule)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_one_or_one_and
|
|
45
|
+
@rule.rule = 't1 or ( t2 and t3 )'
|
|
46
|
+
assert_thing_match([1, 2], @rule)
|
|
47
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
48
|
+
assert_thing_match([2, 3], @rule)
|
|
49
|
+
assert_no_thing_match([3], @rule)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_one_or_one_and
|
|
53
|
+
@rule.rule = '( t1 or t2 ) and t3'
|
|
54
|
+
assert_no_thing_match([1, 2], @rule)
|
|
55
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
56
|
+
assert_thing_match([2, 3], @rule)
|
|
57
|
+
assert_no_thing_match([3], @rule)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_one_or_one_and_not
|
|
61
|
+
@rule.rule = 't1 or ( t2 and not t3 )'
|
|
62
|
+
assert_thing_match([1, 3], @rule)
|
|
63
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
64
|
+
assert_no_thing_match([2, 3], @rule)
|
|
65
|
+
assert_thing_match([2], @rule)
|
|
66
|
+
assert_thing_match([2, 4], @rule)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_one_or_one_and_with_no_space_between_tn_and_bracket
|
|
70
|
+
@rule.rule = 't1 or (t2 and t3)'
|
|
71
|
+
assert_thing_match([1, 2], @rule)
|
|
72
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
73
|
+
assert_thing_match([2, 3], @rule)
|
|
74
|
+
assert_no_thing_match([3], @rule)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_one_in_three
|
|
78
|
+
@rule.rule = '1 in t1, t2, t3'
|
|
79
|
+
assert_thing_match([1, 2], @rule)
|
|
80
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
81
|
+
assert_thing_match([3], @rule)
|
|
82
|
+
assert_no_thing_match([4], @rule)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_one_in_three_no_commas
|
|
86
|
+
@rule.rule = '1 in t1 t2 t3'
|
|
87
|
+
assert_thing_match([1, 2], @rule)
|
|
88
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
89
|
+
assert_thing_match([3], @rule)
|
|
90
|
+
assert_no_thing_match([4], @rule)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def test_one_in_three_with_and
|
|
94
|
+
@rule.rule = '(1 in t1, t2, t3) and t3'
|
|
95
|
+
assert_no_thing_match([1, 2], @rule)
|
|
96
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
97
|
+
assert_thing_match([3], @rule)
|
|
98
|
+
assert_no_thing_match([4], @rule)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def test_one_in_three_with_and_without_brackets
|
|
102
|
+
@rule.rule = '1 in t1, t2, t3 and t3'
|
|
103
|
+
assert_no_thing_match([1, 2], @rule)
|
|
104
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
105
|
+
assert_thing_match([3], @rule)
|
|
106
|
+
assert_no_thing_match([4], @rule)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_one_in_three_with_and_without_brackets_and_commas
|
|
110
|
+
@rule.rule = '1 in t1 t2 t3 and t3'
|
|
111
|
+
assert_no_thing_match([1, 2], @rule)
|
|
112
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
113
|
+
assert_thing_match([3], @rule)
|
|
114
|
+
assert_no_thing_match([4], @rule)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_2_in_with_and_at_start
|
|
118
|
+
@rule.rule = 't1 and t2 and 2 in t2 t3 t4'
|
|
119
|
+
assert_no_thing_match([1, 2], @rule)
|
|
120
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
121
|
+
assert_thing_match([1, 2, 4], @rule)
|
|
122
|
+
assert_no_thing_match([2, 3, 4], @rule)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_in_within_logic_string
|
|
126
|
+
@rule.rule = '(t1 and 1 in t2 t3) or t4'
|
|
127
|
+
assert_thing_match([1, 2], @rule)
|
|
128
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
129
|
+
assert_no_thing_match([3], @rule)
|
|
130
|
+
assert_thing_match([4], @rule)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_uppercase_in_within_logic_string
|
|
134
|
+
@rule.rule = '(t1 AND 1 IN t2 t3) OR t4'
|
|
135
|
+
assert_thing_match([1, 2], @rule)
|
|
136
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
137
|
+
assert_no_thing_match([3], @rule)
|
|
138
|
+
assert_thing_match([4], @rule)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def test_operators_in_within_logic_string
|
|
142
|
+
@rule.rule = '(t1 && 1 in t2 t3) || t4'
|
|
143
|
+
assert_thing_match([1, 2], @rule)
|
|
144
|
+
assert_thing_match([1, 2, 3], @rule)
|
|
145
|
+
assert_no_thing_match([3], @rule)
|
|
146
|
+
assert_thing_match([4], @rule)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def test_match_without_rule
|
|
150
|
+
assert_raise RuntimeError do
|
|
151
|
+
@rule.match([1, 2])
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_match_with_number_rule
|
|
156
|
+
@rule.rule = 1
|
|
157
|
+
assert_raise RuntimeError do
|
|
158
|
+
@rule.match([1, 2])
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def test_replace_item
|
|
163
|
+
@rule.rule = 't1 or ( t2 and t3 )'
|
|
164
|
+
process = lambda {|s| [1, 2].include?(s[/\d+/].to_i)}
|
|
165
|
+
result = @rule.replace_item(/\w\d+/, process)
|
|
166
|
+
assert_equal('true or ( true and false )', result)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def test_invalid_input
|
|
170
|
+
@rule.rule = 'invalid'
|
|
171
|
+
assert_raise RuntimeError do
|
|
172
|
+
@rule.match([1])
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def test_another_invalid_input
|
|
177
|
+
@rule.rule = 'a1 and User.delete_all'
|
|
178
|
+
assert_raise RuntimeError do
|
|
179
|
+
@rule.match([1])
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def test_matches
|
|
184
|
+
@rule.rule = 't1 and t2'
|
|
185
|
+
t1 = Thing.new(1)
|
|
186
|
+
t2 = Thing.new(2)
|
|
187
|
+
t3 = Thing.new(3)
|
|
188
|
+
match_one = [t1, t2]
|
|
189
|
+
match_two = [t1, t2, t3]
|
|
190
|
+
no_match_one = [t2, t3]
|
|
191
|
+
no_match_two = [t3]
|
|
192
|
+
|
|
193
|
+
result = @rule.matches(match_one, match_two, no_match_one, no_match_two)
|
|
194
|
+
expected = [match_one, match_two]
|
|
195
|
+
assert_equal(expected, result)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_matches_with_or
|
|
199
|
+
@rule.rule = 't1 or t2'
|
|
200
|
+
t1 = Thing.new(1)
|
|
201
|
+
t2 = Thing.new(2)
|
|
202
|
+
t3 = Thing.new(3)
|
|
203
|
+
match_one = [t1, t2]
|
|
204
|
+
match_two = [t1, t2, t3]
|
|
205
|
+
match_three = [t2, t3]
|
|
206
|
+
no_match_two = [t3]
|
|
207
|
+
|
|
208
|
+
result = @rule.matches(match_one, match_two, match_three, no_match_two)
|
|
209
|
+
expected = [match_one, match_two, match_three]
|
|
210
|
+
assert_equal(expected, result)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
end
|
|
214
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require_relative '../../lib/array_logic'
|
|
3
|
+
|
|
4
|
+
module ArrayLogic
|
|
5
|
+
class TestCase < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def self.things
|
|
8
|
+
@things ||= Thing.make(10)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def get_things(thing_ids)
|
|
12
|
+
@things = thing_ids.collect{|id| self.class.things[id]}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def assert_thing_match(thing_ids, rule)
|
|
16
|
+
get_things(thing_ids)
|
|
17
|
+
assert(rule.match(@things), "#{thing_ids.inspect} should match '#{rule.rule}'")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def assert_no_thing_match(thing_ids, rule)
|
|
21
|
+
get_things(thing_ids)
|
|
22
|
+
assert(!rule.match(@things), "#{thing_ids.inspect} should not match '#{rule.rule}'")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require_relative '../../lib/array_logic'
|
|
3
|
+
|
|
4
|
+
module ArrayLogic
|
|
5
|
+
class ThingTest < Test::Unit::TestCase
|
|
6
|
+
def test_make
|
|
7
|
+
number = 10
|
|
8
|
+
things = Thing.make(number)
|
|
9
|
+
assert_equal(number, things.length)
|
|
10
|
+
assert_equal((1..number).to_a, things.values.collect(&:id))
|
|
11
|
+
assert_equal((1..number).to_a, things.keys)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: array_logic
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Rob Nichols
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2012-11-26 00:00:00.000000000 Z
|
|
13
|
+
dependencies: []
|
|
14
|
+
description: Allow a user to define a set of rules, and then test to see if an array
|
|
15
|
+
of object match those rules.
|
|
16
|
+
email:
|
|
17
|
+
- rob@undervale.co.uk
|
|
18
|
+
executables: []
|
|
19
|
+
extensions: []
|
|
20
|
+
extra_rdoc_files: []
|
|
21
|
+
files:
|
|
22
|
+
- lib/array_logic.rb
|
|
23
|
+
- lib/main.rb
|
|
24
|
+
- lib/array_logic/thing.rb
|
|
25
|
+
- lib/array_logic/version.rb
|
|
26
|
+
- lib/array_logic/rule.rb
|
|
27
|
+
- MIT-LICENSE
|
|
28
|
+
- Rakefile
|
|
29
|
+
- README.rdoc
|
|
30
|
+
- test/array_logic/thing_test.rb
|
|
31
|
+
- test/array_logic/rule_test.rb
|
|
32
|
+
- test/array_logic/test_case.rb
|
|
33
|
+
homepage: https://github.com/reggieb/array_logic
|
|
34
|
+
licenses: []
|
|
35
|
+
post_install_message:
|
|
36
|
+
rdoc_options: []
|
|
37
|
+
require_paths:
|
|
38
|
+
- lib
|
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
|
+
none: false
|
|
41
|
+
requirements:
|
|
42
|
+
- - ! '>='
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
version: '0'
|
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
|
+
none: false
|
|
47
|
+
requirements:
|
|
48
|
+
- - ! '>='
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: '0'
|
|
51
|
+
requirements: []
|
|
52
|
+
rubyforge_project:
|
|
53
|
+
rubygems_version: 1.8.24
|
|
54
|
+
signing_key:
|
|
55
|
+
specification_version: 3
|
|
56
|
+
summary: Matches arrays of objects against logical rules.
|
|
57
|
+
test_files:
|
|
58
|
+
- test/array_logic/thing_test.rb
|
|
59
|
+
- test/array_logic/rule_test.rb
|
|
60
|
+
- test/array_logic/test_case.rb
|