rufus-decision 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -2,6 +2,11 @@
2
2
  = rufus-decision CHANGELOG.txt
3
3
 
4
4
 
5
+ == rufus-decision - 1.3.1 released 2010/02/16
6
+
7
+ - implemented Rufus::Decision::Participant, a ruote participant
8
+
9
+
5
10
  == rufus-decision - 1.3.0 released 2010/02/15
6
11
 
7
12
  - removing 'require "rubygems"' from lib/ (argh)
@@ -14,7 +14,7 @@ http://jmettraux.wordpress.com/2009/04/25/rufus-decision-11-ruby-decision-tables
14
14
 
15
15
  == usage
16
16
 
17
- More info at http://rufus.rubyforge.org/rufus-decision/classes/Rufus/Decision/Table.html but here is a recap.
17
+ More info at http://rufus.rubyforge.org/rufus-decision/Rufus/Decision/Table.html but here is a recap.
18
18
 
19
19
  An example where a few rules determine which salesperson should interact with a customer with given characteristics.
20
20
 
@@ -98,6 +98,18 @@ In this example, the CSV table is the direction CSV representation of the Google
98
98
  WARNING though : use at your own risk. CSV loaded from untrusted locations may contain harmful code. The rufus-decision gem has an abstract tree checker integrated, it will check all the CSVs that contain calls in Ruby and raise a security error when possibly harmful code is spotted. Bullet vs Armor. Be warned.
99
99
 
100
100
 
101
+ == web demo
102
+
103
+ There is a small demo of an input table + a decision table. You can run it by doing :
104
+
105
+ gem install sinatra
106
+ git clone git://github.com/jmettraux/rufus-decision.git
107
+ cd rufus-decision
108
+ ruby demo/start.rb
109
+
110
+ and then point your browser to http://localost:4567/
111
+
112
+
101
113
  == uninstalling it
102
114
 
103
115
  gem uninstall rufus-decision
data/Rakefile CHANGED
@@ -39,6 +39,7 @@ CSV based Ruby decision tables
39
39
  gem.add_dependency 'rufus-treechecker'
40
40
  gem.add_development_dependency 'yard'
41
41
  gem.add_development_dependency 'jeweler'
42
+ #gem.add_development_dependency 'ruote', '>= 2.1.7'
42
43
 
43
44
  # gemspec spec : http://www.rubygems.org/read/chapter/20
44
45
  end
data/TODO.txt CHANGED
@@ -1,8 +1,13 @@
1
1
 
2
+ [o] move demo to sinatra
3
+ [o] nuke fluo-json in demo
2
4
  [x] transform(h, options), :accumulate option ? NO
5
+ [o] something about demo in README
6
+ [o] demo/README.txt
7
+ [o] ruote participant
3
8
 
4
-
5
- [ ] non csv string representation ?
9
+ [ ] non csv string representation ? JSON ?
6
10
  [ ] dsl ?
7
- [ ] ruote participant
11
+
12
+ [ ] rufus-jig for GETting the table (304 ftw)
8
13
 
data/demo/README.txt ADDED
@@ -0,0 +1,12 @@
1
+
2
+ = rufus-decision demo webapp
3
+
4
+ This is a small sinatra webapp.
5
+
6
+ gem install sinatra
7
+ ruby start.rb
8
+
9
+ then point your browser to :
10
+
11
+ http://localhost:4567/
12
+
@@ -61,7 +61,6 @@
61
61
  }
62
62
  </style>
63
63
 
64
- <script src="js/fluo-json.js"></script>
65
64
  <script src="js/ruote-sheets.js"></script>
66
65
  <script src="js/request.js"></script>
67
66
  </head>
@@ -123,12 +122,12 @@
123
122
 
124
123
  var data =
125
124
  '[' +
126
- fluoToJson(RuoteSheets.toArray('sheet_in')) + ',' +
127
- fluoToJson(RuoteSheets.toArray('sheet_decision')) +
125
+ JSON.stringify(RuoteSheets.toArray('sheet_in')) + ',' +
126
+ JSON.stringify(RuoteSheets.toArray('sheet_decision')) +
128
127
  ']';
129
128
 
130
- var result = httpPost('/decision', data);
131
- result = fluoFromJson(result);
129
+ var result = httpPost('/decide', data);
130
+ result = JSON.parse(result);
132
131
 
133
132
  RuoteSheets.render('sheet_out', result);
134
133
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2009, John Mettraux, jmettraux@gmail.com
2
+ * Copyright (c) 2009-2010, John Mettraux, jmettraux@gmail.com
3
3
  *
4
4
  * Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  * of this software and associated documentation files (the "Software"), to deal
data/demo/start.rb CHANGED
@@ -13,66 +13,65 @@
13
13
  # if necessary)
14
14
  #
15
15
 
16
- $:.unshift('lib')
16
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
17
17
 
18
18
  require 'rubygems'
19
- require 'rack'
20
19
  require 'json'
20
+ require 'sinatra'
21
21
  require 'rufus/decision'
22
22
 
23
-
24
- class App
25
-
26
- def initialize
27
- @rfapp = Rack::File.new(File.dirname(__FILE__) + '/public')
28
- end
29
-
30
- def call (env)
31
- return decide(env) if env['PATH_INFO'] == '/decision'
32
- env['PATH_INFO'] = '/index.html' if env['PATH_INFO'] == '/'
33
- @rfapp.call(env)
34
- end
35
-
36
- protected
37
-
38
- def in_to_h (keys, values)
39
- keys.inject({}) { |h, k| h[k] = values.shift; h }
40
- end
41
-
42
- def decide (env)
43
-
44
- json = env['rack.input'].read
45
- json = JSON.parse(json)
46
-
47
- dt = Rufus::Decision::Table.new(json.last)
48
-
49
- input = Rufus::Decision.transpose(json.first)
50
- # from array of arrays to array of hashes
51
-
52
- output = input.inject([]) { |a, hash| a << dt.transform(hash); a }
53
-
54
- output = Rufus::Decision.transpose(output)
55
- # from array of hashes to array of arrays
56
-
57
- [ 200, {}, output.to_json ]
58
- end
23
+ #class App
24
+ # def initialize
25
+ # @rfapp = Rack::File.new(File.dirname(__FILE__) + '/public')
26
+ # end
27
+ # def call (env)
28
+ # return decide(env) if env['PATH_INFO'] == '/decision'
29
+ # env['PATH_INFO'] = '/index.html' if env['PATH_INFO'] == '/'
30
+ # @rfapp.call(env)
31
+ # end
32
+ # protected
33
+ # def in_to_h (keys, values)
34
+ # keys.inject({}) { |h, k| h[k] = values.shift; h }
35
+ # end
36
+ # def decide (env)
37
+ # json = env['rack.input'].read
38
+ # json = JSON.parse(json)
39
+ # dt = Rufus::Decision::Table.new(json.last)
40
+ # input = Rufus::Decision.transpose(json.first)
41
+ # # from array of arrays to array of hashes
42
+ # output = input.inject([]) { |a, hash| a << dt.transform(hash); a }
43
+ # output = Rufus::Decision.transpose(output)
44
+ # # from array of hashes to array of arrays
45
+ # [ 200, {}, output.to_json ]
46
+ # end
47
+ #end
48
+
49
+ use Rack::CommonLogger
50
+ use Rack::ShowExceptions
51
+
52
+ set :public, File.expand_path(File.join(File.dirname(__FILE__), 'public'))
53
+ #set :views, File.expand_path(File.join(File.dirname(__FILE__), 'views'))
54
+
55
+ get '/' do
56
+
57
+ redirect '/decision.html'
59
58
  end
60
59
 
61
- b = Rack::Builder.new do
60
+ post '/decide' do
62
61
 
63
- use Rack::CommonLogger
64
- use Rack::ShowExceptions
65
- run App.new
66
- end
62
+ json = env['rack.input'].read
63
+ json = JSON.parse(json)
64
+
65
+ dt = Rufus::Decision::Table.new(json.last)
66
+ input = Rufus::Decision.transpose(json.first)
67
+ # from array of arrays to array of hashes
67
68
 
68
- port = 4567
69
+ output = input.inject([]) { |a, hash| a << dt.transform(hash); a }
70
+ output = Rufus::Decision.transpose(output)
71
+ # from array of hashes to array of arrays
69
72
 
70
- puts ".. [#{Time.now}] listening on port #{port}"
73
+ response.headers['Content-Type'] = 'application/json'
71
74
 
72
- Rack::Handler::Mongrel.run(b, :Port => port) do |server|
73
- trap(:INT) do
74
- puts ".. [#{Time.now}] stopped."
75
- server.stop
76
- end
75
+ output.to_json
77
76
  end
78
77
 
@@ -0,0 +1,37 @@
1
+
2
+ require 'rubygems'
3
+ require 'rufus/decision' # sudo gem install rufus-decision
4
+
5
+ table = %{
6
+ in:topic,in:region,out:team_member
7
+ sports,europe,Alice
8
+ sports,,Bob
9
+ finance,america,Charly
10
+ finance,europe,Donald
11
+ finance,,Ernest
12
+ politics,asia,Fujio
13
+ politics,america,Gilbert
14
+ politics,,Henry
15
+ ,,Zach
16
+ }
17
+
18
+ #Rufus::Decision.csv_to_a(table).transpose.each do |row|
19
+ # puts row.join(', ')
20
+ #end
21
+ table = %{
22
+ in:topic,sports,sports,finance,finance,finance,politics,politics,politics,
23
+ in:region,europe,,america,europe,,asia,america,,
24
+ out:team_member,Alice,Bob,Charly,Donald,Ernest,Fujio,Gilbert,Henry,Zach
25
+ }
26
+
27
+ table = Rufus::Decision::Table.new(table)
28
+
29
+ p table.run('topic' => 'politics', 'region' => 'america')
30
+ # => {"region"=>"america", "topic"=>"politics", "team_member"=>"Gilbert"}
31
+
32
+ p table.run('topic' => 'sports', 'region' => 'antarctic')
33
+ # => {"region"=>"antarctic", "topic"=>"sports", "team_member"=>"Bob"}
34
+
35
+ p table.run('topic' => 'culture', 'region' => 'america')
36
+ # => {"region"=>"america", "topic"=>"culture", "team_member"=>"Zach"}
37
+
@@ -2,10 +2,7 @@
2
2
  require 'rubygems'
3
3
  require 'rufus/decision'
4
4
 
5
- include Rufus
6
-
7
-
8
- TABLE = DecisionTable.new("""
5
+ TABLE = Rufus::Decision::Table.new(%{
9
6
  in:age,in:trait,out:salesperson
10
7
 
11
8
  18..35,,adeslky
@@ -17,11 +14,10 @@ in:age,in:trait,out:salesperson
17
14
  25..35,rich,kerfelden
18
15
  ,cheerful,swanson
19
16
  ,maniac,korolev
20
- """)
17
+ })
21
18
 
22
- #
23
- # Given a customer (a Hash instance directly, for
24
- # convenience), returns the name of the first
19
+ # Given a customer (a Hash instance directly, for
20
+ # convenience), returns the name of the first
25
21
  # corresponding salesman.
26
22
  #
27
23
  def determine_salesperson (customer)
@@ -0,0 +1,12 @@
1
+ in:deductible met ?,in:type of visit,in:participating physician ?,out:reimbursement
2
+ yes,doctor office,yes,90%
3
+ yes,doctor office,no,50%
4
+ yes,hospital visit,yes,n/a
5
+ yes,hospital visit,no,80%
6
+ yes,lab visit,yes,n/a
7
+ yes,lab visit,no,70%
8
+ no,doctor office,no,0%
9
+ no,hospital visit,yes,n/a
10
+ no,hospital visit,no,0%
11
+ no,lab visit,yes,n/a
12
+ no,lab visit,no,0%
@@ -0,0 +1,96 @@
1
+ #--
2
+ # Copyright (c) 2007-2010, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+ require 'rufus/decision'
26
+ require 'ruote/participant'
27
+
28
+
29
+ module Rufus::Decision
30
+
31
+ #
32
+ # Decision participants were named 'CSV participants' prior to ruote 2.1.
33
+ #
34
+ # Make sure you have the gem "rufus-decision" installed in order to
35
+ # use this decision participant.
36
+ #
37
+ # In this example, a participant named 'decide_team_member' is bound in the
38
+ # ruote engine and, depending on the value of the workitem fields 'topic'
39
+ # and region, sets the value of the field named 'team_member' :
40
+ #
41
+ # require 'rufus/decision/participant'
42
+ #
43
+ # engine.register_participant(
44
+ # :decide_team_member
45
+ # Rufus::Decision::Participant, :table => %{
46
+ # in:topic,in:region,out:team_member
47
+ # sports,europe,Alice
48
+ # sports,,Bob
49
+ # finance,america,Charly
50
+ # finance,europe,Donald
51
+ # finance,,Ernest
52
+ # politics,asia,Fujio
53
+ # politics,america,Gilbert
54
+ # politics,,Henry
55
+ # ,,Zach
56
+ # })
57
+ #
58
+ # pdef = Ruote.process_definition :name => 'dec-test', :revision => '1' do
59
+ # sequence do
60
+ # decide_team_member
61
+ # participant :ref => '${team_member}'
62
+ # end
63
+ # end
64
+ #
65
+ # A process instance about the election results in Venezuela :
66
+ #
67
+ # engine.launch(
68
+ # pdef,
69
+ # 'topic' => 'politics',
70
+ # 'region' => 'america',
71
+ # 'line' => 'election results in Venezuela')
72
+ #
73
+ # would thus get routed to Gilbert.
74
+ #
75
+ class Participant
76
+ include Ruote::LocalParticipant
77
+
78
+ def initialize (opts={})
79
+
80
+ @options = opts
81
+ end
82
+
83
+ def consume (workitem)
84
+
85
+ table = @options['table']
86
+ raise(ArgumentError.new("'table' option is missing")) unless table
87
+
88
+ table = Rufus::Decision::Table.new(table)
89
+
90
+ workitem.fields = table.run(workitem.fields)
91
+
92
+ reply_to_engine(workitem)
93
+ end
94
+ end
95
+ end
96
+
@@ -347,7 +347,6 @@ module Decision
347
347
  end
348
348
  end
349
349
 
350
-
351
350
  # Returns true if the hash matches the in: values for this row
352
351
  #
353
352
  def matches? (row, hash)
@@ -662,7 +661,6 @@ module Decision
662
661
  }
663
662
  end
664
663
  end
665
-
666
664
  end
667
665
  end
668
666
 
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Rufus
3
3
  module Decision
4
- VERSION = '1.3.0'
4
+ VERSION = '1.3.1'
5
5
  end
6
6
  end
7
7
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rufus-decision}
8
- s.version = "1.3.0"
8
+ s.version = "1.3.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John Mettraux"]
12
- s.date = %q{2010-02-15}
12
+ s.date = %q{2010-02-16}
13
13
  s.default_executable = %q{rufus_decide}
14
14
  s.description = %q{
15
15
  CSV based Ruby decision tables
@@ -18,43 +18,49 @@ CSV based Ruby decision tables
18
18
  s.executables = ["rufus_decide"]
19
19
  s.extra_rdoc_files = [
20
20
  "LICENSE.txt",
21
- "README.txt"
21
+ "README.rdoc"
22
22
  ]
23
23
  s.files = [
24
24
  "CHANGELOG.txt",
25
25
  "CREDITS.txt",
26
26
  "LICENSE.txt",
27
- "README.txt",
27
+ "README.rdoc",
28
28
  "Rakefile",
29
29
  "TODO.txt",
30
30
  "bin/rufus_decide",
31
+ "demo/README.txt",
32
+ "demo/public/decision.html",
31
33
  "demo/public/decision.js",
32
34
  "demo/public/images/arrow.png",
33
35
  "demo/public/images/ruse_head_bg.png",
34
36
  "demo/public/in.js",
35
- "demo/public/index.html",
36
- "demo/public/js/fluo-json.js",
37
37
  "demo/public/js/request.js",
38
38
  "demo/public/js/ruote-sheets.js",
39
39
  "demo/start.rb",
40
+ "examples/journalists.rb",
40
41
  "examples/readme_example.rb",
42
+ "examples/reimbursement.csv",
41
43
  "lib/rufus-decision.rb",
42
44
  "lib/rufus/decision.rb",
43
45
  "lib/rufus/decision/hashes.rb",
46
+ "lib/rufus/decision/participant.rb",
44
47
  "lib/rufus/decision/table.rb",
45
48
  "lib/rufus/decision/version.rb",
46
49
  "rufus-decision.gemspec",
47
- "test/decision_0_test.rb",
48
- "test/decision_1_test.rb",
49
- "test/decision_2_test.rb",
50
- "test/decision_3_test.rb",
51
- "test/eval_test.rb",
50
+ "test/base.rb",
51
+ "test/dt_0_basic.rb",
52
+ "test/dt_1_vertical.rb",
53
+ "test/dt_2_google.rb",
54
+ "test/dt_3_bounded.rb",
55
+ "test/dt_4_eval.rb",
56
+ "test/dt_5_transpose.rb",
52
57
  "test/goal.csv",
53
58
  "test/input.csv",
59
+ "test/ruote/base.rb",
60
+ "test/ruote/rt_0_basic.rb",
61
+ "test/ruote/test.rb",
54
62
  "test/table.csv",
55
- "test/test.rb",
56
- "test/test_base.rb",
57
- "test/transpose_test.rb"
63
+ "test/test.rb"
58
64
  ]
59
65
  s.homepage = %q{http://github.com/jmettraux/rufus-decision/}
60
66
  s.rdoc_options = ["--charset=UTF-8"]
@@ -1,12 +1,13 @@
1
1
 
2
2
  #
3
- # Testing rufus-decision
3
+ # testing rufus-decision
4
4
  #
5
5
  # 2007 something
6
6
  #
7
7
 
8
8
  $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
9
9
 
10
+ require 'test/unit'
10
11
  require 'rubygems'
11
12
  require 'rufus/decision'
12
13
 
@@ -1,16 +1,14 @@
1
1
 
2
2
  #
3
- # Testing rufus-decision
3
+ # testing rufus-decision
4
4
  #
5
5
  # Sun Oct 29 15:41:44 JST 2006
6
6
  #
7
7
 
8
- require 'test/unit'
8
+ require File.join(File.dirname(__FILE__), 'base.rb')
9
9
 
10
- require File.join(File.dirname(__FILE__), 'test_base.rb')
11
10
 
12
-
13
- class Decision0Test < Test::Unit::TestCase
11
+ class Dt0Test < Test::Unit::TestCase
14
12
  include DecisionTestMixin
15
13
 
16
14
  CSV0 = %{
@@ -1,16 +1,14 @@
1
1
 
2
2
  #
3
- # Testing rufus-deciision
3
+ # testing rufus-deciision
4
4
  #
5
5
  # Sun Oct 29 15:41:44 JST 2006
6
6
  #
7
7
 
8
- require 'test/unit'
8
+ require File.join(File.dirname(__FILE__), 'base.rb')
9
9
 
10
- require File.join(File.dirname(__FILE__), 'test_base.rb')
11
10
 
12
-
13
- class Decision1Test < Test::Unit::TestCase
11
+ class Dt1Test < Test::Unit::TestCase
14
12
  include DecisionTestMixin
15
13
 
16
14
  CSV1 = %{
@@ -96,6 +94,5 @@ out:team_member,Alice,Bob,Charly,Donald,Ernest,Fujio,Gilbert,Henry,Zach
96
94
  h = { 'topic' => 'politics', 'region' => 'america' }
97
95
  do_test(table, h, { 'team_member' => 'Gilbert' }, false)
98
96
  end
99
-
100
97
  end
101
98
 
@@ -1,16 +1,14 @@
1
1
 
2
2
  #
3
- # Testing rufus-decision
3
+ # testing rufus-decision
4
4
  #
5
5
  # Sun Oct 29 15:41:44 JST 2006
6
6
  #
7
7
 
8
- require 'test/unit'
8
+ require File.join(File.dirname(__FILE__), 'base.rb')
9
9
 
10
- require File.join(File.dirname(__FILE__), 'test_base.rb')
11
10
 
12
-
13
- class Decision2Test < Test::Unit::TestCase
11
+ class Dt2Test < Test::Unit::TestCase
14
12
  include DecisionTestMixin
15
13
 
16
14
  CSV3D = "http://spreadsheets.google.com/pub?key=pCkopoeZwCNsMWOVeDjR1TQ&output=csv&gid=0"
@@ -1,16 +1,14 @@
1
1
 
2
2
  #
3
- # Testing rufus-decision
3
+ # testing rufus-decision
4
4
  #
5
5
  # Mon Sep 7 13:42:09 JST 2009
6
6
  #
7
7
 
8
- require 'test/unit'
8
+ require File.join(File.dirname(__FILE__), 'base.rb')
9
9
 
10
- require File.join(File.dirname(__FILE__), 'test_base.rb')
11
10
 
12
-
13
- class Decision3Test < Test::Unit::TestCase
11
+ class Dt3Test < Test::Unit::TestCase
14
12
  include DecisionTestMixin
15
13
 
16
14
  CSV14 = %{
@@ -1,18 +1,16 @@
1
1
 
2
2
  #
3
- # Testing rufus-decision
3
+ # testing rufus-decision
4
4
  #
5
5
  # Mon Oct 9 22:19:44 JST 2006
6
6
  #
7
7
 
8
- require 'test/unit'
9
-
10
- require File.dirname(__FILE__) + '/test_base.rb'
8
+ require File.join(File.dirname(__FILE__), 'base.rb')
11
9
 
12
10
  require 'rufus/decision/hashes'
13
11
 
14
12
 
15
- class EvalTest < Test::Unit::TestCase
13
+ class Dt4Test < Test::Unit::TestCase
16
14
 
17
15
  def test_0
18
16
 
@@ -26,3 +24,4 @@ class EvalTest < Test::Unit::TestCase
26
24
  assert_equal 72, eh['r:36+36']
27
25
  end
28
26
  end
27
+
@@ -1,16 +1,14 @@
1
1
 
2
2
  #
3
- # Testing rufus-decision
3
+ # testing rufus-decision
4
4
  #
5
5
  # Thu Apr 23 15:18:15 JST 2009
6
6
  #
7
7
 
8
- require 'test/unit'
8
+ require File.join(File.dirname(__FILE__), 'base.rb')
9
9
 
10
- require File.dirname(__FILE__) + '/test_base.rb'
11
10
 
12
-
13
- class MiscTest < Test::Unit::TestCase
11
+ class Dt5Test < Test::Unit::TestCase
14
12
 
15
13
  def test_transpose_empty_array
16
14
 
@@ -62,3 +60,4 @@ class MiscTest < Test::Unit::TestCase
62
60
  )
63
61
  end
64
62
  end
63
+
@@ -0,0 +1,36 @@
1
+
2
+ #
3
+ # testing rufus-decision (ruote participant)
4
+ #
5
+ # Tue Feb 16 14:37:13 JST 2010
6
+ #
7
+
8
+ $:.unshift(
9
+ File.expand_path(File.join(File.dirname(__FILE__), %w[ .. .. lib ])))
10
+ $:.unshift(
11
+ File.expand_path(File.join(File.dirname(__FILE__), %w[ .. .. .. .. ruote lib ])))
12
+
13
+ require 'test/unit'
14
+ require 'rubygems'
15
+ require 'ruote'
16
+ require 'rufus/decision'
17
+
18
+
19
+ module RuoteBase
20
+
21
+ def setup
22
+
23
+ @engine =
24
+ Ruote::Engine.new(
25
+ Ruote::Worker.new(
26
+ Ruote::HashStorage.new(
27
+ 's_logger' => %w[ ruote/log/test_logger Ruote::TestLogger ])))
28
+ end
29
+
30
+ def teardown
31
+
32
+ @engine.shutdown
33
+ @engine.context.storage.purge!
34
+ end
35
+ end
36
+
@@ -0,0 +1,44 @@
1
+
2
+ #
3
+ # testing rufus-decision (ruote participant)
4
+ #
5
+ # Tue Feb 16 14:54:55 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'rufus/decision/participant'
11
+
12
+ class Rt0Test < Test::Unit::TestCase
13
+ include RuoteBase
14
+
15
+ def test_basic
16
+
17
+ @engine.register_participant(
18
+ :decision,
19
+ Rufus::Decision::Participant, :table => %{
20
+ in:topic,in:region,out:team_member
21
+ sports,europe,Alice
22
+ sports,,Bob
23
+ finance,america,Charly
24
+ finance,europe,Donald
25
+ finance,,Ernest
26
+ politics,asia,Fujio
27
+ politics,america,Gilbert
28
+ politics,,Henry
29
+ ,,Zach
30
+ })
31
+
32
+ pdef = Ruote.process_definition :name => 'dec-test', :revision => '1' do
33
+ decision
34
+ end
35
+
36
+ wfid = @engine.launch(pdef, 'topic' => 'politics', 'region' => 'america')
37
+ r = @engine.wait_for(wfid)
38
+
39
+ assert_equal(
40
+ {"topic"=>"politics", "region"=>"america", "team_member"=>"Gilbert"},
41
+ r['workitem']['fields'])
42
+ end
43
+ end
44
+
@@ -0,0 +1,9 @@
1
+
2
+ #
3
+ # testing rufus-decision (ruote_participant)
4
+ #
5
+ # Tue Feb 16 14:36:34 JST 2010
6
+ #
7
+
8
+ Dir["#{File.dirname(__FILE__)}/rt_*.rb"].each { |path| load(path) }
9
+
data/test/test.rb CHANGED
@@ -1,9 +1,9 @@
1
1
 
2
2
  #
3
- # Testing rufus-decision
3
+ # testing rufus-decision
4
4
  #
5
5
  # 2007 something
6
6
  #
7
7
 
8
- Dir["#{File.dirname(__FILE__)}/*_test.rb"].each { |path| load(path) }
8
+ Dir["#{File.dirname(__FILE__)}/dt_*.rb"].each { |path| load(path) }
9
9
 
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.3.0
4
+ version: 1.3.1
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: 2010-02-15 00:00:00 +09:00
12
+ date: 2010-02-16 00:00:00 +09:00
13
13
  default_executable: rufus_decide
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -61,42 +61,48 @@ extensions: []
61
61
 
62
62
  extra_rdoc_files:
63
63
  - LICENSE.txt
64
- - README.txt
64
+ - README.rdoc
65
65
  files:
66
66
  - CHANGELOG.txt
67
67
  - CREDITS.txt
68
68
  - LICENSE.txt
69
- - README.txt
69
+ - README.rdoc
70
70
  - Rakefile
71
71
  - TODO.txt
72
72
  - bin/rufus_decide
73
+ - demo/README.txt
74
+ - demo/public/decision.html
73
75
  - demo/public/decision.js
74
76
  - demo/public/images/arrow.png
75
77
  - demo/public/images/ruse_head_bg.png
76
78
  - demo/public/in.js
77
- - demo/public/index.html
78
- - demo/public/js/fluo-json.js
79
79
  - demo/public/js/request.js
80
80
  - demo/public/js/ruote-sheets.js
81
81
  - demo/start.rb
82
+ - examples/journalists.rb
82
83
  - examples/readme_example.rb
84
+ - examples/reimbursement.csv
83
85
  - lib/rufus-decision.rb
84
86
  - lib/rufus/decision.rb
85
87
  - lib/rufus/decision/hashes.rb
88
+ - lib/rufus/decision/participant.rb
86
89
  - lib/rufus/decision/table.rb
87
90
  - lib/rufus/decision/version.rb
88
91
  - rufus-decision.gemspec
89
- - test/decision_0_test.rb
90
- - test/decision_1_test.rb
91
- - test/decision_2_test.rb
92
- - test/decision_3_test.rb
93
- - test/eval_test.rb
92
+ - test/base.rb
93
+ - test/dt_0_basic.rb
94
+ - test/dt_1_vertical.rb
95
+ - test/dt_2_google.rb
96
+ - test/dt_3_bounded.rb
97
+ - test/dt_4_eval.rb
98
+ - test/dt_5_transpose.rb
94
99
  - test/goal.csv
95
100
  - test/input.csv
101
+ - test/ruote/base.rb
102
+ - test/ruote/rt_0_basic.rb
103
+ - test/ruote/test.rb
96
104
  - test/table.csv
97
105
  - test/test.rb
98
- - test/test_base.rb
99
- - test/transpose_test.rb
100
106
  has_rdoc: true
101
107
  homepage: http://github.com/jmettraux/rufus-decision/
102
108
  licenses: []
@@ -1,186 +0,0 @@
1
- // Copyright (C) 2008 Google Inc.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- // ruote 'source' :
16
- // http://github.com/jmettraux/ruote-fluo/tree/master/public/js/fluo-json.js
17
-
18
- /**
19
- * @param {string} json per RFC 4627
20
- * @return {Object|Array}
21
- * @author Mike Samuel <mikesamuel@gmail.com>
22
- */
23
- //var jsonParse = (function () {
24
- var fluoFromJson = (function () {
25
- var number
26
- = '(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)';
27
- var oneChar = '(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]'
28
- + '|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))';
29
- var string = '(?:\"' + oneChar + '*\")';
30
-
31
- // Will match a value in a well-formed JSON file.
32
- // If the input is not well-formed, may match strangely, but not in an unsafe
33
- // way.
34
- // Since this only matches value tokens, it does not match whitespace, colons,
35
- // or commas.
36
- var jsonToken = new RegExp(
37
- '(?:false|true|null|[\\{\\}\\[\\]]'
38
- + '|' + number
39
- + '|' + string
40
- + ')', 'g');
41
-
42
- // Matches escape sequences in a string literal
43
- var escapeSequence = new RegExp('\\\\(?:([^u])|u(.{4}))', 'g');
44
-
45
- // Decodes escape sequences in object literals
46
- var escapes = {
47
- '"': '"',
48
- '/': '/',
49
- '\\': '\\',
50
- 'b': '\b',
51
- 'f': '\f',
52
- 'n': '\n',
53
- 'r': '\r',
54
- 't': '\t'
55
- };
56
- function unescapeOne(_, ch, hex) {
57
- return ch ? escapes[ch] : String.fromCharCode(parseInt(hex, 16));
58
- }
59
-
60
- // A non-falsy value that coerces to the empty string when used as a key.
61
- var EMPTY_STRING = new String('');
62
- var SLASH = '\\';
63
-
64
- // Constructor to use based on an open token.
65
- var firstTokenCtors = { '{': Object, '[': Array };
66
-
67
- return function (json) {
68
- // Split into tokens
69
- var toks = json.match(jsonToken);
70
- // Construct the object to return
71
- var result;
72
- var tok = toks[0];
73
- if ('{' === tok) {
74
- result = {};
75
- } else if ('[' === tok) {
76
- result = [];
77
- } else {
78
- throw new Error(tok);
79
- }
80
-
81
- // If undefined, the key in an object key/value record to use for the next
82
- // value parsed.
83
- var key;
84
- // Loop over remaining tokens maintaining a stack of uncompleted objects and
85
- // arrays.
86
- var stack = [result];
87
- for (var i = 1, n = toks.length; i < n; ++i) {
88
- tok = toks[i];
89
-
90
- var cont;
91
- switch (tok.charCodeAt(0)) {
92
- default: // sign or digit
93
- cont = stack[0];
94
- cont[key || cont.length] = +(tok);
95
- key = void 0;
96
- break;
97
- case 0x22: // '"'
98
- tok = tok.substring(1, tok.length - 1);
99
- if (tok.indexOf(SLASH) !== -1) {
100
- tok = tok.replace(escapeSequence, unescapeOne);
101
- }
102
- cont = stack[0];
103
- if (!key) {
104
- if (cont instanceof Array) {
105
- key = cont.length;
106
- } else {
107
- key = tok || EMPTY_STRING; // Use as key for next value seen.
108
- break;
109
- }
110
- }
111
- cont[key] = tok;
112
- key = void 0;
113
- break;
114
- case 0x5b: // '['
115
- cont = stack[0];
116
- stack.unshift(cont[key || cont.length] = []);
117
- key = void 0;
118
- break;
119
- case 0x5d: // ']'
120
- stack.shift();
121
- break;
122
- case 0x66: // 'f'
123
- cont = stack[0];
124
- cont[key || cont.length] = false;
125
- key = void 0;
126
- break;
127
- case 0x6e: // 'n'
128
- cont = stack[0];
129
- cont[key || cont.length] = null;
130
- key = void 0;
131
- break;
132
- case 0x74: // 't'
133
- cont = stack[0];
134
- cont[key || cont.length] = true;
135
- key = void 0;
136
- break;
137
- case 0x7b: // '{'
138
- cont = stack[0];
139
- stack.unshift(cont[key || cont.length] = {});
140
- key = void 0;
141
- break;
142
- case 0x7d: // '}'
143
- stack.shift();
144
- break;
145
- }
146
- }
147
- // Fail if we've got an uncompleted object.
148
- if (stack.length) { throw new Error(); }
149
- return result;
150
- };
151
- })();
152
-
153
-
154
- //
155
- // the following code is ruote-fluo code, under the BSD license.
156
- //
157
- function fluoToJson (o, quotes) {
158
- if (quotes != false) quotes = true;
159
- if (o == null) return 'null';
160
- var t = (typeof o);
161
- if (t == 'undefined') return 'null' // really ?
162
- if (t == 'number') return o;
163
- if (t == 'string') {
164
- //return quotes ? '"' + o + '"' : o;
165
- if ( ! quotes) return o;
166
- return '"' +
167
- o
168
- .replace(/"/g, '\\"')
169
- .replace(/\r/g, '')
170
- .replace(/\n/g, '\\n') +
171
- '"';
172
- // this global replace works with safari (webkit) and ffox
173
- }
174
- if (o.constructor.toString().indexOf(' Array()') == 8) {
175
- var a = [];
176
- for (var i = 0; i < o.length; i++) a.push(fluoToJson(o[i]));
177
- return '[' + a.join(', ') + ']';
178
- }
179
- if (t == 'object') {
180
- var a = [];
181
- for (var key in o) a.push(fluoToJson(key) + ': ' + fluoToJson(o[key]));
182
- return '{' + a.join(', ') + '}';
183
- }
184
- return o.toString();
185
- }
186
-