array_logic 0.1.0 → 0.1.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/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