BMorearty-looksee 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,425 @@
1
+ require 'spec_helper'
2
+
3
+ describe Looksee do
4
+ include TemporaryClasses
5
+
6
+ describe ".lookup_modules" do
7
+ #
8
+ # Wrapper for the method under test.
9
+ #
10
+ # Filter out modules which are hard to test against, and returns
11
+ # the list of module names. #inspect strings are used for names
12
+ # of singleton classes, since they have no name.
13
+ #
14
+ def filtered_lookup_modules(object)
15
+ result = Looksee.lookup_modules(object)
16
+ # Singleton classes have no name ('' in <1.9, nil in 1.9+). Use
17
+ # the inspect string instead.
18
+ names = result.map{|mod| mod.name.to_s.empty? ? mod.inspect : mod.name}
19
+ names.select{|name| deterministic_module_name?(name)}
20
+ end
21
+
22
+ #
23
+ # Return true if the given module name is of a module we can test
24
+ # for.
25
+ #
26
+ # This excludes ruby version dependent modules, and modules tossed
27
+ # into the hierarchy by testing frameworks.
28
+ #
29
+ def deterministic_module_name?(name)
30
+ junk_patterns = [
31
+ # pollution from testing libraries
32
+ 'Mocha', 'Spec',
33
+ # RSpec adds this under ruby 1.8.6
34
+ 'InstanceExecHelper',
35
+ # only in ruby 1.9
36
+ 'BasicObject',
37
+ # something pulls this in under ruby 1.9
38
+ 'PP',
39
+ ]
40
+
41
+ # Singleton classes of junk are junk.
42
+ while name =~ /\A#<Class:(.*)>\z/
43
+ name = $1
44
+ end
45
+
46
+ name !~ /\A(#{junk_patterns.join('|')})/
47
+ end
48
+
49
+ it "should contain an entry for each module in the object's lookup path" do
50
+ temporary_module :Mod1
51
+ temporary_module :Mod2
52
+ temporary_class :Base
53
+ temporary_class :Derived, :superclass => Base do
54
+ include Mod1
55
+ include Mod2
56
+ end
57
+ filtered_lookup_modules(Derived.new) == %w'Derived Mod2 Mod1 Base Object Kernel'
58
+ end
59
+
60
+ it "contain an entry for the object's singleton class if it exists" do
61
+ object = Object.new
62
+ object.singleton_class
63
+
64
+ result = filtered_lookup_modules(object)
65
+ result.shift.should =~ /\A#<Class:\#<Object:0x[\da-f]+>>\z/
66
+ result.should == %w"Object Kernel"
67
+ end
68
+
69
+ it "should contain entries for singleton classes of all ancestors for class objects" do
70
+ temporary_class :C
71
+ result = filtered_lookup_modules(C)
72
+ result.should == %w'#<Class:C> #<Class:Object> Class Module Object Kernel'
73
+ end
74
+
75
+ it "should work for immediate objects" do
76
+ filtered_lookup_modules(1).first.should == 'Fixnum'
77
+ end
78
+ end
79
+
80
+ describe ".lookup_path" do
81
+ it "should return a LookupPath object" do
82
+ object = Object.new
83
+ lookup_path = Looksee.lookup_path(object)
84
+ lookup_path.should be_a(Looksee::LookupPath)
85
+ end
86
+
87
+ it "should return a LookupPath object for the given object" do
88
+ object = Object.new
89
+ Looksee.stubs(:default_lookup_path_options).returns({})
90
+ Looksee::LookupPath.expects(:for).with(object, {})
91
+ lookup_path = Looksee.lookup_path(object)
92
+ end
93
+
94
+ it "should allow symbol arguments as shortcuts for true options" do
95
+ object = Object.new
96
+ Looksee.stubs(:default_lookup_path_options).returns({})
97
+ Looksee::LookupPath.expects(:for).with(object, {:public => true, :overridden => true})
98
+ Looksee.lookup_path(object, :public, :overridden)
99
+ end
100
+
101
+ it "should merge the default options, with the symbols, and the options hash" do
102
+ object = Object.new
103
+ Looksee.stubs(:default_lookup_path_options).returns({:public => false, :protected => false, :private => false})
104
+ Looksee::LookupPath.expects(:for).with(object, {:public => false, :protected => true, :private => false})
105
+ Looksee.lookup_path(object, :protected, :private, :private => false)
106
+ end
107
+ end
108
+
109
+ describe "internal instance methods:" do
110
+ def self.target_method(name)
111
+ define_method(:target_method){name}
112
+ end
113
+
114
+ def self.it_should_list_methods_with_visibility(visibility)
115
+ it "should return the list of #{visibility} instance methods defined directly on a class" do
116
+ temporary_class :C
117
+ replace_methods C, visibility => [:one, :two]
118
+ Looksee.send(target_method, C).to_set.should == Set[:one, :two]
119
+ end
120
+
121
+ it "should return the list of #{visibility} instance methods defined directly on a module" do
122
+ temporary_module :M
123
+ replace_methods M, visibility => [:one, :two]
124
+ Looksee.send(target_method, M).to_set.should == Set[:one, :two]
125
+ end
126
+
127
+ it "should return the list of #{visibility} instance methods defined directly on a singleton class" do
128
+ temporary_class :C
129
+ c = C.new
130
+ replace_methods c.singleton_class, visibility => [:one, :two]
131
+ Looksee.send(target_method, c.singleton_class).to_set.should == Set[:one, :two]
132
+ end
133
+
134
+ it "should return the list of #{visibility} instance methods defined directly on a class' singleton class" do
135
+ temporary_class :C
136
+ replace_methods C.singleton_class, visibility => [:one, :two], :class_singleton => true
137
+ Looksee.send(target_method, C.singleton_class).to_set.should == Set[:one, :two]
138
+ end
139
+
140
+ # Worth checking as ruby keeps undef'd methods in method tables.
141
+ it "should not return undefined methods" do
142
+ temporary_class :C
143
+ replace_methods C, visibility => [:removed]
144
+ C.send(:undef_method, :removed)
145
+ Looksee.send(target_method, C).to_set.should == Set[]
146
+ end
147
+ end
148
+
149
+ def self.it_should_not_list_methods_with_visibility(visibility1, visibility2)
150
+ it "should not return any #{visibility1} or #{visibility2} instance methods" do
151
+ temporary_class :C
152
+ replace_methods C, {visibility1 => [:a], visibility2 => [:b]}
153
+ Looksee.send(target_method, C).to_set.should == Set[]
154
+ end
155
+ end
156
+
157
+ describe ".internal_public_instance_methods" do
158
+ target_method :internal_public_instance_methods
159
+ it_should_list_methods_with_visibility :public
160
+ it_should_not_list_methods_with_visibility :private, :protected
161
+ end
162
+
163
+ describe ".internal_protected_instance_methods" do
164
+ target_method :internal_protected_instance_methods
165
+ it_should_list_methods_with_visibility :protected
166
+ it_should_not_list_methods_with_visibility :public, :private
167
+ end
168
+
169
+ describe ".internal_private_instance_methods" do
170
+ target_method :internal_private_instance_methods
171
+ it_should_list_methods_with_visibility :private
172
+ it_should_not_list_methods_with_visibility :public, :protected
173
+ end
174
+
175
+ describe ".internal_undefined_instance_methods" do
176
+ it "should return the list of undefined instance methods directly on a class" do
177
+ temporary_class :C
178
+ C.send(:define_method, :f){}
179
+ C.send(:undef_method, :f)
180
+ Looksee.internal_undefined_instance_methods(C).should == [:f]
181
+ end
182
+
183
+ it "should return the list of undefined instance methods directly on a module" do
184
+ temporary_module :M
185
+ M.send(:define_method, :f){}
186
+ M.send(:undef_method, :f)
187
+ Looksee.internal_undefined_instance_methods(M).should == [:f]
188
+ end
189
+
190
+ it "should return the list of undefined instance methods directly on a singleton class" do
191
+ temporary_class :C
192
+ c = C.new
193
+ c.singleton_class.send(:define_method, :f){}
194
+ c.singleton_class.send(:undef_method, :f)
195
+ Looksee.internal_undefined_instance_methods(c.singleton_class).should == [:f]
196
+ end
197
+
198
+ it "should return the list of undefined instance methods directly on a class' singleton class" do
199
+ temporary_class :C
200
+ C.singleton_class.send(:define_method, :f){}
201
+ C.singleton_class.send(:undef_method, :f)
202
+ Looksee.internal_undefined_instance_methods(C.singleton_class).should == [:f]
203
+ end
204
+
205
+ it "should not return defined methods" do
206
+ temporary_class :C
207
+ C.send(:define_method, :f){}
208
+ Looksee.internal_undefined_instance_methods(C).should == []
209
+ end
210
+
211
+ it "should not return removed methods" do
212
+ temporary_class :C
213
+ C.send(:define_method, :f){}
214
+ C.send(:remove_method, :f)
215
+ Looksee.internal_undefined_instance_methods(C).should == []
216
+ end
217
+ end
218
+ end
219
+ end
220
+
221
+ describe Looksee::LookupPath do
222
+ include TemporaryClasses
223
+
224
+ def stub_methods(mod, public, protected, private, undefined)
225
+ Looksee.stubs(:internal_public_instance_methods ).with(mod).returns(public)
226
+ Looksee.stubs(:internal_protected_instance_methods).with(mod).returns(protected)
227
+ Looksee.stubs(:internal_private_instance_methods ).with(mod).returns(private)
228
+ Looksee.stubs(:internal_undefined_instance_methods).with(mod).returns(undefined)
229
+ end
230
+
231
+ describe "#entries" do
232
+ it "should contain an entry for each module in the object's lookup path" do
233
+ object = Object.new
234
+ temporary_class :C
235
+ temporary_class :D
236
+ Looksee.stubs(:lookup_modules).with(object).returns([C, D])
237
+ Looksee::LookupPath.for(object).entries.map{|entry| entry.module_name}.should == %w'C D'
238
+ end
239
+ end
240
+
241
+ describe "grep" do
242
+ it "should only include methods matching the given regexp" do
243
+ temporary_class :C
244
+ temporary_class :D
245
+ stub_methods(C, ['axbyc', 'xy'], [], [], [])
246
+ stub_methods(D, ['axbyc', 'xdy'], [], [], [])
247
+ object = Object.new
248
+ Looksee.stubs(:lookup_modules).with(object).returns([C, D])
249
+ lookup_path = Looksee::LookupPath.for(object, :public => true, :overridden => true).grep(/x.y/)
250
+ lookup_path.entries.map{|entry| entry.module_name}.should == %w'C D'
251
+ lookup_path.entries[0].methods.to_set.should == Set['axbyc']
252
+ lookup_path.entries[1].methods.to_set.should == Set['axbyc', 'xdy']
253
+ end
254
+
255
+ it "should only include methods including the given string" do
256
+ temporary_class :C
257
+ temporary_class :D
258
+ stub_methods(C, ['axxa', 'axa'], [], [], [])
259
+ stub_methods(D, ['bxxb', 'axxa'], [], [], [])
260
+ object = Object.new
261
+ Looksee.stubs(:lookup_modules).with(object).returns([C, D])
262
+ lookup_path = Looksee::LookupPath.for(object, :public => true, :overridden => true).grep('xx')
263
+ lookup_path.entries.map{|entry| entry.module_name}.should == %w'C D'
264
+ lookup_path.entries[0].methods.to_set.should == Set['axxa']
265
+ lookup_path.entries[1].methods.to_set.should == Set['axxa', 'bxxb']
266
+ end
267
+ end
268
+
269
+ describe "#inspect" do
270
+ before do
271
+ Looksee.stubs(:default_lookup_path_options).returns({})
272
+ end
273
+
274
+ before do
275
+ Looksee.stubs(:styles).returns(Hash.new{'%s'})
276
+ end
277
+
278
+ describe "contents" do
279
+ before do
280
+ temporary_module :M
281
+ temporary_class :C do
282
+ include M
283
+ end
284
+ @object = Object.new
285
+ Looksee.stubs(:lookup_modules).with(@object).returns([C, M])
286
+ stub_methods(C, ['public1', 'public2'], ['protected1', 'protected2'], ['private1', 'private2'], ['undefined1', 'undefined2'])
287
+ stub_methods(M, ['public1', 'public2'], ['protected1', 'protected2'], ['private1', 'private2'], ['undefined1', 'undefined2'])
288
+ end
289
+
290
+ it "should show only public instance methods when only public methods are requested" do
291
+ lookup_path = Looksee::LookupPath.for(@object, :public => true, :overridden => true)
292
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
293
+ |C
294
+ | public1 public2
295
+ |M
296
+ | public1 public2
297
+ EOS
298
+ end
299
+
300
+ it "should show modules and protected instance methods when only protected methods are requested" do
301
+ lookup_path = Looksee::LookupPath.for(@object, :protected => true, :overridden => true)
302
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
303
+ |C
304
+ | protected1 protected2
305
+ |M
306
+ | protected1 protected2
307
+ EOS
308
+ end
309
+
310
+ it "should show modules and private instance methods when only private methods are requested" do
311
+ lookup_path = Looksee::LookupPath.for(@object, :private => true, :overridden => true)
312
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
313
+ |C
314
+ | private1 private2
315
+ |M
316
+ | private1 private2
317
+ EOS
318
+ end
319
+
320
+ it "should show modules and undefined instance methods when only undefined methods are requested" do
321
+ lookup_path = Looksee::LookupPath.for(@object, :undefined => true, :overridden => true)
322
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
323
+ |C
324
+ | undefined1 undefined2
325
+ |M
326
+ | undefined1 undefined2
327
+ EOS
328
+ end
329
+
330
+ it "should show modules with public and private instance methods when only public and private methods are requested" do
331
+ lookup_path = Looksee::LookupPath.for(@object, :public => true, :private => true, :overridden => true)
332
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
333
+ |C
334
+ | private1 private2 public1 public2
335
+ |M
336
+ | private1 private2 public1 public2
337
+ EOS
338
+ end
339
+
340
+ it "should show singleton classes as class names in brackets" do
341
+ Looksee.stubs(:lookup_modules).with(C).returns([C.singleton_class])
342
+ stub_methods(C.singleton_class, ['public1', 'public2'], [], [], [])
343
+ lookup_path = Looksee::LookupPath.for(C, :public => true)
344
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
345
+ |[C]
346
+ | public1 public2
347
+ EOS
348
+ end
349
+
350
+ it "should handle singleton classes of singleton classes correctly" do
351
+ Looksee.stubs(:lookup_modules).with(C.singleton_class).returns([C.singleton_class.singleton_class])
352
+ stub_methods(C.singleton_class.singleton_class, ['public1', 'public2'], [], [], [])
353
+ lookup_path = Looksee::LookupPath.for(C.singleton_class, :public => true)
354
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
355
+ |[[C]]
356
+ | public1 public2
357
+ EOS
358
+ end
359
+
360
+ it "should not show any blank lines if a module has no methods" do
361
+ stub_methods(C, [], [], [], [])
362
+ lookup_path = Looksee::LookupPath.for(@object, :public => true, :overridden => true)
363
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
364
+ |C
365
+ |M
366
+ | public1 public2
367
+ EOS
368
+ end
369
+ end
370
+
371
+ describe "styles" do
372
+ before do
373
+ styles = {
374
+ :module => "`%s'",
375
+ :public => "{%s}",
376
+ :protected => "[%s]",
377
+ :private => "<%s>",
378
+ :undefined => "~%s~",
379
+ :overridden => "(%s)",
380
+ }
381
+ Looksee.stubs(:styles).returns(styles)
382
+ end
383
+
384
+ it "should delimit each word with the configured delimiters" do
385
+ temporary_class :C
386
+ Looksee.stubs(:lookup_modules).returns([C])
387
+ stub_methods(C, ['public'], ['protected'], ['private'], ['undefined'])
388
+ lookup_path = Looksee::LookupPath.for(Object.new, :public => true, :protected => true, :private => true, :undefined => true, :overridden => true)
389
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
390
+ |\`C\'
391
+ | <private> [protected] {public} ~undefined~
392
+ EOS
393
+ end
394
+ end
395
+
396
+ describe "layout" do
397
+ it "should wrap method lists at the configured number of columns, sorting vertically first, and aligning into a grid" do
398
+ temporary_class :C
399
+ Looksee.stubs(:lookup_modules).returns([C])
400
+ stub_methods(C, %w'aa b c dd ee f g hh i', [], [], [])
401
+ lookup_path = Looksee::LookupPath.for(Object.new, :public => true)
402
+ lookup_path.inspect(:width => 20).should == <<-EOS.demargin.chomp
403
+ |C
404
+ | aa c ee g i
405
+ | b dd f hh
406
+ EOS
407
+ end
408
+
409
+ it "should lay the methods of each module out independently" do
410
+ temporary_class :A
411
+ temporary_class :B
412
+ Looksee.stubs(:lookup_modules).returns([A, B])
413
+ stub_methods(A, ['a', 'long_long_long_long_name'], [], [], [])
414
+ stub_methods(B, ['long_long_long', 'short'], [], [], [])
415
+ lookup_path = Looksee::LookupPath.for(Object.new, :public => true)
416
+ lookup_path.inspect.should == <<-EOS.demargin.chomp
417
+ |A
418
+ | a long_long_long_long_name
419
+ |B
420
+ | long_long_long short
421
+ EOS
422
+ end
423
+ end
424
+ end
425
+ end
@@ -0,0 +1,139 @@
1
+ require 'spec'
2
+ require 'mocha'
3
+ require 'looksee'
4
+
5
+ require 'rbconfig'
6
+ require 'set'
7
+
8
+ Spec::Runner.configure do |config|
9
+ config.mock_with :mocha
10
+ end
11
+
12
+ class Object
13
+ #
14
+ # Return this object's singleton class.
15
+ #
16
+ def singleton_class
17
+ class << self; self; end
18
+ end
19
+
20
+ #
21
+ # Return true if the given object include?-s this object.
22
+ #
23
+ def in?(object)
24
+ object.include?(self)
25
+ end
26
+ end
27
+
28
+ class String
29
+ #
30
+ # Remove a left margin delimited by '|'-characters. Useful for
31
+ # heredocs:
32
+ #
33
+ def demargin
34
+ gsub(/^ *\|/, '')
35
+ end
36
+ end
37
+
38
+ #
39
+ # Include these in example groups to add facilities to create
40
+ # temporary classes and modules, which are swept up at the end of each
41
+ # example.
42
+ #
43
+ # Call make_class('ClassName') or make_module('ModuleName') to create
44
+ # a temporary class, then access them with plain constants (ClassName,
45
+ # ModuleName).
46
+ #
47
+ module TemporaryClasses
48
+ def self.included(mod)
49
+ mod.before do
50
+ @temporary_modules = []
51
+ end
52
+
53
+ mod.after do
54
+ @temporary_modules.each do |mod|
55
+ Object.send :remove_const, mod.name
56
+ end
57
+ end
58
+ end
59
+
60
+ #
61
+ # Create a temporary class with the given name and superclass.
62
+ #
63
+ def temporary_class(name, options={}, &block)
64
+ klass = Class.new(options[:superclass] || Object)
65
+ Object.const_set(name, klass)
66
+ klass.class_eval(&block) if block
67
+ @temporary_modules << klass
68
+ klass
69
+ end
70
+
71
+ #
72
+ # Create a temporary module with the given name.
73
+ #
74
+ def temporary_module(name, &block)
75
+ mod = Module.new
76
+ Object.const_set(name, mod)
77
+ mod.class_eval(&block) if block
78
+ @temporary_modules << mod
79
+ mod
80
+ end
81
+
82
+ #
83
+ # Remove all methods defined exactly on the given module.
84
+ #
85
+ # As Ruby's reflection on singleton classes of classes isn't quite
86
+ # adequate, you need to provide a :class_singleton option when such
87
+ # a class is given.
88
+ #
89
+ def remove_methods(mod, opts={})
90
+ names = all_instance_methods(mod)
91
+
92
+ # all_instance_methods can't get just the methods on a class
93
+ # singleton class. Filter out superclass methods here.
94
+ if opts[:class_singleton]
95
+ klass = ObjectSpace.each_object(mod){|klass| break klass}
96
+ names -= all_instance_methods(klass.superclass.singleton_class)
97
+ end
98
+
99
+ names.sort_by{|name| name.in?([:remove_method, :send]) ? 1 : 0}.flatten
100
+ names.each do |name|
101
+ mod.send :remove_method, name
102
+ end
103
+ end
104
+
105
+ #
106
+ # Replace the methods of the given module with those named.
107
+ #
108
+ # +methods+ is a hash of visibilities to names.
109
+ #
110
+ # As Ruby's reflection on singleton classes of classes isn't quite
111
+ # adequate, you need to provide a :class_singleton option when such
112
+ # a class is given.
113
+ #
114
+ # e.g.:
115
+ #
116
+ # replace_methods MyClass, :public => [:a, :b]
117
+ #
118
+ def replace_methods(mod, options={})
119
+ remove_methods(mod, options)
120
+ mod.module_eval do
121
+ [:public, :protected, :private].each do |visibility|
122
+ Array(options[visibility]).each do |name|
123
+ define_method(name){}
124
+ send visibility, name
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ private # ---------------------------------------------------------
131
+
132
+ def all_instance_methods(mod)
133
+ names =
134
+ mod.public_instance_methods(false) +
135
+ mod.protected_instance_methods(false) +
136
+ mod.private_instance_methods(false)
137
+ names.map{|name| name.to_sym} # they're strings in ruby <1.9
138
+ end
139
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+ gem 'wirble' # die if wirble unavailable
3
+
4
+ describe Looksee::WirbleCompatibility do
5
+ describe "when looksee is loaded" do
6
+ #
7
+ # Run the given ruby string, and return the standard output.
8
+ #
9
+ def init_irb_with(code)
10
+ code = <<-EOS.demargin.gsub(/\n/, ';')
11
+ |#{code}
12
+ |#{stubbing_code}
13
+ |lp Object.new
14
+ EOS
15
+ irb = File.join Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'].sub(/ruby/, 'irb')
16
+ lib_dir = File.expand_path('lib')
17
+ # irb hangs when using readline without a tty
18
+ output = IO.popen("#{irb} -f --noreadline --noprompt --noverbose -I#{lib_dir} 2>&1", 'r+') do |io|
19
+ io.puts code
20
+ io.flush
21
+ io.close_write
22
+ io.read
23
+ end
24
+ end
25
+
26
+ def stubbing_code
27
+ <<-EOS.demargin
28
+ |C = Class.new
29
+ |
30
+ |Looksee.styles = Hash.new{'%s'}
31
+ |Looksee.styles[:public] = "\\e[1;32m%s\\e[0m"
32
+ |
33
+ |def Looksee.lookup_modules(object)
34
+ | [C]
35
+ |end
36
+ |def Looksee.internal_public_instance_methods(mod)
37
+ | [:a]
38
+ |end
39
+ |def Looksee.internal_protected_instance_methods(mod)
40
+ | []
41
+ |end
42
+ |def Looksee.internal_private_instance_methods(mod)
43
+ | []
44
+ |end
45
+ EOS
46
+ end
47
+
48
+ it "should work if wirble is not loaded" do
49
+ output = init_irb_with(<<-EOS.demargin)
50
+ |require 'irb'
51
+ |require 'looksee/shortcuts'
52
+ |require 'wirble'
53
+ |Wirble.init
54
+ |Wirble.colorize
55
+ EOS
56
+ output.should == <<-EOS.demargin
57
+ |C
58
+ | \e[1;32ma\e[0m
59
+ EOS
60
+ end
61
+
62
+ it "should work if wirble is loaded, but not initialized" do
63
+ output = init_irb_with(<<-EOS.demargin)
64
+ |require 'irb'
65
+ |require 'wirble'
66
+ |require 'looksee/shortcuts'
67
+ |Wirble.init
68
+ |Wirble.colorize
69
+ EOS
70
+ output.should == <<-EOS.demargin
71
+ |C
72
+ | \e[1;32ma\e[0m
73
+ EOS
74
+ end
75
+
76
+ it "should work if wirble is loaded and initialized, but colorizing is off" do
77
+ output = init_irb_with(<<-EOS.demargin)
78
+ |require 'irb'
79
+ |require 'wirble'
80
+ |Wirble.init
81
+ |require 'looksee/shortcuts'
82
+ |Wirble.colorize
83
+ EOS
84
+ output.should == <<-EOS.demargin
85
+ |C
86
+ | \e[1;32ma\e[0m
87
+ EOS
88
+ end
89
+
90
+ it "should work if wirble is loaded, initialized, and colorizing is on" do
91
+ output = init_irb_with(<<-EOS.demargin)
92
+ |require 'irb'
93
+ |require 'wirble'
94
+ |Wirble.init
95
+ |Wirble.colorize
96
+ |require 'looksee/shortcuts'
97
+ EOS
98
+ output.should == <<-EOS.demargin
99
+ |C
100
+ | \e[1;32ma\e[0m
101
+ EOS
102
+ end
103
+
104
+ it "should work if wirble colorizing is enabled twice" do
105
+ output = init_irb_with(<<-EOS.demargin)
106
+ |require 'irb'
107
+ |require 'looksee/shortcuts'
108
+ |require 'wirble'
109
+ |Wirble.init
110
+ |Wirble.colorize
111
+ |Wirble.colorize
112
+ EOS
113
+ output.should == <<-EOS.demargin
114
+ |C
115
+ | \e[1;32ma\e[0m
116
+ EOS
117
+ end
118
+ end
119
+ end