fabiokung-sexp_processor 3.0.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.
@@ -0,0 +1,85 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ $TESTING = true
4
+
5
+ require 'test/unit' if $0 == __FILE__
6
+ require 'test/unit/testcase'
7
+ require 'sexp_processor'
8
+
9
+ class TestEnvironment < Test::Unit::TestCase
10
+
11
+ def setup
12
+ @env = SexpProcessor::Environment.new
13
+ end
14
+
15
+ def test_all
16
+ @env.scope do
17
+ @env[:x] = 42
18
+
19
+ @env.scope do
20
+ @env[:y] = 3
21
+ @env[:x] = Math::PI
22
+
23
+ expected = { :x => Math::PI, :y => 3 }
24
+ assert_equal expected, @env.all
25
+ end
26
+
27
+ expected = { :x => Math::PI }
28
+ assert_equal expected, @env.all
29
+ end
30
+ end
31
+
32
+ def test_depth
33
+ assert_equal 1, @env.depth
34
+
35
+ @env.scope do
36
+ assert_equal 2, @env.depth
37
+ end
38
+
39
+ assert_equal 1, @env.depth
40
+ end
41
+
42
+ def test_index
43
+ test_index_equals
44
+ end
45
+
46
+ def test_index_unknown
47
+ assert_nil @env[:unknown]
48
+ end
49
+
50
+ def test_index_out_of_scope
51
+ @env.scope do
52
+ @env[:var] = 42
53
+ assert_equal 42, @env[:var]
54
+ end
55
+
56
+ assert_nil @env[:var]
57
+ end
58
+
59
+ def test_index_equals
60
+ @env[:var] = 42
61
+
62
+ assert_equal 42, @env[:var]
63
+ end
64
+
65
+ def test_lookup_scope
66
+ @env[:var] = 42
67
+ assert_equal 42, @env[:var]
68
+
69
+ @env.scope do
70
+ assert_equal 42, @env[:var]
71
+ end
72
+ end
73
+
74
+ def test_scope
75
+ @env[:var] = 42
76
+ assert_equal 42, @env[:var]
77
+
78
+ @env.scope do
79
+ @env[:var] = Math::PI
80
+ assert_equal Math::PI, @env[:var]
81
+ end
82
+
83
+ assert_equal Math::PI, @env[:var]
84
+ end
85
+ end
data/test/test_sexp.rb ADDED
@@ -0,0 +1,305 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ $TESTING = true
4
+
5
+ require 'test/unit' if $0 == __FILE__ unless defined? $ZENTEST and $ZENTEST
6
+ require 'test/unit/testcase'
7
+ require 'sexp_processor'
8
+ require 'stringio'
9
+ require 'pp'
10
+
11
+ class SexpTestCase < Test::Unit::TestCase
12
+
13
+ unless defined? Mini then
14
+ alias :refute_nil :assert_not_nil
15
+ alias :refute_equal :assert_not_equal
16
+ alias :assert_raises :assert_raise
17
+ end
18
+
19
+ # KEY for regex tests
20
+ # :a == no change
21
+ # :b == will change (but sometimes ONLY once)
22
+ # :c == change to
23
+
24
+ include SexpMatchSpecials
25
+
26
+ def util_equals(x, y)
27
+ result = x == y
28
+ refute_nil result, "#{x.inspect} does not === #{y.inspect}"
29
+ end
30
+
31
+ def util_equals3(x, y)
32
+ result = x === y
33
+ refute_nil result, "#{x.inspect} does not === #{y.inspect}"
34
+ end
35
+
36
+ def setup
37
+ @any = ANY()
38
+ end
39
+
40
+ def test_stupid
41
+ # shuts up test/unit
42
+ end
43
+ end
44
+
45
+ class TestSexp < SexpTestCase # ZenTest FULL
46
+
47
+ class SexpFor
48
+ def method
49
+ 1
50
+ end
51
+ end
52
+
53
+ def util_pretty_print(expect, input)
54
+ io = StringIO.new
55
+ PP.pp(input, io)
56
+ io.rewind
57
+ assert_equal(expect, io.read.chomp)
58
+ end
59
+
60
+ def setup
61
+ super
62
+ @sexp_class = Object.const_get(self.class.name[4..-1])
63
+ @processor = SexpProcessor.new
64
+ @sexp = @sexp_class.new(1, 2, 3)
65
+ @basic_sexp = s(:lasgn, :var, s(:lit, 42))
66
+ @re = s(:lit, 42)
67
+ @bad1 = s(:lit, 24)
68
+ @bad1 = s(:blah, 42)
69
+ end
70
+
71
+ def test_class_from_array
72
+ # raise NotImplementedError, 'Need to write test_class_from_array'
73
+ end
74
+
75
+ def test_class_index
76
+ # raise NotImplementedError, 'Need to write test_class_index'
77
+ end
78
+
79
+ def test_array_type_eh
80
+ assert_equal false, @sexp.array_type?
81
+ @sexp.unshift :array
82
+ assert_equal true, @sexp.array_type?
83
+ end
84
+
85
+ def test_each_of_type
86
+ # TODO: huh... this tests fails if top level sexp :b is removed
87
+ @sexp = s(:b, s(:a, s(:b, s(:a), :a, s(:b, :a), s(:b, s(:a)))))
88
+ count = 0
89
+ @sexp.each_of_type(:a) do |exp|
90
+ count += 1
91
+ end
92
+ assert_equal(3, count, "must find 3 a's in #{@sexp.inspect}")
93
+ end
94
+
95
+ def test_equals2_array
96
+ # can't use assert_equals because it uses array as receiver
97
+ refute_equal(@sexp, [1, 2, 3],
98
+ "Sexp must not be equal to equivalent array")
99
+ # both directions just in case
100
+ # HACK - this seems to be a bug in ruby as far as I'm concerned
101
+ # assert_not_equal([1, 2, 3], @sexp,
102
+ # "Sexp must not be equal to equivalent array")
103
+ end
104
+
105
+ def test_equals2_not_body
106
+ sexp2 = s(1, 2, 5)
107
+ refute_equal(@sexp, sexp2)
108
+ end
109
+
110
+ def test_equals2_sexp
111
+ sexp2 = s(1, 2, 3)
112
+ unless @sexp.class == Sexp then
113
+ refute_equal(@sexp, sexp2)
114
+ end
115
+ end
116
+
117
+ def test_equals3_any
118
+ util_equals3 @any, s()
119
+ util_equals3 @any, s(:a)
120
+ util_equals3 @any, s(:a, :b, s(:c))
121
+ end
122
+
123
+ def test_equals3_full_match
124
+ util_equals3 s(), s() # 0
125
+ util_equals3 s(:blah), s(:blah) # 1
126
+ util_equals3 s(:a, :b), s(:a, :b) # 2
127
+ util_equals3 @basic_sexp, @basic_sexp.dup # deeper structure
128
+ end
129
+
130
+ def test_equals3_mismatch
131
+ assert_nil s() === s(:a)
132
+ assert_nil s(:a) === s()
133
+ assert_nil s(:blah1) === s(:blah2)
134
+ assert_nil s(:a) === s(:a, :b)
135
+ assert_nil s(:a, :b) === s(:a)
136
+ assert_nil s(:a1, :b) === s(:a2, :b)
137
+ assert_nil s(:a, :b1) === s(:a, :b2)
138
+ assert_nil @basic_sexp === @basic_sexp.dup.push(42)
139
+ assert_nil @basic_sexp.dup.push(42) === @basic_sexp
140
+ end
141
+
142
+ def test_equals3_subset_match
143
+ util_equals3 s(:a), s(s(:a), s(:b)) # left
144
+ util_equals3 s(:a), s(:blah, s(:a ), s(:b)) # mid 1
145
+ util_equals3 s(:a, 1), s(:blah, s(:a, 1), s(:b)) # mid 2
146
+ util_equals3 @basic_sexp, s(:blah, @basic_sexp.dup, s(:b)) # mid deeper
147
+ util_equals3 @basic_sexp, s(@basic_sexp.dup, s(:a), s(:b)) # left deeper
148
+
149
+ util_equals3 s(:a), s(:blah, s(:blah, s(:a))) # left deeper
150
+ end
151
+
152
+ # def test_equalstilde_any
153
+ # result = @basic_sexp =~ s(:lit, ANY())
154
+ # p result
155
+ # assert result
156
+ # end
157
+
158
+ def test_equalstilde_fancy
159
+ assert_nil s(:b) =~ s(:a, s(:b), :c)
160
+ refute_nil s(:a, s(:b), :c) =~ s(:b)
161
+ end
162
+
163
+ def test_equalstilde_plain
164
+ result = @basic_sexp =~ @re
165
+ assert result
166
+ end
167
+
168
+ def test_find_and_replace_all
169
+ @sexp = s(:a, s(:b, s(:a), s(:b), s(:b, s(:a))))
170
+ expected = s(:a, s(:a, s(:a), s(:a), s(:a, s(:a))))
171
+
172
+ @sexp.find_and_replace_all(:b, :a)
173
+
174
+ assert_equal(expected, @sexp)
175
+ end
176
+
177
+ def test_gsub
178
+ assert_equal s(:c), s().gsub(s(), s(:c))
179
+ assert_equal s(:c), s(:b).gsub(s(:b), s(:c))
180
+ assert_equal s(:a), s(:a).gsub(s(:b), s(:c))
181
+ assert_equal s(:a, s(:c)), s(:a, s(:b)).gsub(s(:b), s(:c))
182
+
183
+ assert_equal(s(:a, s(:c), s(:c)),
184
+ s(:a, s(:b), s(:b)).gsub(s(:b), s(:c)))
185
+ assert_equal(s(:a, s(:c), s(:a, s(:c))),
186
+ s(:a, s(:b), s(:a, s(:b))).gsub(s(:b), s(:c)))
187
+ end
188
+
189
+ def test_inspect
190
+ k = @sexp_class
191
+ n = k.name[0].chr.downcase
192
+ assert_equal("#{n}()",
193
+ k.new().inspect)
194
+ assert_equal("#{n}(:a)",
195
+ k.new(:a).inspect)
196
+ assert_equal("#{n}(:a, :b)",
197
+ k.new(:a, :b).inspect)
198
+ assert_equal("#{n}(:a, #{n}(:b))",
199
+ k.new(:a, k.new(:b)).inspect)
200
+ end
201
+
202
+ def test_method_missing
203
+ assert_nil @sexp.not_there
204
+ assert_equal s(:lit, 42), @basic_sexp.lit
205
+ end
206
+
207
+ def test_method_missing_ambigious
208
+ assert_raises NoMethodError do
209
+ pirate = s(:says, s(:arrr!), s(:arrr!), s(:arrr!))
210
+ pirate.arrr!
211
+ end
212
+ end
213
+
214
+ def test_method_missing_deep
215
+ sexp = s(:blah, s(:a, s(:b, s(:c, :yay!))))
216
+ assert_equal(s(:c, :yay!), sexp.a.b.c)
217
+ end
218
+
219
+ def test_method_missing_delete
220
+ sexp = s(:blah, s(:a, s(:b, s(:c, :yay!))))
221
+
222
+ assert_equal(s(:c, :yay!), sexp.a.b.c(true))
223
+ assert_equal(s(:blah, s(:a, s(:b))), sexp)
224
+ end
225
+
226
+ def test_pretty_print
227
+ util_pretty_print("s()",
228
+ s())
229
+ util_pretty_print("s(:a)",
230
+ s(:a))
231
+ util_pretty_print("s(:a, :b)",
232
+ s(:a, :b))
233
+ util_pretty_print("s(:a, s(:b))",
234
+ s(:a, s(:b)))
235
+ end
236
+
237
+ def test_sexp_body
238
+ assert_equal [2, 3], @sexp.sexp_body
239
+ end
240
+
241
+ def test_shift
242
+ assert_equal(1, @sexp.shift)
243
+ assert_equal(2, @sexp.shift)
244
+ assert_equal(3, @sexp.shift)
245
+
246
+ assert_raises(RuntimeError) do
247
+ @sexp.shift
248
+ end
249
+ end
250
+
251
+ def test_structure
252
+ @sexp = s(:a, 1, 2, s(:b, 3, 4), 5, 6)
253
+ backup = @sexp.deep_clone
254
+ expected = s(:a, s(:b))
255
+
256
+ assert_equal(expected, @sexp.structure)
257
+ assert_equal(backup, @sexp)
258
+ end
259
+
260
+ def test_sub
261
+ assert_equal s(:c), s().sub(s(), s(:c))
262
+ assert_equal s(:c), s(:b).sub(s(:b), s(:c))
263
+ assert_equal s(:a), s(:a).sub(s(:b), s(:c))
264
+ assert_equal s(:a, s(:c)), s(:a, s(:c)).sub(s(:b), s(:c))
265
+
266
+ assert_equal s(:a, s(:c), s(:b)), s(:a, s(:b), s(:b)).sub(s(:b), s(:c))
267
+
268
+ assert_equal(s(:a, s(:c), s(:a)),
269
+ s(:a, s(:b), s(:a)).sub(s(:b), s(:c)))
270
+ assert_equal(s(:a, s(:c), s(:a, s(:a))),
271
+ s(:a, s(:b), s(:a, s(:a))).sub(s(:b), s(:c)))
272
+ assert_equal(s(:a, s(:a), s(:a, s(:c), s(:b))),
273
+ s(:a, s(:a), s(:a, s(:b), s(:b))).sub(s(:b), s(:c)))
274
+ assert_equal(s(:a, s(:c, s(:b))),
275
+ s(:a, s(:b)).sub(s(:b), s(:c, s(:b))))
276
+ end
277
+
278
+ def test_to_a
279
+ assert_equal([1, 2, 3], @sexp.to_a)
280
+ end
281
+
282
+ def test_to_s
283
+ test_inspect
284
+ end
285
+ end
286
+
287
+ class TestSexpAny < SexpTestCase
288
+
289
+ def setup
290
+ super
291
+ end
292
+
293
+ def test_equals
294
+ util_equals @any, s()
295
+ util_equals @any, s(:a)
296
+ util_equals @any, s(:a, :b, s(:c))
297
+ end
298
+
299
+ def test_equals3
300
+ util_equals3 @any, s()
301
+ util_equals3 @any, s(:a)
302
+ util_equals3 @any, s(:a, :b, s(:c))
303
+ end
304
+
305
+ end
@@ -0,0 +1,297 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ $TESTING = true
4
+
5
+ require 'sexp_processor'
6
+ require 'stringio'
7
+ require 'test/unit'
8
+ require 'pp'
9
+
10
+ # Fake test classes:
11
+
12
+ class TestProcessor < SexpProcessor # ZenTest SKIP
13
+ attr_accessor :auto_shift_type
14
+
15
+ def process_acc1(exp)
16
+ out = self.expected.new(:acc2, exp.thing_three, exp.thing_two, exp.thing_one)
17
+ exp.clear
18
+ return out
19
+ end
20
+
21
+ def process_acc2(exp)
22
+ out = []
23
+ out << exp.thing_one
24
+ end
25
+
26
+ def process_specific(exp)
27
+ name = exp.shift
28
+ result = s(:blah)
29
+ until exp.empty?
30
+ result.push process(exp.shift)
31
+ end
32
+ result
33
+ end
34
+
35
+ def process_strip(exp)
36
+ result = exp.deep_clone
37
+ exp.clear
38
+ result
39
+ end
40
+
41
+ def process_nonempty(exp)
42
+ s(*exp)
43
+ end
44
+
45
+ def process_broken(exp)
46
+ result = [*exp]
47
+ exp.clear
48
+ result
49
+ end
50
+
51
+ def process_expected(exp)
52
+ exp.clear
53
+ return {}
54
+ end
55
+
56
+ def process_string(exp)
57
+ return exp.shift
58
+ end
59
+
60
+ def rewrite_rewritable(exp) # (a b c) => (a c b)
61
+ return s(exp.shift, exp.pop, exp.shift)
62
+ end
63
+
64
+ def process_rewritable(exp)
65
+ @n ||= 0
66
+ exp.shift # name
67
+ result = s(:rewritten)
68
+ until exp.empty?
69
+ result.push process(exp.shift)
70
+ end
71
+ result.push @n
72
+ @n += 1
73
+ result
74
+ end
75
+
76
+ def rewrite_major_rewrite(exp)
77
+ exp[0] = :rewritable
78
+ exp
79
+ end
80
+ end
81
+
82
+ class TestProcessorDefault < SexpProcessor # ZenTest SKIP
83
+ def initialize
84
+ super
85
+ self.default_method = :def_method
86
+ end
87
+
88
+ def def_method(exp)
89
+ exp.clear
90
+ self.expected.new(42)
91
+ end
92
+ end
93
+
94
+ # Real test classes:
95
+
96
+ class TestSexpProcessor < Test::Unit::TestCase
97
+
98
+ def setup
99
+ @processor = TestProcessor.new
100
+ end
101
+
102
+ def test_process_specific
103
+ a = [:specific, [:x, 1], [:y, 2], [:z, 3]]
104
+ expected = [:blah, [:x, 1], [:y, 2], [:z, 3]]
105
+ assert_equal(expected, @processor.process(a))
106
+ end
107
+
108
+ def test_process_generic
109
+ a = [:blah, 1, 2, 3]
110
+ expected = a.deep_clone
111
+ assert_equal(expected, @processor.process(a))
112
+ end
113
+
114
+ def test_process_default
115
+ @processor = TestProcessorDefault.new
116
+ @processor.warn_on_default = false
117
+
118
+ a = s(:blah, 1, 2, 3)
119
+ assert_equal(@processor.expected.new(42), @processor.process(a))
120
+ end
121
+
122
+ def test_process_not_sexp
123
+ @processor = TestProcessor.new
124
+ @processor.warn_on_default = false
125
+
126
+ assert_raises SexpTypeError do
127
+ @processor.process([:broken, 1, 2, 3])
128
+ end
129
+ end
130
+
131
+ def test_process_unsupported_wrong
132
+ @processor = TestProcessor.new
133
+ @processor.unsupported << :strip
134
+
135
+ assert_raises UnsupportedNodeError do
136
+ @processor.process([:whatever])
137
+ end
138
+ end
139
+
140
+ def test_unsupported_equal
141
+ @processor.strict = true
142
+ @processor.unsupported = [ :unsupported ]
143
+ assert_raises UnsupportedNodeError do
144
+ @processor.process([:unsupported, 42])
145
+ end
146
+ end
147
+
148
+ def test_strict
149
+ @processor.strict = true
150
+ assert_raises UnknownNodeError do
151
+ @processor.process([:blah, 1, 2, 3])
152
+ end
153
+ end
154
+ def test_strict=; end #Handled
155
+
156
+ def test_require_empty_false
157
+ @processor.require_empty = false
158
+
159
+ @processor.process([:nonempty, 1, 2, 3])
160
+ end
161
+
162
+ def test_require_empty_true
163
+ assert_raises NotEmptyError do
164
+ @processor.process([:nonempty, 1, 2, 3])
165
+ end
166
+ end
167
+ def test_require_empty=; end # handled
168
+
169
+ def test_process_strip
170
+ @processor.auto_shift_type = true
171
+ assert_equal([1, 2, 3], @processor.process(s(:strip, 1, 2, 3)))
172
+ end
173
+
174
+ def test_rewrite
175
+ assert_equal(s(:rewritable, :b, :a),
176
+ @processor.rewrite(s(:rewritable, :a, :b)))
177
+ end
178
+
179
+ def test_rewrite_different_type
180
+ assert_equal(s(:rewritable, :b, :a),
181
+ @processor.rewrite(s(:major_rewrite, :a, :b)))
182
+ end
183
+
184
+ def test_rewrite_deep
185
+ assert_equal(s(:specific, s(:rewritable, :b, :a)),
186
+ @processor.rewrite(s(:specific, s(:rewritable, :a, :b))))
187
+ end
188
+
189
+ def test_rewrite_not_empty
190
+ insert = s(:rewritable, 1, 2, 2)
191
+ expect = s(:rewritable, 2, 1)
192
+ result = @processor.rewrite(insert)
193
+ assert_equal(expect, result)
194
+ assert_equal(s(2), insert) # post-processing
195
+ end
196
+
197
+ def test_process_rewrite
198
+ assert_equal(s(:rewritten, s(:y, 2), s(:x, 1), 0),
199
+ @processor.process(s(:rewritable, s(:x, 1), s(:y, 2))))
200
+ end
201
+
202
+ def test_process_rewrite_deep
203
+ assert_equal(s(:blah, s(:rewritten, s(:b), s(:a), 0)),
204
+ @processor.process(s(:specific, s(:rewritable, s(:a), s(:b)))))
205
+ end
206
+
207
+ def test_rewrite_depth_first
208
+ inn = s(:specific,
209
+ s(:rewritable,
210
+ s(:a),
211
+ s(:rewritable,
212
+ s(:rewritable, s(:b), s(:c)),
213
+ s(:d))))
214
+ out = s(:specific,
215
+ s(:rewritable,
216
+ s(:rewritable,
217
+ s(:d),
218
+ s(:rewritable, s(:c), s(:b))),
219
+ s(:a)))
220
+
221
+ assert_equal(out, @processor.rewrite(inn))
222
+ end
223
+
224
+ def test_process_rewrite_depth_first
225
+ inn = s(:specific,
226
+ s(:rewritable,
227
+ s(:a),
228
+ s(:rewritable,
229
+ s(:rewritable, s(:b), s(:c)),
230
+ s(:d))))
231
+ out = s(:blah,
232
+ s(:rewritten,
233
+ s(:rewritten,
234
+ s(:d),
235
+ s(:rewritten, s(:c), s(:b), 0), 1),
236
+ s(:a), 2))
237
+
238
+ assert_equal(out, @processor.process(inn))
239
+ end
240
+
241
+ def test_assert_type_hit
242
+ @processor.assert_type([:blah, 1, 2, 3], :blah)
243
+ end
244
+
245
+ def test_assert_type_miss
246
+ assert_raises SexpTypeError do
247
+ @processor.assert_type([:thingy, 1, 2, 3], :blah)
248
+ end
249
+ end
250
+
251
+ def test_generate
252
+ # nothing to test at this time... soon.
253
+ end
254
+
255
+ def test_auto_shift_type
256
+ @processor.auto_shift_type = false
257
+ assert_equal(false, @processor.auto_shift_type)
258
+ @processor.auto_shift_type = true
259
+ assert_equal(true, @processor.auto_shift_type)
260
+ end
261
+ def test_auto_shift_type_equal; end # handled
262
+
263
+ def test_default_method
264
+ # default functionality tested in process_default
265
+ assert_nil @processor.default_method
266
+ @processor.default_method = :something
267
+ assert_equal :something, @processor.default_method
268
+ end
269
+ def test_default_method=; end # handled
270
+
271
+ def test_expected
272
+ assert_equal Sexp, @processor.expected
273
+ assert_raises SexpTypeError do
274
+ @processor.process([:expected]) # should raise
275
+ end
276
+
277
+ @processor.process(s(:str, "string")) # shouldn't raise
278
+
279
+ @processor.expected = Hash
280
+ assert_equal Hash, @processor.expected
281
+ assert !(Hash === s()), "Hash === s() should not be true"
282
+
283
+ assert_raises SexpTypeError do
284
+ @processor.process(s(:string, "string")) # should raise
285
+ end
286
+
287
+ @processor.process([:expected]) # shouldn't raise
288
+ end
289
+ def test_expected=; end # handled
290
+
291
+ # Not Testing:
292
+ def test_debug; end
293
+ def test_debug=; end
294
+ def test_warn_on_default; end
295
+ def test_warn_on_default=; end
296
+
297
+ end