strings 0.1.5 → 0.1.6
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/CHANGELOG.md +11 -0
- data/README.md +1 -1
- data/lib/strings/align.rb +14 -8
- data/lib/strings/pad.rb +8 -6
- data/lib/strings/padder.rb +2 -2
- data/lib/strings/version.rb +1 -1
- data/lib/strings/wrap.rb +45 -34
- data/spec/spec_helper.rb +4 -2
- data/spec/unit/align/align_left_spec.rb +9 -0
- data/spec/unit/align/align_right_spec.rb +9 -0
- data/spec/unit/align/align_spec.rb +18 -0
- data/spec/unit/pad/pad_spec.rb +11 -0
- data/spec/unit/wrap/insert_ansi_spec.rb +65 -0
- data/spec/unit/wrap/wrap_spec.rb +54 -2
- data/tasks/console.rake +4 -6
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 921f81ef625130227be2240cdd40e00a88db1f902abd30af157833b31fc9e57c
|
4
|
+
data.tar.gz: f26a6ca02ea2a3fb59cd81c4347ee2381f7b745c1b80975ce8e3262d33b91a9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03de4bc3bc330b62ea283a86904edf9a67d2921c1c42c12e12168f5b4d1d306cabd2bee7bbfc519e70bdbfc5f2a93f356aa99a47b830e1b28135d1f07b42ec36
|
7
|
+
data.tar.gz: 547a0b7849b8fa00db911f2e066cb0157f64cb5b169f64d5f62068f0e34be387b86bf862edefee08c6d98598d7f37f37416ea480bd58e2cff0338b1fb8ab31cc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## [v0.1.6] - 2019-08-28
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
* Change Wrap#wrap, Align#align & Pad#pad to handle different line endings
|
7
|
+
* Change Pad#pad to pad empty lines
|
8
|
+
|
9
|
+
### Fixed
|
10
|
+
* Fix Wrap#wrap to handle adjacent ANSI codes
|
11
|
+
* Fix Wrap#insert_ansi to handle nested ANSI codes
|
12
|
+
|
3
13
|
## [v0.1.5] - 2019-03-29
|
4
14
|
|
5
15
|
### Changed
|
@@ -30,6 +40,7 @@
|
|
30
40
|
|
31
41
|
* Initial implementation and release
|
32
42
|
|
43
|
+
[v0.1.6]: https://github.com/piotrmurach/strings/compare/v0.1.4...v0.1.5
|
33
44
|
[v0.1.5]: https://github.com/piotrmurach/strings/compare/v0.1.4...v0.1.5
|
34
45
|
[v0.1.4]: https://github.com/piotrmurach/strings/compare/v0.1.3...v0.1.4
|
35
46
|
[v0.1.3]: https://github.com/piotrmurach/strings/compare/v0.1.2...v0.1.3
|
data/README.md
CHANGED
@@ -386,7 +386,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
386
386
|
|
387
387
|
Bug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/strings. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
388
388
|
|
389
|
-
1. Fork it ( https://github.com/piotrmurach/
|
389
|
+
1. Fork it ( https://github.com/piotrmurach/strings/fork )
|
390
390
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
391
391
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
392
392
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/lib/strings/align.rb
CHANGED
@@ -7,8 +7,8 @@ module Strings
|
|
7
7
|
# Responsible for text alignment
|
8
8
|
module Align
|
9
9
|
NEWLINE = "\n".freeze
|
10
|
-
|
11
|
-
|
10
|
+
SPACE = " ".freeze
|
11
|
+
LINE_BREAK = %r{\r\n|\r|\n}.freeze
|
12
12
|
|
13
13
|
# Aligns text within the width.
|
14
14
|
#
|
@@ -62,9 +62,11 @@ module Strings
|
|
62
62
|
# @return [String]
|
63
63
|
#
|
64
64
|
# @api public
|
65
|
-
def align_left(text, width, fill: SPACE, separator:
|
65
|
+
def align_left(text, width, fill: SPACE, separator: nil)
|
66
66
|
return if width.nil?
|
67
|
-
|
67
|
+
sep = separator || text[LINE_BREAK] || NEWLINE
|
68
|
+
|
69
|
+
each_line(text, sep) do |line|
|
68
70
|
width_diff = width - display_width(line)
|
69
71
|
if width_diff > 0
|
70
72
|
line + fill * width_diff
|
@@ -80,9 +82,11 @@ module Strings
|
|
80
82
|
# @return [String]
|
81
83
|
#
|
82
84
|
# @api public
|
83
|
-
def align_center(text, width, fill: SPACE, separator:
|
85
|
+
def align_center(text, width, fill: SPACE, separator: nil)
|
84
86
|
return text if width.nil?
|
85
|
-
|
87
|
+
sep = separator || text[LINE_BREAK] || NEWLINE
|
88
|
+
|
89
|
+
each_line(text, sep) do |line|
|
86
90
|
width_diff = width - display_width(line)
|
87
91
|
if width_diff > 0
|
88
92
|
right_count = (width_diff.to_f / 2).ceil
|
@@ -100,9 +104,11 @@ module Strings
|
|
100
104
|
# @return [String]
|
101
105
|
#
|
102
106
|
# @api public
|
103
|
-
def align_right(text, width, fill: SPACE, separator:
|
107
|
+
def align_right(text, width, fill: SPACE, separator: nil)
|
104
108
|
return text if width.nil?
|
105
|
-
|
109
|
+
sep = separator || text[LINE_BREAK] || NEWLINE
|
110
|
+
|
111
|
+
each_line(text, sep) do |line|
|
106
112
|
width_diff = width - display_width(line)
|
107
113
|
if width_diff > 0
|
108
114
|
fill * width_diff + line
|
data/lib/strings/pad.rb
CHANGED
@@ -9,8 +9,8 @@ module Strings
|
|
9
9
|
# Responsible for text padding
|
10
10
|
module Pad
|
11
11
|
NEWLINE = "\n".freeze
|
12
|
-
|
13
|
-
|
12
|
+
SPACE = " ".freeze
|
13
|
+
LINE_BREAK = %r{\r\n|\r|\n}.freeze
|
14
14
|
|
15
15
|
# Apply padding to multiline text with ANSI codes
|
16
16
|
#
|
@@ -31,10 +31,11 @@ module Strings
|
|
31
31
|
# @return [String]
|
32
32
|
#
|
33
33
|
# @api private
|
34
|
-
def pad(text, padding, fill: SPACE, separator:
|
34
|
+
def pad(text, padding, fill: SPACE, separator: nil)
|
35
35
|
padding = Strings::Padder.parse(padding)
|
36
36
|
text_copy = text.dup
|
37
|
-
|
37
|
+
sep = separator || text[LINE_BREAK] || NEWLINE
|
38
|
+
line_width = max_line_length(text, sep)
|
38
39
|
output = []
|
39
40
|
|
40
41
|
filler_line = fill * line_width
|
@@ -43,7 +44,8 @@ module Strings
|
|
43
44
|
output << pad_around(filler_line, padding, fill: fill)
|
44
45
|
end
|
45
46
|
|
46
|
-
text_copy.split(
|
47
|
+
text_copy.split(sep).each do |line|
|
48
|
+
line = line.empty? ? filler_line : line
|
47
49
|
output << pad_around(line, padding, fill: fill)
|
48
50
|
end
|
49
51
|
|
@@ -51,7 +53,7 @@ module Strings
|
|
51
53
|
output << pad_around(filler_line, padding, fill: fill)
|
52
54
|
end
|
53
55
|
|
54
|
-
output.join(
|
56
|
+
output.join(sep)
|
55
57
|
end
|
56
58
|
module_function :pad
|
57
59
|
|
data/lib/strings/padder.rb
CHANGED
@@ -72,7 +72,7 @@ module Strings
|
|
72
72
|
|
73
73
|
# Set top padding
|
74
74
|
#
|
75
|
-
# @param [Integer]
|
75
|
+
# @param [Integer] value
|
76
76
|
#
|
77
77
|
# @return [nil]
|
78
78
|
#
|
@@ -92,7 +92,7 @@ module Strings
|
|
92
92
|
|
93
93
|
# Set right padding
|
94
94
|
#
|
95
|
-
# @param [Integer]
|
95
|
+
# @param [Integer] value
|
96
96
|
#
|
97
97
|
# @api public
|
98
98
|
def right=(value)
|
data/lib/strings/version.rb
CHANGED
data/lib/strings/wrap.rb
CHANGED
@@ -9,12 +9,10 @@ require_relative 'fold'
|
|
9
9
|
module Strings
|
10
10
|
module Wrap
|
11
11
|
DEFAULT_WIDTH = 80
|
12
|
-
|
13
12
|
NEWLINE = "\n".freeze
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
LINE_BREAK = "\r\n+|\r+|\n+".freeze
|
13
|
+
SPACE = " ".freeze
|
14
|
+
LINE_BREAK = %r{\r\n|\r|\n}.freeze
|
15
|
+
LINE_BREAKS = "\r\n+|\r+|\n+".freeze
|
18
16
|
|
19
17
|
# Wrap a text into lines no longer than wrap_at length.
|
20
18
|
# Preserves existing lines and existing word boundaries.
|
@@ -26,14 +24,15 @@ module Strings
|
|
26
24
|
# >text
|
27
25
|
#
|
28
26
|
# @api public
|
29
|
-
def wrap(text, wrap_at = DEFAULT_WIDTH)
|
30
|
-
if text.length < wrap_at.to_i || wrap_at.to_i.zero?
|
27
|
+
def wrap(text, wrap_at = DEFAULT_WIDTH, separator: nil)
|
28
|
+
if text.scan(/[[:print:]]/).length < wrap_at.to_i || wrap_at.to_i.zero?
|
31
29
|
return text
|
32
30
|
end
|
33
31
|
ansi_stack = []
|
34
|
-
text
|
32
|
+
sep = separator || text[LINE_BREAK] || NEWLINE
|
33
|
+
text.split(%r{#{LINE_BREAKS}}, -1).map do |paragraph|
|
35
34
|
format_paragraph(paragraph, wrap_at, ansi_stack)
|
36
|
-
end *
|
35
|
+
end * sep
|
37
36
|
end
|
38
37
|
module_function :wrap
|
39
38
|
|
@@ -70,7 +69,12 @@ module Strings
|
|
70
69
|
elsif ansi_matched
|
71
70
|
ansi_stack << [ansi[0...-1].join, line_length + word_length]
|
72
71
|
ansi_matched = false
|
73
|
-
|
72
|
+
|
73
|
+
if ansi.last == Strings::ANSI::CSI
|
74
|
+
ansi = [ansi.last]
|
75
|
+
else
|
76
|
+
ansi = []
|
77
|
+
end
|
74
78
|
end
|
75
79
|
next if ansi.length > 0
|
76
80
|
end
|
@@ -91,26 +95,26 @@ module Strings
|
|
91
95
|
end
|
92
96
|
|
93
97
|
if char == SPACE # ends with space
|
94
|
-
lines << insert_ansi(
|
98
|
+
lines << insert_ansi(line.join, ansi_stack)
|
95
99
|
line = []
|
96
100
|
line_length = 0
|
97
101
|
word << char
|
98
102
|
word_length += char_length
|
99
103
|
elsif word_length + char_length <= wrap_at
|
100
|
-
lines << insert_ansi(
|
104
|
+
lines << insert_ansi(line.join, ansi_stack)
|
101
105
|
line = [word.join + char]
|
102
106
|
line_length = word_length + char_length
|
103
107
|
word = []
|
104
108
|
word_length = 0
|
105
109
|
else # hyphenate word - too long to fit a line
|
106
|
-
lines << insert_ansi(
|
110
|
+
lines << insert_ansi(word.join, ansi_stack)
|
107
111
|
line_length = 0
|
108
112
|
word = [char]
|
109
113
|
word_length = char_length
|
110
114
|
end
|
111
115
|
end
|
112
|
-
lines << insert_ansi(
|
113
|
-
lines << insert_ansi(
|
116
|
+
lines << insert_ansi(line.join, ansi_stack) unless line.empty?
|
117
|
+
lines << insert_ansi(word.join, ansi_stack) unless word.empty?
|
114
118
|
lines
|
115
119
|
end
|
116
120
|
module_function :format_paragraph
|
@@ -120,36 +124,43 @@ module Strings
|
|
120
124
|
# Check if there are any ANSI states, if present
|
121
125
|
# insert ANSI codes at given positions unwinding the stack.
|
122
126
|
#
|
123
|
-
# @param [Array[Array[String, Integer]]] ansi_stack
|
124
|
-
# the ANSI codes to apply
|
125
|
-
#
|
126
127
|
# @param [String] string
|
127
128
|
# the string to insert ANSI codes into
|
128
129
|
#
|
130
|
+
# @param [Array[Array[String, Integer]]] ansi_stack
|
131
|
+
# the ANSI codes to apply
|
132
|
+
#
|
129
133
|
# @return [String]
|
130
134
|
#
|
131
135
|
# @api private
|
132
|
-
def insert_ansi(
|
136
|
+
def insert_ansi(string, ansi_stack = [])
|
133
137
|
return string if ansi_stack.empty?
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
138
|
+
return string if string.empty?
|
139
|
+
|
140
|
+
new_stack = []
|
141
|
+
output = string.dup
|
142
|
+
length = string.size
|
143
|
+
matched_reset = false
|
144
|
+
ansi_reset = Strings::ANSI::RESET
|
145
|
+
|
146
|
+
# Reversed so that string index don't count ansi
|
147
|
+
ansi_stack.reverse_each do |ansi|
|
148
|
+
if ansi[0] =~ /#{Regexp.quote(ansi_reset)}/
|
149
|
+
matched_reset = true
|
150
|
+
output.insert(ansi[1], ansi_reset)
|
143
151
|
next
|
144
|
-
elsif !
|
145
|
-
|
146
|
-
|
152
|
+
elsif !matched_reset # ansi without reset
|
153
|
+
matched_reset = false
|
154
|
+
new_stack << ansi # keep the ansi
|
155
|
+
next if ansi[1] == length
|
156
|
+
output.insert(-1, ansi_reset) # add reset at the end
|
147
157
|
end
|
148
158
|
|
149
|
-
|
150
|
-
output.insert(reset_index, Strings::ANSI::RESET).insert(color_index, color)
|
159
|
+
output.insert(ansi[1], ansi[0])
|
151
160
|
end
|
152
|
-
|
161
|
+
|
162
|
+
ansi_stack.replace(new_stack)
|
163
|
+
|
153
164
|
output
|
154
165
|
end
|
155
166
|
module_function :insert_ansi
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
if ENV['COVERAGE'] || ENV['TRAVIS']
|
2
4
|
require 'simplecov'
|
3
5
|
require 'coveralls'
|
4
6
|
|
5
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
7
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
6
8
|
SimpleCov::Formatter::HTMLFormatter,
|
7
9
|
Coveralls::SimpleCov::Formatter
|
8
|
-
]
|
10
|
+
])
|
9
11
|
|
10
12
|
SimpleCov.start do
|
11
13
|
command_name 'spec'
|
@@ -59,4 +59,13 @@ RSpec.describe Strings::Align, '#align_left' do
|
|
59
59
|
"outdone by the madness of men***********"
|
60
60
|
].join)
|
61
61
|
end
|
62
|
+
|
63
|
+
it "handles \r\n line separator" do
|
64
|
+
text = "Closes #360\r\n\r\nCloses !217"
|
65
|
+
expect(Strings::Align.align_left(text, 27)).to eq([
|
66
|
+
"Closes #360 ",
|
67
|
+
" ",
|
68
|
+
"Closes !217 "
|
69
|
+
].join("\r\n"))
|
70
|
+
end
|
62
71
|
end
|
@@ -59,4 +59,13 @@ RSpec.describe Strings::Align, '#align_right' do
|
|
59
59
|
"***********outdone by the madness of men"
|
60
60
|
].join)
|
61
61
|
end
|
62
|
+
|
63
|
+
it "handles \r\n line separator" do
|
64
|
+
text = "Closes #360\r\n\r\nCloses !217"
|
65
|
+
expect(Strings::Align.align_right(text, 27)).to eq([
|
66
|
+
" Closes #360",
|
67
|
+
" ",
|
68
|
+
" Closes !217"
|
69
|
+
].join("\r\n"))
|
70
|
+
end
|
62
71
|
end
|
@@ -74,4 +74,22 @@ RSpec.describe Strings::Align, '#align' do
|
|
74
74
|
"*****outdone by the madness of men******"
|
75
75
|
].join)
|
76
76
|
end
|
77
|
+
|
78
|
+
it "handles \r\n line separator" do
|
79
|
+
text = "Closes #360\r\n\r\nCloses !217"
|
80
|
+
expect(Strings::Align.align(text, 27)).to eq([
|
81
|
+
"Closes #360 ",
|
82
|
+
" ",
|
83
|
+
"Closes !217 "
|
84
|
+
].join("\r\n"))
|
85
|
+
end
|
86
|
+
|
87
|
+
it "handles \r\n line separator and centers" do
|
88
|
+
text = "Closes #360\r\n\r\nCloses !217"
|
89
|
+
expect(Strings::Align.align_center(text, 27)).to eq([
|
90
|
+
" Closes #360 ",
|
91
|
+
" ",
|
92
|
+
" Closes !217 "
|
93
|
+
].join("\r\n"))
|
94
|
+
end
|
77
95
|
end
|
data/spec/unit/pad/pad_spec.rb
CHANGED
@@ -60,4 +60,15 @@ RSpec.describe Strings::Pad, '#pad' do
|
|
60
60
|
" ",
|
61
61
|
].join("\n"))
|
62
62
|
end
|
63
|
+
|
64
|
+
it "handles \r\n line separator" do
|
65
|
+
text = "Closes #360\r\n\r\nCloses !217"
|
66
|
+
expect(Strings::Pad.pad(text, [1,1,1,1])).to eq([
|
67
|
+
" ",
|
68
|
+
" Closes #360 ",
|
69
|
+
" ",
|
70
|
+
" Closes !217 ",
|
71
|
+
" "
|
72
|
+
].join("\r\n"))
|
73
|
+
end
|
63
74
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "#insert_ansi" do
|
4
|
+
it "doesn't do anything when empty stack" do
|
5
|
+
text = "Ignorance is the parent of fear."
|
6
|
+
|
7
|
+
val = Strings::Wrap.insert_ansi(text, [])
|
8
|
+
|
9
|
+
expect(val).to eq(text)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "inserts ANSI strings in a single line" do
|
13
|
+
text = "Ignorance is the parent of fear."
|
14
|
+
stack = [["\e[32;44m", 0], ["\e[0m", text.size]]
|
15
|
+
|
16
|
+
val = Strings::Wrap.insert_ansi(text, stack)
|
17
|
+
|
18
|
+
expect(val).to eq("\e[32;44mIgnorance is the parent of fear.\e[0m")
|
19
|
+
expect(stack).to eq([])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "inserts ANSI strings with missing reset in a single line" do
|
23
|
+
text = "Ignorance is the parent of fear."
|
24
|
+
stack = [["\e[32;44m", 0]]
|
25
|
+
|
26
|
+
val = Strings::Wrap.insert_ansi(text, stack)
|
27
|
+
|
28
|
+
expect(val).to eq("\e[32;44mIgnorance is the parent of fear.\e[0m")
|
29
|
+
expect(stack).to eq([["\e[32;44m", 0]])
|
30
|
+
end
|
31
|
+
|
32
|
+
it "inserts 3 ansi strings in a single line" do
|
33
|
+
text = "Ignorance is the parent of fear."
|
34
|
+
stack = [
|
35
|
+
["\e[32m", 0], ["\e[0m", 9],
|
36
|
+
["\e[33m", 13], ["\e[0m", 16],
|
37
|
+
["\e[34m", 27], ["\e[0m", 31]
|
38
|
+
]
|
39
|
+
|
40
|
+
val = Strings::Wrap.insert_ansi(text, stack)
|
41
|
+
|
42
|
+
expect(val).to eq("\e[32mIgnorance\e[0m is \e[33mthe\e[0m parent of \e[34mfear\e[0m.")
|
43
|
+
expect(stack).to eq([])
|
44
|
+
end
|
45
|
+
|
46
|
+
it "inserts nested ANSI strings in a single line" do
|
47
|
+
text = "Ignorance is the parent of fear."
|
48
|
+
stack = [["\e[32m", 10], ["\e[33m", 17], ["\e[0m", 23], ["\e[0m", 26]]
|
49
|
+
|
50
|
+
val = Strings::Wrap.insert_ansi(text, stack)
|
51
|
+
|
52
|
+
expect(val).to eq("Ignorance \e[32mis the \e[33mparent\e[0m of\e[0m fear.")
|
53
|
+
expect(stack).to eq([])
|
54
|
+
end
|
55
|
+
|
56
|
+
it "removes matching pairs of ANSI codes only" do
|
57
|
+
text = "one"
|
58
|
+
stack = [["\e[32m", 0], ["\e[0m", 3], ["\e[33m", 3]]
|
59
|
+
|
60
|
+
val = Strings::Wrap.insert_ansi(text, stack)
|
61
|
+
|
62
|
+
expect(val).to eq("\e[32mone\e[0m")
|
63
|
+
expect(stack).to eq([["\e[33m", 3]])
|
64
|
+
end
|
65
|
+
end
|
data/spec/unit/wrap/wrap_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe Strings::Wrap, '.wrap' do
|
4
4
|
context 'when unicode' do
|
@@ -16,6 +16,18 @@ RSpec.describe Strings::Wrap, '.wrap' do
|
|
16
16
|
expect(Strings::Wrap.wrap(text, 100)).to eq(text)
|
17
17
|
end
|
18
18
|
|
19
|
+
it "wraps minimal width" do
|
20
|
+
str = "#?%"
|
21
|
+
|
22
|
+
val = Strings::Wrap.wrap(str, 1)
|
23
|
+
|
24
|
+
expect(val).to eq([
|
25
|
+
"#",
|
26
|
+
"?",
|
27
|
+
"%"
|
28
|
+
].join("\n"))
|
29
|
+
end
|
30
|
+
|
19
31
|
it "wraps correctly unbreakable words" do
|
20
32
|
expect(Strings::Wrap.wrap('foobar1', 3)).to eq([
|
21
33
|
"foo",
|
@@ -34,7 +46,7 @@ RSpec.describe Strings::Wrap, '.wrap' do
|
|
34
46
|
" ",
|
35
47
|
"conte",
|
36
48
|
"nt "
|
37
|
-
].join("\n"))
|
49
|
+
].join("\r\n"))
|
38
50
|
end
|
39
51
|
|
40
52
|
it "preserves newlines" do
|
@@ -113,6 +125,11 @@ RSpec.describe Strings::Wrap, '.wrap' do
|
|
113
125
|
"も含み\n"
|
114
126
|
].join("\n"))
|
115
127
|
end
|
128
|
+
|
129
|
+
it "handles \r\n line separator" do
|
130
|
+
text = "Closes #360\r\n\r\nCloses !217"
|
131
|
+
expect(Strings::Wrap.wrap(text, 15)).to eq(text)
|
132
|
+
end
|
116
133
|
end
|
117
134
|
|
118
135
|
context 'with ANSI codes' do
|
@@ -151,5 +168,40 @@ RSpec.describe Strings::Wrap, '.wrap' do
|
|
151
168
|
"insulted me."
|
152
169
|
].join("\n"))
|
153
170
|
end
|
171
|
+
|
172
|
+
it "applies ANSI codes when below wrap width" do
|
173
|
+
str = "\e[32mone\e[0m\e[33mtwo\e[0m"
|
174
|
+
|
175
|
+
val = Strings::Wrap.wrap(str, 6)
|
176
|
+
|
177
|
+
expect(val).to eq("\e[32mone\e[0m\e[33mtwo\e[0m")
|
178
|
+
end
|
179
|
+
|
180
|
+
xit "splits ANSI codes matching wrap width with space between codes" do
|
181
|
+
str = "\e[32mone\e[0m \e[33mtwo\e[0m"
|
182
|
+
|
183
|
+
val = Strings::Wrap.wrap(str, 3)
|
184
|
+
|
185
|
+
expect(val).to eq("\e[32mone\e[0m\n\e[33mtwo\e[0m")
|
186
|
+
end
|
187
|
+
|
188
|
+
xit "splits ANSI codes matching wrap width" do
|
189
|
+
str = "\e[32mone\e[0m\e[33mtwo\e[0m"
|
190
|
+
|
191
|
+
val = Strings::Wrap.wrap(str, 3)
|
192
|
+
|
193
|
+
expect(val).to eq("\e[32mone\e[0m\n\e[33mtwo\e[0m")
|
194
|
+
end
|
195
|
+
|
196
|
+
xit "wraps deeply nested ANSI codes correctly" do
|
197
|
+
str = "\e[32mone\e[33mtwo\e[0m\e[0m"
|
198
|
+
|
199
|
+
val = Strings::Wrap.wrap(str, 3)
|
200
|
+
|
201
|
+
expect(val).to eq([
|
202
|
+
"\e[32mone\e[0m",
|
203
|
+
"\e[33mtwo\e[0m",
|
204
|
+
].join("\n"))
|
205
|
+
end
|
154
206
|
end
|
155
207
|
end
|
data/tasks/console.rake
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
desc 'Load gem inside irb console'
|
1
|
+
desc "Load gem inside irb console"
|
4
2
|
task :console do
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require File.join(__FILE__,
|
3
|
+
require "irb"
|
4
|
+
require "irb/completion"
|
5
|
+
require File.join(__FILE__, "../../lib/strings")
|
8
6
|
ARGV.clear
|
9
7
|
IRB.start
|
10
8
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: strings-ansi
|
@@ -132,6 +132,7 @@ files:
|
|
132
132
|
- spec/unit/sanitize_spec.rb
|
133
133
|
- spec/unit/truncate/truncate_spec.rb
|
134
134
|
- spec/unit/truncate_spec.rb
|
135
|
+
- spec/unit/wrap/insert_ansi_spec.rb
|
135
136
|
- spec/unit/wrap/wrap_spec.rb
|
136
137
|
- spec/unit/wrap_spec.rb
|
137
138
|
- strings.gemspec
|