facets 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. data/HISTORY.rdoc +135 -294
  2. data/MANIFEST +40 -91
  3. data/NOTES +1 -1
  4. data/README.rdoc +10 -8
  5. data/Rakefile +11 -34
  6. data/demo/{hook.rd → hook.rdoc} +2 -0
  7. data/demo/{scenario_require.rd → scenario_require.rdoc} +3 -0
  8. data/lib/core/facets-live.rb +7 -5
  9. data/lib/core/facets.rb +379 -359
  10. data/lib/core/facets/array/conjoin.rb +2 -2
  11. data/lib/core/facets/array/pad.rb +1 -1
  12. data/lib/core/facets/array/recursively.rb +2 -2
  13. data/lib/core/facets/array/splice.rb +1 -1
  14. data/lib/core/facets/binding/caller.rb +2 -4
  15. data/lib/core/facets/comparable/comparable.rb +2 -2
  16. data/lib/core/facets/dir/ascend.rb +3 -0
  17. data/lib/core/facets/dir/recurse.rb +4 -0
  18. data/lib/core/facets/duplicable.rb +6 -8
  19. data/lib/core/facets/enumerable/count.rb +22 -13
  20. data/lib/core/facets/enumerable/map_detect.rb +28 -0
  21. data/lib/core/facets/enumerable/mash.rb +13 -5
  22. data/lib/core/facets/enumerable/per.rb +3 -1
  23. data/lib/core/facets/hash/count.rb +14 -0
  24. data/lib/core/facets/hash/data.rb +14 -0
  25. data/lib/core/facets/kernel/__method__.rb +1 -1
  26. data/lib/core/facets/kernel/d.rb +9 -8
  27. data/lib/core/facets/kernel/eigenclass.rb +20 -0
  28. data/lib/core/facets/kernel/extend.rb +10 -0
  29. data/lib/core/facets/kernel/instance_class.rb +1 -0
  30. data/lib/core/facets/kernel/instance_variables.rb +6 -6
  31. data/lib/core/facets/kernel/meta_alias.rb +18 -0
  32. data/lib/core/facets/kernel/meta_class.rb +17 -0
  33. data/lib/core/facets/kernel/meta_def.rb +18 -0
  34. data/lib/core/facets/kernel/meta_eval.rb +18 -0
  35. data/lib/core/facets/kernel/object_hexid.rb +21 -6
  36. data/lib/core/facets/kernel/object_state.rb +4 -2
  37. data/lib/core/facets/kernel/populate.rb +3 -1
  38. data/lib/core/facets/kernel/with.rb +1 -1
  39. data/lib/core/facets/metaid.rb +6 -93
  40. data/lib/core/facets/module/class_def.rb +2 -0
  41. data/lib/core/facets/module/extend.rb +10 -11
  42. data/lib/core/facets/module/is.rb +5 -5
  43. data/lib/core/facets/module/module_def.rb +31 -0
  44. data/lib/core/facets/string/camelcase.rb +14 -12
  45. data/lib/core/facets/string/cleanlines.rb +35 -0
  46. data/lib/core/facets/string/edit_distance.rb +62 -0
  47. data/lib/core/facets/string/indent.rb +86 -4
  48. data/lib/core/facets/string/index_all.rb +24 -0
  49. data/lib/core/facets/string/lines.rb +3 -6
  50. data/lib/core/facets/string/margin.rb +2 -1
  51. data/lib/core/facets/string/newlines.rb +35 -0
  52. data/lib/core/facets/string/op_div.rb +14 -0
  53. data/lib/core/facets/string/range.rb +2 -22
  54. data/lib/core/facets/string/range_all.rb +1 -0
  55. data/lib/core/facets/string/range_of_line.rb +1 -0
  56. data/lib/core/facets/string/similarity.rb +92 -0
  57. data/lib/core/facets/string/start_with.rb +6 -6
  58. data/lib/core/facets/string/titlecase.rb +1 -1
  59. data/lib/more/facets/basicobject.rb +16 -15
  60. data/lib/more/facets/blankslate.rb +8 -0
  61. data/lib/more/facets/class_extend.rb +126 -1
  62. data/lib/more/facets/continuation.rb +53 -54
  63. data/lib/more/facets/dictionary.rb +9 -63
  64. data/lib/more/facets/erb.rb +63 -0
  65. data/lib/more/facets/filelist.rb +5 -5
  66. data/lib/more/facets/hashbuilder.rb +101 -0
  67. data/lib/more/facets/inheritor.rb +36 -45
  68. data/lib/more/facets/ini.rb +267 -0
  69. data/lib/more/facets/instance_eval.rb +4 -4
  70. data/lib/more/facets/ioredirect.rb +7 -60
  71. data/lib/more/facets/linkedlist.rb +195 -0
  72. data/lib/more/facets/matcher.rb +140 -0
  73. data/lib/more/facets/memoizer.rb +64 -0
  74. data/lib/more/facets/methodspace.rb +9 -4
  75. data/lib/more/facets/module/class_extend.rb +2 -121
  76. data/lib/more/facets/ostruct.rb +9 -9
  77. data/lib/more/facets/pathlist.rb +1 -9
  78. data/lib/more/facets/pathname.rb +11 -4
  79. data/lib/more/facets/plugin_manager.rb +50 -0
  80. data/lib/more/facets/random.rb +25 -3
  81. data/lib/more/facets/roman.rb +174 -0
  82. data/lib/more/facets/semaphore.rb +92 -0
  83. data/lib/more/facets/shellwords.rb +21 -48
  84. data/lib/more/facets/succ.rb +1 -1
  85. data/meta/{modified → released} +0 -0
  86. data/meta/repository +1 -0
  87. data/meta/suite +1 -0
  88. data/meta/version +1 -1
  89. data/script/conflicts +63 -0
  90. data/script/methods +49 -0
  91. data/test/core/binding/test_caller.rb +11 -4
  92. data/test/core/enumerable/test_count.rb +19 -10
  93. data/test/core/enumerable/test_map_detect.rb +75 -0
  94. data/test/core/enumerable/test_take.rb +1 -1
  95. data/test/core/kernel/test_object_hexid.rb +2 -1
  96. data/test/core/proc/test_to_method.rb +1 -1
  97. data/test/core/string/test_cleanlines.rb +11 -0
  98. data/test/core/string/test_indent.rb +66 -4
  99. data/test/core/string/test_lines.rb +2 -1
  100. data/test/core/string/test_newlines.rb +13 -0
  101. data/test/core/time/test_change.rb +1 -1
  102. data/test/core/time/test_stamp.rb +4 -7
  103. data/test/core/unboundmethod/test_name.rb +1 -1
  104. data/test/more/test_basicobject.rb +1 -20
  105. data/test/more/test_class_extend.rb +7 -0
  106. data/test/more/test_continuation.rb +8 -6
  107. data/test/more/test_inheritor.rb +12 -6
  108. data/test/more/test_random.rb +19 -10
  109. data/test/more/test_shellwords.rb +33 -0
  110. metadata +60 -31
  111. data/TODO +0 -5
  112. data/doc/README.core +0 -102
  113. data/doc/README.more +0 -61
  114. data/doc/manual/about.rb +0 -47
  115. data/doc/manual/annotations.rdoc +0 -60
  116. data/doc/manual/associations.rdoc +0 -55
  117. data/doc/manual/blockups.rdoc +0 -101
  118. data/doc/manual/capsule.rdoc +0 -34
  119. data/doc/manual/command.rdoc +0 -177
  120. data/doc/manual/core.rdoc +0 -37
  121. data/doc/manual/faq.rdoc +0 -32
  122. data/doc/manual/typecast.html +0 -112
  123. data/lib/more/facets/capsule.rb +0 -258
  124. data/lib/more/facets/coroutine.rb +0 -159
  125. data/lib/more/facets/enumerablepass.rb +0 -3
  126. data/lib/more/facets/fileable.rb +0 -162
  127. data/lib/more/facets/progressbar.rb +0 -253
  128. data/lib/more/facets/recorder.rb +0 -108
  129. data/meta/releases +0 -14
  130. data/test/more/test_coroutine.rb +0 -46
@@ -0,0 +1,18 @@
1
+ module Kernel
2
+
3
+ # Add method to a meta-class --i.e. a singleton method.
4
+ #
5
+ # class X; end
6
+ # X.meta_def(:x){"x"}
7
+ # X.x #=> "x"
8
+ #
9
+ # CREDIT: WhyTheLuckyStiff
10
+
11
+ def meta_def( name, &block )
12
+ meta_class do
13
+ define_method( name, &block )
14
+ end
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,18 @@
1
+ module Kernel
2
+
3
+
4
+ # Evaluate code in a metaclass. This is equivalent to
5
+ # 'meta_class.instance_eval'.
6
+ #
7
+ # CREDIT: WhyTheLuckyStiff
8
+
9
+ def meta_eval(str=nil, &blk)
10
+ if str
11
+ meta_class.instance_eval(str)
12
+ else
13
+ meta_class.instance_eval(&blk)
14
+ end
15
+ end
16
+
17
+ end
18
+
@@ -1,12 +1,27 @@
1
1
  module Kernel
2
2
 
3
- # Returns the object id as a string in hexideciaml,
4
- # which is how Ruby reports them with inspect.
5
- #
6
- # "ABC".object_hexid #=> "0x402d359c"
3
+ if RUBY_VERSION < "1.8.7"
4
+
5
+ # Returns the object id as a string in hexideciaml,
6
+ # which is how Ruby reports them with inspect.
7
+ #
8
+ # "ABC".object_hexid #=> "0x402d359c"
9
+
10
+ def object_hexid
11
+ return "0x" << (('%.x' % (2*self.__id__))[1..-1])
12
+ end
13
+
14
+ else
15
+
16
+ # Returns the object id as a string in hexideciaml,
17
+ # which is how Ruby reports them with inspect.
18
+ #
19
+ # "ABC".object_hexid #=> "0x402d359c"
20
+
21
+ def object_hexid
22
+ return "0x" << ('%.x' % (2*self.__id__)) #[1..-1]
23
+ end
7
24
 
8
- def object_hexid
9
- return "0x" << ('%.x' % (2*self.__id__)) #[1..-1]
10
25
  end
11
26
 
12
27
  end
@@ -1,5 +1,7 @@
1
1
  class Object
2
- # Get state of object.
2
+ # Get or set state of object.
3
+ #
4
+ # TODO: Would #instance_state be a more appropriate name?
3
5
  def object_state(data=nil)
4
6
  if data
5
7
  instance_variables.each do |iv|
@@ -12,7 +14,7 @@ class Object
12
14
  name = iv.to_s.sub(/^[@]/, '').to_sym
13
15
  data[name] = instance_variable_get(iv)
14
16
  end
15
- snap
17
+ data
16
18
  end
17
19
  end
18
20
 
@@ -18,7 +18,9 @@ module Kernel
18
18
  # order of assignemnt.
19
19
  #
20
20
  # Using a hash or array will not raise an error if the
21
- # accessor does not exits --it will simply be skipped.
21
+ # accessor does not exits -- it will simply be skipped.
22
+ #
23
+ # (See also: instance_vars.update, which sets instance variables directly, bypassing accessor method.)
22
24
  #
23
25
  # TODO: Better name, #set_with ?
24
26
 
@@ -1,6 +1,6 @@
1
1
  module Kernel
2
2
 
3
- # Like returning but exectures the block
3
+ # Like returning but exectues the block
4
4
  # via instance_eval.
5
5
  #
6
6
  # def foo
@@ -1,94 +1,7 @@
1
- module Kernel
2
-
3
- # Alias a method defined in the metaclass (ie. singleton class).
4
- #
5
- # def X.y?; "y?" ; end
6
- # X.meta_alias "ynot?", "y?"
7
- # X.ynot? #=> y?
8
- #
9
- # CREDIT: Trans
10
-
11
- def meta_alias(*args)
12
- meta_class do
13
- alias_method(*args)
14
- end
15
- end
16
-
17
- # Evaluate code in a metaclass. This is equivalent to
18
- # 'meta_class.instance_eval'.
19
- #
20
- # CREDIT: WhyTheLuckyStiff
21
-
22
- def meta_eval(str=nil, &blk)
23
- if str
24
- meta_class.instance_eval(str)
25
- else
26
- meta_class.instance_eval(&blk)
27
- end
28
- end
29
-
30
- # Add method to a meta-class --i.e. a singleton method.
31
- #
32
- # class X; end
33
- # X.meta_def(:x){"x"}
34
- # X.x #=> "x"
35
- #
36
- # CREDIT: WhyTheLuckyStiff
37
-
38
- def meta_def( name, &block )
39
- meta_class do
40
- define_method( name, &block )
41
- end
42
- end
43
-
44
- # Easy access to an object's "special" class,
45
- # otherwise known as it's metaclass or singleton class.
46
-
47
- def meta_class(&block)
48
- if block_given?
49
- (class << self; self; end).class_eval(&block)
50
- else
51
- (class << self; self; end)
52
- end
53
- end
54
-
55
- alias_method :metaclass, :meta_class
56
-
57
- # During this trying time when no one can get their
58
- # techie catchwords to stick to the refrigerator no
59
- # matter how hard they slap it # with the enchanted
60
- # magnetic spatula, it’s good to know that the
61
- # contrived phrases really do fly, graceful and
62
- # unclasped and bearing north toward chilled shrimp.
63
- # I know what my Hallowe’en pumpkin is going to say.
64
- #
65
- # -- why the lucky stiff
66
- #
67
- # CREDIT: WhyTheLuckyStiff
68
-
69
- def eigenclass
70
- (class << self; self; end)
71
- end
72
-
73
- end
74
-
75
-
76
- class Module
77
-
78
- # Defines an instance method within a class.
79
- #
80
- # CREDIT: WhyTheLuckyStiff
81
-
82
- def class_def name, &blk
83
- class_eval { define_method name, &blk }
84
- end
85
-
86
- protected :attr
87
- protected :attr_reader
88
- protected :attr_writer
89
- protected :attr_accessor
90
- protected :remove_method
91
- protected :undef_method
92
-
93
- end
1
+ require 'facets/kernel/meta_alias'
2
+ require 'facets/kernel/meta_class'
3
+ require 'facets/kernel/meta_def'
4
+ require 'facets/kernel/meta_eval'
5
+ require 'facets/kernel/eigenclass'
6
+ require 'facets/module/class_def'
94
7
 
@@ -0,0 +1,2 @@
1
+ require 'facets/module/module_def'
2
+
@@ -1,11 +1,10 @@
1
- class Module
2
-
3
- alias_method :_extend, :extend
4
-
5
- def extend(*mod, &blk)
6
- _extend *mod unless mod.empty?
7
- _extend Module.new(&blk) if blk
8
- end
9
-
10
- end
11
-
1
+ #class Module
2
+ #
3
+ # alias_method :_extend, :extend
4
+ #
5
+ # def extend(*mod, &blk)
6
+ # _extend *mod unless mod.empty?
7
+ # _extend Module.new(&blk) if blk
8
+ # end
9
+ #
10
+ #end
@@ -6,12 +6,12 @@ class Module
6
6
  # class X ; end
7
7
  # class Y < X ; end
8
8
  #
9
- # Y.is?(X) #=> true
9
+ # Y.is?(X) #=> true
10
10
  #
11
11
  # CREDIT: Trans
12
12
 
13
13
  def is?(base)
14
- ancestors.slice(1..-1).include?(base)
14
+ Module===base && ancestors.slice(1..-1).include?(base)
15
15
  end
16
16
 
17
17
  # An alias for #include.
@@ -22,8 +22,6 @@ class Module
22
22
  #
23
23
  # CREDIT: Trans
24
24
 
25
- #alias_method :is, :include
26
-
27
25
  def is(*mods)
28
26
  mods.each do |mod|
29
27
  if mod.const_defined?(:Self)
@@ -38,9 +36,11 @@ class Module
38
36
  include(*mods)
39
37
  end
40
38
 
39
+ #alias_method :is, :include
40
+
41
41
  # Expirmental idea for #is.
42
42
  #
43
- # If the module has #append_function_function
43
+ # If the module has #append_feature_function
44
44
  # defined, this will use that instead of #include.
45
45
  #
46
46
  # def is(*modules)
@@ -0,0 +1,31 @@
1
+ class Module
2
+
3
+ # Defines an instance method within a class/module.
4
+ #
5
+ # CREDIT: WhyTheLuckyStiff
6
+
7
+ def class_def name, &blk
8
+ class_eval { define_method name, &blk }
9
+ end
10
+
11
+ # Defines an instance method within a class/module.
12
+ #
13
+ # CREDIT: WhyTheLuckyStiff
14
+
15
+ def module_def name, &blk
16
+ module_eval { define_method name, &blk }
17
+ end
18
+
19
+ #--
20
+ # TODO: Why are we making these protected,
21
+ # and where should these really go in Facets?
22
+ #++
23
+ protected :attr
24
+ protected :attr_reader
25
+ protected :attr_writer
26
+ protected :attr_accessor
27
+ protected :remove_method
28
+ protected :undef_method
29
+
30
+ end
31
+
@@ -16,18 +16,20 @@ class String
16
16
  # "Camel_case".camelcase(false) #=> "camelCase"
17
17
  #
18
18
  # TODO: Is this the best approach? Should lowerCamelCase be default instead?
19
- def camelcase(first_letter=nil)
20
- case first_letter
21
- when :upper, true
22
- upper_camelcase
23
- when :lower, false
24
- lower_camelcase
25
- else
26
- str = dup
27
- str.gsub!(/\/(.?)/){ "::#{$1.upcase}" } # NOT SO SURE ABOUT THIS
28
- str.gsub!(/(?:_+|-+)([a-z])/){ $1.upcase }
29
- #str.gsub!(/(\A|\s)([a-z])/){ $1 + $2.upcase }
30
- str
19
+ unless method_defined?(:camelcase)
20
+ def camelcase(first_letter=nil)
21
+ case first_letter
22
+ when :upper, true
23
+ upper_camelcase
24
+ when :lower, false
25
+ lower_camelcase
26
+ else
27
+ str = dup
28
+ str.gsub!(/\/(.?)/){ "::#{$1.upcase}" } # NOT SO SURE ABOUT THIS
29
+ str.gsub!(/(?:_+|-+)([a-z])/){ $1.upcase }
30
+ #str.gsub!(/(\A|\s)([a-z])/){ $1 + $2.upcase }
31
+ str
32
+ end
31
33
  end
32
34
  end
33
35
 
@@ -0,0 +1,35 @@
1
+ require "facets/enumerator"
2
+
3
+ class String
4
+
5
+ # Returns an Enumerator for iterating over each
6
+ # line of the string, stripped of whitespace on
7
+ # either side.
8
+ #
9
+ def cleanlines(&block)
10
+ if block
11
+ scan(/^.*?$/) do |line|
12
+ block.call(line.strip)
13
+ end
14
+ else
15
+ Enumerator.new(self) do |output|
16
+ scan(/^.*?$/) do |line|
17
+ output.yield(line.strip)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ =begin test
26
+
27
+ "a \n b \n c".newlines.class.must == Enumerator
28
+ "a \n b \n c".newlines.to_a.must == %w{a b c}
29
+
30
+ a = []
31
+ "a \n b \n c".newlines{|nl| a << nl}
32
+ a.must == %w{a b c}
33
+
34
+ =end
35
+
@@ -0,0 +1,62 @@
1
+ class String
2
+
3
+ # Levenshtein distance algorithm implementation for Ruby, with UTF-8 support.
4
+ #
5
+ # The Levenshtein distance is a measure of how similar two strings s and t are,
6
+ # calculated as the number of deletions/insertions/substitutions needed to
7
+ # transform s into t. The greater the distance, the more the strings differ.
8
+ #
9
+ # The Levenshtein distance is also sometimes referred to as the
10
+ # easier-to-pronounce-and-spell 'edit distance'.
11
+ #
12
+ # Calculate the Levenshtein distance between two strings +self+ and +str2+.
13
+ # +self+ and +str2+ should be ASCII, UTF-8, or a one-byte-per character encoding
14
+ # such as ISO-8859-*.
15
+ #
16
+ # The strings will be treated as UTF-8 if $KCODE is set appropriately (i.e. 'u').
17
+ # Otherwise, the comparison will be performed byte-by-byte. There is no specific support
18
+ # for Shift-JIS or EUC strings.
19
+ #
20
+ # When using Unicode text, be aware that this algorithm does not perform normalisation.
21
+ # If there is a possibility of different normalised forms being used, normalisation
22
+ # should be performed beforehand.
23
+ #
24
+ # CREDIT: Paul Battley
25
+ #
26
+ def edit_distance(str2)
27
+ str1 = self
28
+ if $KCODE =~ /^U/i
29
+ unpack_rule = 'U*'
30
+ else
31
+ unpack_rule = 'C*'
32
+ end
33
+ s = str1.unpack(unpack_rule)
34
+ t = str2.unpack(unpack_rule)
35
+ n = s.length
36
+ m = t.length
37
+ return m if (0 == n)
38
+ return n if (0 == m)
39
+
40
+ d = (0..m).to_a
41
+ x = nil
42
+
43
+ (0...n).each do |i|
44
+ e = i+1
45
+ (0...m).each do |j|
46
+ cost = (s[i] == t[j]) ? 0 : 1
47
+ x = [
48
+ d[j+1] + 1, # insertion
49
+ e + 1, # deletion
50
+ d[j] + cost # substitution
51
+ ].min
52
+ d[j] = e
53
+ e = x
54
+ end
55
+ d[m] = x
56
+ end
57
+
58
+ return x
59
+ end
60
+
61
+ end
62
+
@@ -3,13 +3,13 @@ class String
3
3
  # Indent left or right by n spaces.
4
4
  # (This used to be called #tab and aliased as #indent.)
5
5
  #
6
- # CREDIT: Gavin Sinclair, Trans
6
+ # CREDIT: Gavin Sinclair, Trans, Tyler Rick
7
7
 
8
- def indent(n)
8
+ def indent(n, c=' ')
9
9
  if n >= 0
10
- gsub(/^/, ' ' * n)
10
+ gsub(/^/, c * n)
11
11
  else
12
- gsub(/^ {0,#{-n}}/, "")
12
+ gsub(/^#{Regexp.escape(c)}{0,#{-n}}/, "")
13
13
  end
14
14
  end
15
15
 
@@ -23,3 +23,85 @@ class String
23
23
 
24
24
  end
25
25
 
26
+
27
+ # _____ _
28
+ # |_ _|__ ___| |_
29
+ # | |/ _ \/ __| __|
30
+ # | | __/\__ \ |_
31
+ # |_|\___||___/\__|
32
+ #
33
+ =begin test
34
+ require 'test/unit'
35
+
36
+ class TC_String_Indent < Test::Unit::TestCase
37
+
38
+ def test_positive_indent
39
+ assert_equal ' xyz', "xyz". indent(4)
40
+ assert_equal ' xyz', " xyz".indent(2)
41
+ end
42
+
43
+ def test_multi_line_positive_indent
44
+ assert_equal " abc\n" +
45
+ " xyz" ,
46
+ ("abc\n" +
47
+ "xyz" ).indent(2)
48
+ end
49
+
50
+ def test_0_indent
51
+ assert_equal 'xyz', 'xyz'.indent(0)
52
+ end
53
+
54
+ def test_negative_indent
55
+ assert_equal ' xyz', ' xyz'.indent(-2)
56
+ assert_equal 'xyz', ' xyz'. indent(-2)
57
+ end
58
+
59
+ def test_multi_line_negative_indent
60
+ assert_equal " abc\n" +
61
+ " xyz" ,
62
+ (" abc\n" +
63
+ " xyz" ).indent(-2)
64
+ end
65
+
66
+ def test_outdent_is_alias_for_negative_indent
67
+ assert_equal 'xyz', ' xyz'.outdent(2)
68
+ end
69
+
70
+ def test_negative_indent_more_than_is_possible
71
+ assert_equal 'xyz', ' xyz'.indent(-3)
72
+ end
73
+
74
+ #-----------------------------------
75
+ # Using a character other than space
76
+
77
+ def test_nonspace_positive__indent
78
+ assert_equal '----xyz', "xyz".indent(4, '-')
79
+ end
80
+
81
+ def test_nonspace_0_indent
82
+ assert_equal 'xyz', 'xyz'.indent(0, '-')
83
+ end
84
+
85
+ def test_nonspace_negative_indent_nonmatching_character
86
+ assert_equal ' xyz', ' xyz'.indent(-2, '-')
87
+ assert_equal ' xyz', ' xyz'. indent(-2, '-')
88
+ end
89
+
90
+ def test_nonspace_negative_indent
91
+ assert_equal '--xyz', '----xyz'.indent(-2, '-')
92
+ assert_equal 'xyz', '--xyz'.indent(-2, '-')
93
+ end
94
+
95
+ def test_special_regexp_characters_are_escaped
96
+ # make sure . is treated as a literal '.' and not an "any character" wildcard
97
+ assert_equal ' xyz', ' xyz'.indent(-2, '.')
98
+ assert_equal 'xyz', '..xyz'.indent(-2, '.')
99
+
100
+ assert_equal ' xyz', ' xyz'.indent(-2, '^')
101
+ assert_equal 'xyz', '^^xyz'.indent(-2, '^')
102
+
103
+ assert_equal ' xyz', ' xyz'.indent(-2, '*')
104
+ assert_equal 'xyz', '**xyz'.indent(-2, '*')
105
+ end
106
+ end
107
+ =end