rufus-decision 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -10,10 +10,13 @@ or at
10
10
 
11
11
  http://rubyforge.org/frs/?group_id=4812
12
12
 
13
+ == intro blog post
14
+
15
+ http://jmettraux.wordpress.com/2009/04/25/rufus-decision-11-ruby-decision-tables/
13
16
 
14
17
  == usage
15
18
 
16
- more info at http://rufus.rubyforge.org/rufus-decision/classes/Rufus/Decision/Table.html, but here is a recap.
19
+ More info at http://rufus.rubyforge.org/rufus-decision/classes/Rufus/Decision/Table.html but here is a recap.
17
20
 
18
21
  An example where a few rules determine which salesperson should interact with a customer with given characteristics.
19
22
 
@@ -35,7 +35,7 @@ require 'rufus/hashes'
35
35
  module Rufus
36
36
  module Decision
37
37
 
38
- VERSION = '1.1.0'
38
+ VERSION = '1.2.0'
39
39
 
40
40
  #
41
41
  # A decision table is a description of a set of rules as a CSV (comma
@@ -171,6 +171,11 @@ module Decision
171
171
  #
172
172
  # will yield { result => [ 'normal', 'large' ]} for f0 => 56
173
173
  #
174
+ # * "unbounded", by default, string matching is 'bounded', "apple" will match
175
+ # 'apple', but not 'greenapple'. When "unbounded" is set, 'greenapple' will
176
+ # match. ('bounded', in reality, means the target value is surrounded
177
+ # by ^ and $)
178
+ #
174
179
  # === Setting options at table initialization
175
180
  #
176
181
  # It's OK to set the options at initialization time :
@@ -250,33 +255,58 @@ module Decision
250
255
  #
251
256
  attr_accessor :accumulate
252
257
 
258
+ # when set to true, evaluation of ruby code for output is allowed. False
259
+ # by default.
260
+ #
261
+ attr_accessor :ruby_eval
262
+
263
+ # false (bounded) by default : exact matches for string matching. When
264
+ # 'unbounded', target 'apple' will match for values like 'greenapples' or
265
+ # 'apple seed'.
266
+ #
267
+ attr_accessor :unbound
268
+
253
269
  # The constructor for DecisionTable, you can pass a String, an Array
254
270
  # (of arrays), a File object. The CSV parser coming with Ruby will take
255
271
  # care of it and a DecisionTable instance will be built.
256
272
  #
257
- # parameters (options) are :through, :ignore_case, :accumulate (which
273
+ # Options are :through, :ignore_case, :accumulate (which
258
274
  # forces :through to true when set) and :ruby_eval. See
259
275
  # Rufus::Decision::Table for more details.
260
276
  #
261
- def initialize (csv, params={})
262
-
263
- @first_match = (params[:through] != true)
264
- @ignore_case = params[:ignore_case] || params[:ignorecase]
265
- @accumulate = params[:accumulate]
266
- @ruby_eval = params[:ruby_eval]
267
-
268
- @first_match = false if @accumulate
277
+ # Options passed to this method do override the options defined
278
+ # in the CSV itself.
279
+ #
280
+ # == options
281
+ #
282
+ # * :through : when set, all the rows of the decision table are considered
283
+ # * :ignore_case : case is ignored (not ignored by default)
284
+ # * :accumulate : gather instead of overriding (implies :through)
285
+ # * :ruby_eval : ruby code evaluation is OK
286
+ #
287
+ def initialize (csv, options={})
269
288
 
270
289
  @rows = Rufus::Decision.csv_to_a(csv)
271
290
 
272
291
  extract_options
292
+
273
293
  parse_header_row
294
+
295
+ @first_match = false if options[:through] == true
296
+ @first_match = true if @first_match.nil?
297
+
298
+ set_opt(options, :ignore_case, :ignorecase)
299
+ set_opt(options, :accumulate)
300
+ set_opt(options, :ruby_eval)
301
+ set_opt(options, :unbounded)
302
+
303
+ @first_match = false if @accumulate
274
304
  end
275
305
 
276
306
  # Like transform, but the original hash doesn't get touched,
277
307
  # a copy of it gets transformed and finally returned.
278
308
  #
279
- def transform (hash, options={})
309
+ def transform (hash)
280
310
 
281
311
  transform!(hash.dup)
282
312
  end
@@ -284,10 +314,9 @@ module Decision
284
314
  # Passes the hash through the decision table and returns it,
285
315
  # transformed.
286
316
  #
287
- def transform! (hash, options={})
317
+ def transform! (hash)
288
318
 
289
- hash = Rufus::Decision::EvalHashFilter.new(hash) \
290
- if @ruby_eval || options[:ruby_eval] == true
319
+ hash = Rufus::Decision::EvalHashFilter.new(hash) if @ruby_eval
291
320
 
292
321
  @rows.each do |row|
293
322
  next unless matches?(row, hash)
@@ -304,11 +333,24 @@ module Decision
304
333
  #
305
334
  def to_csv
306
335
 
307
- a = [ @header.to_csv ]
308
- @rows.inject(a) { |a, row| a << row.join(',') }.join("\n")
336
+ @rows.inject([ @header.to_csv ]) { |a, row|
337
+ a << row.join(',')
338
+ }.join("\n")
339
+ end
340
+
341
+ protected
342
+
343
+ def set_opt (options, *optnames)
344
+
345
+ optnames.each do |oname|
346
+
347
+ v = options[oname]
348
+ next unless v != nil
349
+ instance_variable_set("@#{optnames.first.to_s}", v)
350
+ return
351
+ end
309
352
  end
310
353
 
311
- private
312
354
 
313
355
  # Returns true if the hash matches the in: values for this row
314
356
  #
@@ -332,7 +374,7 @@ module Decision
332
374
  else
333
375
 
334
376
  range = to_ruby_range(cell)
335
- range ? range.include?(value) : regex_compare(value, cell)
377
+ range ? range.include?(value) : string_compare(value, cell)
336
378
  end
337
379
 
338
380
  return false unless b
@@ -341,12 +383,13 @@ module Decision
341
383
  true
342
384
  end
343
385
 
344
- def regex_compare (value, cell)
386
+ def string_compare (value, cell)
345
387
 
346
388
  modifiers = 0
347
389
  modifiers += Regexp::IGNORECASE if @ignore_case
348
390
 
349
- rcell = Regexp.new(cell, modifiers)
391
+ rcell = @unbounded ?
392
+ Regexp.new(cell, modifiers) : Regexp.new("^#{cell}$", modifiers)
350
393
 
351
394
  rcell.match(value)
352
395
  end
@@ -423,6 +466,8 @@ module Decision
423
466
  elsif cell == 'accumulate'
424
467
  @first_match = false
425
468
  @accumulate = true
469
+ elsif cell == 'unbounded'
470
+ @unbounded = true
426
471
  end
427
472
  end
428
473
 
@@ -435,13 +480,16 @@ module Decision
435
480
  # an "out:"
436
481
  #
437
482
  def is_vertical_table? (first_row)
483
+
438
484
  bin = false
439
485
  bout = false
486
+
440
487
  first_row.each do |cell|
441
488
  bin ||= cell.match(IN)
442
489
  bout ||= cell.match(OUT)
443
490
  return false if bin and bout
444
491
  end
492
+
445
493
  true
446
494
  end
447
495
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  require 'test/unit'
9
9
 
10
- require File.dirname(__FILE__) + '/test_base.rb'
10
+ require File.join(File.dirname(__FILE__), 'test_base.rb')
11
11
 
12
12
 
13
13
  class Decision0Test < Test::Unit::TestCase
@@ -28,13 +28,13 @@ e,f,2
28
28
  "fx" => "c",
29
29
  "fy" => "d"
30
30
  }
31
- do_test(CSV0, wi, {}, { "fz" => "1" }, false)
31
+ do_test(CSV0, wi, { "fz" => "1" }, false)
32
32
 
33
33
  wi = {
34
34
  "fx" => "a",
35
35
  "fy" => "d"
36
36
  }
37
- do_test(CSV0, wi, {}, { "fz" => nil }, false)
37
+ do_test(CSV0, wi, { "fz" => nil }, false)
38
38
  end
39
39
 
40
40
  CSV0B = %{
@@ -51,7 +51,7 @@ e,f,2
51
51
  "fx" => "c",
52
52
  "fy" => "d"
53
53
  }
54
- do_test(CSV0B, wi, {}, { "fz" => "1" }, false)
54
+ do_test(CSV0B, wi, { "fz" => "1" }, false)
55
55
  end
56
56
 
57
57
  # test 1 moved to decision_1_test.rb
@@ -67,10 +67,10 @@ e, f, 2
67
67
  def test_2
68
68
 
69
69
  wi = { "fx" => "c", "fy" => "d" }
70
- do_test(CSV2, wi, {}, { "fz" => "1" }, false)
70
+ do_test(CSV2, wi, { "fz" => "1" }, false)
71
71
 
72
72
  wi = { "fx" => "a", "fy" => "d" }
73
- do_test(CSV2, wi, {}, { "fz" => nil }, false)
73
+ do_test(CSV2, wi, { "fz" => nil }, false)
74
74
  end
75
75
 
76
76
  CSV3 = %{
@@ -89,19 +89,19 @@ cloudy, , no
89
89
  "weather" => "raining",
90
90
  "month" => "december"
91
91
  }
92
- do_test(CSV3, wi, {}, { "take_umbrella?" => "yes" }, false)
92
+ do_test(CSV3, wi, { "take_umbrella?" => "yes" }, false)
93
93
 
94
94
  wi = {
95
95
  "weather" => "cloudy",
96
96
  "month" => "june"
97
97
  }
98
- do_test(CSV3, wi, {}, { "take_umbrella?" => "yes" }, false)
98
+ do_test(CSV3, wi, { "take_umbrella?" => "yes" }, false)
99
99
 
100
100
  wi = {
101
101
  "weather" => "cloudy",
102
102
  "month" => "march"
103
103
  }
104
- do_test(CSV3, wi, {}, { "take_umbrella?" => "no" }, false)
104
+ do_test(CSV3, wi, { "take_umbrella?" => "no" }, false)
105
105
  end
106
106
 
107
107
  def test_3b
@@ -109,17 +109,17 @@ cloudy, , no
109
109
  h = {}
110
110
  h["weather"] = "raining"
111
111
  h["month"] = "december"
112
- do_test(CSV3, h, {}, { "take_umbrella?" => "yes" }, false)
112
+ do_test(CSV3, h, { "take_umbrella?" => "yes" }, false)
113
113
 
114
114
  h = {}
115
115
  h["weather"] = "cloudy"
116
116
  h["month"] = "june"
117
- do_test(CSV3, h, {}, { "take_umbrella?" => "yes" }, false)
117
+ do_test(CSV3, h, { "take_umbrella?" => "yes" }, false)
118
118
 
119
119
  h = {}
120
120
  h["weather"] = "cloudy"
121
121
  h["month"] = "march"
122
- do_test(CSV3, h, {}, { "take_umbrella?" => "no" }, false)
122
+ do_test(CSV3, h, { "take_umbrella?" => "no" }, false)
123
123
  end
124
124
 
125
125
  def test_3c
@@ -144,35 +144,6 @@ cloudy, , no
144
144
  assert_equal "Henry", h["team_member"]
145
145
  end
146
146
 
147
- CSV3D = "http://spreadsheets.google.com/pub?key=pCkopoeZwCNsMWOVeDjR1TQ&output=csv&gid=0"
148
-
149
- def test_3d
150
-
151
- #return unless online?
152
-
153
- h = {}
154
- h["weather"] = "raining"
155
- h["month"] = "december"
156
-
157
- do_test(CSV3D, h, {}, { "take_umbrella?" => "yes" }, false)
158
-
159
- h = {}
160
- h["weather"] = "cloudy"
161
- h["month"] = "june"
162
-
163
- sleep 0.5 # don't request the doc too often
164
-
165
- do_test(CSV3D, h, {}, { "take_umbrella?" => "yes" }, false)
166
-
167
- h = {}
168
- h["weather"] = "cloudy"
169
- h["month"] = "march"
170
-
171
- sleep 0.5 # don't request the doc too often
172
-
173
- do_test(CSV3D, h, {}, { "take_umbrella?" => "no" }, false)
174
- end
175
-
176
147
  def test_3e
177
148
 
178
149
  table = Rufus::DecisionTable.new(%{
@@ -208,13 +179,13 @@ cloudy, , no
208
179
  }
209
180
 
210
181
  wi = { 'fx' => 'a', 'fy' => 'a' }
211
- do_test(table, wi, {}, { 'fX' => 'true', 'fY' => 'true' }, false)
182
+ do_test(table, wi, { 'fX' => 'true', 'fY' => 'true' }, false)
212
183
 
213
184
  wi = { 'fx' => 'a', 'fy' => 'b' }
214
- do_test(table, wi, {}, { 'fX' => 'true', 'fY' => 'false' }, false)
185
+ do_test(table, wi, { 'fX' => 'true', 'fY' => 'false' }, false)
215
186
 
216
187
  wi = { 'fx' => 'A', 'fy' => 'b' }
217
- do_test(table, wi, {}, { 'fX' => 'true', 'fY' => 'false' }, false)
188
+ do_test(table, wi, { 'fX' => 'true', 'fY' => 'false' }, false)
218
189
  end
219
190
 
220
191
  def test_through_and_ignorecase_set_at_table_initialization
@@ -232,13 +203,13 @@ cloudy, , no
232
203
  table, :through => true, :ignore_case => true)
233
204
 
234
205
  wi = { 'fx' => 'a', 'fy' => 'a' }
235
- do_test(table, wi, {}, { 'fX' => 'true', 'fY' => 'true' }, false)
206
+ do_test(table, wi, { 'fX' => 'true', 'fY' => 'true' }, false)
236
207
 
237
208
  wi = { 'fx' => 'a', 'fy' => 'b' }
238
- do_test(table, wi, {}, { 'fX' => 'true', 'fY' => 'false' }, false)
209
+ do_test(table, wi, { 'fX' => 'true', 'fY' => 'false' }, false)
239
210
 
240
211
  wi = { 'fx' => 'A', 'fy' => 'b' }
241
- do_test(table, wi, {}, { 'fX' => 'true', 'fY' => 'false' }, false)
212
+ do_test(table, wi, { 'fX' => 'true', 'fY' => 'false' }, false)
242
213
  end
243
214
 
244
215
  #
@@ -258,12 +229,12 @@ in:fx, out:fy
258
229
  wi = {
259
230
  "fx" => "5"
260
231
  }
261
- do_test(CSV6, wi, {}, { "fy" => "a" }, false)
232
+ do_test(CSV6, wi, { "fy" => "a" }, false)
262
233
 
263
234
  wi = {
264
235
  "fx" => "100.0001"
265
236
  }
266
- do_test(CSV6, wi, {}, { "fy" => "c" }, false)
237
+ do_test(CSV6, wi, { "fy" => "c" }, false)
267
238
  end
268
239
 
269
240
  #
@@ -283,17 +254,17 @@ in:fx, out:fy
283
254
  wi = {
284
255
  "fx" => "5"
285
256
  }
286
- do_test(CSV7, wi, {}, { "fy" => "c" }, false)
257
+ do_test(CSV7, wi, { "fy" => "c" }, false)
287
258
 
288
259
  wi = {
289
260
  "fx" => "10"
290
261
  }
291
- do_test(CSV7, wi, {}, { "fy" => "b" }, false)
262
+ do_test(CSV7, wi, { "fy" => "b" }, false)
292
263
 
293
264
  wi = {
294
265
  "fx" => "10a"
295
266
  }
296
- do_test(CSV7, wi, {}, { "fy" => "a" }, false)
267
+ do_test(CSV7, wi, { "fy" => "a" }, false)
297
268
  end
298
269
 
299
270
  CSV8 = %{
@@ -317,16 +288,10 @@ e,f,2
317
288
 
318
289
  def test_ruby_eval
319
290
 
320
- wi = { 'fx' => 'c', 'fy' => 'd' }
321
- do_test(CSV9, wi, { :ruby_eval => true }, { 'fz' => '3' }, false)
322
- end
323
-
324
- def test_ruby_eval_set_at_table_initialization
325
-
326
291
  table = Rufus::Decision::Table.new(CSV9, :ruby_eval => true)
327
292
 
328
293
  wi = { 'fx' => 'c', 'fy' => 'd' }
329
- do_test(table, wi, {}, { 'fz' => '3' }, false)
294
+ do_test(table, wi, { 'fz' => '3' }, false)
330
295
  end
331
296
 
332
297
  CSV10 = %{
@@ -338,13 +303,13 @@ in:fx,in:fx,out:fz
338
303
  def test_10
339
304
 
340
305
  wi = { "fx" => "91" }
341
- do_test(CSV10, wi, {}, { "fz" => "ok" }, false)
306
+ do_test(CSV10, wi, { "fz" => "ok" }, false)
342
307
 
343
308
  wi = { "fx" => "95" }
344
- do_test(CSV10, wi, {}, { "fz" => "bad" }, false)
309
+ do_test(CSV10, wi, { "fz" => "bad" }, false)
345
310
 
346
311
  wi = { "fx" => "81" }
347
- do_test(CSV10, wi, {}, { "fz" => "bad" }, false)
312
+ do_test(CSV10, wi, { "fz" => "bad" }, false)
348
313
  end
349
314
 
350
315
  CSV11 = %{
@@ -361,7 +326,7 @@ in:f1,in:f1,in:f2,in:f3,out:o1,out:e1,out:e2
361
326
  def test_fu_zhang
362
327
 
363
328
  wi = { 'f1' => 97, 'f2' => 5 }
364
- do_test CSV11, wi, {}, { 'o1' => 'Expection1' }, false
329
+ do_test CSV11, wi, { 'o1' => 'Expection1' }, false
365
330
  end
366
331
 
367
332
  CSV12 = %{
@@ -378,14 +343,14 @@ b, , yellow, beige
378
343
  def test_accumulate
379
344
 
380
345
  wi = { "fx" => "a", "fy" => "a" }
381
- do_test CSV12, wi, {}, { "fX" => "red;blue", "fY" => "green;purple" }, false
346
+ do_test CSV12, wi, { "fX" => "red;blue", "fY" => "green;purple" }, false
382
347
 
383
348
  wi = { "fx" => "a", "fy" => "a", "fX" => "BLACK" }
384
- do_test CSV12, wi, {}, {
349
+ do_test CSV12, wi, {
385
350
  "fX" => "BLACK;red;blue", "fY" => "green;purple" }, false
386
351
 
387
352
  wi = { "fx" => "a", "fy" => "a", "fX" => [ "BLACK", "BLUE" ] }
388
- do_test CSV12, wi, {}, {
353
+ do_test CSV12, wi, {
389
354
  "fX" => "BLACK;BLUE;red;blue", "fY" => "green;purple" }, false
390
355
  end
391
356
 
@@ -424,14 +389,13 @@ in:fx,out:fz
424
389
  def test_range
425
390
 
426
391
  wi = { "fx" => "91" }
427
- do_test CSV13, wi, {}, { "fz" => "ok" }, false
392
+ do_test CSV13, wi, { "fz" => "ok" }, false
428
393
 
429
394
  wi = { "fx" => "95" }
430
- do_test CSV13, wi, {}, { "fz" => "bad" }, false
395
+ do_test CSV13, wi, { "fz" => "bad" }, false
431
396
 
432
397
  wi = { "fx" => "81" }
433
- do_test CSV13, wi, {}, { "fz" => "bad" }, false
398
+ do_test CSV13, wi, { "fz" => "bad" }, false
434
399
  end
435
-
436
400
  end
437
401
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  require 'test/unit'
9
9
 
10
- require File.dirname(__FILE__) + '/test_base.rb'
10
+ require File.join(File.dirname(__FILE__), 'test_base.rb')
11
11
 
12
12
 
13
13
  class Decision1Test < Test::Unit::TestCase
@@ -26,22 +26,26 @@ g,h,${r:'${fx}' + '${fy}'}
26
26
  def test_1
27
27
 
28
28
  wi = { 'fx' => 'c', 'fy' => 'd' }
29
- do_test(CSV1, wi, {}, { 'fz' => 'c' }, false)
29
+ do_test(CSV1, wi, { 'fz' => 'c' }, false)
30
30
 
31
31
  wi = { 'fx' => 'a', 'fy' => 'a' }
32
- do_test(CSV1, wi, {}, { 'fz' => '0' }, false)
32
+ do_test(CSV1, wi, { 'fz' => '0' }, false)
33
33
  end
34
34
 
35
35
  def test_1b
36
36
 
37
+ table = Rufus::Decision::Table.new(CSV1, :ruby_eval => true)
38
+
37
39
  h = { 'fx' => 'e', 'fy' => 'f' }
38
- do_test(CSV1, h, { :ruby_eval => true }, { 'fz' => '7' }, false)
40
+ do_test(table, h, { 'fz' => '7' }, false)
39
41
  end
40
42
 
41
43
  def test_1c
42
44
 
45
+ table = Rufus::Decision::Table.new(CSV1, :ruby_eval => true)
46
+
43
47
  h = { 'fx' => 'g', 'fy' => 'h' }
44
- do_test(CSV1, h, { :ruby_eval => true }, { 'fz' => 'gh' }, false)
48
+ do_test(table, h, { 'fz' => 'gh' }, false)
45
49
  end
46
50
 
47
51
  CSV2 = [
@@ -55,7 +59,7 @@ g,h,${r:'${fx}' + '${fy}'}
55
59
  def test_with_array_table
56
60
 
57
61
  wi = { 'fx' => 'c', 'fy' => 'd' }
58
- do_test(CSV2, wi, {}, { 'fz' => 'c' }, false)
62
+ do_test(CSV2, wi, { 'fz' => 'c' }, false)
59
63
  end
60
64
 
61
65
  def test_empty_string_to_float
@@ -70,7 +74,7 @@ g,h,${r:'${fx}' + '${fy}'}
70
74
  [ '', 'maniac', 'Korolev' ]
71
75
  ]
72
76
 
73
- do_test(table, wi, {}, { 'salesperson' => 'Korolev' }, false)
77
+ do_test(table, wi, { 'salesperson' => 'Korolev' }, false)
74
78
  end
75
79
 
76
80
  def test_vertical_rules
@@ -78,7 +82,7 @@ g,h,${r:'${fx}' + '${fy}'}
78
82
  table = CSV2.transpose
79
83
 
80
84
  wi = { 'fx' => 'c', 'fy' => 'd' }
81
- do_test(table, wi, {}, { 'fz' => 'c' }, false)
85
+ do_test(table, wi, { 'fz' => 'c' }, false)
82
86
  end
83
87
 
84
88
  def test_vertical_rules_2
@@ -90,7 +94,7 @@ out:team_member,Alice,Bob,Charly,Donald,Ernest,Fujio,Gilbert,Henry,Zach
90
94
  }
91
95
 
92
96
  h = { 'topic' => 'politics', 'region' => 'america' }
93
- do_test(table, h, {}, { 'team_member' => 'Gilbert' }, false)
97
+ do_test(table, h, { 'team_member' => 'Gilbert' }, false)
94
98
  end
95
99
 
96
100
  end
@@ -0,0 +1,45 @@
1
+
2
+ #
3
+ # Testing rufus-decision
4
+ #
5
+ # Sun Oct 29 15:41:44 JST 2006
6
+ #
7
+
8
+ require 'test/unit'
9
+
10
+ require File.join(File.dirname(__FILE__), 'test_base.rb')
11
+
12
+
13
+ class Decision2Test < Test::Unit::TestCase
14
+ include DecisionTestMixin
15
+
16
+ CSV3D = "http://spreadsheets.google.com/pub?key=pCkopoeZwCNsMWOVeDjR1TQ&output=csv&gid=0"
17
+
18
+ def test_3d
19
+
20
+ #return unless online?
21
+
22
+ h = {}
23
+ h["weather"] = "raining"
24
+ h["month"] = "december"
25
+
26
+ do_test(CSV3D, h, { "take_umbrella?" => "yes" }, false)
27
+
28
+ h = {}
29
+ h["weather"] = "cloudy"
30
+ h["month"] = "june"
31
+
32
+ sleep 0.3 # don't request the doc too often
33
+
34
+ do_test(CSV3D, h, { "take_umbrella?" => "yes" }, false)
35
+
36
+ h = {}
37
+ h["weather"] = "cloudy"
38
+ h["month"] = "march"
39
+
40
+ sleep 0.3 # don't request the doc too often
41
+
42
+ do_test(CSV3D, h, { "take_umbrella?" => "no" }, false)
43
+ end
44
+ end
45
+
@@ -0,0 +1,56 @@
1
+
2
+ #
3
+ # Testing rufus-decision
4
+ #
5
+ # Mon Sep 7 13:42:09 JST 2009
6
+ #
7
+
8
+ require 'test/unit'
9
+
10
+ require File.join(File.dirname(__FILE__), 'test_base.rb')
11
+
12
+
13
+ class Decision3Test < Test::Unit::TestCase
14
+ include DecisionTestMixin
15
+
16
+ CSV14 = %{
17
+ in:fstate,out:result
18
+ apple,1
19
+ orange,2
20
+ }
21
+
22
+ def test_bounded_match
23
+
24
+ dt = Rufus::DecisionTable.new(CSV14)
25
+
26
+ assert_equal(
27
+ { 'fstate' => 'greenapples' },
28
+ dt.transform({ 'fstate' => 'greenapples' }))
29
+ end
30
+
31
+ def test_unbounded_match
32
+
33
+ dt = Rufus::DecisionTable.new(CSV14, :unbounded => true)
34
+
35
+ assert_equal(
36
+ { 'fstate' => 'apples', 'result' => '1' },
37
+ dt.transform({ 'fstate' => 'apples' }))
38
+ end
39
+
40
+ CSV14b = %{
41
+ unbounded,
42
+ in:fstate,out:result
43
+ apple,1
44
+ orange,2
45
+ }
46
+
47
+ def test_unbounded_match_set_in_table
48
+
49
+ dt = Rufus::DecisionTable.new(CSV14b)
50
+
51
+ assert_equal(
52
+ { 'fstate' => 'apples', 'result' => '1' },
53
+ dt.transform({ 'fstate' => 'apples' }))
54
+ end
55
+ end
56
+
@@ -14,7 +14,7 @@ module DecisionTestMixin
14
14
 
15
15
  protected
16
16
 
17
- def do_test (table_data, h, options, expected_result, verbose=false)
17
+ def do_test (table_data, h, expected_result, verbose=false)
18
18
 
19
19
  table = table_data.is_a?(Rufus::Decision::Table) ?
20
20
  table_data :
@@ -29,7 +29,7 @@ module DecisionTestMixin
29
29
  p h
30
30
  end
31
31
 
32
- h = table.transform!(h, options)
32
+ h = table.transform!(h)
33
33
 
34
34
  if verbose
35
35
  puts
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufus-decision
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-25 00:00:00 +09:00
12
+ date: 2009-09-07 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -44,11 +44,14 @@ extra_rdoc_files:
44
44
  - CREDITS.txt
45
45
  files:
46
46
  - bin/rufus_decide
47
+ - lib/rufus
47
48
  - lib/rufus/decision.rb
48
49
  - lib/rufus/hashes.rb
49
50
  - lib/rufus-decision.rb
50
51
  - test/decision_0_test.rb
51
52
  - test/decision_1_test.rb
53
+ - test/decision_2_test.rb
54
+ - test/decision_3_test.rb
52
55
  - test/eval_test.rb
53
56
  - test/goal.csv
54
57
  - test/input.csv
@@ -61,8 +64,6 @@ files:
61
64
  - CREDITS.txt
62
65
  has_rdoc: true
63
66
  homepage: http://rufus.rubyforge.org/rufus-decision
64
- licenses: []
65
-
66
67
  post_install_message:
67
68
  rdoc_options: []
68
69
 
@@ -84,9 +85,9 @@ requirements:
84
85
  - rufus-dollar
85
86
  - rufus-treechecker
86
87
  rubyforge_project: rufus
87
- rubygems_version: 1.3.2
88
+ rubygems_version: 1.3.1
88
89
  signing_key:
89
- specification_version: 3
90
+ specification_version: 2
90
91
  summary: CSV based Ruby decision tables
91
92
  test_files:
92
93
  - test/test.rb