subaltern 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,251 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ describe Subaltern do
6
+
7
+ describe 'if' do
8
+
9
+ it 'works (then)' do
10
+
11
+ Subaltern.eval(%{
12
+ if true
13
+ :ok
14
+ end
15
+ }).should == :ok
16
+ end
17
+
18
+ it 'works (complex expression)' do
19
+
20
+ Subaltern.eval(%{
21
+ if false or true
22
+ :ok
23
+ end
24
+ }).should == :ok
25
+ end
26
+
27
+ it 'works (else)' do
28
+
29
+ Subaltern.eval(%{
30
+ if false
31
+ :not_ok
32
+ else
33
+ :ok
34
+ end
35
+ }).should == :ok
36
+ end
37
+
38
+ it 'works postfix' do
39
+
40
+ Subaltern.eval(%{
41
+ 'ok' if true
42
+ }).should == 'ok'
43
+ end
44
+ end
45
+
46
+ describe 'elsif' do
47
+
48
+ it 'works' do
49
+
50
+ Subaltern.eval(%{
51
+ if false
52
+ :not_ok
53
+ elsif true
54
+ :ok
55
+ else
56
+ :really_not_ok
57
+ end
58
+ }).should == :ok
59
+ end
60
+ end
61
+
62
+ describe 'unless' do
63
+
64
+ it 'works' do
65
+
66
+ Subaltern.eval(%{
67
+ unless false
68
+ :ok
69
+ else
70
+ :not_ok
71
+ end
72
+ }).should == :ok
73
+ end
74
+ end
75
+
76
+ describe 'case' do
77
+
78
+ it 'works' do
79
+
80
+ Subaltern.eval(%{
81
+ case true
82
+ when true then :ok
83
+ when false then :not_ok
84
+ else :really_not_ok
85
+ end
86
+ }).should == :ok
87
+ end
88
+
89
+ it 'works (else)' do
90
+
91
+ Subaltern.eval(%{
92
+ case false
93
+ when true then :not_ok
94
+ else :ok
95
+ end
96
+ }).should == :ok
97
+ end
98
+
99
+ it 'works (multiline)' do
100
+
101
+ Subaltern.eval(%{
102
+ case true
103
+ when true
104
+ :not_ok
105
+ :ok
106
+ else
107
+ :really_not_ok
108
+ end
109
+ }).should == :ok
110
+ end
111
+
112
+ it 'works (classes)' do
113
+
114
+ Subaltern.eval(%{
115
+ case true
116
+ when FalseClass
117
+ :not_ok
118
+ when TrueClass
119
+ :ok
120
+ else
121
+ :really_not_ok
122
+ end
123
+ }).should == :ok
124
+ end
125
+
126
+ it 'works (regexes)' do
127
+
128
+ Subaltern.eval(%{
129
+ case 'the little bird'
130
+ when /fox/
131
+ :not_ok
132
+ when /bird/
133
+ :ok
134
+ else
135
+ :really_not_ok
136
+ end
137
+ }).should == :ok
138
+ end
139
+
140
+ it 'works (regexes 2)' do
141
+
142
+ Subaltern.eval(%{
143
+ case 'the little bird'
144
+ when /squirrel/
145
+ :not_ok
146
+ when /chipmunk/
147
+ :really_not_ok
148
+ else
149
+ :ok
150
+ end
151
+ }).should == :ok
152
+ end
153
+ end
154
+
155
+ context '#each' do
156
+
157
+ describe 'break' do
158
+
159
+ it 'works' do
160
+
161
+ Subaltern.eval(%{
162
+ [ 1, 2, 3 ].each do |i|
163
+ break
164
+ end
165
+ }).should == nil
166
+ end
167
+ end
168
+
169
+ describe 'break y' do
170
+
171
+ it 'works' do
172
+
173
+ Subaltern.eval(%{
174
+ [ 1, 2, 3 ].each do |i|
175
+ break i
176
+ end
177
+ }).should == 1
178
+ end
179
+ end
180
+
181
+ describe 'next' do
182
+
183
+ it 'works' do
184
+
185
+ Subaltern.eval(%{
186
+ a = []
187
+ [ 1, 2, 3 ].each do |i|
188
+ next
189
+ a << i
190
+ end
191
+ a
192
+ }).should == []
193
+ end
194
+ end
195
+ end
196
+
197
+ context '#collect' do
198
+
199
+ describe 'next x' do
200
+
201
+ it 'works' do
202
+
203
+ Subaltern.eval(%{
204
+ [ 1, 2, 3 ].collect do |i|
205
+ next i * 3
206
+ end
207
+ }).should == [ 3, 6, 9 ]
208
+ end
209
+
210
+ it 'works with multiple values' do
211
+
212
+ Subaltern.eval(%{
213
+ [ 1, 2, 3 ].collect do |i|
214
+ next i, i * 3
215
+ end
216
+ }).should == [ [ 1, 3 ], [ 2, 6 ], [ 3, 9 ] ]
217
+ end
218
+ end
219
+ end
220
+
221
+ describe '#?' do
222
+
223
+ it 'works' do
224
+
225
+ Subaltern.eval(%{
226
+ true ? 1 : 0
227
+ }).should == 1
228
+ end
229
+
230
+ it 'works (then)' do
231
+
232
+ Subaltern.eval(%{
233
+ false ? 0 : 1
234
+ }).should == 1
235
+ end
236
+ end
237
+
238
+ describe 'rescue' do
239
+
240
+ describe 'rescue :x' do
241
+
242
+ it 'works' do
243
+
244
+ Subaltern.eval(%{
245
+ 1 / 0 rescue :limit
246
+ }).should == :limit
247
+ end
248
+ end
249
+ end
250
+ end
251
+
@@ -0,0 +1,106 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ class String
6
+ def constantize
7
+ eval(self)
8
+ end
9
+ end
10
+
11
+ describe Subaltern do
12
+
13
+ context 'evil' do
14
+
15
+ describe "''.eval('1 + 1')" do
16
+
17
+ it 'raises' do
18
+
19
+ lambda {
20
+ Subaltern.eval("''.eval('1 + 1')")
21
+ }.should raise_error(Subaltern::NonWhitelistedMethodError)
22
+ end
23
+ end
24
+
25
+ describe 'calls on non-whitelisted classes' do
26
+
27
+ it 'raises' do
28
+
29
+ lambda {
30
+ Subaltern.eval("'File'.constantize.read('#{__FILE__}')")
31
+ #}.should raise_error(Subaltern::NonWhitelistedClassError)
32
+ }.should raise_error(Subaltern::NonWhitelistedMethodError)
33
+ end
34
+ end
35
+
36
+ describe 'a constant lookup' do
37
+
38
+ it 'raises (ENV)' do
39
+
40
+ lambda {
41
+ Subaltern.eval('ENV')
42
+ }.should raise_error(Subaltern::AccessError)
43
+ end
44
+
45
+ it 'raises (File::Utils)' do
46
+
47
+ lambda {
48
+ Subaltern.eval('File::Utils')
49
+ }.should raise_error(Subaltern::AccessError)
50
+ end
51
+ end
52
+
53
+ describe 'a call on a constant' do
54
+
55
+ it 'raises (ENV["HOME"])' do
56
+
57
+ lambda {
58
+ Subaltern.eval('ENV["HOME"]')
59
+ }.should raise_error(Subaltern::AccessError)
60
+ end
61
+ end
62
+
63
+ describe 'a global variable lookup' do
64
+
65
+ it 'raises ($nada)' do
66
+
67
+ lambda {
68
+ Subaltern.eval('$nada')
69
+ }.should raise_error(Subaltern::AccessError)
70
+ end
71
+ end
72
+
73
+ describe 'backquoting' do
74
+
75
+ it 'raises (simple case)' do
76
+
77
+ lambda {
78
+ Subaltern.eval('`ls -al`')
79
+ }.should raise_error(Subaltern::AccessError)
80
+ end
81
+
82
+ it 'raises (string extrapolation case)' do
83
+
84
+ lambda {
85
+ Subaltern.eval('`ls -al #{nada}`')
86
+ }.should raise_error(Subaltern::AccessError)
87
+ end
88
+ end
89
+
90
+ describe 'method with a block' do
91
+
92
+ it 'is not automatically whitelisted' do
93
+
94
+ class Array
95
+ def whatever
96
+ end
97
+ end
98
+
99
+ lambda {
100
+ Subaltern.eval('[].whatever { |e| false }')
101
+ }.should raise_error(Subaltern::NonWhitelistedMethodError)
102
+ end
103
+ end
104
+ end
105
+ end
106
+
@@ -0,0 +1,20 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ describe Subaltern do
6
+
7
+ describe 'Fixnum' do
8
+
9
+ it 'works' do
10
+
11
+ Subaltern.eval('1.0').should == 1.0
12
+ Subaltern.eval('1 + 1').should == 2
13
+ Subaltern.eval('1 * 2').should == 2
14
+ Subaltern.eval('3 - 1').should == 2
15
+ Subaltern.eval('1.even?').should == false
16
+ Subaltern.eval('1.odd?').should == true
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,123 @@
1
+
2
+ require 'spec_helper'
3
+
4
+
5
+ describe Subaltern do
6
+
7
+ context 'functions' do
8
+
9
+ it 'accepts function definitions' do
10
+
11
+ Subaltern.eval(%{
12
+ def addition(a, b)
13
+ a + b
14
+ end
15
+ }).should == nil
16
+ end
17
+
18
+ it 'accepts calls to defined functions' do
19
+
20
+ Subaltern.eval(%{
21
+ def addition(a, b)
22
+ a + b
23
+ end
24
+ addition(1, 2)
25
+ }).should == 3
26
+ end
27
+
28
+ it 'accepts functions with optional parameters' do
29
+
30
+ Subaltern.eval(%{
31
+ def add(a, b=1, c=2)
32
+ a + b + c
33
+ end
34
+ [ add(1, 2), add(4) ]
35
+ }).should == [ 5, 7 ]
36
+ end
37
+
38
+ it 'accepts functions with starred parameters' do
39
+
40
+ Subaltern.eval(%{
41
+ def concat(a, *args)
42
+ [ a ] + args
43
+ end
44
+ concat(1, 2, 3, 4)
45
+ }).should == [ 1, 2, 3, 4 ]
46
+ end
47
+
48
+ it 'accepts a final hash argument' do
49
+
50
+ Subaltern.eval(%{
51
+ def pretty(a, b)
52
+ [ a, b ]
53
+ end
54
+ pretty('a', 'b' => 'c')
55
+ }).should == [ 'a', { 'b' => 'c' } ]
56
+ end
57
+
58
+ it 'accepts "return" in the middle of functions' do
59
+
60
+ Subaltern.eval(%{
61
+ def hello
62
+ 1
63
+ return 'nada'
64
+ 2
65
+ end
66
+ hello
67
+ }).should == 'nada'
68
+ end
69
+
70
+ it 'accepts functions with blocks' do
71
+
72
+ Subaltern.eval(%{
73
+ def hello
74
+ 1 + yield
75
+ end
76
+ hello { 3 }
77
+ }).should == 4
78
+ end
79
+
80
+ it 'accepts functions with explicit blocks' do
81
+
82
+ Subaltern.eval(%{
83
+ def hello(start, &block)
84
+ start + block.call
85
+ end
86
+ hello(1) { 3 }
87
+ }).should == 4
88
+ end
89
+
90
+ it 'accepts functions that call blocks with arguments' do
91
+
92
+ Subaltern.eval(%{
93
+ def hello(start, &block)
94
+ start + block.call(start)
95
+ end
96
+ hello(3) { |s| s * 3 }
97
+ }).should == 12
98
+ end
99
+
100
+ it 'accepts functions that yield arguments to blocks' do
101
+
102
+ Subaltern.eval(%{
103
+ def hello(start)
104
+ start + yield(start)
105
+ end
106
+ hello(3) { |s| s * 3 }
107
+ }).should == 12
108
+ end
109
+
110
+ it 'raises when a block is called without its arg' do
111
+
112
+ lambda {
113
+ Subaltern.eval(%{
114
+ def hello(start, &block)
115
+ start + block.call
116
+ end
117
+ hello(3) { |start| start * 3 }
118
+ })
119
+ }.should raise_error(Subaltern::NonWhitelistedMethodError)
120
+ end
121
+ end
122
+ end
123
+