forked from wycats/ruby_decorators
-
Notifications
You must be signed in to change notification settings - Fork 0
/
specs.rb
216 lines (178 loc) · 4.51 KB
/
specs.rb
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
require "decorators"
module Spec
module Matchers
def have_stdout(regex)
regex = /^#{Regexp.escape(regex)}$/ if regex.is_a?(String)
simple_matcher("have_stdout") do |given, matcher|
$stdout = StringIO.new
given.call
$stdout.rewind
captured = $stdout.read
matcher.failure_message = "Expected #{regex} but got #{captured}"
$stdout = STDOUT
captured =~ regex
end
end
end
end
module Kernel
def silence_stdout
$stdout = StringIO.new
yield
$stdout = STDOUT
end
end
describe "a class with simple method decorators" do
class MyDecorator
def initialize(klass, meth)
puts "Initializing MyDecorator for #{klass}"
@meth = meth
end
def call(this)
puts "Inside MyDecorator#call"
end
end
class MyDecorator2
def initialize(klass, meth)
puts "Initializing MyDecorator2 for #{klass}"
@meth = meth
end
def call(this)
puts "Inside MyDecorator#call"
end
end
it "makes a new instance of the decorator when a decorated method is added" do
lambda do
class Simple1
extend MethodDecorators
decorate MyDecorator
def a_function
puts "Inside a_function"
end
end
end.should have_stdout "Initializing MyDecorator for Simple1\n"
end
it "initializes multiple decorators when a decorated method is added" do
lambda do
class Simple2
extend MethodDecorators
decorate MyDecorator
decorate MyDecorator2
def a_function
puts "Inside a_function"
end
end
end.should have_stdout "Initializing MyDecorator for Simple2\n" \
"Initializing MyDecorator2 for Simple2\n"
end
it "calls the decorator instead of the method" do
silence_stdout do
class Simple3
extend MethodDecorators
decorate MyDecorator
def a_function
puts "Inside a_function"
end
end
end
lambda do
Simple3.new.a_function
end.should have_stdout "Inside MyDecorator#call"
end
it "can wrap a function" do
lambda do
class MyDecorator3 < Decorator
def initialize(klass, meth)
@meth = meth
end
def call(this)
puts "Before MyDecorator#call"
@meth.bind(this).call
puts "After MyDecorator#call"
end
end
class Simple4
extend MethodDecorators
decorate MyDecorator3
def a_function
puts "Inside a_function"
end
end
Simple4.new.a_function
end.should have_stdout "Before MyDecorator#call\nInside a_function\nAfter MyDecorator#call"
end
it "passes on any arguments to the method to decorator#call" do
class MyDecorator4 < Decorator
def call(this, *args)
puts args.inspect
puts "BLOCK" if block_given?
end
end
lambda do
class Simple5
extend MethodDecorators
decorate MyDecorator4
def a_function
puts "Inside a_function"
end
end
Simple5.new.a_function("omg", "omg") {}
end.should have_stdout %{["omg", "omg"]\nBLOCK}
end
it "supports a simpler syntax" do
class MyDecorator5 < Decorator
def call(this, *args)
puts args.inspect
puts "BLOCK" if block_given?
end
end
lambda do
class Simple5
extend MethodDecorators
MyDecorator5()
def a_function
puts "Inside a_function"
end
end
Simple5.new.a_function("omg", "omg") {}
end.should have_stdout %{["omg", "omg"]\nBLOCK}
end
it "supports giving the decorator a name" do
module Omg
class MyDecorator6 < Decorator
decorator_name :surround_it
def call(this, *args)
puts args.inspect
puts "BLOCK" if block_given?
end
end
end
lambda do
class Simple6
extend MethodDecorators
surround_it
def a_function
puts "Inside a_function"
end
end
end
end
it "supports decorators with arguments" do
class ExtraParams
def initialize(klass, method, *args)
@method, @args = method, args
end
def call(this, *args)
@method.bind(this).call(*(args + @args))
end
end
class WithExtraParams
extend MethodDecorators
ExtraParams(:c, :d)
def function(a, b, c, d)
[a, b, c, d]
end
end
WithExtraParams.new.function(:a, :b).should == [:a, :b, :c, :d]
end
end