rubysl-ipaddr 1.0.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 +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/ipaddr.rb +1 -0
- data/lib/rubysl/ipaddr.rb +2 -0
- data/lib/rubysl/ipaddr/ipaddr.rb +814 -0
- data/lib/rubysl/ipaddr/version.rb +5 -0
- data/rubysl-ipaddr.gemspec +23 -0
- data/spec/hton_spec.rb +29 -0
- data/spec/ipv4_conversion_spec.rb +45 -0
- data/spec/new_spec.rb +94 -0
- data/spec/operator_spec.rb +79 -0
- data/spec/reverse_spec.rb +26 -0
- data/spec/to_s_spec.rb +19 -0
- metadata +123 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require './lib/rubysl/ipaddr/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "rubysl-ipaddr"
|
6
|
+
spec.version = RubySL::IPAddr::VERSION
|
7
|
+
spec.authors = ["Brian Shirai"]
|
8
|
+
spec.email = ["brixen@gmail.com"]
|
9
|
+
spec.description = %q{Ruby standard library ipaddr.}
|
10
|
+
spec.summary = %q{Ruby standard library ipaddr.}
|
11
|
+
spec.homepage = "https://github.com/rubysl/rubysl-ipaddr"
|
12
|
+
spec.license = "BSD"
|
13
|
+
|
14
|
+
spec.files = `git ls-files`.split($/)
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
20
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
21
|
+
spec.add_development_dependency "mspec", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rubysl-prettyprint", "~> 1.0"
|
23
|
+
end
|
data/spec/hton_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
describe "IPAddr#hton" do
|
4
|
+
|
5
|
+
it "converts IPAddr to network byte order" do
|
6
|
+
addr = ''
|
7
|
+
IPAddr.new("1234:5678:9abc:def0:1234:5678:9abc:def0").hton.each_byte do |c|
|
8
|
+
addr += sprintf("%02x", c)
|
9
|
+
end
|
10
|
+
addr.should == "123456789abcdef0123456789abcdef0"
|
11
|
+
addr = ''
|
12
|
+
IPAddr.new("123.45.67.89").hton.each_byte do |c|
|
13
|
+
addr += sprintf("%02x", c)
|
14
|
+
end
|
15
|
+
addr.should == sprintf("%02x%02x%02x%02x", 123, 45, 67, 89)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "IPAddr#new_ntoh" do
|
21
|
+
|
22
|
+
it "creates a new IPAddr using hton notation" do
|
23
|
+
a = IPAddr.new("3ffe:505:2::")
|
24
|
+
IPAddr.new_ntoh(a.hton).to_s.should == "3ffe:505:2::"
|
25
|
+
a = IPAddr.new("192.168.2.1")
|
26
|
+
IPAddr.new_ntoh(a.hton).to_s.should == "192.168.2.1"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
describe "IPAddr#ipv4_compat" do
|
4
|
+
|
5
|
+
it "should ipv4_compat?" do
|
6
|
+
a = IPAddr.new("::192.168.1.2")
|
7
|
+
a.to_s.should == "::192.168.1.2"
|
8
|
+
a.to_string.should == "0000:0000:0000:0000:0000:0000:c0a8:0102"
|
9
|
+
a.family.should == Socket::AF_INET6
|
10
|
+
a.ipv4_compat?.should == true
|
11
|
+
b = a.native
|
12
|
+
b.to_s.should == "192.168.1.2"
|
13
|
+
b.family.should == Socket::AF_INET
|
14
|
+
b.ipv4_compat?.should == false
|
15
|
+
|
16
|
+
a = IPAddr.new("192.168.1.2")
|
17
|
+
b = a.ipv4_compat
|
18
|
+
b.to_s.should == "::192.168.1.2"
|
19
|
+
b.family.should == Socket::AF_INET6
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "IPAddr#ipv4_mapped" do
|
25
|
+
|
26
|
+
it "should ipv4_mapped" do
|
27
|
+
a = IPAddr.new("::ffff:192.168.1.2")
|
28
|
+
a.to_s.should == "::ffff:192.168.1.2"
|
29
|
+
a.to_string.should == "0000:0000:0000:0000:0000:ffff:c0a8:0102"
|
30
|
+
a.family.should == Socket::AF_INET6
|
31
|
+
a.ipv4_mapped?.should == true
|
32
|
+
b = a.native
|
33
|
+
b.to_s.should == "192.168.1.2"
|
34
|
+
b.family.should == Socket::AF_INET
|
35
|
+
b.ipv4_mapped?.should == false
|
36
|
+
|
37
|
+
a = IPAddr.new("192.168.1.2")
|
38
|
+
b = a.ipv4_mapped
|
39
|
+
b.to_s.should == "::ffff:192.168.1.2"
|
40
|
+
b.family.should == Socket::AF_INET6
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
data/spec/new_spec.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
describe "IPAddr#new" do
|
4
|
+
it "initializes IPAddr" do
|
5
|
+
lambda{ IPAddr.new("3FFE:505:ffff::/48") }.should_not raise_error
|
6
|
+
lambda{ IPAddr.new("0:0:0:1::") }.should_not raise_error
|
7
|
+
lambda{ IPAddr.new("2001:200:300::/48") }.should_not raise_error
|
8
|
+
end
|
9
|
+
|
10
|
+
it "initializes IPAddr ipv6 address with short notation" do
|
11
|
+
a = IPAddr.new
|
12
|
+
a.to_s.should == "::"
|
13
|
+
a.to_string.should == "0000:0000:0000:0000:0000:0000:0000:0000"
|
14
|
+
a.family.should == Socket::AF_INET6
|
15
|
+
end
|
16
|
+
|
17
|
+
it "initializes IPAddr ipv6 address with long notation" do
|
18
|
+
a = IPAddr.new("0123:4567:89ab:cdef:0ABC:DEF0:1234:5678")
|
19
|
+
a.to_s.should == "123:4567:89ab:cdef:abc:def0:1234:5678"
|
20
|
+
a.to_string.should == "0123:4567:89ab:cdef:0abc:def0:1234:5678"
|
21
|
+
a.family.should == Socket::AF_INET6
|
22
|
+
end
|
23
|
+
|
24
|
+
it "initializes IPAddr ipv6 address with / subnet notation" do
|
25
|
+
a = IPAddr.new("3ffe:505:2::/48")
|
26
|
+
a.to_s.should == "3ffe:505:2::"
|
27
|
+
a.to_string.should == "3ffe:0505:0002:0000:0000:0000:0000:0000"
|
28
|
+
a.family.should == Socket::AF_INET6
|
29
|
+
a.ipv4?.should == false
|
30
|
+
a.ipv6?.should == true
|
31
|
+
a.inspect.should == "#<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000>"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "initializes IPAddr ipv6 address with mask subnet notation" do
|
35
|
+
a = IPAddr.new("3ffe:505:2::/ffff:ffff:ffff::")
|
36
|
+
a.to_s.should == "3ffe:505:2::"
|
37
|
+
a.to_string.should == "3ffe:0505:0002:0000:0000:0000:0000:0000"
|
38
|
+
a.family.should == Socket::AF_INET6
|
39
|
+
end
|
40
|
+
|
41
|
+
it "initializes IPAddr ipv4 address with all zeroes" do
|
42
|
+
a = IPAddr.new("0.0.0.0")
|
43
|
+
a.to_s.should == "0.0.0.0"
|
44
|
+
a.to_string.should == "0.0.0.0"
|
45
|
+
a.family.should == Socket::AF_INET
|
46
|
+
end
|
47
|
+
|
48
|
+
it "initializes IPAddr ipv4 address" do
|
49
|
+
a = IPAddr.new("192.168.1.2")
|
50
|
+
a.to_s.should == "192.168.1.2"
|
51
|
+
a.to_string.should == "192.168.1.2"
|
52
|
+
a.family.should == Socket::AF_INET
|
53
|
+
a.ipv4?.should == true
|
54
|
+
a.ipv6?.should == false
|
55
|
+
end
|
56
|
+
|
57
|
+
it "initializes IPAddr ipv4 address with / subnet notation" do
|
58
|
+
a = IPAddr.new("192.168.1.2/24")
|
59
|
+
a.to_s.should == "192.168.1.0"
|
60
|
+
a.to_string.should == "192.168.1.0"
|
61
|
+
a.family.should == Socket::AF_INET
|
62
|
+
a.inspect.should == "#<IPAddr: IPv4:192.168.1.0/255.255.255.0>"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "initializes IPAddr ipv4 address with subnet mask" do
|
66
|
+
a = IPAddr.new("192.168.1.2/255.255.255.0")
|
67
|
+
a.to_s.should == "192.168.1.0"
|
68
|
+
a.to_string.should == "192.168.1.0"
|
69
|
+
a.family.should == Socket::AF_INET
|
70
|
+
end
|
71
|
+
|
72
|
+
ruby_bug "#6479", "1.9.3.235" do
|
73
|
+
it "initializes IPAddr ipv4 mapped address with subnet mask" do
|
74
|
+
a = IPAddr.new("::1:192.168.1.2/120")
|
75
|
+
a.to_s.should == "::1:c0a8:100"
|
76
|
+
a.to_string.should == "0000:0000:0000:0000:0000:0001:c0a8:0100"
|
77
|
+
a.family.should == Socket::AF_INET6
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "raises on incorrect IPAddr strings" do
|
82
|
+
[
|
83
|
+
["fe80::1%fxp0"],
|
84
|
+
["::1/255.255.255.0"],
|
85
|
+
[IPAddr.new("::1").to_i],
|
86
|
+
["::ffff:192.168.1.2/120", Socket::AF_INET],
|
87
|
+
["[192.168.1.2]/120"],
|
88
|
+
].each { |args|
|
89
|
+
lambda{
|
90
|
+
IPAddr.new(*args)
|
91
|
+
}.should raise_error(ArgumentError)
|
92
|
+
}
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
describe "IPAddr Operator" do
|
4
|
+
IN6MASK32 = "ffff:ffff::"
|
5
|
+
IN6MASK128 = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
|
6
|
+
|
7
|
+
before do
|
8
|
+
@in6_addr_any = IPAddr.new()
|
9
|
+
@a = IPAddr.new("3ffe:505:2::/48")
|
10
|
+
@b = IPAddr.new("0:0:0:1::")
|
11
|
+
@c = IPAddr.new(IN6MASK32)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "bitwises or" do
|
15
|
+
(@a | @b).to_s.should == "3ffe:505:2:1::"
|
16
|
+
a = @a
|
17
|
+
a |= @b
|
18
|
+
a.to_s.should == "3ffe:505:2:1::"
|
19
|
+
@a.to_s.should == "3ffe:505:2::"
|
20
|
+
(@a | 0x00000000000000010000000000000000).to_s.should == "3ffe:505:2:1::"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "bitwises and" do
|
24
|
+
(@a & @c).to_s.should == "3ffe:505::"
|
25
|
+
a = @a
|
26
|
+
a &= @c
|
27
|
+
a.to_s.should == "3ffe:505::"
|
28
|
+
@a.to_s.should == "3ffe:505:2::"
|
29
|
+
(@a & 0xffffffff000000000000000000000000).to_s.should == "3ffe:505::"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "bitshifts right" do
|
33
|
+
(@a >> 16).to_s.should == "0:3ffe:505:2::"
|
34
|
+
a = @a
|
35
|
+
a >>= 16
|
36
|
+
a.to_s.should == "0:3ffe:505:2::"
|
37
|
+
@a.to_s.should == "3ffe:505:2::"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "bitshifts left" do
|
41
|
+
(@a << 16).to_s.should == "505:2::"
|
42
|
+
a = @a
|
43
|
+
a <<= 16
|
44
|
+
a.to_s.should == "505:2::"
|
45
|
+
@a.to_s.should == "3ffe:505:2::"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "inverts" do
|
49
|
+
a = ~@in6_addr_any
|
50
|
+
a.to_s.should == IN6MASK128
|
51
|
+
@in6_addr_any.to_s.should == "::"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "tests for equality" do
|
55
|
+
@a.should == IPAddr.new("3ffe:505:2::")
|
56
|
+
@a.should_not == IPAddr.new("3ffe:505:3::")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "sets a mask" do
|
60
|
+
a = @a.mask(32)
|
61
|
+
a.to_s.should == "3ffe:505::"
|
62
|
+
@a.to_s.should == "3ffe:505:2::"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "checks whether an addres is included in a range" do
|
66
|
+
@a.should include(IPAddr.new("3ffe:505:2::"))
|
67
|
+
@a.should include(IPAddr.new("3ffe:505:2::1"))
|
68
|
+
@a.should_not include(IPAddr.new("3ffe:505:3::"))
|
69
|
+
net1 = IPAddr.new("192.168.2.0/24")
|
70
|
+
net1.should include(IPAddr.new("192.168.2.0"))
|
71
|
+
net1.should include(IPAddr.new("192.168.2.255"))
|
72
|
+
net1.should_not include(IPAddr.new("192.168.3.0"))
|
73
|
+
# test with integer parameter
|
74
|
+
int = (192 << 24) + (168 << 16) + (2 << 8) + 13
|
75
|
+
|
76
|
+
net1.should include(int)
|
77
|
+
net1.should_not include(int+255)
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
describe "IPAddr#reverse" do
|
4
|
+
it "generates the reverse DNS lookup entry" do
|
5
|
+
IPAddr.new("3ffe:505:2::f").reverse.should == "f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa"
|
6
|
+
IPAddr.new("192.168.2.1").reverse.should == "1.2.168.192.in-addr.arpa"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "IPAddr#ip6_arpa" do
|
11
|
+
it "converts an IPv6 address into the reverse DNS lookup representation according to RFC3172" do
|
12
|
+
IPAddr.new("3ffe:505:2::f").ip6_arpa.should == "f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa"
|
13
|
+
lambda{
|
14
|
+
IPAddr.new("192.168.2.1").ip6_arpa
|
15
|
+
}.should raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "IPAddr#ip6_int" do
|
20
|
+
it "converts an IPv6 address into the reverse DNS lookup representation according to RFC1886" do
|
21
|
+
IPAddr.new("3ffe:505:2::f").ip6_int.should == "f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.int"
|
22
|
+
lambda{
|
23
|
+
IPAddr.new("192.168.2.1").ip6_int
|
24
|
+
}.should raise_error(ArgumentError)
|
25
|
+
end
|
26
|
+
end
|
data/spec/to_s_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
describe "IPAddr#to_s" do
|
4
|
+
|
5
|
+
it "displays IPAddr using short notation" do
|
6
|
+
IPAddr.new("0:0:0:1::").to_s.should == "0:0:0:1::"
|
7
|
+
IPAddr.new("2001:200:300::/48").to_s.should == "2001:200:300::"
|
8
|
+
IPAddr.new("[2001:200:300::]/48").to_s.should == "2001:200:300::"
|
9
|
+
IPAddr.new("3ffe:505:2::1").to_s.should == "3ffe:505:2::1"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "IPAddr#to_string" do
|
15
|
+
it "displays an IPAddr using full notation" do
|
16
|
+
IPAddr.new("3ffe:505:2::1").to_string.should == "3ffe:0505:0002:0000:0000:0000:0000:0001"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubysl-ipaddr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Shirai
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-27 00:00:00.000000000 Z
|
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.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubysl-prettyprint
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
description: Ruby standard library ipaddr.
|
70
|
+
email:
|
71
|
+
- brixen@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .travis.yml
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/ipaddr.rb
|
83
|
+
- lib/rubysl/ipaddr.rb
|
84
|
+
- lib/rubysl/ipaddr/ipaddr.rb
|
85
|
+
- lib/rubysl/ipaddr/version.rb
|
86
|
+
- rubysl-ipaddr.gemspec
|
87
|
+
- spec/hton_spec.rb
|
88
|
+
- spec/ipv4_conversion_spec.rb
|
89
|
+
- spec/new_spec.rb
|
90
|
+
- spec/operator_spec.rb
|
91
|
+
- spec/reverse_spec.rb
|
92
|
+
- spec/to_s_spec.rb
|
93
|
+
homepage: https://github.com/rubysl/rubysl-ipaddr
|
94
|
+
licenses:
|
95
|
+
- BSD
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.0.7
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Ruby standard library ipaddr.
|
117
|
+
test_files:
|
118
|
+
- spec/hton_spec.rb
|
119
|
+
- spec/ipv4_conversion_spec.rb
|
120
|
+
- spec/new_spec.rb
|
121
|
+
- spec/operator_spec.rb
|
122
|
+
- spec/reverse_spec.rb
|
123
|
+
- spec/to_s_spec.rb
|