chars 0.2.4 → 0.3.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.
- checksums.yaml +4 -4
- data/ChangeLog.md +12 -0
- data/README.md +61 -10
- data/benchmarks/compare.rb +1 -1
- data/benchmarks/substrings.rb +25 -0
- data/lib/chars/char_set.rb +285 -56
- data/lib/chars/chars.rb +33 -4
- data/lib/chars/string_enumerator.rb +98 -0
- data/lib/chars/version.rb +1 -1
- data/spec/char_set_spec.rb +415 -31
- data/spec/chars_spec.rb +183 -27
- data/spec/string_enumerator_spec.rb +99 -0
- metadata +4 -2
- data/benchmarks/strings_in.rb +0 -23
data/spec/chars_spec.rb
CHANGED
@@ -2,55 +2,211 @@ require 'spec_helper'
|
|
2
2
|
require 'chars/chars'
|
3
3
|
|
4
4
|
describe Chars do
|
5
|
-
|
6
|
-
|
5
|
+
let(:numeric_chars) { '0123456789'.chars }
|
6
|
+
|
7
|
+
describe "NUMERIC" do
|
8
|
+
subject { described_class::NUMERIC }
|
9
|
+
|
10
|
+
it "must contain numeric characters" do
|
11
|
+
expect(subject.chars).to match_array(numeric_chars)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "DIGITS" do
|
16
|
+
subject { described_class::DIGITS }
|
17
|
+
|
18
|
+
it "must equal NUMERIC" do
|
19
|
+
expect(subject).to be(described_class::NUMERIC)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "OCTAL" do
|
24
|
+
subject { described_class::OCTAL }
|
25
|
+
|
26
|
+
it "must contain all octal characters" do
|
27
|
+
expect(subject.chars).to match_array("01234567".chars)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:uppercase_hex_chars) { "0123456789ABCDEF".chars }
|
32
|
+
|
33
|
+
describe "UPPERCASE_HEXADECIMAL" do
|
34
|
+
subject { described_class::UPPERCASE_HEXADECIMAL }
|
35
|
+
|
36
|
+
it "must contain all upper-case hexadecimal characters" do
|
37
|
+
expect(subject.chars).to match_array(uppercase_hex_chars)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:lowercase_hex_chars) { "0123456789abcdef".chars }
|
42
|
+
|
43
|
+
describe "LOWERCASE_HEXADECIMAL" do
|
44
|
+
subject { described_class::LOWERCASE_HEXADECIMAL }
|
45
|
+
|
46
|
+
it "must contain all lower-case hexadecimal characters" do
|
47
|
+
expect(subject.chars).to match_array(lowercase_hex_chars)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "HEXADECIMAL" do
|
52
|
+
subject { described_class::HEXADECIMAL }
|
53
|
+
|
54
|
+
it "must contain both upper-case and lower-case hexadecimal characters" do
|
55
|
+
expect(subject.chars).to match_array(uppercase_hex_chars | lowercase_hex_chars)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
let(:uppercase_alpha_chars) { "ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars }
|
60
|
+
|
61
|
+
describe "UPPERCASE_ALPHA" do
|
62
|
+
subject { described_class::UPPERCASE_ALPHA }
|
63
|
+
|
64
|
+
it "must contain all upper-case alpha characters" do
|
65
|
+
expect(subject.chars).to match_array(uppercase_alpha_chars)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
let(:lowercase_alpha_chars) { "abcdefghijklmnopqrstuvwxyz".chars }
|
70
|
+
|
71
|
+
describe "LOWERCASE_ALPHA" do
|
72
|
+
subject { described_class::LOWERCASE_ALPHA }
|
73
|
+
|
74
|
+
it "must contain all lower-case alpha characters" do
|
75
|
+
expect(subject.chars).to match_array(lowercase_alpha_chars)
|
76
|
+
end
|
7
77
|
end
|
8
78
|
|
9
|
-
|
10
|
-
|
79
|
+
let(:alpha_chars) { uppercase_alpha_chars | lowercase_alpha_chars }
|
80
|
+
|
81
|
+
describe "ALPHA" do
|
82
|
+
subject { described_class::ALPHA }
|
83
|
+
|
84
|
+
it "must contain all alpha characters" do
|
85
|
+
expect(subject.chars).to match_array(alpha_chars)
|
86
|
+
end
|
11
87
|
end
|
12
88
|
|
13
|
-
|
14
|
-
|
89
|
+
let(:alpha_numeric_chars) { alpha_chars | numeric_chars }
|
90
|
+
|
91
|
+
describe "ALPHA_NUMERIC" do
|
92
|
+
subject { described_class::ALPHA_NUMERIC }
|
93
|
+
|
94
|
+
it "must contain all alpha-numeric characters" do
|
95
|
+
expect(subject.chars).to match_array(alpha_numeric_chars)
|
96
|
+
end
|
15
97
|
end
|
16
98
|
|
17
|
-
|
18
|
-
|
99
|
+
let(:punctuation_chars) { " !\"'(),-.:;?[]`{}~".chars }
|
100
|
+
|
101
|
+
describe "PUNCTUATION" do
|
102
|
+
subject { described_class::PUNCTUATION }
|
103
|
+
|
104
|
+
it "must contain all punctuation characters" do
|
105
|
+
expect(subject.chars).to match_array(punctuation_chars)
|
106
|
+
end
|
19
107
|
end
|
20
108
|
|
21
|
-
|
22
|
-
|
109
|
+
let(:symbolic_chars) { " !\"\#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".chars }
|
110
|
+
|
111
|
+
describe "SYMBOLS" do
|
112
|
+
subject { described_class::SYMBOLS }
|
113
|
+
|
114
|
+
it "must contain all symbolic characters" do
|
115
|
+
expect(subject.chars).to match_array(symbolic_chars)
|
116
|
+
end
|
23
117
|
end
|
24
118
|
|
25
|
-
|
26
|
-
|
119
|
+
let(:whitespace_chars) { "\t\n\v\f\r ".chars }
|
120
|
+
|
121
|
+
describe "WHITESPACE" do
|
122
|
+
subject { described_class::WHITESPACE }
|
123
|
+
|
124
|
+
it "must contain all white-space characters" do
|
125
|
+
expect(subject.chars).to match_array(whitespace_chars)
|
126
|
+
end
|
27
127
|
end
|
28
128
|
|
29
|
-
|
30
|
-
|
129
|
+
describe "SPACE" do
|
130
|
+
subject { described_class::SPACE }
|
131
|
+
|
132
|
+
it "must equal WHITESPACE" do
|
133
|
+
expect(subject).to be(described_class::WHITESPACE)
|
134
|
+
end
|
31
135
|
end
|
32
136
|
|
33
|
-
|
34
|
-
|
137
|
+
describe "VISIBLE" do
|
138
|
+
subject { described_class::VISIBLE }
|
139
|
+
|
140
|
+
it "must contain all all alpha-numeric, symbols, and some punctuation" do
|
141
|
+
expect(subject.chars).to match_array(alpha_numeric_chars | "!\"\#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".chars)
|
142
|
+
end
|
35
143
|
end
|
36
144
|
|
37
|
-
|
38
|
-
|
145
|
+
describe "PRINTABLE" do
|
146
|
+
subject { described_class::PRINTABLE }
|
147
|
+
|
148
|
+
it "must contain all alpha-numeric, punctuation, symbols, and whitespace characters" do
|
149
|
+
expect(subject.chars).to match_array(
|
150
|
+
alpha_numeric_chars |
|
151
|
+
punctuation_chars |
|
152
|
+
symbolic_chars |
|
153
|
+
whitespace_chars
|
154
|
+
)
|
155
|
+
end
|
39
156
|
end
|
40
|
-
|
41
|
-
|
42
|
-
|
157
|
+
|
158
|
+
describe "CONTROL" do
|
159
|
+
subject { described_class::CONTROL }
|
160
|
+
|
161
|
+
it "must contain ASCII bytes 0x00 - 0x1f and 0x7f" do
|
162
|
+
expect(subject.bytes).to eq([*0x00..0x1f, 0x7f])
|
163
|
+
end
|
43
164
|
end
|
44
165
|
|
45
|
-
|
46
|
-
|
166
|
+
describe "SIGNED_ASCII" do
|
167
|
+
subject { described_class::SIGNED_ASCII }
|
168
|
+
|
169
|
+
it "must contain ASCII bytes 0x00 - 0x7f" do
|
170
|
+
expect(subject.bytes).to eq([*0x00..0x7f])
|
171
|
+
end
|
47
172
|
end
|
48
173
|
|
49
|
-
|
50
|
-
|
174
|
+
describe "ASCII" do
|
175
|
+
subject { described_class::ASCII }
|
176
|
+
|
177
|
+
it "must contain ASCII bytes 0x00 - 0xff" do
|
178
|
+
expect(subject.bytes).to eq([*0x00..0xff])
|
179
|
+
end
|
51
180
|
end
|
52
181
|
|
53
|
-
|
54
|
-
|
182
|
+
{
|
183
|
+
:numeric => :NUMERIC,
|
184
|
+
:digits => :DIGITS,
|
185
|
+
:octal => :OCTAL,
|
186
|
+
|
187
|
+
:uppercase_hexadecimal => :UPPERCASE_HEXADECIMAL,
|
188
|
+
:lowercase_hexadecimal => :LOWERCASE_HEXADECIMAL,
|
189
|
+
:hexadecimal => :HEXADECIMAL,
|
190
|
+
|
191
|
+
:uppercase_alpha => :UPPERCASE_ALPHA,
|
192
|
+
:lowercase_alpha => :LOWERCASE_ALPHA,
|
193
|
+
:alpha => :ALPHA,
|
194
|
+
|
195
|
+
:punctuation => :PUNCTUATION,
|
196
|
+
:symbols => :SYMBOLS,
|
197
|
+
:whitespace => :WHITESPACE,
|
198
|
+
:space => :SPACE,
|
199
|
+
:visible => :VISIBLE,
|
200
|
+
:printable => :PRINTABLE,
|
201
|
+
:control => :CONTROL,
|
202
|
+
|
203
|
+
:signed_ascii => :SIGNED_ASCII,
|
204
|
+
:ascii => :ASCII
|
205
|
+
}.each do |method,constant|
|
206
|
+
describe ".#{method}" do
|
207
|
+
it "must return #{constant}" do
|
208
|
+
expect(subject.send(method)).to be(described_class.const_get(constant))
|
209
|
+
end
|
210
|
+
end
|
55
211
|
end
|
56
212
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'chars/char_set'
|
3
|
+
require 'chars/string_enumerator'
|
4
|
+
|
5
|
+
describe Chars::StringEnumerator do
|
6
|
+
let(:char_set) { Chars::CharSet['a', 'b', 'c'] }
|
7
|
+
let(:length) { 3 }
|
8
|
+
|
9
|
+
subject { described_class.new(char_set,length) }
|
10
|
+
|
11
|
+
describe "#initialize" do
|
12
|
+
it "must set #char_set" do
|
13
|
+
expect(subject.char_set).to eq(char_set)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must set #length" do
|
17
|
+
expect(subject.length).to eq(length)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#each" do
|
22
|
+
let(:expected_strings) do
|
23
|
+
%w[
|
24
|
+
aaa
|
25
|
+
aab
|
26
|
+
aac
|
27
|
+
aba
|
28
|
+
abb
|
29
|
+
abc
|
30
|
+
aca
|
31
|
+
acb
|
32
|
+
acc
|
33
|
+
baa
|
34
|
+
bab
|
35
|
+
bac
|
36
|
+
bba
|
37
|
+
bbb
|
38
|
+
bbc
|
39
|
+
bca
|
40
|
+
bcb
|
41
|
+
bcc
|
42
|
+
caa
|
43
|
+
cab
|
44
|
+
cac
|
45
|
+
cba
|
46
|
+
cbb
|
47
|
+
cbc
|
48
|
+
cca
|
49
|
+
ccb
|
50
|
+
ccc
|
51
|
+
]
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when a block is given" do
|
55
|
+
it "must enumerate through each sequential string in the char-set and of the desired length" do
|
56
|
+
expect { |b|
|
57
|
+
subject.each(&b)
|
58
|
+
}.to yield_successive_args(*expected_strings)
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when the length is 1" do
|
62
|
+
let(:length) { 1 }
|
63
|
+
|
64
|
+
it "must enumerate over each individual character" do
|
65
|
+
expect { |b|
|
66
|
+
subject.each(&b)
|
67
|
+
}.to yield_successive_args(*char_set.chars)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when the length is 0" do
|
72
|
+
let(:length) { 0 }
|
73
|
+
|
74
|
+
it "must yield an empty String" do
|
75
|
+
expect { |b|
|
76
|
+
subject.each(&b)
|
77
|
+
}.to yield_successive_args("")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when #char_set is empty" do
|
82
|
+
let(:char_set) { Chars::CharSet.new }
|
83
|
+
|
84
|
+
it "must yield an empty String" do
|
85
|
+
expect { |b|
|
86
|
+
subject.each(&b)
|
87
|
+
}.to_not yield_control
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "when no block is given" do
|
93
|
+
it "must return an Enumerator object" do
|
94
|
+
expect(subject.each).to be_kind_of(Enumerator)
|
95
|
+
expect(subject.each.to_a).to eq(expected_strings)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chars
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Postmodern
|
@@ -46,7 +46,7 @@ files:
|
|
46
46
|
- README.md
|
47
47
|
- Rakefile
|
48
48
|
- benchmarks/compare.rb
|
49
|
-
- benchmarks/
|
49
|
+
- benchmarks/substrings.rb
|
50
50
|
- chars.gemspec
|
51
51
|
- gemspec.yml
|
52
52
|
- lib/chars.rb
|
@@ -55,12 +55,14 @@ files:
|
|
55
55
|
- lib/chars/extensions.rb
|
56
56
|
- lib/chars/extensions/integer.rb
|
57
57
|
- lib/chars/extensions/string.rb
|
58
|
+
- lib/chars/string_enumerator.rb
|
58
59
|
- lib/chars/version.rb
|
59
60
|
- spec/char_set_spec.rb
|
60
61
|
- spec/chars_spec.rb
|
61
62
|
- spec/extensions/integer_spec.rb
|
62
63
|
- spec/extensions/string_spec.rb
|
63
64
|
- spec/spec_helper.rb
|
65
|
+
- spec/string_enumerator_spec.rb
|
64
66
|
homepage: https://github.com/postmodern/chars.rb#readme
|
65
67
|
licenses:
|
66
68
|
- MIT
|
data/benchmarks/strings_in.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
|
4
|
-
|
5
|
-
require 'chars'
|
6
|
-
require 'benchmark'
|
7
|
-
|
8
|
-
CHARSET = Chars::ALPHA_NUMERIC
|
9
|
-
STRING = File.open('/usr/bin/openssl','rb') do |file|
|
10
|
-
file.read
|
11
|
-
end
|
12
|
-
|
13
|
-
Benchmark.bm(24) do |b|
|
14
|
-
b.report('strings_in') do
|
15
|
-
CHARSET.strings_in(STRING) { |offset,string| }
|
16
|
-
end
|
17
|
-
|
18
|
-
(5..20).step(5) do |n|
|
19
|
-
b.report("strings_in (length=#{n})") do
|
20
|
-
CHARSET.strings_in(STRING, :length => n) { |offset,string| }
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|