array_logic 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -29,6 +29,12 @@ The *match* and *matches* methods allow arrays to be tested against these rules:
29
29
  rule_two.match([a1, a2]) --> false
30
30
  rule_two.matches([a1, a2], [a1]) --> [[a1]]
31
31
 
32
+ You can also test for arrays that do not match the rule by using *block*
33
+ and *blockers*:
34
+
35
+ rule_two.block([a1, a2]) --> true
36
+ rule_two.blockers([a1, a2], [a1]) --> [[a1, a2]]
37
+
32
38
  See test/array_logic/rule_test for more examples
33
39
 
34
40
  === Combinations that match
@@ -37,11 +43,12 @@ Two methods allow you to determine sample combinations that match the current
37
43
  rule.
38
44
 
39
45
  rule = ArrayLogic::Rule.new 'a1 and a2'
40
- rule.matching_combinations --> [[1,2]]
41
- rule.blocking_combinations --> [[1],[2]]
46
+
47
+ rule.matching_combinations --> [[1,2]]
48
+ rule.blocking_combinations --> [[1],[2]]
42
49
 
43
50
  To limit the number of samples presented, both only use ids used within
44
- the rule. For the example about, an array that includes [1,2] would match,
51
+ the rule. For the example above, an array that includes [1,2] would match,
45
52
  and so would [1,2,3]. However, arrays that only contain 1 or 2 would not match
46
53
  (for example [1,3])
47
54
 
@@ -8,7 +8,11 @@ module ArrayLogic
8
8
  end
9
9
 
10
10
  def matches(*array_of_things)
11
- array_of_things.delete_if{|things| !match(things)}
11
+ array_of_things.delete_if{|things| block(things)}
12
+ end
13
+
14
+ def blockers(*array_of_things)
15
+ array_of_things.delete_if{|things| match(things)}
12
16
  end
13
17
 
14
18
  def match(things)
@@ -17,6 +21,10 @@ module ArrayLogic
17
21
  @thing_ids = things.collect(&:id)
18
22
  logic
19
23
  end
24
+
25
+ def block(things)
26
+ ! match(things)
27
+ end
20
28
 
21
29
  def logic
22
30
  eval(expression)
@@ -45,7 +53,12 @@ module ArrayLogic
45
53
  def blocking_combinations
46
54
  combinations_of_identifiers_in_rule_that_pass {|c| ! match_ids(c)}
47
55
  end
48
-
56
+
57
+ def check_rule
58
+ check_rule_entered
59
+ check_allowed_characters
60
+ end
61
+
49
62
  private
50
63
  def match_ids(ids)
51
64
  @thing_ids = ids
@@ -64,13 +77,6 @@ module ArrayLogic
64
77
  object_ids_used.length
65
78
  end
66
79
 
67
- def combinations_of_identifiers_in_rule
68
- ids = object_ids_used
69
- combinations = Array.new
70
- (1..ids.length).each{|n| ids.combination(n).each{|c| combinations << c}}
71
- return combinations
72
- end
73
-
74
80
  def objects_identifiers_in_rule
75
81
  rule_without_punctuation.split.delete_if{|x| !(thing_id_pattern =~ x)}
76
82
  end
@@ -88,6 +94,7 @@ module ArrayLogic
88
94
  replace_item(number_in_set_pattern, comparison_of_number_with_true_count)
89
95
  end
90
96
 
97
+ # for example: 2 in t1, t2, t3
91
98
  def number_in_set_pattern
92
99
  /\d+\s+in\s+((true|false)[\,\s]*)+/
93
100
  end
@@ -142,40 +149,39 @@ module ArrayLogic
142
149
  def rule_without_punctuation
143
150
  rule.gsub(/[[:punct:]]/, '')
144
151
  end
145
-
146
- def check_rule
147
- check_rule_entered
148
- check_allowed_characters
149
- end
150
152
 
151
153
  def check_rule_entered
152
154
  raise "You must define a rule before trying to match" unless rule.kind_of? String
153
155
  end
154
156
 
155
157
  def check_allowed_characters
156
- raise_invalid_charachers unless allowed_charachers_pattern =~ rule
158
+ raise_invalid_characters unless allowed_characters_pattern =~ rule
157
159
  end
160
+
161
+ def raise_invalid_characters
162
+ invalid = rule.split.collect{|s| (allowed_characters_pattern =~ s) ? nil : s }.compact
163
+ raise "The rule '#{rule}' is not valid. The problem is within '#{invalid.join(' ')}'"
164
+ end
158
165
 
159
- def allowed_charachers_pattern
166
+ def allowed_characters_pattern
160
167
  case_insensitive = true
161
- Regexp.new("^(#{allowed_characters.join('|')})*$", case_insensitive)
168
+ Regexp.new("^(#{array_of_allowed_patterns.join('|')})*$", case_insensitive)
162
169
  end
163
170
 
164
171
  def allowed_characters
165
- brackets = ['\(', '\)']
166
- in_pattern = ['\d+\s+in']
167
- ids = ['\w\d+']
168
- logic_words = %w{and or not}
169
- logic_chrs = ['&&', '\|\|', '!']
170
- commas = ['\,']
171
- white_space = ['\s']
172
-
173
- [brackets, in_pattern, ids, logic_words, logic_chrs, commas, white_space].flatten
172
+ {
173
+ :brackets => ['\(', '\)'],
174
+ :in_pattern => ['\d+\s+in'],
175
+ :ids => ['\w\d+'],
176
+ :logic_words => %w{and or not},
177
+ :logic_chrs => ['&&', '\|\|', '!'],
178
+ :commas => ['\,'],
179
+ :white_space => ['\s'],
180
+ }
174
181
  end
175
-
176
- def raise_invalid_charachers
177
- invalid = rule.split.collect{|s| (allowed_charachers_pattern =~ s) ? nil : s }.compact
178
- raise "The rule '#{rule}' is not valid. The problem is within '#{invalid.join(' ')}'"
182
+
183
+ def array_of_allowed_patterns
184
+ allowed_characters.values.flatten
179
185
  end
180
186
 
181
187
  end
@@ -1,3 +1,3 @@
1
1
  module ArrayLogic
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -158,6 +158,31 @@ module ArrayLogic
158
158
  @rule.match([1, 2])
159
159
  end
160
160
  end
161
+
162
+ def test_match_with_empty_rule
163
+ @rule.rule = ""
164
+ things = get_things([1, 2])
165
+ assert(!@rule.match([things.first]), "Should be no match when rule empty")
166
+ end
167
+
168
+ def test_block_without_rule
169
+ assert_raise RuntimeError do
170
+ @rule.block([1, 2])
171
+ end
172
+ end
173
+
174
+ def test_block_with_number_rule
175
+ @rule.rule = 1
176
+ assert_raise RuntimeError do
177
+ @rule.block([1, 2])
178
+ end
179
+ end
180
+
181
+ def test_block_with_empty_rule
182
+ @rule.rule = ""
183
+ things = get_things([1, 2])
184
+ assert(@rule.block([things.first]), "Should be block when rule empty")
185
+ end
161
186
 
162
187
  def test_replace_item
163
188
  @rule.rule = 't1 or ( t2 and t3 )'
@@ -180,46 +205,48 @@ module ArrayLogic
180
205
  end
181
206
  end
182
207
 
183
- def test_matches
208
+ def test_matches_and_blokers
184
209
  @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]
210
+ match_one = get_things [1, 2]
211
+ match_two = get_things [1, 2, 3]
212
+ no_match_one = get_things [2, 3]
213
+ no_match_two = get_things [3]
214
+
215
+ matches = @rule.matches(match_one, match_two, no_match_one, no_match_two)
216
+ expected_matches = [match_one, match_two]
217
+ assert_equal(expected_matches, matches, "Matches should be returned")
192
218
 
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)
219
+ blockers = @rule.blockers(match_one, match_two, no_match_one, no_match_two)
220
+ expected_blockers = [no_match_one, no_match_two]
221
+ assert_equal(expected_blockers, blockers, "Blockers should be returned")
196
222
  end
197
223
 
198
- def test_matches_with_or
224
+ def test_matches_and_blokers_with_or
199
225
  @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]
226
+ match_one = get_things [1, 2]
227
+ match_two = get_things [1, 2, 3]
228
+ match_three = get_things [2, 3]
229
+ no_match_one = get_things [3]
230
+
231
+ matches = @rule.matches(match_one, match_two, match_three, no_match_one)
232
+ expected_matches = [match_one, match_two, match_three]
233
+ assert_equal(expected_matches, matches, "Matches should be returned")
207
234
 
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)
235
+ blockers = @rule.blockers(match_one, match_two, match_three, no_match_one)
236
+ expected_blockers = [no_match_one]
237
+ assert_equal(expected_blockers, blockers, "Blockers should be returned")
211
238
  end
212
239
 
213
- def test_match_with_empty_rule
240
+ def test_matches_with_empty_rule
214
241
  @rule.rule = ""
215
- things = get_things([1, 2])
216
- assert(!@rule.match([things.first]), "Should be no match when rule empty")
242
+ things = get_things([1, 2]).collect{|t| [t]}
243
+ assert_equal([], @rule.matches(*things))
217
244
  end
218
245
 
219
- def test_matches_with_empty_rule
246
+ def test_blokers_with_empty_rule
220
247
  @rule.rule = ""
221
- things = get_things([1, 2])
222
- assert_equal([], @rule.matches([things.first], [things.last]))
248
+ things = get_things([1, 2]).collect{|t| [t]}
249
+ assert_equal(things, @rule.blockers(*things))
223
250
  end
224
251
 
225
252
  def test_object_ids_used
@@ -15,11 +15,13 @@ module ArrayLogic
15
15
  def assert_thing_match(thing_ids, rule)
16
16
  get_things(thing_ids)
17
17
  assert(rule.match(@things), "#{thing_ids.inspect} should match '#{rule.rule}'")
18
+ assert(!rule.block(@things), "#{thing_ids.inspect} should not block '#{rule.rule}'")
18
19
  end
19
20
 
20
21
  def assert_no_thing_match(thing_ids, rule)
21
22
  get_things(thing_ids)
22
23
  assert(!rule.match(@things), "#{thing_ids.inspect} should not match '#{rule.rule}'")
24
+ assert(rule.block(@things), "#{thing_ids.inspect} should block '#{rule.rule}'")
23
25
  end
24
26
  end
25
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: array_logic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-12 00:00:00.000000000 Z
12
+ date: 2012-12-13 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Allow a user to define a set of rules, and then test to see if an array
15
15
  of object match those rules.
@@ -19,17 +19,17 @@ executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
- - lib/array_logic.rb
23
- - lib/array_logic/thing.rb
24
22
  - lib/array_logic/version.rb
23
+ - lib/array_logic/thing.rb
25
24
  - lib/array_logic/rule.rb
25
+ - lib/array_logic.rb
26
26
  - lib/example.rb
27
27
  - MIT-LICENSE
28
28
  - Rakefile
29
29
  - README.rdoc
30
- - test/array_logic/thing_test.rb
31
- - test/array_logic/rule_test.rb
32
30
  - test/array_logic/test_case.rb
31
+ - test/array_logic/rule_test.rb
32
+ - test/array_logic/thing_test.rb
33
33
  homepage: https://github.com/reggieb/array_logic
34
34
  licenses: []
35
35
  post_install_message:
@@ -55,6 +55,6 @@ signing_key:
55
55
  specification_version: 3
56
56
  summary: Matches arrays of objects against logical rules.
57
57
  test_files:
58
- - test/array_logic/thing_test.rb
59
- - test/array_logic/rule_test.rb
60
58
  - test/array_logic/test_case.rb
59
+ - test/array_logic/rule_test.rb
60
+ - test/array_logic/thing_test.rb