rufus-treechecker 1.0.1 → 1.0.2

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.
@@ -125,7 +125,7 @@ module Rufus
125
125
  #
126
126
  class TreeChecker
127
127
 
128
- VERSION = '1.0.1'
128
+ VERSION = '1.0.2'
129
129
 
130
130
  #
131
131
  # pretty-prints the sexp tree of the given rubycode
@@ -142,20 +142,19 @@ module Rufus
142
142
  #
143
143
  def initialize (&block)
144
144
 
145
- @root_checks = []
146
- @checks = []
147
-
148
- @current_checks = @checks
145
+ @root_set = RuleSet.new
146
+ @set = RuleSet.new
147
+ @current_set = @set
149
148
 
150
149
  add_rules(&block)
151
150
  end
152
151
 
153
152
  def to_s
154
- p self.class
155
- puts ' root_checks :'
156
- puts @root_checks.collect { |r| r.inspect }.join("\n")
157
- puts ' checks :'
158
- puts @checks.collect { |r| r.inspect }.join("\n")
153
+ s = "#{self.class} (#{self.object_id})\n"
154
+ s << "root_set :\n"
155
+ s << @root_set.to_s
156
+ s << "set :\n"
157
+ s << @set.to_s
159
158
  end
160
159
 
161
160
  #
@@ -167,9 +166,10 @@ module Rufus
167
166
 
168
167
  sexp = parse(rubycode)
169
168
 
170
- @root_checks.each do |meth, *args|
171
- send meth, sexp, args
172
- end
169
+ #@root_checks.each do |meth, *args|
170
+ # send meth, sexp, args
171
+ #end
172
+ @root_set.check(sexp)
173
173
 
174
174
  do_check(sexp)
175
175
  end
@@ -179,9 +179,10 @@ module Rufus
179
179
  #
180
180
  def clone
181
181
 
182
- copy = TreeChecker.new
183
- copy.instance_variable_set(:@checks, @checks.dup)
184
- copy
182
+ tc = TreeChecker.new
183
+ tc.instance_variable_set(:@root_set, @root_set.clone)
184
+ tc.instance_variable_set(:@set, @set.clone)
185
+ tc
185
186
  end
186
187
 
187
188
  #
@@ -199,46 +200,117 @@ module Rufus
199
200
  #
200
201
  def freeze
201
202
  super
202
- @root_checks.freeze
203
- @root_checks.each { |c| c.freeze }
204
- @checks.freeze
205
- @checks.each { |c| c.freeze }
206
- end
207
-
208
- #
209
- # generates a 'classic' tree checker
210
- #
211
- # Here is how it's built :
212
- #
213
- # return TreeChecker.new do
214
- # exclude_fvccall :abort
215
- # exclude_fvccall :exit, :exit!
216
- # exclude_fvccall :system
217
- # exclude_eval
218
- # exclude_alias
219
- # exclude_global_vars
220
- # exclude_call_on File, FileUtils
221
- # exclude_class_tinkering
222
- # exclude_module_tinkering
223
- # end
224
- #
225
- def self.new_classic_tree_checker
226
-
227
- return TreeChecker.new do
228
- exclude_fvccall :abort
229
- exclude_fvccall :exit, :exit!
230
- exclude_fvccall :system
231
- exclude_eval
232
- exclude_alias
233
- exclude_global_vars
234
- exclude_call_on File, FileUtils
235
- exclude_class_tinkering
236
- exclude_module_tinkering
237
- end
203
+ @root_set.freeze
204
+ @set.freeze
238
205
  end
239
206
 
240
207
  protected
241
208
 
209
+ class RuleSet
210
+
211
+ def initialize
212
+
213
+ @excluded_symbols = {} # symbol => exclusion_message
214
+ @accepted_patterns = {} # 1st elt of pattern => pattern
215
+ @excluded_patterns = {} # 1st elt of pattern => pattern, excl_message
216
+ end
217
+
218
+ def clone
219
+ rs = RuleSet.new
220
+ rs.instance_variable_set(:@excluded_symbols, @excluded_symbols.dup)
221
+ rs.instance_variable_set(:@accepted_patterns, @accepted_patterns.dup)
222
+ rs.instance_variable_set(:@excluded_patterns, @excluded_patterns.dup)
223
+ rs
224
+ end
225
+
226
+ def exclude_symbol (s, message)
227
+
228
+ @excluded_symbols[s] = (message || ":#{s} is excluded")
229
+ end
230
+
231
+ def accept_pattern (pat)
232
+
233
+ (@accepted_patterns[pat.first] ||= []) << pat
234
+ end
235
+
236
+ def exclude_pattern (pat, message)
237
+
238
+ (@excluded_patterns[pat.first] ||= []) << [
239
+ pat, message || "#{pat.inspect} is excluded" ]
240
+ end
241
+
242
+ def check (sexp)
243
+
244
+ if sexp.is_a?(Symbol)
245
+
246
+ m = @excluded_symbols[sexp]
247
+ raise SecurityError.new(m) if m
248
+
249
+ elsif sexp.is_a?(Array)
250
+
251
+ # accepted patterns are evaluated before excluded patterns
252
+ # if one is found the excluded patterns are skipped
253
+
254
+ pats = @accepted_patterns[sexp.first]
255
+ pats.each { |pat| return if check_pattern(sexp, pat) } if pats
256
+
257
+ pats = @excluded_patterns[sexp.first]
258
+ return unless pats
259
+
260
+ pats.each do |pat, msg|
261
+ raise SecurityError.new(msg) if check_pattern(sexp, pat)
262
+ end
263
+ end
264
+ end
265
+
266
+ def freeze
267
+
268
+ super
269
+
270
+ @excluded_symbols.freeze
271
+ @excluded_symbols.each { |k, v| k.freeze; v.freeze }
272
+ @accepted_patterns.freeze
273
+ @accepted_patterns.each { |k, v| k.freeze; v.freeze }
274
+ @excluded_patterns.freeze
275
+ @excluded_patterns.each { |k, v| k.freeze; v.freeze }
276
+ end
277
+
278
+ def to_s
279
+
280
+ s = "#{self.class} (#{self.object_id})\n"
281
+ s << " excluded symbols :\n"
282
+ @excluded_symbols.each do |k, v|
283
+ s << " - #{k.inspect}, #{v}\n"
284
+ end
285
+ s << " accepted patterns :\n"
286
+ @accepted_patterns.each do |k, v|
287
+ v.each do |p|
288
+ s << " - #{k.inspect}, #{p.inspect}\n"
289
+ end
290
+ end
291
+ s << " excluded patterns :\n"
292
+ @excluded_patterns.each do |k, v|
293
+ v.each do |p|
294
+ s << " - #{k.inspect}, #{p.inspect}\n"
295
+ end
296
+ end
297
+ s
298
+ end
299
+
300
+ protected
301
+
302
+ def check_pattern (sexp, pat)
303
+
304
+ return false if sexp.length < pat.length
305
+
306
+ (1..pat.length-1).each do |i|
307
+ return false if (pat[i] != :any and pat[i] != sexp[i])
308
+ end
309
+
310
+ return true # we have a match
311
+ end
312
+ end
313
+
242
314
  #--
243
315
  # the methods used to define the checks
244
316
  #++
@@ -249,9 +321,26 @@ module Rufus
249
321
  #
250
322
  def at_root (&block)
251
323
 
252
- @current_checks = @root_checks
324
+ @current_set = @root_set
253
325
  add_rules(&block)
254
- @current_checks = @checks
326
+ @current_set = @set
327
+ end
328
+
329
+ def extract_message (args)
330
+
331
+ message = nil
332
+ args = args.dup
333
+ message = args.pop if args.last.is_a?(String)
334
+ [ args, message ]
335
+ end
336
+
337
+ def expand_class (arg)
338
+
339
+ if arg.is_a?(Class) or arg.is_a?(Module)
340
+ [ parse(arg.to_s), parse("::#{arg.to_s}") ]
341
+ else
342
+ [ arg ]
343
+ end
255
344
  end
256
345
 
257
346
  #
@@ -266,33 +355,39 @@ module Rufus
266
355
  #
267
356
  def exclude_head (head, message=nil)
268
357
 
269
- @current_checks << [ :do_exclude_head, head, message ]
358
+ @current_set.exclude_pattern(head, message)
270
359
  end
271
360
 
272
- [
273
- :exclude_symbol,
274
- :exclude_fcall,
275
- :exclude_vcall,
276
- :exclude_fvcall,
277
- :exclude_fvccall,
278
- :exclude_call_on,
279
- :exclude_call_to
361
+ def exclude_symbol (*args)
362
+ args, message = extract_message(args)
363
+ args.each { |a| @current_set.exclude_symbol(a, message) }
364
+ end
280
365
 
281
- ].each do |m|
282
- class_eval <<-EOS
283
- def #{m} (*args)
366
+ def exclude_fcall (*args)
367
+ do_exclude_pair(:fcall, args)
368
+ end
284
369
 
285
- message = args.last.is_a?(String) ? args.pop : nil
370
+ def exclude_vcall (*args)
371
+ do_exclude_pair(:vcall, args)
372
+ end
286
373
 
287
- args.each do |a|
374
+ def exclude_fvcall (*args)
375
+ do_exclude_pair(:fcall, args)
376
+ do_exclude_pair(:vcall, args)
377
+ end
288
378
 
289
- a = [ Class, Module ].include?(a.class) ? \
290
- parse(a.to_s) : a.to_sym
379
+ def exclude_call_on (*args)
380
+ do_exclude_pair(:call, args)
381
+ end
291
382
 
292
- @current_checks << [ :do_#{m}, a, message ]
293
- end
294
- end
295
- EOS
383
+ def exclude_call_to (*args)
384
+ args, message = extract_message(args)
385
+ args.each { |a| @current_set.exclude_pattern([ :call, :any, a], message) }
386
+ end
387
+
388
+ def exclude_fvccall (*args)
389
+ exclude_fvcall(*args)
390
+ exclude_call_to(*args)
296
391
  end
297
392
 
298
393
  #
@@ -306,14 +401,11 @@ module Rufus
306
401
  # k = ::Kernel
307
402
  #
308
403
  def exclude_rebinding (*args)
309
-
310
- message = args.last.is_a?(String) ? args.pop : nil
311
-
404
+ args, message = extract_message(args)
312
405
  args.each do |a|
313
- c0 = parse(a.to_s)
314
- c1 = parse("::#{a.to_s}")
315
- @current_checks << [ :do_exclude_rebinding, c0, message ]
316
- @current_checks << [ :do_exclude_rebinding, c1, message ]
406
+ expand_class(a).each do |c|
407
+ @current_set.exclude_pattern([ :lasgn, :any, c], message)
408
+ end
317
409
  end
318
410
  end
319
411
 
@@ -322,7 +414,6 @@ module Rufus
322
414
  # of classes
323
415
  #
324
416
  def exclude_access_to (*args)
325
-
326
417
  exclude_call_on *args
327
418
  exclude_rebinding *args
328
419
  end
@@ -332,8 +423,7 @@ module Rufus
332
423
  #
333
424
  def exclude_def
334
425
 
335
- @current_checks << [
336
- :do_exclude_symbol, :defn, 'method definitions are forbidden' ]
426
+ @current_set.exclude_symbol(:defn, 'method definitions are forbidden')
337
427
  end
338
428
 
339
429
  #
@@ -342,23 +432,21 @@ module Rufus
342
432
  # a list of exceptions (classes) can be passed. Subclassing those
343
433
  # exceptions is permitted.
344
434
  #
345
- def exclude_class_tinkering (*exceptions)
346
-
347
- #
348
- # :class
435
+ # exclude_class_tinkering :except => [ String, Array ]
436
+ #
437
+ def exclude_class_tinkering (*args)
349
438
 
350
- @current_checks << [
351
- :do_exclude_class_tinkering
352
- ] + exceptions.collect { |e| parse(e.to_s) }
439
+ @current_set.exclude_pattern(
440
+ [ :sclass ], 'opening the metaclass of an instance is forbidden')
353
441
 
354
- #
355
- # :sclass
442
+ Array(args.last[:except]).each { |e|
443
+ expand_class(e).each do |c|
444
+ @current_set.accept_pattern([ :class, :any, c ])
445
+ end
446
+ } if args.last.is_a?(Hash)
356
447
 
357
- @current_checks << [
358
- :do_exclude_symbol,
359
- :sclass,
360
- 'opening the metaclass of an instance is forbidde'
361
- ]
448
+ @current_set.exclude_pattern(
449
+ [ :class ], 'defining a class is forbidden')
362
450
  end
363
451
 
364
452
  #
@@ -366,9 +454,8 @@ module Rufus
366
454
  #
367
455
  def exclude_module_tinkering
368
456
 
369
- @current_checks << [
370
- :do_exclude_symbol, :module, 'defining or opening a module is forbidden'
371
- ]
457
+ @current_set.exclude_symbol(
458
+ :module, 'defining or opening a module is forbidden')
372
459
  end
373
460
 
374
461
  #
@@ -376,10 +463,8 @@ module Rufus
376
463
  #
377
464
  def exclude_global_vars
378
465
 
379
- @current_checks << [
380
- :do_exclude_symbol, :gvar, "global vars are forbidden" ]
381
- @current_checks << [
382
- :do_exclude_symbol, :gasgn, "global vars are forbidden" ]
466
+ @current_set.exclude_symbol(:gvar, 'global vars are forbidden')
467
+ @current_set.exclude_symbol(:gasgn, 'global vars are forbidden')
383
468
  end
384
469
 
385
470
  #
@@ -387,10 +472,8 @@ module Rufus
387
472
  #
388
473
  def exclude_alias
389
474
 
390
- @current_checks << [
391
- :do_exclude_symbol, :alias, "'alias' is forbidden" ]
392
- @current_checks << [
393
- :do_exclude_symbol, :alias_method, "'alias_method' is forbidden" ]
475
+ @current_set.exclude_symbol(:alias, "'alias' is forbidden")
476
+ @current_set.exclude_symbol(:alias_method, "'alias_method' is forbidden")
394
477
  end
395
478
 
396
479
  #
@@ -398,26 +481,17 @@ module Rufus
398
481
  #
399
482
  def exclude_eval
400
483
 
401
- @current_checks << [
402
- :do_exclude_fcall,
403
- :eval,
404
- "eval() is forbidden" ]
405
- @current_checks << [
406
- :do_exclude_call_to,
407
- :instance_eval,
408
- "instance_eval() is forbidden" ]
409
- @current_checks << [
410
- :do_exclude_call_to,
411
- :module_eval,
412
- "module_eval() is forbidden" ]
484
+ exclude_fcall(:eval, 'eval() is forbidden')
485
+ exclude_call_to(:module_eval, 'module_eval() is forbidden')
486
+ exclude_call_to(:instance_eval, 'instance_eval() is forbidden')
413
487
  end
414
488
 
415
489
  #
416
490
  # bans the use of backquotes
417
491
  #
418
492
  def exclude_backquotes
419
- @current_checks << [
420
- :do_exclude_symbol, :xstr, "backquotes are forbidden" ]
493
+
494
+ @current_set.exclude_symbol(:xstr, 'backquotes are forbidden')
421
495
  end
422
496
 
423
497
  #
@@ -425,8 +499,18 @@ module Rufus
425
499
  #
426
500
  def exclude_raise
427
501
 
428
- @current_checks << [ :do_exclude_fvccall, :raise, "raise is forbidden" ]
429
- @current_checks << [ :do_exclude_fvccall, :throw, "throw is forbidden" ]
502
+ exclude_fvccall(:raise, 'raise is forbidden')
503
+ exclude_fvccall(:throw, 'throw is forbidden')
504
+ end
505
+
506
+ def do_exclude_pair (first, args)
507
+
508
+ args, message = extract_message(args)
509
+ args.each do |a|
510
+ expand_class(a).each do |c|
511
+ @current_set.exclude_pattern([ first, c ], message)
512
+ end
513
+ end
430
514
  end
431
515
 
432
516
  #
@@ -434,9 +518,7 @@ module Rufus
434
518
  #
435
519
  def do_check (sexp)
436
520
 
437
- @checks.each do |exclusion_method, *args|
438
- send exclusion_method, sexp, args
439
- end
521
+ @set.check(sexp)
440
522
 
441
523
  return unless sexp.is_a?(Array) # check over, seems fine...
442
524
 
@@ -445,125 +527,6 @@ module Rufus
445
527
  sexp.each { |c| do_check c }
446
528
  end
447
529
 
448
- #
449
- # the methods that actually perform the checks
450
- # (and potentially raise security exceptions)
451
-
452
- #
453
- # constructs a new set of arguments by inserting the newhead at the
454
- # beginning of the arguments
455
- #
456
- def cons (newhead, args)
457
-
458
- newhead = Array(newhead)
459
- newhead << args[0]
460
-
461
- [ newhead ] + (args[1, -1] || [])
462
- end
463
-
464
- def do_exclude_fcall (sexp, args)
465
-
466
- do_exclude_head(sexp, cons(:fcall, args))
467
- end
468
-
469
- def do_exclude_vcall (sexp, args)
470
-
471
- do_exclude_head(sexp, cons(:vcall, args))
472
- end
473
-
474
- #
475
- # excludes :fcall and :vcall
476
- #
477
- def do_exclude_fvcall (sexp, args)
478
-
479
- do_exclude_fcall(sexp, args)
480
- do_exclude_vcall(sexp, args)
481
- end
482
-
483
- #
484
- # excludes :fcall and :vcall and :call (to)
485
- #
486
- def do_exclude_fvccall (sexp, args)
487
-
488
- do_exclude_fvcall(sexp, args)
489
- #do_exclude_head(sexp, cons([ :call, [ :const, :Kernel ] ], args))
490
- do_exclude_call_to(sexp, args)
491
- end
492
-
493
- #
494
- # raises a Rufus::SecurityError if the sexp is a reference to
495
- # a certain symbol (like :gvar or :alias).
496
- #
497
- def do_exclude_symbol (sexp, args)
498
-
499
- raise SecurityError.new(
500
- args[1] || "symbol :#{excluded_symbol} is forbidden"
501
- ) if sexp == args[0]
502
- end
503
-
504
- #
505
- # raises a security error if the sexp is a call on a given constant or
506
- # module (class)
507
- #
508
- def do_exclude_call_on (sexp, args)
509
-
510
- do_exclude_head(sexp, [ [:call, args[0]] ] + (args[1, -1] || []))
511
- end
512
-
513
- #
514
- # this method is called by all the methods checking composite sexps.
515
- #
516
- def do__exclude (sexp, args, default_error_message, &block)
517
-
518
- return unless sexp.is_a?(Array)
519
-
520
- raise SecurityError.new(
521
- args[1] || default_error_message
522
- ) if block.call(args)
523
- end
524
-
525
- #
526
- # raises a security error if a call to a given method of any instance
527
- # is found
528
- #
529
- def do_exclude_call_to (sexp, args)
530
-
531
- do__exclude(sexp, args, "calls to '#{args[0]}' are forbidden") do
532
-
533
- (sexp[0] == :call and sexp[2] == args[0])
534
- end
535
- end
536
-
537
- def do_exclude_rebinding (sexp, args)
538
-
539
- do__exclude(sexp, args, "rebinding '#{args[0]}' is forbidden") do
540
-
541
- (sexp[0] == :lasgn and sexp[2] == args[0])
542
- end
543
- end
544
-
545
- def do_exclude_head (sexp, args)
546
-
547
- do__exclude(sexp, args, "#{args[0].inspect} is forbidden") do
548
-
549
- (sexp[0, args[0].length] == args[0])
550
- end
551
- end
552
-
553
- def do_exclude_class_tinkering (sexp, args)
554
-
555
- return unless sexp.is_a?(Array) # lonely symbols are not class definitions
556
-
557
- return unless sexp[0] == :class
558
-
559
- raise SecurityError.new(
560
- 'defining or opening a class is forbidden'
561
- ) if args.length == 0 or ( ! args.include?(sexp[2]))
562
- #
563
- # raise error if there are no exceptions or
564
- # if the parent class is not a member of the exception list
565
- end
566
-
567
530
  #
568
531
  # a simple parse (relies on ruby_parser currently)
569
532
  #
data/test/bm.rb ADDED
@@ -0,0 +1,95 @@
1
+
2
+ require 'rubygems'
3
+
4
+ require 'benchmark'
5
+ include Benchmark
6
+
7
+ require 'rufus/treechecker'
8
+
9
+ Benchmark.benchmark do |b|
10
+
11
+ tc = nil
12
+
13
+ b.report do
14
+ tc = Rufus::TreeChecker.new do
15
+
16
+ exclude_fvccall :abort, :exit, :exit!
17
+ exclude_fvccall :system, :fork, :syscall, :trap, :require, :load
18
+
19
+ #exclude_call_to :class
20
+ exclude_fvcall :private, :public, :protected
21
+
22
+ #exclude_def # no method definition
23
+ exclude_eval # no eval, module_eval or instance_eval
24
+ exclude_backquotes # no `rm -fR the/kitchen/sink`
25
+ exclude_alias # no alias or aliast_method
26
+ exclude_global_vars # $vars are off limits
27
+ exclude_module_tinkering # no module opening
28
+ exclude_raise # no raise or throw
29
+
30
+ exclude_rebinding Kernel # no 'k = Kernel'
31
+
32
+ exclude_access_to(
33
+ IO, File, FileUtils, Process, Signal, Thread, ThreadGroup)
34
+
35
+ #exclude_class_tinkering :except => OpenWFE::ProcessDefinition
36
+ exclude_class_tinkering :except => Rufus::TreeChecker
37
+ #
38
+ # excludes defining/opening any class except
39
+ # OpenWFE::ProcessDefinition
40
+
41
+ exclude_call_to :instance_variable_get, :instance_variable_set
42
+ end
43
+ end
44
+
45
+ DEF0 = <<-EOS
46
+ #class MyDef0 < OpenWFE::ProcessDefinition
47
+ class MyDef0 < Rufus::TreeChecker
48
+ sequence do
49
+ participant "alpha"
50
+ participant 'alpha'
51
+ alpha
52
+ end
53
+ end
54
+ EOS
55
+
56
+ N = 100
57
+ #N = 1
58
+
59
+ b.report do
60
+ N.times { tc.check(DEF0) }
61
+ end
62
+ end
63
+
64
+ #
65
+ # before RuleSet (N=100)
66
+ #
67
+ # mettraux:rufus-treechecker[master]/$ date
68
+ # Tue Sep 2 09:33:06 JST 2008
69
+ # mettraux:rufus-treechecker[master]/$ ruby -Ilib test/bm.rb
70
+ # 0.000000 0.000000 0.000000 ( 0.004252)
71
+ # 5.680000 0.040000 5.720000 ( 5.745755)
72
+ # mettraux:rufus-treechecker[master]/$ ruby -Ilib test/bm.rb
73
+ # 0.010000 0.000000 0.010000 ( 0.004367)
74
+ # 5.670000 0.040000 5.710000 ( 5.731221)
75
+ # mettraux:rufus-treechecker[master]/$ ruby -Ilib test/bm.rb
76
+ # 0.010000 0.000000 0.010000 ( 0.004247)
77
+ # 5.670000 0.040000 5.710000 ( 5.727363)
78
+ #
79
+
80
+ #
81
+ # with RuleSet (N=100)
82
+ #
83
+ # mettraux:rufus-treechecker[master]/$ date
84
+ # Tue Sep 2 13:25:24 JST 2008
85
+ # mettraux:rufus-treechecker[master]/$ ruby -Ilib test/bm.rb
86
+ # 0.000000 0.000000 0.000000 ( 0.006439)
87
+ # 0.340000 0.000000 0.340000 ( 0.342302)
88
+ # mettraux:rufus-treechecker[master]/$ ruby -Ilib test/bm.rb
89
+ # 0.000000 0.000000 0.000000 ( 0.006269)
90
+ # 0.340000 0.000000 0.340000 ( 0.342301)
91
+ # mettraux:rufus-treechecker[master]/$ ruby -Ilib test/bm.rb
92
+ # 0.000000 0.000000 0.000000 ( 0.006350)
93
+ # 0.340000 0.000000 0.340000 ( 0.342841)
94
+ #
95
+
data/test/ft_0_basic.rb CHANGED
@@ -68,6 +68,7 @@ class BasicTest < Test::Unit::TestCase
68
68
  exclude_call_on File, FileUtils
69
69
  exclude_call_on IO
70
70
  end
71
+ #puts tc.to_s
71
72
 
72
73
  assert_nok(tc, 'data = File.read("surf.txt")')
73
74
  assert_nok(tc, 'f = File.new("surf.txt")')
@@ -99,23 +100,9 @@ class BasicTest < Test::Unit::TestCase
99
100
  def test_5b_exclude_class_tinkering_with_exceptions
100
101
 
101
102
  tc = Rufus::TreeChecker.new do
102
- exclude_class_tinkering String, Rufus::TreeChecker
103
- end
104
-
105
- assert_nok(tc, 'class String; def length; 3; end; end')
106
-
107
- assert_ok(tc, 'class S2 < String; def length; 3; end; end')
108
- assert_ok(tc, 'class Toto < Rufus::TreeChecker; def length; 3; end; end')
109
-
110
- assert_nok(tc, 'class Toto; end')
111
- assert_nok(tc, 'class Alpha::Toto; end')
112
- end
113
-
114
- def test_5c_exclude_class_tinkering_with_exceptions
115
-
116
- tc = Rufus::TreeChecker.new do
117
- exclude_class_tinkering 'String', 'Rufus::TreeChecker'
103
+ exclude_class_tinkering :except => [ String, Rufus::TreeChecker ]
118
104
  end
105
+ #puts tc.to_s
119
106
 
120
107
  assert_nok(tc, 'class String; def length; 3; end; end')
121
108
 
@@ -238,9 +225,12 @@ class BasicTest < Test::Unit::TestCase
238
225
  exclude_access_to File
239
226
  end
240
227
 
228
+ #puts tc.to_s
229
+
241
230
  assert_nok(tc, 'f = File')
242
231
  assert_nok(tc, 'f = ::File')
243
232
  assert_nok(tc, 'File.read "hello.txt"')
233
+ assert_nok(tc, '::File.read "hello.txt"')
244
234
  end
245
235
 
246
236
  #def test_X
@@ -28,7 +28,7 @@ class OldTreeCheckerTest < Test::Unit::TestCase
28
28
  exclude_alias
29
29
  exclude_global_vars
30
30
  exclude_call_on File, FileUtils
31
- exclude_class_tinkering Testy::Tasty
31
+ exclude_class_tinkering :except => Testy::Tasty
32
32
  exclude_module_tinkering
33
33
 
34
34
  exclude_fvcall :public
@@ -0,0 +1,32 @@
1
+
2
+ #
3
+ # Testing rufus-treechecker
4
+ #
5
+ # jmettraux at gmail.org
6
+ #
7
+ # Tue Sep 2 14:28:01 JST 2008
8
+ #
9
+
10
+ require 'testmixin'
11
+
12
+ class CloneTest < Test::Unit::TestCase
13
+ include TestMixin
14
+
15
+
16
+ def test_0
17
+
18
+ tc0 = Rufus::TreeChecker.new do
19
+ exclude_fvccall :abort
20
+ end
21
+
22
+ tc1 = tc0.clone
23
+ tc1.add_rules do
24
+ at_root do
25
+ exclude_head [ :block ]
26
+ end
27
+ end
28
+
29
+ assert_not_equal tc0.object_id, tc1.object_id
30
+ end
31
+ end
32
+
data/test/test.rb CHANGED
@@ -1,4 +1,5 @@
1
1
 
2
2
  require 'ft_0_basic'
3
3
  require 'ft_1_old_treechecker'
4
+ require 'ft_2_clone'
4
5
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufus-treechecker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
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: 2008-09-01 00:00:00 +09:00
12
+ date: 2008-09-02 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -33,8 +33,10 @@ extra_rdoc_files:
33
33
  files:
34
34
  - lib/rufus
35
35
  - lib/rufus/treechecker.rb
36
+ - test/bm.rb
36
37
  - test/ft_0_basic.rb
37
38
  - test/ft_1_old_treechecker.rb
39
+ - test/ft_2_clone.rb
38
40
  - test/test.rb
39
41
  - test/testmixin.rb
40
42
  - README.txt