Ascii85 1.1.1 → 2.0.1
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/Ascii85.gemspec +15 -14
- data/CHANGELOG.md +70 -0
- data/Gemfile +3 -1
- data/README.md +28 -12
- data/Rakefile +5 -3
- data/bin/ascii85 +79 -56
- data/lib/Ascii85/version.rb +1 -1
- data/lib/ascii85.rb +409 -163
- data/spec/bin/cli_spec.rb +211 -0
- data/spec/lib/ascii85_spec.rb +171 -103
- metadata +19 -25
- data/History.txt +0 -37
@@ -0,0 +1,211 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
require 'minitest/autorun'
|
7
|
+
|
8
|
+
# We can't require the executable file because it doesn't
|
9
|
+
# have the '.rb' extension, so we have to load it.
|
10
|
+
unless defined?(CLI)
|
11
|
+
load File.join(__dir__, '..','..', 'bin', 'ascii85')
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'CLI' do
|
15
|
+
it 'should recognize the -h and --help options' do
|
16
|
+
[%w[-h], %w[--help]].each do |args|
|
17
|
+
cli = CLI.new(args)
|
18
|
+
assert_equal :help, cli.options[:action]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should recognize the -V and --version options' do
|
23
|
+
[%w[-V], %w[--version]].each do |args|
|
24
|
+
cli = CLI.new(args)
|
25
|
+
assert_equal :version, cli.options[:action]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should complain about superfluous arguments' do
|
30
|
+
assert_raises(OptionParser::ParseError) do
|
31
|
+
CLI.new(%w[foo bar])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'wrap' do
|
36
|
+
it 'should default to wrapping at 80 characters' do
|
37
|
+
cli = CLI.new([])
|
38
|
+
assert_equal 80, cli.options[:wrap]
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should recognize the -w and --wrap options' do
|
42
|
+
[%w[-w 17], %w[--wrap 17]].each do |args|
|
43
|
+
cli = CLI.new(args)
|
44
|
+
assert_equal 17, cli.options[:wrap]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should recognize the no-wrapping setting' do
|
49
|
+
cli = CLI.new(%w[-w 0])
|
50
|
+
assert_equal false, cli.options[:wrap]
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should raise an error if the wrap option is not an integer' do
|
54
|
+
assert_raises(OptionParser::ParseError) do
|
55
|
+
CLI.new(%w[-w foo])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'encoding' do
|
61
|
+
it 'should encode from STDIN' do
|
62
|
+
stdin = StringIO.new('Ruby')
|
63
|
+
stdout = StringIO.new
|
64
|
+
|
65
|
+
CLI.new([], stdin: stdin, stdout: stdout).call
|
66
|
+
|
67
|
+
assert_equal '<~;KZGo~>', stdout.string
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should accept "-" as a file name' do
|
71
|
+
stdin = StringIO.new('Ruby')
|
72
|
+
stdout = StringIO.new
|
73
|
+
|
74
|
+
CLI.new(['-'], stdin: stdin, stdout: stdout).call
|
75
|
+
|
76
|
+
assert_equal '<~;KZGo~>', stdout.string
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should encode a file' do
|
80
|
+
begin
|
81
|
+
f = Tempfile.create('ascii85_encode')
|
82
|
+
f.write('Ruby')
|
83
|
+
f.close
|
84
|
+
|
85
|
+
stdout = StringIO.new
|
86
|
+
CLI.new([f.path], stdout: stdout).call
|
87
|
+
|
88
|
+
assert_equal '<~;KZGo~>', stdout.string
|
89
|
+
ensure
|
90
|
+
File.unlink(f.path)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should wrap lines' do
|
95
|
+
begin
|
96
|
+
f = Tempfile.create('ascii85_wrap')
|
97
|
+
f.write('a' * 20)
|
98
|
+
f.close
|
99
|
+
|
100
|
+
stdout = StringIO.new
|
101
|
+
CLI.new([f.path, '-w2'], stdout: stdout).call
|
102
|
+
|
103
|
+
assert stdout.string.lines.all? { |l| l.chomp.length <= 2 }
|
104
|
+
ensure
|
105
|
+
File.unlink(f.path)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should fail when the input file is not found' do
|
110
|
+
assert_raises(StandardError) do
|
111
|
+
CLI.new(['./foo/bar/baz']).call
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should fail when the input file is not readable' do
|
116
|
+
begin
|
117
|
+
f = Tempfile.create('ascii85_encode')
|
118
|
+
f.chmod(0o000)
|
119
|
+
|
120
|
+
assert_raises(StandardError) do
|
121
|
+
CLI.new([f.path]).call
|
122
|
+
end
|
123
|
+
ensure
|
124
|
+
File.unlink(f.path)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe 'decoding' do
|
130
|
+
it 'should decode from STDIN' do
|
131
|
+
stdin = StringIO.new('<~;KZGo~>')
|
132
|
+
stdout = StringIO.new
|
133
|
+
|
134
|
+
CLI.new(['-d'], stdin: stdin, stdout: stdout).call
|
135
|
+
|
136
|
+
assert_equal 'Ruby', stdout.string
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should accept "-" as a file name' do
|
140
|
+
stdin = StringIO.new('<~;KZGo~>')
|
141
|
+
stdout = StringIO.new
|
142
|
+
|
143
|
+
CLI.new(['-d','-'], stdin: stdin, stdout: stdout).call
|
144
|
+
|
145
|
+
assert_equal 'Ruby', stdout.string
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should decode a file' do
|
149
|
+
begin
|
150
|
+
f = Tempfile.create('ascii85_decode')
|
151
|
+
f.write('<~;KZGo~>')
|
152
|
+
f.close
|
153
|
+
|
154
|
+
stdout = StringIO.new
|
155
|
+
CLI.new(['-d', f.path], stdout: stdout).call
|
156
|
+
|
157
|
+
assert_equal 'Ruby', stdout.string
|
158
|
+
ensure
|
159
|
+
File.unlink(f.path)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should fail when the input file is not found' do
|
164
|
+
assert_raises(StandardError) do
|
165
|
+
CLI.new(['-d', './foo/bar/baz']).call
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should fail when the input file is not readable' do
|
170
|
+
begin
|
171
|
+
f = Tempfile.create('ascii85_decode')
|
172
|
+
f.chmod(0o000)
|
173
|
+
|
174
|
+
assert_raises(StandardError) do
|
175
|
+
CLI.new(['-d', f.path]).call
|
176
|
+
end
|
177
|
+
ensure
|
178
|
+
File.unlink(f.path)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe 'invalid input' do
|
183
|
+
it 'should return the empty string when the input does not have delimiters' do
|
184
|
+
stdin = StringIO.new('No delimiters')
|
185
|
+
stdout = StringIO.new
|
186
|
+
|
187
|
+
CLI.new(['-d'], stdin: stdin, stdout: stdout).call
|
188
|
+
|
189
|
+
assert_equal '', stdout.string
|
190
|
+
end
|
191
|
+
|
192
|
+
ERROR_CASES = [
|
193
|
+
'<~!!y!!~>',
|
194
|
+
'<~!!z!!~>',
|
195
|
+
'<~s8W-#~>',
|
196
|
+
'<~!~>',
|
197
|
+
]
|
198
|
+
|
199
|
+
it 'should raise an error when invalid input is encountered' do
|
200
|
+
ERROR_CASES.each do |input|
|
201
|
+
stdin = StringIO.new(input)
|
202
|
+
stdout = StringIO.new
|
203
|
+
|
204
|
+
assert_raises(Ascii85::DecodingError) do
|
205
|
+
CLI.new(['-d'], stdin: stdin, stdout: stdout).call
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
data/spec/lib/ascii85_spec.rb
CHANGED
@@ -1,133 +1,162 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rubygems'
|
4
3
|
require 'minitest/autorun'
|
4
|
+
require 'stringio'
|
5
5
|
|
6
6
|
# Require implementation
|
7
|
-
require File.expand_path('
|
7
|
+
require File.expand_path('../../lib/ascii85', __dir__)
|
8
|
+
|
9
|
+
TEST_CASES = {
|
10
|
+
'' => '',
|
11
|
+
' ' => '<~+9~>',
|
12
|
+
|
13
|
+
"\0" * 1 => '<~!!~>',
|
14
|
+
"\0" * 2 => '<~!!!~>',
|
15
|
+
"\0" * 3 => '<~!!!!~>',
|
16
|
+
"\0" * 4 => '<~z~>',
|
17
|
+
"\0" * 5 => '<~z!!~>',
|
18
|
+
"A\0\0\0\0" => '<~5l^lb!!~>', # No z-abbreviation!
|
19
|
+
|
20
|
+
'A' => '<~5l~>',
|
21
|
+
'AB' => '<~5sb~>',
|
22
|
+
'ABC' => '<~5sdp~>',
|
23
|
+
'ABCD' => '<~5sdq,~>',
|
24
|
+
'ABCDE' => '<~5sdq,70~>',
|
25
|
+
'ABCDEF' => '<~5sdq,77I~>',
|
26
|
+
'ABCDEFG' => '<~5sdq,77Kc~>',
|
27
|
+
'ABCDEFGH' => '<~5sdq,77Kd<~>',
|
28
|
+
'ABCDEFGHI' => '<~5sdq,77Kd<8H~>',
|
29
|
+
'Ascii85' => '<~6$$OMBfIs~>',
|
30
|
+
|
31
|
+
'Antidisestablishmentarianism' => '<~6#LdYA8-*rF*(i"Ch[s(D.RU,@<-\'jDJ=0/~>',
|
32
|
+
|
33
|
+
# Dōmo arigatō, Mr. Roboto (according to Wikipedia)
|
34
|
+
'どうもありがとうミスターロボット' =>
|
35
|
+
'<~j+42iJVN3:K&_E6j+<0KJW/W?W8iG`j+EuaK"9on^Z0sZj+FJoK:LtSKB%T?~>',
|
36
|
+
|
37
|
+
[Math::PI].pack('G') => '<~5RAV2<(&;T~>',
|
38
|
+
[Math::E].pack('G') => '<~5R"n0M\\K6,~>',
|
39
|
+
|
40
|
+
# Minified example from Github issue 8.
|
41
|
+
# Note that OT and OU as the trailing characters are equivalent.
|
42
|
+
"\x9B\xB6\xB9+\x91" => '<~S$ojXOT~>'
|
43
|
+
}.freeze
|
8
44
|
|
9
45
|
describe Ascii85 do
|
10
|
-
|
11
|
-
|
12
|
-
TEST_CASES = {
|
13
|
-
"" => "",
|
14
|
-
" " => "<~+9~>",
|
15
|
-
|
16
|
-
"\0" * 1 => "<~!!~>",
|
17
|
-
"\0" * 2 => "<~!!!~>",
|
18
|
-
"\0" * 3 => "<~!!!!~>",
|
19
|
-
"\0" * 4 => "<~z~>",
|
20
|
-
"\0" * 5 => "<~z!!~>",
|
21
|
-
"A\0\0\0\0" => "<~5l^lb!!~>", # No z-abbreviation!
|
22
|
-
|
23
|
-
"A" => "<~5l~>",
|
24
|
-
"AB" => "<~5sb~>",
|
25
|
-
"ABC" => "<~5sdp~>",
|
26
|
-
"ABCD" => "<~5sdq,~>",
|
27
|
-
"ABCDE" => "<~5sdq,70~>",
|
28
|
-
"ABCDEF" => "<~5sdq,77I~>",
|
29
|
-
"ABCDEFG" => "<~5sdq,77Kc~>",
|
30
|
-
"ABCDEFGH" => "<~5sdq,77Kd<~>",
|
31
|
-
"ABCDEFGHI" => "<~5sdq,77Kd<8H~>",
|
32
|
-
"Ascii85" => "<~6$$OMBfIs~>",
|
33
|
-
|
34
|
-
'Antidisestablishmentarianism' => '<~6#LdYA8-*rF*(i"Ch[s(D.RU,@<-\'jDJ=0/~>',
|
35
|
-
|
36
|
-
# Dōmo arigatō, Mr. Roboto (according to Wikipedia)
|
37
|
-
'どうもありがとうミスターロボット' =>
|
38
|
-
"<~j+42iJVN3:K&_E6j+<0KJW/W?W8iG`j+EuaK\"9on^Z0sZj+FJoK:LtSKB%T?~>",
|
39
|
-
|
40
|
-
[Math::PI].pack('G') => "<~5RAV2<(&;T~>",
|
41
|
-
[Math::E].pack('G') => "<~5R\"n0M\\K6,~>"
|
42
|
-
}
|
43
|
-
|
44
|
-
it "#decode should be the inverse of #encode" do
|
45
|
-
# Generate a random string
|
46
|
+
it '#decode should be the inverse of #encode' do
|
47
|
+
# Generate a test string that contains all possible bytes
|
46
48
|
test_str = String.new
|
47
|
-
(
|
48
|
-
test_str <<
|
49
|
+
(0..255).each do |c|
|
50
|
+
test_str << c.chr
|
49
51
|
end
|
50
52
|
|
51
53
|
encoded = Ascii85.encode(test_str)
|
52
54
|
decoded = Ascii85.decode(encoded)
|
53
55
|
|
54
|
-
assert_equal
|
56
|
+
assert_equal test_str, decoded
|
55
57
|
end
|
56
58
|
|
57
|
-
describe
|
58
|
-
it
|
59
|
+
describe '#encode' do
|
60
|
+
it 'should encode all specified test-cases correctly' do
|
59
61
|
TEST_CASES.each_pair do |input, encoded|
|
60
|
-
assert_equal Ascii85.encode(input)
|
62
|
+
assert_equal encoded, Ascii85.encode(input)
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
64
|
-
it
|
65
|
-
|
66
|
-
|
66
|
+
it 'should always return unfrozen Strings' do
|
67
|
+
TEST_CASES.each_pair do |input, encoded|
|
68
|
+
assert_equal false, Ascii85.encode(input).frozen?
|
67
69
|
end
|
70
|
+
end
|
68
71
|
|
69
|
-
|
70
|
-
|
72
|
+
it 'should encode Strings in different encodings correctly' do
|
73
|
+
input_euc_jp = 'どうもありがとうミスターロボット'.encode('EUC-JP')
|
74
|
+
input_binary = input_euc_jp.force_encoding('ASCII-8BIT')
|
71
75
|
|
72
|
-
assert_equal Ascii85.encode(
|
76
|
+
assert_equal Ascii85.encode(input_binary), Ascii85.encode(input_euc_jp)
|
73
77
|
end
|
74
78
|
|
75
|
-
it
|
79
|
+
it 'should produce output lines no longer than specified' do
|
76
80
|
test_str = '0123456789' * 30
|
77
81
|
|
78
82
|
#
|
79
83
|
# No wrap
|
80
84
|
#
|
81
|
-
assert_equal Ascii85.encode(test_str, false).count("\n")
|
85
|
+
assert_equal 0, Ascii85.encode(test_str, false).count("\n")
|
82
86
|
|
83
87
|
#
|
84
88
|
# x characters per line, except for the last one
|
85
89
|
#
|
86
|
-
|
87
|
-
|
90
|
+
(2..12).each do |x|
|
91
|
+
encoded = Ascii85.encode(test_str, x)
|
88
92
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
93
|
+
# Determine the length of all lines
|
94
|
+
count_arr = []
|
95
|
+
encoded.each_line do |line|
|
96
|
+
count_arr << line.chomp.length
|
97
|
+
end
|
98
|
+
|
99
|
+
# The last line is allowed to be shorter than x, so remove it
|
100
|
+
count_arr.pop if count_arr.last <= x
|
94
101
|
|
95
|
-
|
96
|
-
|
102
|
+
# If the end-marker is on a line of its own, the next-to-last line is
|
103
|
+
# allowed to be shorter than specified by exactly one character
|
104
|
+
count_arr.pop if (encoded[-3].chr =~ /[\r\n]/) && (count_arr.last == x - 1)
|
97
105
|
|
98
|
-
|
99
|
-
|
100
|
-
count_arr.pop if (encoded[-3].chr =~ /[\r\n]/) and (count_arr.last == x-1)
|
106
|
+
# Remove all line-lengths that are of length x from count_arr
|
107
|
+
count_arr.delete_if { |len| len == x }
|
101
108
|
|
102
|
-
|
103
|
-
|
109
|
+
# Now count_arr should be empty
|
110
|
+
assert_empty count_arr
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should not split the end-marker to achieve correct line length' do
|
115
|
+
assert_equal "<~z\n~>", Ascii85.encode("\0" * 4, 4)
|
116
|
+
end
|
104
117
|
|
105
|
-
|
106
|
-
|
118
|
+
it 'should encode to an IO object when provided' do
|
119
|
+
output = StringIO.new
|
120
|
+
result = Ascii85.encode('Ruby', out: output)
|
121
|
+
assert_equal output, result
|
122
|
+
assert_equal '<~;KZGo~>', output.string
|
107
123
|
end
|
108
124
|
|
109
|
-
it
|
110
|
-
|
125
|
+
it 'should encode from an IO object' do
|
126
|
+
input = StringIO.new('Ruby')
|
127
|
+
result = Ascii85.encode(input)
|
128
|
+
assert_equal '<~;KZGo~>', result
|
111
129
|
end
|
112
130
|
end
|
113
131
|
|
114
|
-
describe
|
115
|
-
it
|
132
|
+
describe '#extract' do
|
133
|
+
it 'should extract data within delimiters only' do
|
134
|
+
assert_empty Ascii85.extract('<~~>')
|
135
|
+
assert_empty Ascii85.extract("Doesn't contain delimiters")
|
136
|
+
assert_empty Ascii85.extract('Mismatched ~> delimiters 1')
|
137
|
+
assert_empty Ascii85.extract('Mismatched <~ delimiters 2')
|
138
|
+
assert_empty Ascii85.extract('Mismatched ~><~ delimiters 3')
|
139
|
+
|
140
|
+
assert_equal ';KZGo', Ascii85.extract('<~;KZGo~><~z~>')
|
141
|
+
assert_equal 'z', Ascii85.extract('FooBar<~z~>BazQux')
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#decode' do
|
146
|
+
it 'should decode all specified test-cases correctly' do
|
116
147
|
TEST_CASES.each_pair do |decoded, input|
|
117
|
-
|
118
|
-
assert_equal Ascii85.decode(input), decoded.dup.force_encoding('ASCII-8BIT')
|
119
|
-
else
|
120
|
-
assert_equal Ascii85.decode(input), decoded
|
121
|
-
end
|
148
|
+
assert_equal decoded.dup.force_encoding('ASCII-8BIT'), Ascii85.decode(input)
|
122
149
|
end
|
123
150
|
end
|
124
151
|
|
125
|
-
it
|
126
|
-
|
127
|
-
|
152
|
+
it 'should always return unfrozen Strings' do
|
153
|
+
TEST_CASES.each_pair do |input, encoded|
|
154
|
+
assert_equal false, Ascii85.decode(encoded).frozen?
|
128
155
|
end
|
156
|
+
end
|
129
157
|
|
130
|
-
|
158
|
+
it 'should accept valid input in encodings other than the default' do
|
159
|
+
input = 'Ragnarök τέχνη русский язык I ♥ Ruby'
|
131
160
|
input_ascii85 = Ascii85.encode(input)
|
132
161
|
|
133
162
|
# Try to encode input_ascii85 in all possible encodings and see if we
|
@@ -139,57 +168,96 @@ describe Ascii85 do
|
|
139
168
|
# CP949 is a Microsoft Codepage for Korean, which apparently does not
|
140
169
|
# include a backslash, even though #ascii_compatible? returns true. This
|
141
170
|
# leads to an Ascii85::DecodingError, so we simply skip the encoding.
|
142
|
-
next if encoding.name ==
|
171
|
+
next if encoding.name == 'CP949'
|
143
172
|
|
144
173
|
begin
|
145
174
|
to_test = input_ascii85.encode(encoding)
|
146
|
-
assert_equal Ascii85.decode(to_test).force_encoding('UTF-8')
|
175
|
+
assert_equal input, Ascii85.decode(to_test).force_encoding('UTF-8')
|
147
176
|
rescue Encoding::ConverterNotFoundError
|
148
177
|
# Ignore this encoding
|
149
178
|
end
|
150
179
|
end
|
151
180
|
end
|
152
181
|
|
153
|
-
it
|
154
|
-
assert_empty Ascii85.decode(
|
182
|
+
it 'should only process data within delimiters' do
|
183
|
+
assert_empty Ascii85.decode('<~~>')
|
155
184
|
assert_empty Ascii85.decode("Doesn't contain delimiters")
|
156
|
-
assert_empty Ascii85.decode(
|
157
|
-
assert_empty Ascii85.decode(
|
158
|
-
assert_empty Ascii85.decode(
|
185
|
+
assert_empty Ascii85.decode('Mismatched ~> delimiters 1')
|
186
|
+
assert_empty Ascii85.decode('Mismatched <~ delimiters 2')
|
187
|
+
assert_empty Ascii85.decode('Mismatched ~><~ delimiters 3')
|
159
188
|
|
160
|
-
assert_equal Ascii85.decode(
|
161
|
-
assert_equal Ascii85.decode(
|
189
|
+
assert_equal 'Ruby', Ascii85.decode('<~;KZGo~><~z~>')
|
190
|
+
assert_equal "\0\0\0\0", Ascii85.decode('FooBar<~z~>BazQux')
|
162
191
|
end
|
163
192
|
|
164
|
-
it
|
193
|
+
it 'should ignore whitespace' do
|
165
194
|
decoded = Ascii85.decode("<~6 #LdYA\r\08\n \n\n- *rF*(i\"Ch[s \t(D.RU,@ <-\'jDJ=0\f/~>")
|
166
|
-
assert_equal
|
195
|
+
assert_equal 'Antidisestablishmentarianism', decoded
|
167
196
|
end
|
168
197
|
|
169
|
-
it
|
170
|
-
|
171
|
-
|
172
|
-
end
|
198
|
+
it 'should return ASCII-8BIT encoded strings' do
|
199
|
+
assert_equal 'ASCII-8BIT', Ascii85.decode('<~;KZGo~>').encoding.name
|
200
|
+
end
|
173
201
|
|
174
|
-
|
202
|
+
it 'should decode to an IO object when provided' do
|
203
|
+
output = StringIO.new
|
204
|
+
result = Ascii85.decode('<~;KZGo~>', out: output)
|
205
|
+
assert_equal output, result
|
206
|
+
assert_equal 'Ruby', output.string
|
175
207
|
end
|
176
208
|
|
177
|
-
describe
|
178
|
-
it
|
209
|
+
describe 'Error conditions' do
|
210
|
+
it 'should raise DecodingError if it encounters a word >= 2**32' do
|
179
211
|
assert_raises(Ascii85::DecodingError) { Ascii85.decode('<~s8W-#~>') }
|
180
212
|
end
|
181
213
|
|
182
|
-
it
|
214
|
+
it 'should raise DecodingError if it encounters an invalid character' do
|
183
215
|
assert_raises(Ascii85::DecodingError) { Ascii85.decode('<~!!y!!~>') }
|
184
216
|
end
|
185
217
|
|
186
|
-
it
|
218
|
+
it 'should raise DecodingError if the last tuple consists of a single character' do
|
187
219
|
assert_raises(Ascii85::DecodingError) { Ascii85.decode('<~!~>') }
|
188
220
|
end
|
189
221
|
|
190
|
-
it
|
222
|
+
it 'should raise DecodingError if a z is found inside a 5-tuple' do
|
191
223
|
assert_raises(Ascii85::DecodingError) { Ascii85.decode('<~!!z!!~>') }
|
192
224
|
end
|
193
225
|
end
|
194
226
|
end
|
227
|
+
|
228
|
+
describe '#decode_raw' do
|
229
|
+
it 'should decode raw Ascii85 without delimiters' do
|
230
|
+
TEST_CASES.each_pair do |decoded, input|
|
231
|
+
raw_input = input[2...-2] # Remove '<~' and '~>'
|
232
|
+
assert_equal decoded.dup.force_encoding('ASCII-8BIT'), Ascii85.decode_raw(raw_input)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'should always return unfrozen Strings' do
|
237
|
+
TEST_CASES.each_pair do |decoded, input|
|
238
|
+
raw_input = input[2...-2] # Remove '<~' and '~>'
|
239
|
+
assert_equal false, Ascii85.decode_raw(raw_input).frozen?
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should decode from an IO object' do
|
244
|
+
input = StringIO.new(';KZGo')
|
245
|
+
result = Ascii85.decode_raw(input)
|
246
|
+
assert_equal 'Ruby', result
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'should decode to an IO object when provided' do
|
250
|
+
output = StringIO.new
|
251
|
+
result = Ascii85.decode_raw(';KZGo', out: output)
|
252
|
+
assert_equal output, result
|
253
|
+
assert_equal 'Ruby', output.string
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should raise DecodingError for invalid input' do
|
257
|
+
assert_raises(Ascii85::DecodingError) { Ascii85.decode_raw('s8W-#') }
|
258
|
+
assert_raises(Ascii85::DecodingError) { Ascii85.decode_raw('!!y!!') }
|
259
|
+
assert_raises(Ascii85::DecodingError) { Ascii85.decode_raw('!') }
|
260
|
+
assert_raises(Ascii85::DecodingError) { Ascii85.decode_raw('!!z!!') }
|
261
|
+
end
|
262
|
+
end
|
195
263
|
end
|
metadata
CHANGED
@@ -1,57 +1,49 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Ascii85
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johannes Holzfuß
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 1.0.0
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 1.0.0
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: minitest
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5'
|
31
20
|
- - ">="
|
32
21
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
22
|
+
version: 5.12.0
|
34
23
|
type: :development
|
35
24
|
prerelease: false
|
36
25
|
version_requirements: !ruby/object:Gem::Requirement
|
37
26
|
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '5'
|
38
30
|
- - ">="
|
39
31
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
32
|
+
version: 5.12.0
|
41
33
|
- !ruby/object:Gem::Dependency
|
42
34
|
name: rake
|
43
35
|
requirement: !ruby/object:Gem::Requirement
|
44
36
|
requirements:
|
45
|
-
- - "
|
37
|
+
- - "~>"
|
46
38
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
39
|
+
version: '13'
|
48
40
|
type: :development
|
49
41
|
prerelease: false
|
50
42
|
version_requirements: !ruby/object:Gem::Requirement
|
51
43
|
requirements:
|
52
|
-
- - "
|
44
|
+
- - "~>"
|
53
45
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
46
|
+
version: '13'
|
55
47
|
description: Ascii85 provides methods to encode/decode Adobe's binary-to-text encoding
|
56
48
|
of the same name.
|
57
49
|
email: johannes@holzfuss.name
|
@@ -63,14 +55,15 @@ extra_rdoc_files:
|
|
63
55
|
- LICENSE
|
64
56
|
files:
|
65
57
|
- Ascii85.gemspec
|
58
|
+
- CHANGELOG.md
|
66
59
|
- Gemfile
|
67
|
-
- History.txt
|
68
60
|
- LICENSE
|
69
61
|
- README.md
|
70
62
|
- Rakefile
|
71
63
|
- bin/ascii85
|
72
64
|
- lib/Ascii85/version.rb
|
73
65
|
- lib/ascii85.rb
|
66
|
+
- spec/bin/cli_spec.rb
|
74
67
|
- spec/lib/ascii85_spec.rb
|
75
68
|
homepage: https://github.com/DataWraith/ascii85gem/
|
76
69
|
licenses:
|
@@ -84,16 +77,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
77
|
requirements:
|
85
78
|
- - ">="
|
86
79
|
- !ruby/object:Gem::Version
|
87
|
-
version:
|
80
|
+
version: 2.7.0
|
88
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
82
|
requirements:
|
90
83
|
- - ">="
|
91
84
|
- !ruby/object:Gem::Version
|
92
85
|
version: '0'
|
93
86
|
requirements: []
|
94
|
-
rubygems_version: 3.5.
|
87
|
+
rubygems_version: 3.5.15
|
95
88
|
signing_key:
|
96
89
|
specification_version: 4
|
97
90
|
summary: Ascii85 encoder/decoder
|
98
91
|
test_files:
|
92
|
+
- spec/bin/cli_spec.rb
|
99
93
|
- spec/lib/ascii85_spec.rb
|