File: test_blankslate.rb

package info (click to toggle)
ruby-builder 3.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 304 kB
  • sloc: ruby: 1,987; makefile: 15
file content (217 lines) | stat: -rw-r--r-- 5,309 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/usr/bin/env ruby

#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.

# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++

require_relative 'helper'
require_relative 'preload'
require 'blankslate'
require 'stringio'

# Methods to be introduced into the Object class late.
module LateObject
  def late_object
    33
  end
  def LateObject.included(mod)
    # Modules defining an included method should not prevent blank
    # slate erasure!
  end
end

# Methods to be introduced into the Kernel module late.
module LateKernel
  def late_kernel
    44
  end
  def LateKernel.included(mod)
    # Modules defining an included method should not prevent blank
    # slate erasure!
  end
end

# Introduce some late methods (both module and direct) into the Kernel
# module.
module Kernel
  include LateKernel

  def late_addition
    1234
  end

  def double_late_addition
    22
  end
end


# Introduce some late methods (both module and direct) into the Object
# class.
class Object
  include LateObject
  def another_late_addition
    4321
  end
end

# Introduce some late methods by inclusion.
module GlobalModule
 def global_inclusion
   42
 end
end
include GlobalModule

def direct_global
  43
end

######################################################################
# Test case for blank slate.
#
class TestBlankSlate < Builder::Test
  def setup
    if Object::const_defined?(:BasicObject) and respond_to?(:skip)
      skip "BlankSlate is not used in this environment"
    end

    @bs = BlankSlate.new
  end

  def test_undefined_methods_remain_undefined
    assert_raise(NoMethodError) { @bs.no_such_method }
    assert_raise(NoMethodError) { @bs.nil? }
  end


  # NOTE: NameError is acceptable because the lack of a '.' means that
  # Ruby can't tell if it is a method or a local variable.
  def test_undefined_methods_remain_undefined_during_instance_eval
    assert_raise(NoMethodError, NameError)  do
      @bs.instance_eval do nil? end
    end
    assert_raise(NoMethodError, NameError)  do
      @bs.instance_eval do no_such_method end
    end
  end

  def test_private_methods_are_undefined
    assert_raise(NoMethodError) do
      @bs.puts "HI"
    end
  end

  def test_targetted_private_methods_are_undefined_during_instance_eval
    assert_raise(NoMethodError, NameError) do
      @bs.instance_eval do self.puts "HI" end
    end
  end

  def test_untargetted_private_methods_are_defined_during_instance_eval
    oldstdout = $stdout
    $stdout = StringIO.new
    @bs.instance_eval do
      puts "HI"
    end
  ensure
    $stdout = oldstdout
  end

  def test_methods_added_late_to_kernel_remain_undefined
    assert_equal 1234, nil.late_addition
    assert_raise(NoMethodError) { @bs.late_addition }
  end

  def test_methods_added_late_to_object_remain_undefined
    assert_equal 4321, nil.another_late_addition
    assert_raise(NoMethodError) { @bs.another_late_addition }
  end

  def test_methods_added_late_to_global_remain_undefined
    assert_equal 42, global_inclusion
    assert_raise(NoMethodError) { @bs.global_inclusion }
  end

  def test_preload_method_added
    assert Kernel.k_added_names.include?(:late_addition)
    assert Object.o_added_names.include?(:another_late_addition)
  end

  def test_method_defined_late_multiple_times_remain_undefined
    assert_equal 22, nil.double_late_addition
    assert_raise(NoMethodError) { @bs.double_late_addition }
  end

  def test_late_included_module_in_object_is_ok
    assert_equal 33, 1.late_object
    assert_raise(NoMethodError) { @bs.late_object }
  end

  def test_late_included_module_in_kernel_is_ok
    assert_raise(NoMethodError) { @bs.late_kernel }
  end

  def test_revealing_previously_hidden_methods_are_callable
    with_to_s = Class.new(BlankSlate) do
      reveal :to_s
    end
    assert_match(/^#<.*>$/, with_to_s.new.to_s)
  end

  def test_revealing_previously_hidden_methods_are_callable_with_block
    Object.class_eval <<-EOS
      def given_block(&block)
        block
      end
    EOS

    with_given_block = Class.new(BlankSlate) do
      reveal :given_block
    end
    assert_not_nil with_given_block.new.given_block {}
  end

  def test_revealing_a_hidden_method_twice_is_ok
    with_to_s = Class.new(BlankSlate) do
      reveal :to_s
      reveal :to_s
    end
    assert_match(/^#<.*>$/, with_to_s.new.to_s)
  end

  def test_revealing_unknown_hidden_method_is_an_error
    assert_raises(RuntimeError) do
      Class.new(BlankSlate) do
        reveal :xyz
      end
    end
  end

  def test_global_includes_still_work
    assert_nothing_raised do
      assert_equal 42, global_inclusion
      assert_equal 42, Object.new.global_inclusion
      assert_equal 42, "magic number".global_inclusion
      assert_equal 43, direct_global
    end
  end

  def test_reveal_should_not_bind_to_an_instance
    with_object_id = Class.new(BlankSlate) do
      reveal(:object_id)
    end

    obj1 = with_object_id.new
    obj2 = with_object_id.new

    assert obj1.object_id != obj2.object_id,
       "Revealed methods should not be bound to a particular instance"
  end
end