pry 0.9.11.4 → 0.9.12pre1
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.
- data/.travis.yml +2 -0
- data/Rakefile +4 -0
- data/lib/pry.rb +1 -1
- data/lib/pry/cli.rb +14 -8
- data/lib/pry/code.rb +3 -3
- data/lib/pry/command.rb +20 -5
- data/lib/pry/command_set.rb +3 -3
- data/lib/pry/commands.rb +1 -1
- data/lib/pry/commands/disabled_commands.rb +2 -0
- data/lib/pry/commands/ls.rb +1 -2
- data/lib/pry/commands/reload_code.rb +8 -1
- data/lib/pry/commands/show_info.rb +27 -4
- data/lib/pry/commands/show_source.rb +2 -1
- data/lib/pry/commands/whereami.rb +87 -19
- data/lib/pry/completion.rb +7 -4
- data/lib/pry/helpers/base_helpers.rb +5 -2
- data/lib/pry/helpers/command_helpers.rb +3 -1
- data/lib/pry/helpers/documentation_helpers.rb +18 -7
- data/lib/pry/helpers/table.rb +4 -4
- data/lib/pry/indent.rb +2 -7
- data/lib/pry/method.rb +89 -129
- data/lib/pry/method/disowned.rb +53 -0
- data/lib/pry/method/weird_method_locator.rb +186 -0
- data/lib/pry/module_candidate.rb +3 -3
- data/lib/pry/pager.rb +13 -11
- data/lib/pry/pry_class.rb +10 -3
- data/lib/pry/terminal.rb +73 -0
- data/lib/pry/version.rb +1 -1
- data/lib/pry/wrapped_module.rb +51 -1
- data/spec/command_helpers_spec.rb +21 -1
- data/spec/commands/ls_spec.rb +4 -0
- data/spec/commands/show_doc_spec.rb +28 -28
- data/spec/commands/show_source_spec.rb +70 -22
- data/spec/commands/whereami_spec.rb +60 -11
- data/spec/documentation_helper_spec.rb +73 -0
- data/spec/fixtures/whereami_helper.rb +6 -0
- data/spec/helpers/table_spec.rb +19 -0
- data/spec/method_spec.rb +24 -7
- metadata +13 -7
- data/lib/pry/commands/deprecated_commands.rb +0 -2
- data/lib/pry/terminal_info.rb +0 -48
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
class Pry
|
|
2
|
+
class Method
|
|
3
|
+
|
|
4
|
+
# This class is responsible for locating the *real* `Pry::Method`
|
|
5
|
+
# object captured by a binding.
|
|
6
|
+
#
|
|
7
|
+
# Given a `Binding` from inside a method and a 'seed' Pry::Method object,
|
|
8
|
+
# there are primarily two situations where the seed method doesn't match
|
|
9
|
+
# the Binding:
|
|
10
|
+
# 1. The Pry::Method is from a subclass 2. The Pry::Method represents a method of the same name
|
|
11
|
+
# while the original was renamed to something else. For 1. we
|
|
12
|
+
# search vertically up the inheritance chain,
|
|
13
|
+
# and for 2. we search laterally along the object's method table.
|
|
14
|
+
#
|
|
15
|
+
# When we locate the method that matches the Binding we wrap it in
|
|
16
|
+
# Pry::Method and return it, or return nil if we fail.
|
|
17
|
+
class WeirdMethodLocator
|
|
18
|
+
class << self
|
|
19
|
+
|
|
20
|
+
# Whether the given method object matches the associated binding.
|
|
21
|
+
# If the method object does not match the binding, then it's
|
|
22
|
+
# most likely not the method captured by the binding, and we
|
|
23
|
+
# must commence a search.
|
|
24
|
+
#
|
|
25
|
+
# @param [Pry::Method] method
|
|
26
|
+
# @param [Binding] b
|
|
27
|
+
# @return [Boolean]
|
|
28
|
+
def normal_method?(method, b)
|
|
29
|
+
method && (method.source_file && method.source_range rescue false) &&
|
|
30
|
+
File.expand_path(method.source_file) == File.expand_path(b.eval('__FILE__')) &&
|
|
31
|
+
method.source_range.include?(b.eval('__LINE__'))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def weird_method?(method, b)
|
|
35
|
+
!normal_method?(method, b)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
attr_accessor :method
|
|
40
|
+
attr_accessor :target
|
|
41
|
+
|
|
42
|
+
# @param [Pry::Method] method The seed method.
|
|
43
|
+
# @param [Binding] target The Binding that captures the method
|
|
44
|
+
# we want to locate.
|
|
45
|
+
def initialize(method, target)
|
|
46
|
+
@method, @target = method, target
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @return [Pry::Method, nil] The Pry::Method that matches the
|
|
50
|
+
# given binding.
|
|
51
|
+
def get_method
|
|
52
|
+
find_method_in_superclass || find_renamed_method
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [Boolean] Whether the Pry::Method is unrecoverable
|
|
56
|
+
# This usually happens when the method captured by the Binding
|
|
57
|
+
# has been subsequently deleted.
|
|
58
|
+
def lost_method?
|
|
59
|
+
!!(get_method.nil? && renamed_method_source_location)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def normal_method?(method)
|
|
65
|
+
self.class.normal_method?(method, target)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def target_self
|
|
69
|
+
target.eval('self')
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def target_file
|
|
73
|
+
pry_file? ? target.eval('__FILE__') : File.expand_path(target.eval('__FILE__'))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def target_line
|
|
77
|
+
target.eval('__LINE__')
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def pry_file?
|
|
81
|
+
Pry.eval_path == target.eval('__FILE__')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# it's possible in some cases that the method we find by this approach is a sub-method of
|
|
85
|
+
# the one we're currently in, consider:
|
|
86
|
+
#
|
|
87
|
+
# class A; def b; binding.pry; end; end
|
|
88
|
+
# class B < A; def b; super; end; end
|
|
89
|
+
#
|
|
90
|
+
# Given that we can normally find the source_range of methods, and that we know which
|
|
91
|
+
# __FILE__ and __LINE__ the binding is at, we can hope to disambiguate these cases.
|
|
92
|
+
#
|
|
93
|
+
# This obviously won't work if the source is unavaiable for some reason, or if both
|
|
94
|
+
# methods have the same __FILE__ and __LINE__, or if we're in rbx where b.eval('__LINE__')
|
|
95
|
+
# is broken.
|
|
96
|
+
#
|
|
97
|
+
# @return [Pry::Method, nil] The Pry::Method representing the
|
|
98
|
+
# superclass method.
|
|
99
|
+
def find_method_in_superclass
|
|
100
|
+
guess = method
|
|
101
|
+
|
|
102
|
+
while guess
|
|
103
|
+
# needs rescue if this is a Disowned method or a C method or something...
|
|
104
|
+
# TODO: Fix up the exception handling so we don't need a bare rescue
|
|
105
|
+
if normal_method?(guess)
|
|
106
|
+
return guess
|
|
107
|
+
else
|
|
108
|
+
guess = guess.super
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Uhoh... none of the methods in the chain had the right __FILE__ and __LINE__
|
|
113
|
+
# This may be caused by rbx https://github.com/rubinius/rubinius/issues/953,
|
|
114
|
+
# or other unknown circumstances (TODO: we should warn the user when this happens)
|
|
115
|
+
nil
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# This is the case where the name of a method has changed
|
|
119
|
+
# (via alias_method) so we locate the Method object for the
|
|
120
|
+
# renamed method.
|
|
121
|
+
#
|
|
122
|
+
# @return [Pry::Method, nil] The Pry::Method representing the
|
|
123
|
+
# renamed method
|
|
124
|
+
def find_renamed_method
|
|
125
|
+
return if !valid_file?(target_file)
|
|
126
|
+
alias_name = all_methods_for(target_self).find do |v|
|
|
127
|
+
expanded_source_location(target_self.method(v).source_location) == renamed_method_source_location
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
alias_name && Pry::Method(target_self.method(alias_name))
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def expanded_source_location(sl)
|
|
134
|
+
return if !sl
|
|
135
|
+
|
|
136
|
+
if pry_file?
|
|
137
|
+
sl
|
|
138
|
+
else
|
|
139
|
+
[File.expand_path(sl.first), sl.last]
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Use static analysis to locate the start of the method definition.
|
|
144
|
+
# We have the `__FILE__` and `__LINE__` from the binding and the
|
|
145
|
+
# original name of the method so we search up until we find a
|
|
146
|
+
# def/define_method, etc defining a method of the appropriate name.
|
|
147
|
+
#
|
|
148
|
+
# @return [Array<String, Fixnum>] The `source_location` of the
|
|
149
|
+
# renamed method
|
|
150
|
+
def renamed_method_source_location
|
|
151
|
+
return @original_method_source_location if defined?(@original_method_source_location)
|
|
152
|
+
|
|
153
|
+
source_index = lines_for_file(target_file)[0..(target_line - 1)].rindex do |v|
|
|
154
|
+
Pry::Method.method_definition?(method.name, v)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
@original_method_source_location = source_index &&
|
|
158
|
+
[target_file, index_to_line_number(source_index)]
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def index_to_line_number(index)
|
|
162
|
+
# Pry.line_buffer is 0-indexed
|
|
163
|
+
pry_file? ? index : index + 1
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def valid_file?(file)
|
|
167
|
+
File.exists?(file) || Pry.eval_path == file
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def lines_for_file(file)
|
|
171
|
+
@lines_for_file ||= {}
|
|
172
|
+
@lines_for_file[file] ||= if Pry.eval_path == file
|
|
173
|
+
Pry.line_buffer
|
|
174
|
+
else
|
|
175
|
+
File.readlines(file)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def all_methods_for(obj)
|
|
180
|
+
obj.public_methods(false) +
|
|
181
|
+
obj.private_methods(false) +
|
|
182
|
+
obj.protected_methods(false)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
data/lib/pry/module_candidate.rb
CHANGED
|
@@ -52,8 +52,8 @@ class Pry
|
|
|
52
52
|
# @return [String] The source for the candidate, i.e the
|
|
53
53
|
# complete module/class definition.
|
|
54
54
|
def source
|
|
55
|
+
return nil if file.nil?
|
|
55
56
|
return @source if @source
|
|
56
|
-
raise CommandError, "Could not locate source for #{wrapped}!" if file.nil?
|
|
57
57
|
|
|
58
58
|
@source = strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line, number_of_lines_in_first_chunk))
|
|
59
59
|
end
|
|
@@ -61,10 +61,10 @@ class Pry
|
|
|
61
61
|
# @raise [Pry::CommandError] If documentation cannot be found.
|
|
62
62
|
# @return [String] The documentation for the candidate.
|
|
63
63
|
def doc
|
|
64
|
+
return nil if file.nil?
|
|
64
65
|
return @doc if @doc
|
|
65
|
-
raise CommandError, "Could not locate doc for #{wrapped}!" if file.nil?
|
|
66
66
|
|
|
67
|
-
@doc =
|
|
67
|
+
@doc = get_comment_content(Pry::Code.from_file(file).comment_describing(line))
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
# @return [Array, nil] A `[String, Fixnum]` pair representing the
|
data/lib/pry/pager.rb
CHANGED
|
@@ -12,8 +12,11 @@ class Pry::Pager
|
|
|
12
12
|
case pager
|
|
13
13
|
when nil
|
|
14
14
|
no_pager = !SystemPager.available?
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
if no_pager || Pry::Helpers::BaseHelpers.jruby?
|
|
16
|
+
SimplePager.new(text).page
|
|
17
|
+
else
|
|
18
|
+
SystemPager.new(text).page
|
|
19
|
+
end
|
|
17
20
|
when :simple
|
|
18
21
|
SimplePager.new(text).page
|
|
19
22
|
when :system
|
|
@@ -24,12 +27,8 @@ class Pry::Pager
|
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
def self.page_size
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
$stdout.winsize.first
|
|
30
|
-
rescue LoadError
|
|
31
|
-
27
|
|
32
|
-
end
|
|
30
|
+
rows = Pry::Terminal.screen_size
|
|
31
|
+
@page_size ||= (rows && rows.first || 27)
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
def initialize(text)
|
|
@@ -38,11 +37,14 @@ class Pry::Pager
|
|
|
38
37
|
|
|
39
38
|
class SimplePager < Pry::Pager
|
|
40
39
|
def page
|
|
40
|
+
# The pager size minus the number of lines used by the simple pager info bar.
|
|
41
|
+
page_size = Pry::Pager.page_size - 3
|
|
41
42
|
text_array = @text.lines.to_a
|
|
42
|
-
|
|
43
|
+
|
|
44
|
+
text_array.each_slice(page_size) do |chunk|
|
|
43
45
|
puts chunk.join
|
|
44
|
-
break if chunk.size <
|
|
45
|
-
if text_array.size >
|
|
46
|
+
break if chunk.size < page_size
|
|
47
|
+
if text_array.size > page_size
|
|
46
48
|
puts "\n<page break> --- Press enter to continue ( q<enter> to break ) --- <page break>"
|
|
47
49
|
break if $stdin.gets.chomp == "q"
|
|
48
50
|
end
|
data/lib/pry/pry_class.rb
CHANGED
|
@@ -263,9 +263,16 @@ class Pry
|
|
|
263
263
|
|
|
264
264
|
def self.auto_resize!
|
|
265
265
|
trap :WINCH do
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
266
|
+
begin
|
|
267
|
+
Readline.set_screen_size *Terminal.size!
|
|
268
|
+
rescue => e
|
|
269
|
+
warn "\nPry.auto_resize!'s Readline.set_screen_size failed: #{e}"
|
|
270
|
+
end
|
|
271
|
+
begin
|
|
272
|
+
Readline.refresh_line
|
|
273
|
+
rescue => e
|
|
274
|
+
warn "\nPry.auto_resize!'s Readline.refresh_line failed: #{e}"
|
|
275
|
+
end
|
|
269
276
|
end
|
|
270
277
|
end
|
|
271
278
|
|
data/lib/pry/terminal.rb
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
class Pry::Terminal
|
|
2
|
+
class << self
|
|
3
|
+
# Return a pair of [rows, columns] which gives the size of the window.
|
|
4
|
+
#
|
|
5
|
+
# If the window size cannot be determined, return nil.
|
|
6
|
+
def screen_size
|
|
7
|
+
rows, cols = actual_screen_size
|
|
8
|
+
if rows && cols
|
|
9
|
+
[rows.to_i, cols.to_i]
|
|
10
|
+
else
|
|
11
|
+
nil
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Return a screen size or a default if that fails.
|
|
16
|
+
def size! default = [25, 80]
|
|
17
|
+
screen_size || default
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Return a screen width or the default if that fails.
|
|
21
|
+
def width! default = 80
|
|
22
|
+
size![1]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def actual_screen_size
|
|
26
|
+
# The best way, if possible (requires non-jruby ≥1.9 or io-console gem)
|
|
27
|
+
screen_size_according_to_io_console or
|
|
28
|
+
# Fall back to the old standby, though it might be stale:
|
|
29
|
+
screen_size_according_to_env or
|
|
30
|
+
# Fall further back, though this one is also out of date without something
|
|
31
|
+
# calling Readline.set_screen_size
|
|
32
|
+
screen_size_according_to_readline or
|
|
33
|
+
# Windows users can otherwise run ansicon and get a decent answer:
|
|
34
|
+
screen_size_according_to_ansicon_env
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def screen_size_according_to_io_console
|
|
38
|
+
return if Pry::Helpers::BaseHelpers.jruby?
|
|
39
|
+
require 'io/console'
|
|
40
|
+
$stdout.winsize if $stdout.tty? and $stdout.respond_to?(:winsize)
|
|
41
|
+
rescue LoadError
|
|
42
|
+
# They're probably on 1.8 without the io-console gem. We'll keep trying.
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def screen_size_according_to_env
|
|
46
|
+
size = [ENV['LINES'] || ENV['ROWS'], ENV['COLUMNS']]
|
|
47
|
+
size if nonzero_column?(size)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def screen_size_according_to_readline
|
|
51
|
+
if Readline.respond_to?(:get_screen_size)
|
|
52
|
+
size = Readline.get_screen_size
|
|
53
|
+
size if nonzero_column?(size)
|
|
54
|
+
end
|
|
55
|
+
rescue Java::JavaLang::NullPointerException
|
|
56
|
+
# This rescue won't happen on jrubies later than:
|
|
57
|
+
# https://github.com/jruby/jruby/pull/436
|
|
58
|
+
nil
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def screen_size_according_to_ansicon_env
|
|
62
|
+
return unless ENV['ANSICON'] =~ /\((.*)x(.*)\)/
|
|
63
|
+
size = [$2, $1]
|
|
64
|
+
size if nonzero_column?(size)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def nonzero_column?(size)
|
|
70
|
+
size[1].to_i > 0
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
data/lib/pry/version.rb
CHANGED
data/lib/pry/wrapped_module.rb
CHANGED
|
@@ -65,6 +65,30 @@ class Pry
|
|
|
65
65
|
@doc = nil
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
# Returns an array of the names of the constants accessible in the wrapped
|
|
69
|
+
# module. This provides a consistent interface between 1.8 and 1.9 and also
|
|
70
|
+
# avoids the problem of accidentally calling the singleton method
|
|
71
|
+
# `Module.constants`.
|
|
72
|
+
# @param [Boolean] inherit (true) Include the names of constants from
|
|
73
|
+
# included modules?
|
|
74
|
+
def constants(inherit = true)
|
|
75
|
+
method = Module.instance_method(:constants).bind(@wrapped)
|
|
76
|
+
|
|
77
|
+
# If we're on 1.8, we have to manually remove ancestors' constants. If
|
|
78
|
+
# we're on 1.9, though, it's better to use the built-in `inherit` param,
|
|
79
|
+
# since it doesn't do things like incorrectly remove Pry::Config.
|
|
80
|
+
if method.arity == 0
|
|
81
|
+
consts = method.call
|
|
82
|
+
if !inherit
|
|
83
|
+
consts -= (@wrapped.ancestors - [@wrapped]).map(&:constants).flatten
|
|
84
|
+
end
|
|
85
|
+
else
|
|
86
|
+
consts = method.call(inherit)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
consts
|
|
90
|
+
end
|
|
91
|
+
|
|
68
92
|
# The prefix that would appear before methods defined on this class.
|
|
69
93
|
#
|
|
70
94
|
# i.e. the "String." or "String#" in String.new and String#initialize.
|
|
@@ -205,13 +229,27 @@ class Pry
|
|
|
205
229
|
@memoized_candidates[rank] ||= Candidate.new(self, rank)
|
|
206
230
|
end
|
|
207
231
|
|
|
208
|
-
|
|
209
232
|
# @return [Fixnum] The number of candidate definitions for the
|
|
210
233
|
# current module.
|
|
211
234
|
def number_of_candidates
|
|
212
235
|
method_candidates.count
|
|
213
236
|
end
|
|
214
237
|
|
|
238
|
+
# @note On JRuby 1.9 and higher, in certain conditions, this method chucks
|
|
239
|
+
# away its ability to be quick (when there are lots of monkey patches,
|
|
240
|
+
# like in Rails). However, it should be efficient enough on other rubies.
|
|
241
|
+
# @see https://github.com/jruby/jruby/issues/525
|
|
242
|
+
# @return [Enumerator, Array] on JRuby 1.9 and higher returns Array, on
|
|
243
|
+
# other rubies returns Enumerator
|
|
244
|
+
def candidates
|
|
245
|
+
enum = generator.new do |y|
|
|
246
|
+
(0...number_of_candidates).each do |num|
|
|
247
|
+
y.yield candidate(num)
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
Pry::Helpers::BaseHelpers.jruby_19? ? enum.to_a : enum
|
|
251
|
+
end
|
|
252
|
+
|
|
215
253
|
# @return [Boolean] Whether YARD docs are available for this module.
|
|
216
254
|
def yard_docs?
|
|
217
255
|
!!(defined?(YARD) && YARD::Registry.at(name))
|
|
@@ -237,6 +275,18 @@ class Pry
|
|
|
237
275
|
|
|
238
276
|
private
|
|
239
277
|
|
|
278
|
+
# Ruby 1.8 doesn't support `Enumerator` (it's called Generator instead)
|
|
279
|
+
#
|
|
280
|
+
# @return [Object] Return the appropriate generator class.
|
|
281
|
+
def generator
|
|
282
|
+
@generator ||= if defined?(Enumerator)
|
|
283
|
+
Enumerator
|
|
284
|
+
else
|
|
285
|
+
require 'generator'
|
|
286
|
+
Generator
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
240
290
|
# @return [Pry::WrappedModule::Candidate] The candidate of rank 0,
|
|
241
291
|
# that is the 'monkey patch' of this module with the highest
|
|
242
292
|
# number of methods. It is considered the 'canonical' definition
|
|
@@ -5,5 +5,25 @@ describe Pry::Helpers::CommandHelpers do
|
|
|
5
5
|
@helper = Pry::Helpers::CommandHelpers
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
describe "unindent" do
|
|
9
|
+
it "should remove the same prefix from all lines" do
|
|
10
|
+
@helper.unindent(" one\n two\n").should == "one\ntwo\n"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should not be phased by empty lines" do
|
|
14
|
+
@helper.unindent(" one\n\n two\n").should == "one\n\ntwo\n"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should only remove a common prefix" do
|
|
18
|
+
@helper.unindent(" one\n two\n").should == " one\ntwo\n"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should also remove tabs if present" do
|
|
22
|
+
@helper.unindent("\tone\n\ttwo\n").should == "one\ntwo\n"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should ignore lines starting with --" do
|
|
26
|
+
@helper.unindent(" one\n--\n two\n").should == "one\n--\ntwo\n"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
9
29
|
end
|