manager 0.0.0 → 0.1.0
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.
- checksums.yaml +4 -4
- data/CHART.html +1270 -0
- data/MANUAL.html +1252 -0
- data/bin/manager +43 -0
- data/examples/array/CHART.html +1376 -0
- data/examples/array/MANUAL.html +1126 -0
- data/examples/array/spec +3438 -0
- data/lib/manager.rb +528 -0
- data/lib/manager/annotation +96 -0
- data/lib/manager/input +189 -0
- data/lib/manager/js +257 -0
- data/lib/manager/refine_module +142 -0
- data/lib/manager/refine_object_mapping +143 -0
- data/lib/manager/refine_test +97 -0
- data/lib/manager/render +1228 -0
- data/lib/manager/spell_check +49 -0
- data/lib/manager/test +404 -0
- data/lib/manager/test_helper +9 -0
- data/license +9 -0
- data/manager.gemspec +21 -0
- data/spec/alternatives_implemented.png +0 -0
- data/spec/alternatives_unimplemented.png +0 -0
- data/spec/annotations.png +0 -0
- data/spec/benchmark_test.png +0 -0
- data/spec/citation.png +0 -0
- data/spec/code_block.png +0 -0
- data/spec/context_module.png +0 -0
- data/spec/documentation +1289 -0
- data/spec/external_link.png +0 -0
- data/spec/image.png +0 -0
- data/spec/list.png +0 -0
- data/spec/long.png +0 -0
- data/spec/main_and_object.png +0 -0
- data/spec/markup.png +0 -0
- data/spec/module_diagram.png +0 -0
- data/spec/navigation.png +0 -0
- data/spec/nested_section_headers.png +0 -0
- data/spec/ruby.png +0 -0
- data/spec/setup_teardown.png +0 -0
- data/spec/short.png +0 -0
- data/spec/signature.png +0 -0
- data/spec/spec +76 -0
- data/spec/spec_example.png +0 -0
- data/spec/table.png +0 -0
- data/spec/test_header.png +0 -0
- data/spec/test_non_unit_spec +184 -0
- data/spec/test_program +71 -0
- data/spec/test_unit_spec +790 -0
- data/spec/tutorial_1.png +0 -0
- data/spec/tutorial_2.png +0 -0
- data/spec/tutorial_3.png +0 -0
- data/spec/tutorial_4.png +0 -0
- data/spec/tutorial_5.png +0 -0
- data/spec/tutorial_6.png +0 -0
- data/spec/tutorial_7.png +0 -0
- data/spec/tutorial_8.png +0 -0
- data/spec/unambiguous_links.png +0 -0
- data/spec/unit_test_failure.png +0 -0
- data/spec/unit_test_raise.png +0 -0
- data/spec/unit_test_receiver.png +0 -0
- data/spec/unit_test_succeed.png +0 -0
- data/spec/unit_test_success.png +0 -0
- data/spec/unit_test_throw.png +0 -0
- data/spec/valid_heading.png +0 -0
- data/spec/with_expr.png +0 -0
- data/spec/without_expr.png +0 -0
- data/theme/2016a.css +670 -0
- data/theme/coderay_github.css +132 -0
- metadata +140 -11
@@ -0,0 +1,49 @@
|
|
1
|
+
#!ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright (c) 2016 sawa
|
5
|
+
|
6
|
+
module Manager::Spellcheck
|
7
|
+
def self.prepare
|
8
|
+
require "ffi/aspell"
|
9
|
+
rescue LoadError
|
10
|
+
raise "Configuration is set to use spell checking, which requires the `ffi-aspell` gem. "\
|
11
|
+
"Either install this gem, or turn off spell checking."
|
12
|
+
end
|
13
|
+
def self.list
|
14
|
+
prepare
|
15
|
+
speller = FFI::Aspell::Speller.new
|
16
|
+
speller.send(:available_dictionaries)
|
17
|
+
ensure
|
18
|
+
speller &.close
|
19
|
+
end
|
20
|
+
def self.language? language
|
21
|
+
prepare
|
22
|
+
speller = FFI::Aspell::Speller.new
|
23
|
+
speller.dictionary_available?(language)
|
24
|
+
ensure
|
25
|
+
speller &.close
|
26
|
+
end
|
27
|
+
def self.new language
|
28
|
+
prepare
|
29
|
+
FFI::Aspell::Speller.new(language)
|
30
|
+
end
|
31
|
+
def self.regex language
|
32
|
+
#!Make it multilingual
|
33
|
+
/[a-zA-Z][a-zA-Z']*[a-zA-Z]/
|
34
|
+
end
|
35
|
+
def self.filter language, words
|
36
|
+
raise "No dictionary given." unless language
|
37
|
+
begin
|
38
|
+
require "ffi/aspell"
|
39
|
+
speller = FFI::Aspell::Speller.new(language)
|
40
|
+
rescue LoadError
|
41
|
+
raise "Needs the `ffi-aspell` gem."
|
42
|
+
rescue ArgumentError
|
43
|
+
raise "Dictionary `#{language}` is not available."
|
44
|
+
end
|
45
|
+
words.reject{|w| speller.correct?(w)}
|
46
|
+
ensure
|
47
|
+
speller &.close
|
48
|
+
end
|
49
|
+
end
|
data/lib/manager/test
ADDED
@@ -0,0 +1,404 @@
|
|
1
|
+
#!ruby
|
2
|
+
#frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright (c) 2016 sawa
|
5
|
+
|
6
|
+
using Manager::ModuleRefinement
|
7
|
+
using Manager::TesterRefinement
|
8
|
+
|
9
|
+
class Manager::Binding
|
10
|
+
#!Wrapping in new module to make bare method definitions in `exp` (which would otherwise
|
11
|
+
# be evaluated in the `main` environment) to be evaluated locally. The methods will be
|
12
|
+
# defined in the singleton class of `@module`.
|
13
|
+
def initialize; @binding = Module.new.instance_eval{binding} end
|
14
|
+
def eval exp, f = nil, l = nil; @binding.eval(exp, *f, *l) end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Manager::ExprProc < Proc
|
18
|
+
def initialize exp; @exp = exp end
|
19
|
+
def inspect; @exp end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Manager::Setup
|
23
|
+
def initialize exp, bt
|
24
|
+
@exp, @f, @l = exp, bt.absolute_path, bt.lineno
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Manager::Expr
|
29
|
+
def initialize s, caller_locations
|
30
|
+
@s = s
|
31
|
+
@modifiers, @modifiers_args = [], []
|
32
|
+
bt = caller_locations.first
|
33
|
+
@location = [bt.absolute_path, bt.lineno]
|
34
|
+
end
|
35
|
+
def to_proc
|
36
|
+
# if @s.respond_to?(:to_proc)
|
37
|
+
# s = @s
|
38
|
+
# @s.to_proc.tap{|pr| def pr.inspect; s end}
|
39
|
+
# else
|
40
|
+
esc_exp = "\"#{@s.gsub('"', '\\"')}\""
|
41
|
+
::Kernel.eval("Manager::ExprProc.new(#{esc_exp})#@s", nil, *@location)
|
42
|
+
# end
|
43
|
+
end
|
44
|
+
def method_missing modifier, *args, **kargs, &pr
|
45
|
+
@modifiers.push(modifier)
|
46
|
+
@modifiers_args.push([args, kargs, pr])
|
47
|
+
self
|
48
|
+
end
|
49
|
+
def respond_to_missing? method, private = false
|
50
|
+
#! `respond_to_missing?` is called with `:to_hash` (and that is applied if positive) by Ruby
|
51
|
+
# when `expr` occurs as an argument. Need to override the `true` being returned due to
|
52
|
+
# `method_missing` being defined.
|
53
|
+
method == :to_hash ? false : super
|
54
|
+
end
|
55
|
+
def inspect
|
56
|
+
@exp ||= ::Manager::Render::Expression.new(@s).push(@modifiers, @modifiers_args)
|
57
|
+
@exp.to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Manager::UnitTest
|
62
|
+
def initialize referer, sample, feature_args
|
63
|
+
@referer, @sample, @feature_args = referer, sample, feature_args
|
64
|
+
@verifiers, @verifiers_args = [], []
|
65
|
+
end
|
66
|
+
def method_missing verifier, *args, **kargs, &pr
|
67
|
+
@verifiers.push(verifier)
|
68
|
+
@verifiers_args.push([args, kargs, pr])
|
69
|
+
self
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class Manager::Benchmark
|
74
|
+
def initialize sample, feature_args
|
75
|
+
@sample, @feature_args = sample, feature_args
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class Manager::Context
|
80
|
+
#! `All` cannot be made private constant because it is used in `Expr#tainted?`.
|
81
|
+
All, Alt = Object.new, Object.new
|
82
|
+
InterruptTest = Proc.new{
|
83
|
+
StdoutOrig.print "\b\b\b\b\b"
|
84
|
+
throw All, [:untestable, "Skipped by user.", nil]
|
85
|
+
}
|
86
|
+
attr_reader :modul, :type, :alts
|
87
|
+
def initialize
|
88
|
+
@master_binding = Manager::Binding.new
|
89
|
+
@setups = []
|
90
|
+
end
|
91
|
+
alias teardown initialize
|
92
|
+
public :teardown
|
93
|
+
def set_master_binding exp
|
94
|
+
@setups.push(exp)
|
95
|
+
end
|
96
|
+
def set_branched_binding
|
97
|
+
@branched_bindings = @alts.each_with_object({}) do
|
98
|
+
|alt, h| h[alt] = @binding = Manager::Binding.new
|
99
|
+
@setups.each{|exp| begin silent_evaluate(exp); rescue Exception; end}
|
100
|
+
end
|
101
|
+
@receivers, @returns, @exceptions, @throws = {}, {}, {}, {}
|
102
|
+
end
|
103
|
+
def new_feature modul, type, alts
|
104
|
+
@modul, @type, @alts = modul, type, alts
|
105
|
+
@receivers, @returns, @exceptions, @throws = {}, {}, {}, {}
|
106
|
+
end
|
107
|
+
def setup exp, f, l
|
108
|
+
set_master_binding(exp)
|
109
|
+
catch(All) do catch(Alt) do
|
110
|
+
@binding = @master_binding
|
111
|
+
begin
|
112
|
+
evaluate(exp, f, l)
|
113
|
+
throw Alt, nil
|
114
|
+
rescue Exception => e
|
115
|
+
throw All, [:bad_test, e, @output]
|
116
|
+
end
|
117
|
+
end end || [:success, nil, @output]
|
118
|
+
ensure
|
119
|
+
@output = nil
|
120
|
+
end
|
121
|
+
def unit_test sample, feature_args, referer, verifiers, verifiers_args
|
122
|
+
if referer.!
|
123
|
+
set_branched_binding
|
124
|
+
elsif @branched_bindings.!
|
125
|
+
return [:untestable, "Missing a preceding successful unit test.", nil]
|
126
|
+
end
|
127
|
+
catch(All) do begin
|
128
|
+
Signal.trap("INT", &InterruptTest)
|
129
|
+
@alts.each_with_object({}) do
|
130
|
+
|alt, h|
|
131
|
+
@binding = @branched_bindings[alt]
|
132
|
+
result = catch(Alt) do
|
133
|
+
exercise(alt, sample, feature_args) unless referer
|
134
|
+
first_verify(alt, referer, verifiers.first, verifiers_args.first) unless verifiers.empty?
|
135
|
+
verifiers.zip(verifiers_args).drop(1).each{|a| verify(*a)}
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
if result
|
139
|
+
h[alt] = result
|
140
|
+
elsif @verifee.!
|
141
|
+
h[alt] = [
|
142
|
+
:bug,
|
143
|
+
begin
|
144
|
+
_referer = referer || "return"
|
145
|
+
referer_value = instance_variable_get("@#{_referer}s")[alt]
|
146
|
+
"The receiver of verification `#{verifiers.last}` is "\
|
147
|
+
"`#{@prev_verifee.inspect}`."\
|
148
|
+
# "The receiver of verification `#{verifiers.last}` is "\
|
149
|
+
# "`#{@prev_verifee.inspect}`. "\
|
150
|
+
# "The arguments are: "\
|
151
|
+
# "#{@last_verifier_args[0].map{|e| "`#{e.inspect}`"}.join(", ")},"\
|
152
|
+
# " keyword arguments are: "\
|
153
|
+
# "#{@last_verifier_args[1].map{|k, v| "`#{e.inspect}`: `#{e.inspect}`"}.join(", ")},"\
|
154
|
+
# " proc is: `#{@last_verifier_args[2].inspect}`."
|
155
|
+
end,
|
156
|
+
@output,
|
157
|
+
]
|
158
|
+
end
|
159
|
+
@output = nil
|
160
|
+
end
|
161
|
+
.tap{|h| return h.empty? ? [:success, nil, @output] : h}
|
162
|
+
ensure
|
163
|
+
Signal.trap("INT", &Manager::InterruptionInactive)
|
164
|
+
end end
|
165
|
+
end
|
166
|
+
def exercise alt, sample, feature_args
|
167
|
+
@exceptions.delete(alt)
|
168
|
+
@throws.delete(alt)
|
169
|
+
case @type
|
170
|
+
when :constant
|
171
|
+
@receivers.delete(alt)
|
172
|
+
unless feature_args.nil?
|
173
|
+
throw All, [:bad_test, "Constant invocation cannot take an argument.", nil]
|
174
|
+
end
|
175
|
+
unless alt =~ /\A[A-Z]\w*\z/ and @modul.const_defined?(alt)
|
176
|
+
@returns.delete(alt)
|
177
|
+
throw All, [:untestable, "The constant is unimplemented.", nil]
|
178
|
+
else
|
179
|
+
@returns[alt] = @modul.const_get(alt.to_s)
|
180
|
+
end
|
181
|
+
when :instance, :singleton
|
182
|
+
begin
|
183
|
+
@receivers[alt] = sample.itself
|
184
|
+
rescue Exception => e
|
185
|
+
@returns.delete(alt)
|
186
|
+
throw All, [:bad_test, e, @output]
|
187
|
+
end
|
188
|
+
args, kargs, pr = itself_all(feature_args) || [[], {}, nil]
|
189
|
+
#! Not using `@receivers[alt].kind_of?` and not putting `@receivers[alt]` on the left side
|
190
|
+
# of `!=` since it may be `BasicObject` and undefined.
|
191
|
+
if (@type == :instance and (@modul === @receivers[alt]).!) or
|
192
|
+
(@type == :singleton and @modul != @receivers[alt])
|
193
|
+
@receivers.delete(alt)
|
194
|
+
throw All, [:untestable, "Receiver is not an instance of the appropriate class.", nil]
|
195
|
+
else
|
196
|
+
begin
|
197
|
+
if @receivers[alt].respond_to?(alt, true).!
|
198
|
+
@receivers.delete(alt)
|
199
|
+
throw All, [:untestable, "The method is unimplemented.", nil]
|
200
|
+
end
|
201
|
+
rescue NoMethodError
|
202
|
+
#! `BasicObject` not responding to `respond_to?`. Continue in this case.
|
203
|
+
end
|
204
|
+
end
|
205
|
+
begin
|
206
|
+
if kargs.empty? #! Ruby bug
|
207
|
+
@returns[alt] = in_terminal{@receivers[alt].__send__(alt, *args, &pr)}
|
208
|
+
else
|
209
|
+
@returns[alt] = in_terminal{@receivers[alt].__send__(alt, *args, **kargs, &pr)}
|
210
|
+
end
|
211
|
+
rescue UncaughtThrowError => e
|
212
|
+
@throws[alt] = e
|
213
|
+
@receivers.delete(alt)
|
214
|
+
rescue Exception => e
|
215
|
+
@exceptions[alt] = e
|
216
|
+
@receivers.delete(alt)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
ensure
|
220
|
+
@output = nil
|
221
|
+
end
|
222
|
+
def first_verify alt, referer, verifier, verifier_args
|
223
|
+
args, kargs, pr = itself_all(verifier_args)
|
224
|
+
if referer and @type == :constant
|
225
|
+
throw All, [:bad_test, "Cannot use `#{referer.upcase}` for a constant.", nil]
|
226
|
+
elsif referer and @receivers.key?(alt).!
|
227
|
+
throw All, [:untestable, "Missing a preceding successful unit test.", nil]
|
228
|
+
elsif verifier == :raise?
|
229
|
+
raise?(alt, verifier_args)
|
230
|
+
elsif @exceptions.key?(alt)
|
231
|
+
throw Alt, [:bug, @exceptions[alt], @output]
|
232
|
+
elsif verifier == :throw?
|
233
|
+
throw?(alt, verifier_args)
|
234
|
+
elsif @throws.key?(alt)
|
235
|
+
throw Alt, [:bug, @throws[alt], @output]
|
236
|
+
elsif verifier == :succeed?
|
237
|
+
@verifee = true
|
238
|
+
else
|
239
|
+
@prev_verifee = @verifee = (instance_variable_get("@#{referer || "return"}s"))[alt]
|
240
|
+
@last_verifier_args = [args, kargs, pr]
|
241
|
+
begin
|
242
|
+
if kargs.empty? #Ruby bug#
|
243
|
+
@verifee = in_terminal{@prev_verifee.__send__(verifier, *args, &pr)}
|
244
|
+
else
|
245
|
+
@verifee = in_terminal{@prev_verifee.__send__(verifier, *args, **kargs, &pr)}
|
246
|
+
end
|
247
|
+
rescue Exception => e
|
248
|
+
#! Unlike with `exercise`, exception is a bug here.
|
249
|
+
throw Alt, [:bug, e, @output]
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
def verify verifier, verifier_args
|
254
|
+
args, kargs, pr = itself_all(verifier_args)
|
255
|
+
@prev_verifee = @verifee
|
256
|
+
@last_verifier_args = [args, kargs, pr]
|
257
|
+
begin
|
258
|
+
if kargs.empty? #Ruby bug#
|
259
|
+
@verifee = in_terminal{@prev_verifee.__send__(verifier, *args, &pr)}
|
260
|
+
else
|
261
|
+
@verifee = in_terminal{@prev_verifee.__send__(verifier, *args, **kargs, &pr)}
|
262
|
+
end
|
263
|
+
rescue Exception => e
|
264
|
+
#! Unlike with `exercise`, exception is a bug here.
|
265
|
+
throw Alt, [:bug, e, @output]
|
266
|
+
end
|
267
|
+
end
|
268
|
+
def expr s, location, modifiers, modifiers_args
|
269
|
+
modifiers.zip(modifiers_args).inject(evaluate(s, *location)){|ret, a| _expr(ret, *a)}
|
270
|
+
end
|
271
|
+
def _expr ret, modifier, modifier_args
|
272
|
+
args, kargs, pr = itself_all(modifier_args)
|
273
|
+
if kargs.empty? #Ruby bug#
|
274
|
+
silent{ret.__send__(modifier, *args, &pr)}
|
275
|
+
else
|
276
|
+
silent{ret.__send__(modifier, *args, **kargs, &pr)}
|
277
|
+
end
|
278
|
+
end
|
279
|
+
def benchmark sample, feature_args
|
280
|
+
set_branched_binding
|
281
|
+
@binding = @branched_bindings.values.first
|
282
|
+
catch(All) do begin
|
283
|
+
Signal.trap("INT", &InterruptTest)
|
284
|
+
catch(Alt) do
|
285
|
+
begin
|
286
|
+
@receiver = sample.itself
|
287
|
+
rescue Exception => e
|
288
|
+
throw All, [:bad_test, e, nil]
|
289
|
+
end
|
290
|
+
args, kargs, pr = itself_all(feature_args) || [[], {}, nil]
|
291
|
+
job = ::Benchmark::IPS::Job.new(suite: false, quiet: true)
|
292
|
+
job.config(warmup: 0.1, time: 1)
|
293
|
+
Manager.context.alts.each do
|
294
|
+
|alt|
|
295
|
+
# job.item(alt, Manager::Render::Expression.new.to_s(@receiver.inspect, false, alt, args, kargs, pr))
|
296
|
+
#! By using `__send__`, private and protected methods can be tested as well as public ones.
|
297
|
+
if kargs.empty? #! Ruby bug
|
298
|
+
job.item(alt){@receiver.__send__(alt, *args, &pr)}
|
299
|
+
else
|
300
|
+
job.item(alt){@receiver.__send__(alt, *args, **kargs, &pr)}
|
301
|
+
end
|
302
|
+
end
|
303
|
+
begin
|
304
|
+
job.run_warmup
|
305
|
+
job.run
|
306
|
+
throw Alt, [:success, job.full_report.entries
|
307
|
+
.each.with_object({}){|rp, h| h[rp.label] = {ips: rp.ips, sd: rp.stddev_percentage}}]
|
308
|
+
rescue NoMethodError
|
309
|
+
throw All, [:untestable, "The method is unimplemented.", nil]
|
310
|
+
rescue Exception => e
|
311
|
+
throw Alt, [:bug, e, nil]
|
312
|
+
end
|
313
|
+
end
|
314
|
+
ensure
|
315
|
+
Signal.trap("INT", &Manager::InterruptionInactive)
|
316
|
+
end end
|
317
|
+
ensure
|
318
|
+
@output = nil
|
319
|
+
end
|
320
|
+
def raise? alt, verifier_args
|
321
|
+
exception_class = verifier_args[0][0] || ::StandardError
|
322
|
+
include_subclass = verifier_args[0][1]
|
323
|
+
include_subclass = true if include_subclass.nil?
|
324
|
+
verifier = include_subclass ? :kind_of? : :instance_of?
|
325
|
+
kargs = verifier_args[1]
|
326
|
+
if @exceptions.key?(alt).!
|
327
|
+
throw Alt, [:bug, "Did not raise an exception.", @output]
|
328
|
+
elsif @exceptions[alt].send(verifier, exception_class) and
|
329
|
+
(kargs.key?(:message).! or kargs[:message] === @exceptions[alt].message)
|
330
|
+
@verifee = true
|
331
|
+
else
|
332
|
+
throw Alt, [:bug, @exceptions[alt], @output]
|
333
|
+
end
|
334
|
+
end
|
335
|
+
def throw? alt, verifier_args
|
336
|
+
tag = verifier_args[0][0]
|
337
|
+
kargs = verifier_args[1]
|
338
|
+
if @throws.key?(alt).!
|
339
|
+
throw Alt, [:bug, "Did not throw.", @output]
|
340
|
+
elsif @throws[alt].tag == tag and
|
341
|
+
(kargs.key?(:value).! or kargs[:value] == @throws[alt].value)
|
342
|
+
@verifee = true
|
343
|
+
else
|
344
|
+
throw Alt, [:bug, "Threw tag `#{@throws[alt].tag.inspect}`"\
|
345
|
+
" with value `#{@throws[alt].value.inspect}`.", @output]
|
346
|
+
end
|
347
|
+
end
|
348
|
+
def itself_all arg_suite
|
349
|
+
return nil unless arg_suite
|
350
|
+
args, kargs, pr = arg_suite
|
351
|
+
#! Cannot use symbol to proc because of refinement
|
352
|
+
[args.map{|e| e.itself}, kargs.dup.each{|k, e| kargs[k] = e.itself}, pr.itself]
|
353
|
+
rescue Exception => e
|
354
|
+
throw All, [:bad_test, e, @output]
|
355
|
+
ensure
|
356
|
+
@output = nil
|
357
|
+
end
|
358
|
+
def syntax_check_all sample, *argument_suites
|
359
|
+
old, $stderr = $stderr, StringIO.new
|
360
|
+
catch(All) do
|
361
|
+
#! The result of `tainted?` is insignificant. Its only pupose is to throw `:bad_test`
|
362
|
+
# when the object is a `Manager::Expr` instance that has illicit string.
|
363
|
+
sample.tainted?
|
364
|
+
argument_suites.each do
|
365
|
+
|argument_suite|
|
366
|
+
next unless argument_suite
|
367
|
+
args, kargs, pr = argument_suite
|
368
|
+
#! symbol to proc cannot be used becuase `tainted?` is a refinement for
|
369
|
+
# `Manager::Expr`.
|
370
|
+
args.each{|obj| obj.tainted?}
|
371
|
+
kargs.each_value{|obj| obj.tainted?}
|
372
|
+
end
|
373
|
+
nil
|
374
|
+
end
|
375
|
+
ensure
|
376
|
+
$stderr, @output = old, nil
|
377
|
+
end
|
378
|
+
def evaluate exp, f = nil, l = nil; in_terminal{@binding.eval(exp, f, l)} end
|
379
|
+
def silent_evaluate exp, f = nil, l = nil; silent{@binding.eval(exp, f, l)} end
|
380
|
+
StdoutOrig, StderrOrig = $stdout, $stderr
|
381
|
+
Terminal = StringIO.new
|
382
|
+
def in_terminal
|
383
|
+
return yield if Manager.config(:debug)
|
384
|
+
$stdout = $stderr = Terminal
|
385
|
+
yield
|
386
|
+
ensure
|
387
|
+
@output = (Terminal.string unless Terminal.length.zero?)
|
388
|
+
$stdout, $stderr = StdoutOrig, StderrOrig
|
389
|
+
Terminal.reopen
|
390
|
+
end
|
391
|
+
def silent
|
392
|
+
return yield if Manager.config(:debug)
|
393
|
+
stdout_old = $stdout.dup
|
394
|
+
stderr_old = $stderr.dup
|
395
|
+
$stderr.reopen(IO::NULL)
|
396
|
+
$stdout.reopen(IO::NULL)
|
397
|
+
yield
|
398
|
+
ensure
|
399
|
+
$stdout.flush
|
400
|
+
$stderr.flush
|
401
|
+
$stdout.reopen(stdout_old)
|
402
|
+
$stderr.reopen(stderr_old)
|
403
|
+
end
|
404
|
+
end
|