facets 2.7.0 → 2.8.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.
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