RSRuby 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,97 @@
1
+ #== Synopsis
2
+ #
3
+ #This is an extended #RObj class inspired by the example given in the RPy
4
+ #manual. Methods caught by method_missing are converted into attribute calls
5
+ #on the R object it represents. Also to_s is redefined to print exactly the
6
+ #representation used in R
7
+ #
8
+ #== Usage
9
+ #
10
+ #See examples/erobj.rb for examples of usage.
11
+ #
12
+ #--
13
+ # == Author
14
+ # Alex Gutteridge
15
+ #
16
+ # == Copyright
17
+ #Copyright (C) 2006 Alex Gutteridge
18
+ #
19
+ # The Original Code is the RPy python module.
20
+ #
21
+ # The Initial Developer of the Original Code is Walter Moreira.
22
+ # Portions created by the Initial Developer are Copyright (C) 2002
23
+ # the Initial Developer. All Rights Reserved.
24
+ #
25
+ # Contributor(s):
26
+ # Gregory R. Warnes <greg@warnes.net> (RPy Maintainer)
27
+ #
28
+ #This library is free software; you can redistribute it and/or
29
+ #modify it under the terms of the GNU Lesser General Public
30
+ #License as published by the Free Software Foundation; either
31
+ #version 2.1 of the License, or (at your option) any later version.
32
+ #
33
+ #This library is distributed in the hope that it will be useful,
34
+ #but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+ #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
36
+ #Lesser General Public License for more details.
37
+ #
38
+ #You should have received a copy of the GNU Lesser General Public
39
+ #License along with this library; if not, write to the Free Software
40
+ #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
41
+ #++
42
+
43
+ require 'rsruby'
44
+
45
+ class ERObj
46
+
47
+ @@x = 1
48
+
49
+ #Requires an RObj for intialization.
50
+ def initialize(robj)
51
+ @robj = robj
52
+ @r = RSRuby.instance
53
+ end
54
+
55
+ #Returns the wrapped RObj when RSRuby attempts to convert it to
56
+ #R.
57
+ def as_r
58
+ @robj.as_r
59
+ end
60
+
61
+ #Calls the wrapped RObj.
62
+ def lcall(args)
63
+ @robj.lcall(args)
64
+ end
65
+
66
+ #Outputs the string representation provided by R.
67
+ def to_s
68
+
69
+ @@x += 1
70
+
71
+ mode = RSRuby.get_default_mode
72
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
73
+ a = @r.textConnection("tmpobj#{@@x}",'w')
74
+
75
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
76
+ @r.sink(:file => a, :type => 'output')
77
+ @r.print_(@robj)
78
+ @r.sink.call()
79
+ @r.close_connection(a)
80
+
81
+ str = @r["tmpobj#{@@x}"].join("\n")
82
+
83
+ RSRuby.set_default_mode(mode)
84
+
85
+ return str
86
+
87
+ end
88
+
89
+ def method_missing(attr)
90
+ mode = RSRuby.get_default_mode
91
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
92
+ e = @r['$'].call(@robj,attr.to_s)
93
+ RSRuby.set_default_mode(mode)
94
+ return e
95
+ end
96
+
97
+ end
@@ -0,0 +1,58 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestArray < Test::Unit::TestCase
9
+
10
+ def setup
11
+
12
+ @ruby_AoA = [[[0,6,12,18],[2,8,14,20],[4,10,16,22]],
13
+ [[1,7,13,19],[3,9,15,21],[5,11,17,23]]]
14
+
15
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
16
+ $r.array.autoconvert(RSRuby::NO_CONVERSION)
17
+ @r_array = $r.array({ :data => (0..24).to_a,
18
+ :dim => [2,3,4]})
19
+ $r.array.autoconvert(RSRuby::BASIC_CONVERSION)
20
+ end
21
+
22
+ def test_convert_to_ruby
23
+ assert_equal(@ruby_AoA,@r_array.to_ruby)
24
+ end
25
+
26
+ #I suspect this only works in RPy with Numeric?
27
+ def test_convert_to_R
28
+ $r.list.autoconvert(RSRuby::NO_CONVERSION)
29
+ $r['[['].autoconvert(RSRuby::NO_CONVERSION)
30
+ o = $r['[['].call($r.list(@ruby_AoA),1)
31
+ $r['[['].autoconvert(RSRuby::BASIC_CONVERSION)
32
+ #assert_equal($r.all_equal(o,@r_array),true)
33
+ end
34
+
35
+ def test_dimensions
36
+ assert_equal($r.dim(@r_array),[@ruby_AoA.length,
37
+ @ruby_AoA[0].length,
38
+ @ruby_AoA[0][0].length])
39
+ end
40
+
41
+ def test_elements
42
+ assert_equal(@ruby_AoA[0][0][0],$r['[['].call(@r_array, 1,1,1))
43
+ assert_equal(@ruby_AoA[1][1][1],$r['[['].call(@r_array, 2,2,2))
44
+ end
45
+
46
+ def test_ruby_out_of_bounds
47
+ assert_raise NoMethodError do
48
+ @ruby_AoA[5][5][5]
49
+ end
50
+ end
51
+
52
+ def test_R_out_of_bounds
53
+ assert_raise RException do
54
+ $r['[['].call(@r_array, 5,5,5)
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,27 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestBoolean < Test::Unit::TestCase
9
+
10
+ def setup
11
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
12
+ end
13
+
14
+ def test_true
15
+ assert_block "r.TRUE not working" do
16
+ ($r.typeof($r.FALSE) == 'logical' and
17
+ $r.as_logical($r.TRUE))
18
+ end
19
+ end
20
+
21
+ def test_false
22
+ assert_block "r.FALSE not working" do
23
+ ($r.typeof($r.FALSE) == 'logical' and not
24
+ $r.as_logical($r.FALSE))
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestCleanup < Test::Unit::TestCase
9
+
10
+ def test_shutdown
11
+ #TODO - shutdown doesn't really seem to do anything???
12
+ $r.shutdown
13
+ assert $r.nil?
14
+ $r = RSRuby.instance()
15
+ end
16
+
17
+ def test_restart
18
+ $r.shutdown
19
+ $r = RSRuby.instance()
20
+ assert $r
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ class TestEval < Test::Unit::TestCase
5
+
6
+ def test_eval_R
7
+ #Test integer, Float, String and Boolean return values
8
+ assert_equal($r.eval_R("sum(1,2,3)"),6)
9
+ assert_equal($r.eval_R("sum(1.5,2.5,3.5)"),7.5)
10
+ assert_equal($r.eval_R("eval('R')"),"R")
11
+ assert_equal($r.eval_R("is(1,'numeric')"),true)
12
+ assert_equal($r.eval_R("is(1,'madeup')"),false)
13
+ end
14
+
15
+ end
File without changes
@@ -0,0 +1,60 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class DummyIO
9
+ def write
10
+ end
11
+ end
12
+
13
+ class TestIO < Test::Unit::TestCase
14
+
15
+ def setup
16
+ $stdout = $stderr = DummyIO.new
17
+ end
18
+
19
+ def teardown
20
+ $stdout = STDOUT
21
+ $stderr = STDERR
22
+ end
23
+
24
+ def test_io_stdin
25
+ dummy = lambda{|prompt,n| prompt+'\n'}
26
+ $r.set_rsruby_input(dummy)
27
+ assert $r.readline('foo') == 'foo'
28
+ end
29
+
30
+ def test_io_stdout
31
+ out = []
32
+ dummy = lambda{|string| out.push(string)}
33
+ $r.set_rsruby_output(dummy)
34
+ $r.print(5)
35
+ assert out == ['[1]','5','\n']
36
+ end
37
+
38
+ def test_io_showfiles
39
+ out = []
40
+ dummy = lambda{|files,headers,title,delete|
41
+ out.push('foo')
42
+ }
43
+ $r.set_rsruby_showfiles(dummy)
44
+ $r.help()
45
+ assert out == ['foo']
46
+ end
47
+
48
+ def test_io_stdout_exception
49
+ #TODO - I can't understand this test in Rpy
50
+ end
51
+
52
+ def test_io_stdin_exception
53
+ #TODO - I can't understand this test in Rpy
54
+ end
55
+
56
+ def test_io_stderr_exception
57
+ #TODO - I can't understand this test in Rpy
58
+ end
59
+
60
+ end
@@ -0,0 +1,20 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestLibrary < Test::Unit::TestCase
9
+
10
+ def test_library
11
+ #Test success
12
+ assert_nothing_raised(){$r.library("boot")}
13
+ end
14
+
15
+ def test_library_fail
16
+ #Test failure
17
+ assert_raises(RException){$r.library("Missing")}
18
+ end
19
+
20
+ end
@@ -0,0 +1,212 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestModes < Test::Unit::TestCase
9
+
10
+ def setup
11
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
12
+ $r.class_table.clear
13
+ $r.proc_table.clear
14
+ end
15
+
16
+ def test_to_ruby_args
17
+ assert_raises(ArgumentError){$r.seq.to_ruby(RSRuby::TOP_CONVERSION+1)}
18
+ assert_raises(ArgumentError){$r.seq.to_ruby(-2)}
19
+ assert_raises(TypeError){$r.seq.to_ruby('foo')}
20
+ end
21
+
22
+ def test_to_ruby
23
+ $r.c.autoconvert(RSRuby::NO_CONVERSION)
24
+ four = $r.c(4)
25
+ assert_equal(four.to_ruby, 4)
26
+ assert_equal(four.to_ruby(RSRuby::PROC_CONVERSION), 4)
27
+ assert_equal(four.to_ruby(RSRuby::BASIC_CONVERSION), 4)
28
+ assert_equal(four.to_ruby(RSRuby::VECTOR_CONVERSION), [4])
29
+ assert($r["=="].call(four.to_ruby(RSRuby::NO_CONVERSION),four))
30
+ end
31
+
32
+ def test_to_ruby_default_arg
33
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
34
+ sequence = $r.seq(1,3)
35
+ t_test = $r.t_test([1,2,3])
36
+
37
+ assert_equal(sequence.to_ruby.class , RObj)
38
+ assert_equal(sequence.to_ruby.class, sequence.class)
39
+
40
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
41
+ assert_equal(sequence.to_ruby, [1,2,3])
42
+
43
+ RSRuby.set_default_mode(RSRuby::VECTOR_CONVERSION)
44
+ assert_equal(sequence.to_ruby, [1,2,3])
45
+
46
+ $r.class_table['htest'] = lambda{5}
47
+ RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
48
+ assert_equal(t_test.to_ruby, 5)
49
+
50
+ $r.proc_table[lambda{true}] = lambda{return 6}
51
+ RSRuby.set_default_mode(RSRuby::PROC_CONVERSION)
52
+ assert_equal(t_test.to_ruby, 6)
53
+ end
54
+
55
+ def test_default_modes
56
+ RSRuby.set_default_mode(RSRuby::PROC_CONVERSION)
57
+ assert_equal(RSRuby.get_default_mode, RSRuby::PROC_CONVERSION)
58
+ RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
59
+ assert_equal(RSRuby.get_default_mode, RSRuby::CLASS_CONVERSION)
60
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
61
+ assert_equal(RSRuby.get_default_mode, RSRuby::BASIC_CONVERSION)
62
+ RSRuby.set_default_mode(RSRuby::VECTOR_CONVERSION)
63
+ assert_equal(RSRuby.get_default_mode, RSRuby::VECTOR_CONVERSION)
64
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
65
+ assert_equal(RSRuby.get_default_mode, RSRuby::NO_CONVERSION)
66
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
67
+ assert_equal(RSRuby.get_default_mode, RSRuby::NO_DEFAULT)
68
+ end
69
+
70
+ def test_bad_modes
71
+ assert_raises(ArgumentError){RSRuby.set_default_mode(-2)}
72
+ assert_raises(ArgumentError){RSRuby.set_default_mode(RSRuby::TOP_CONVERSION+1)}
73
+ end
74
+
75
+ def test_no_default_mode
76
+ $r.t_test.autoconvert(RSRuby::CLASS_CONVERSION)
77
+ $r.array.autoconvert(RSRuby::NO_CONVERSION)
78
+ $r.seq.autoconvert(RSRuby::BASIC_CONVERSION)
79
+
80
+ assert_equal($r.array(1,3).class, $r.array.class)
81
+
82
+ assert_equal($r.seq(1,3), [1,2,3])
83
+ $r.class_table['htest'] = lambda{5}
84
+ assert_equal($r.t_test([1,2,3]), 5)
85
+ end
86
+
87
+ def test_individual_conversions
88
+ $r.c.autoconvert(RSRuby::BASIC_CONVERSION)
89
+ $r.seq.autoconvert(RSRuby::PROC_CONVERSION)
90
+ $r.min.autoconvert(RSRuby::VECTOR_CONVERSION)
91
+
92
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
93
+ assert_equal($r.c(4).class, RObj)
94
+ assert_equal($r.seq(1,3).class, RObj)
95
+ assert_equal($r.min(1,3).class, RObj)
96
+
97
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
98
+ assert_equal($r.c.autoconvert, RSRuby::BASIC_CONVERSION)
99
+ assert_equal($r.seq.autoconvert, RSRuby::PROC_CONVERSION)
100
+ assert_equal($r.min.autoconvert, RSRuby::VECTOR_CONVERSION)
101
+ assert_equal($r.c(4), 4)
102
+ assert_equal($r.seq(1,3), [1,2,3])
103
+ assert_equal($r.min(1,3), [1])
104
+
105
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
106
+ assert_equal($r.c.autoconvert, RSRuby::BASIC_CONVERSION)
107
+ assert_equal($r.seq.autoconvert, RSRuby::PROC_CONVERSION)
108
+ assert_equal($r.min.autoconvert, RSRuby::VECTOR_CONVERSION)
109
+ assert_equal($r.c(4), 4)
110
+ assert_equal($r.seq(1,3), [1,2,3])
111
+ assert_equal($r.min(1,3), 1)
112
+
113
+ RSRuby.set_default_mode(RSRuby::VECTOR_CONVERSION)
114
+ assert_equal($r.c.autoconvert, RSRuby::BASIC_CONVERSION)
115
+ assert_equal($r.seq.autoconvert, RSRuby::PROC_CONVERSION)
116
+ assert_equal($r.min.autoconvert, RSRuby::VECTOR_CONVERSION)
117
+ assert_equal($r.c(4), [4])
118
+ assert_equal($r.seq(1,3), [1,2,3])
119
+ assert_equal($r.min(1,3), [1])
120
+
121
+ end
122
+
123
+ def test_vector_conversion
124
+
125
+ RSRuby.set_default_mode(RSRuby::VECTOR_CONVERSION)
126
+
127
+ assert_equal($r.c(true), [true])
128
+ assert_equal($r.c(4) , [4])
129
+ assert_equal($r.c('A') , ['A'])
130
+
131
+ assert_equal($r.c(1,'A',2), ['1','A','2'])
132
+ assert_equal($r.c(:a => 1, :b => 'A', :c => 2), {'a' => '1', 'b' => 'A', 'c' => '2'})
133
+ assert_equal($r.list(:a => 1, :b => 'A', :c => 2),
134
+ {'a' => [1], 'b' => ['A'], 'c' => [2]})
135
+ assert_equal($r.eval_R("x~y").class, RObj)
136
+ end
137
+
138
+ def test_basic_conversion
139
+
140
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
141
+ assert_equal($r.c(true), true)
142
+ assert_equal($r.c(4), 4)
143
+ assert_equal($r.c('A') , 'A')
144
+
145
+ assert_equal($r.c(1,'A',2), ['1','A','2'])
146
+ assert_equal($r.c(:a => 1, :b => 'A', :c => 2), {'a' => '1', 'b' => 'A', 'c' => '2'})
147
+ assert_equal($r.list(:a => 1, :b => 'A', :c => 2),
148
+ {'a' => 1, 'b' => 'A', 'c' => 2})
149
+ assert_equal($r.eval_R("x~y").class, RObj)
150
+
151
+ end
152
+
153
+ def test_class_table
154
+
155
+ $r.class_table['htest'] = lambda{'htest'}
156
+ $r.class_table['data.frame'] = lambda{|x|
157
+ if $r['[['].call(x,1).length > 2
158
+ return 5
159
+ else
160
+ return 'bar'
161
+ end
162
+ }
163
+ RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
164
+ assert_equal($r.t_test([1,2,3]), 'htest')
165
+ assert_equal($r.as_data_frame([1,2,3]), 5)
166
+ assert_equal($r.as_data_frame([1,2]), 'bar')
167
+
168
+ end
169
+
170
+ def test_multiple_class_table
171
+
172
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
173
+ f = $r.class__($r.c(4),'foo')
174
+ g = $r.class__($r.c(4), ['bar','foo'])
175
+
176
+ $r.class_table['foo'] = lambda{'foo'}
177
+ $r.class_table['bar'] = lambda{'bar'}
178
+ $r.class_table[['bar','foo']] = lambda{5}
179
+
180
+ RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
181
+ assert_equal(f.to_ruby, 'foo')
182
+ assert_equal(g.to_ruby, 5)
183
+
184
+ $r.class_table.delete(['bar','foo'])
185
+ assert_equal(g.to_ruby, 'bar')
186
+
187
+ $r.class_table.delete('bar')
188
+ assert_equal(g.to_ruby, 'foo')
189
+
190
+ end
191
+
192
+ def test_proc_table
193
+
194
+ t = lambda{|x|
195
+ e = $r.attr(x,'names')
196
+ return false if e.nil?
197
+ if e == 'alternative' or e.include?('alternative')
198
+ return true
199
+ else
200
+ return false
201
+ end
202
+ }
203
+ f = lambda{|x| $r['$'].call(x,'alternative')}
204
+
205
+ $r.proc_table[t] = f
206
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
207
+ $r.t_test.autoconvert(RSRuby::PROC_CONVERSION)
208
+ assert_equal($r.t_test([1,2,3]), 'two.sided')
209
+
210
+ end
211
+
212
+ end