rippersnapper 0.0.8 → 0.0.9
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/.travis.yml +0 -2
- data/README.md +7 -0
- data/lib/rippersnapper.rb +22 -0
- data/lib/rippersnapper/domain_parser.rb +2 -1
- data/lib/rippersnapper/version.rb +1 -1
- data/rippersnapper.gemspec +1 -1
- data/spec/rippersnapper/domain_parser_spec.rb +58 -9
- data/spec/rippersnapper/suffix_file_validator_spec.rb +20 -12
- data/spec/rippersnapper/url_spec.rb +178 -42
- data/spec/rippersnapper_spec.rb +29 -1
- data/spec/spec_helper.rb +0 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f34bb9857cd7aaebeade923e85ea856d187a2e9
|
4
|
+
data.tar.gz: ccc1cf211881f9d27fd6bccc3fd2c302143f1960
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 467c606b219291dc375c0eb276ce8bd9199551058f5b0081d065f83e6288ce2b960b8795b428844209d375f2e37de18207c80fb4a6efe4be0ad0cb8fe146475c
|
7
|
+
data.tar.gz: 3f9da79c65b973bbfa0e586b7ade9d0304b44bb9157c5012856ce88c4a9a26fa79fa0a4723ddfd589fdadea4c3be81c7af0fb65f4c54ac15b947a51b93f43dba
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -36,6 +36,13 @@ Or install it yourself as:
|
|
36
36
|
url.subdomain # => "foo.bar"
|
37
37
|
url.path # => "/asdf.html?q=arg"
|
38
38
|
|
39
|
+
# optionally preload suffixes file to avoid loading on each call to `#parse`
|
40
|
+
Rippersnapper.load_suffixes
|
41
|
+
# subsequent calls to parse will use the same `SuffixFileReader` instance
|
42
|
+
|
43
|
+
# unloading the suffixes simply sets the internal variable to `nil`
|
44
|
+
Rippersnapper.unload_suffixes
|
45
|
+
|
39
46
|
## Notable differences between Rippersnapper and [Domainatrix](https://github.com/pauldix/domainatrix)
|
40
47
|
|
41
48
|
One of Rippersnappers goals is to be a compatible API with Domainatrix, but
|
data/lib/rippersnapper.rb
CHANGED
@@ -8,4 +8,26 @@ module Rippersnapper
|
|
8
8
|
def self.parse url
|
9
9
|
Url.new url
|
10
10
|
end
|
11
|
+
|
12
|
+
# Load public suffix file into class instance var to be reused
|
13
|
+
#
|
14
|
+
# @return [void]
|
15
|
+
def self.load_suffixes file = nil
|
16
|
+
@suffix_file_reader = SuffixFileReader.new(file)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Accessor for loaded suffix reader
|
20
|
+
#
|
21
|
+
# @return [SuffixFileReader]
|
22
|
+
# @return [nil] if not loaded
|
23
|
+
def self.suffix_file_reader
|
24
|
+
@suffix_file_reader
|
25
|
+
end
|
26
|
+
|
27
|
+
# Unload public suffix file
|
28
|
+
#
|
29
|
+
# @return [void]
|
30
|
+
def self.unload_suffixes
|
31
|
+
@suffix_file_reader = nil
|
32
|
+
end
|
11
33
|
end
|
data/rippersnapper.gemspec
CHANGED
@@ -6,24 +6,73 @@ module Rippersnapper
|
|
6
6
|
|
7
7
|
context "simple domain" do
|
8
8
|
subject { DomainParser.new "www.google.com" }
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
describe '#subdomain' do
|
11
|
+
subject { super().subdomain }
|
12
|
+
it { is_expected.to eq "www" }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#domain' do
|
16
|
+
subject { super().domain }
|
17
|
+
it { is_expected.to eq "google" }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#suffix' do
|
21
|
+
subject { super().suffix }
|
22
|
+
it { is_expected.to eq "com" }
|
23
|
+
end
|
12
24
|
end
|
13
25
|
|
14
26
|
context "complex domain" do
|
15
27
|
subject { DomainParser.new "my.drive.google.whatever.sapporo.jp" }
|
16
|
-
|
17
|
-
|
18
|
-
|
28
|
+
|
29
|
+
describe '#subdomain' do
|
30
|
+
subject { super().subdomain }
|
31
|
+
it { is_expected.to eq "my.drive" }
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#domain' do
|
35
|
+
subject { super().domain }
|
36
|
+
it { is_expected.to eq "google" }
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#suffix' do
|
40
|
+
subject { super().suffix }
|
41
|
+
it { is_expected.to eq "whatever.sapporo.jp" }
|
42
|
+
end
|
19
43
|
end
|
20
44
|
|
21
45
|
context "empty url" do
|
22
46
|
subject { DomainParser.new "" }
|
23
|
-
|
24
|
-
|
25
|
-
|
47
|
+
|
48
|
+
describe '#subdomain' do
|
49
|
+
subject { super().subdomain }
|
50
|
+
it { is_expected.to eq "" }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#domain' do
|
54
|
+
subject { super().domain }
|
55
|
+
it { is_expected.to eq "" }
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#suffix' do
|
59
|
+
subject { super().suffix }
|
60
|
+
it { is_expected.to eq "" }
|
61
|
+
end
|
26
62
|
end
|
27
63
|
|
64
|
+
context "preloaded suffix file" do
|
65
|
+
before { Rippersnapper.load_suffixes }
|
66
|
+
after { Rippersnapper.unload_suffixes }
|
67
|
+
|
68
|
+
subject { described_class.new("").send(:suffix_reader) }
|
69
|
+
|
70
|
+
it { is_expected.to be_kind_of SuffixFileReader }
|
71
|
+
|
72
|
+
it "uses the preloaded reader" do
|
73
|
+
expect(subject.object_id)
|
74
|
+
.to eq(Rippersnapper.suffix_file_reader.object_id)
|
75
|
+
end
|
76
|
+
end
|
28
77
|
end
|
29
78
|
end
|
@@ -8,56 +8,64 @@ module Rippersnapper
|
|
8
8
|
describe '#initialize' do
|
9
9
|
|
10
10
|
context 'passing in a file' do
|
11
|
-
let(:file) {
|
11
|
+
let(:file) { double :file, each_line: [] }
|
12
12
|
subject { SuffixFileReader.new file }
|
13
|
-
|
13
|
+
|
14
|
+
describe '#file' do
|
15
|
+
subject { super().file }
|
16
|
+
it { is_expected.to be file}
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
context 'file default' do
|
17
21
|
subject { SuffixFileReader.new }
|
18
|
-
|
22
|
+
|
23
|
+
describe '#file' do
|
24
|
+
subject { super().file }
|
25
|
+
it { is_expected.to be_a_kind_of File }
|
26
|
+
end
|
19
27
|
end
|
20
28
|
end
|
21
29
|
|
22
30
|
describe '#contains?' do
|
23
31
|
subject { SuffixFileReader.new }
|
24
32
|
|
25
|
-
it {
|
33
|
+
it { is_expected.to respond_to :contains? }
|
26
34
|
|
27
35
|
context "matching valid data" do
|
28
36
|
|
29
37
|
it 'matches a single suffix' do
|
30
|
-
expect(subject.contains?("com")).to
|
38
|
+
expect(subject.contains?("com")).to be_truthy
|
31
39
|
end
|
32
40
|
|
33
41
|
it 'matches a nested suffix' do
|
34
|
-
expect(subject.contains?("la.us")).to
|
42
|
+
expect(subject.contains?("la.us")).to be_truthy
|
35
43
|
end
|
36
44
|
|
37
45
|
it 'matches a suffix with a single asterix' do
|
38
|
-
expect(subject.contains?("whatever.uk")).to
|
46
|
+
expect(subject.contains?("whatever.uk")).to be_truthy
|
39
47
|
end
|
40
48
|
|
41
49
|
it 'matches a suffix with multiple asterix' do
|
42
|
-
expect(subject.contains?("whatever.sapporo.jp")).to
|
50
|
+
expect(subject.contains?("whatever.sapporo.jp")).to be_truthy
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
46
54
|
context "rejecting invalid data" do
|
47
55
|
it "doesn't match suffix that is not in file" do
|
48
|
-
expect(subject.contains?("baz")).to
|
56
|
+
expect(subject.contains?("baz")).to be_falsey
|
49
57
|
end
|
50
58
|
|
51
59
|
it "doesn't match complex suffix that are not in file" do
|
52
|
-
expect(subject.contains?("doesnt.exist.sapporo.jp")).to
|
60
|
+
expect(subject.contains?("doesnt.exist.sapporo.jp")).to be_falsey
|
53
61
|
end
|
54
62
|
|
55
63
|
it "doesn't match comments" do
|
56
|
-
expect(subject.contains?("// comment")).to
|
64
|
+
expect(subject.contains?("// comment")).to be_falsey
|
57
65
|
end
|
58
66
|
|
59
67
|
it "doesn't match empty lines" do
|
60
|
-
expect(subject.contains?("")).to
|
68
|
+
expect(subject.contains?("")).to be_falsey
|
61
69
|
end
|
62
70
|
end
|
63
71
|
end
|
@@ -5,67 +5,203 @@ module Rippersnapper
|
|
5
5
|
describe Url do
|
6
6
|
subject { Url.new "www.google.com" }
|
7
7
|
|
8
|
-
it {
|
9
|
-
it {
|
10
|
-
it {
|
11
|
-
it {
|
12
|
-
it {
|
13
|
-
it {
|
14
|
-
it {
|
15
|
-
it {
|
8
|
+
it { is_expected.to respond_to :domain }
|
9
|
+
it { is_expected.to respond_to :scheme }
|
10
|
+
it { is_expected.to respond_to :host }
|
11
|
+
it { is_expected.to respond_to :path }
|
12
|
+
it { is_expected.to respond_to :url }
|
13
|
+
it { is_expected.to respond_to :suffix }
|
14
|
+
it { is_expected.to respond_to :subdomain }
|
15
|
+
it { is_expected.to respond_to :port }
|
16
16
|
|
17
17
|
context "with a scheme" do
|
18
18
|
subject { Url.new "http://drive.google.com:91/micah" }
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
|
20
|
+
describe '#url' do
|
21
|
+
subject { super().url }
|
22
|
+
it { is_expected.to eq "http://drive.google.com:91/micah" }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#path' do
|
26
|
+
subject { super().path }
|
27
|
+
it { is_expected.to eq "/micah" }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#scheme' do
|
31
|
+
subject { super().scheme }
|
32
|
+
it { is_expected.to eq "http" }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#host' do
|
36
|
+
subject { super().host }
|
37
|
+
it { is_expected.to eq "drive.google.com" }
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#suffix' do
|
41
|
+
subject { super().suffix }
|
42
|
+
it { is_expected.to eq "com" }
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#domain' do
|
46
|
+
subject { super().domain }
|
47
|
+
it { is_expected.to eq "google" }
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#subdomain' do
|
51
|
+
subject { super().subdomain }
|
52
|
+
it { is_expected.to eq "drive" }
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#port' do
|
56
|
+
subject { super().port }
|
57
|
+
it { is_expected.to eq 91 }
|
58
|
+
end
|
27
59
|
end
|
28
60
|
|
29
61
|
context "without a scheme" do
|
30
62
|
subject { Url.new "www.google.com/micah" }
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
63
|
+
|
64
|
+
describe '#url' do
|
65
|
+
subject { super().url }
|
66
|
+
it { is_expected.to eq "http://www.google.com/micah" }
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#path' do
|
70
|
+
subject { super().path }
|
71
|
+
it { is_expected.to eq "/micah" }
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#scheme' do
|
75
|
+
subject { super().scheme }
|
76
|
+
it { is_expected.to eq "http" }
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#host' do
|
80
|
+
subject { super().host }
|
81
|
+
it { is_expected.to eq "www.google.com" }
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#suffix' do
|
85
|
+
subject { super().suffix }
|
86
|
+
it { is_expected.to eq "com" }
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#domain' do
|
90
|
+
subject { super().domain }
|
91
|
+
it { is_expected.to eq "google" }
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#subdomain' do
|
95
|
+
subject { super().subdomain }
|
96
|
+
it { is_expected.to eq "www" }
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#port' do
|
100
|
+
subject { super().port }
|
101
|
+
it { is_expected.to eq 80 }
|
102
|
+
end
|
39
103
|
end
|
40
104
|
|
41
105
|
context "with a query string" do
|
42
106
|
subject { Url.new "www.google.com/micah?date=today" }
|
43
|
-
|
44
|
-
|
45
|
-
|
107
|
+
|
108
|
+
describe '#path' do
|
109
|
+
subject { super().path }
|
110
|
+
it { is_expected.to eq "/micah?date=today" }
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '#suffix' do
|
114
|
+
subject { super().suffix }
|
115
|
+
it { is_expected.to eq "com" }
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#domain' do
|
119
|
+
subject { super().domain }
|
120
|
+
it { is_expected.to eq "google" }
|
121
|
+
end
|
46
122
|
end
|
47
123
|
|
48
124
|
context "when url is nil" do
|
49
125
|
subject {Url.new nil}
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
126
|
+
|
127
|
+
describe '#url' do
|
128
|
+
subject { super().url }
|
129
|
+
it { is_expected.to eq "" }
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '#path' do
|
133
|
+
subject { super().path }
|
134
|
+
it { is_expected.to eq "" }
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '#scheme' do
|
138
|
+
subject { super().scheme }
|
139
|
+
it { is_expected.to eq "" }
|
140
|
+
end
|
141
|
+
|
142
|
+
describe '#host' do
|
143
|
+
subject { super().host }
|
144
|
+
it { is_expected.to eq "" }
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#suffix' do
|
148
|
+
subject { super().suffix }
|
149
|
+
it { is_expected.to eq "" }
|
150
|
+
end
|
151
|
+
|
152
|
+
describe '#domain' do
|
153
|
+
subject { super().domain }
|
154
|
+
it { is_expected.to eq "" }
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#subdomain' do
|
158
|
+
subject { super().subdomain }
|
159
|
+
it { is_expected.to eq "" }
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#port' do
|
163
|
+
subject { super().port }
|
164
|
+
it { is_expected.to be_nil }
|
165
|
+
end
|
58
166
|
end
|
59
167
|
|
60
168
|
context "whith ip address" do
|
61
169
|
subject { Url.new "http://10.0.1.1/" }
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
170
|
+
|
171
|
+
describe '#url' do
|
172
|
+
subject { super().url }
|
173
|
+
it { is_expected.to eq "http://10.0.1.1/" }
|
174
|
+
end
|
175
|
+
|
176
|
+
describe '#path' do
|
177
|
+
subject { super().path }
|
178
|
+
it { is_expected.to eq "/" }
|
179
|
+
end
|
180
|
+
|
181
|
+
describe '#scheme' do
|
182
|
+
subject { super().scheme }
|
183
|
+
it { is_expected.to eq "http" }
|
184
|
+
end
|
185
|
+
|
186
|
+
describe '#host' do
|
187
|
+
subject { super().host }
|
188
|
+
it { is_expected.to eq "10.0.1.1" }
|
189
|
+
end
|
190
|
+
|
191
|
+
describe '#suffix' do
|
192
|
+
subject { super().suffix }
|
193
|
+
it { is_expected.to eq "" }
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#domain' do
|
197
|
+
subject { super().domain }
|
198
|
+
it { is_expected.to eq "10.0.1.1" }
|
199
|
+
end
|
200
|
+
|
201
|
+
describe '#subdomain' do
|
202
|
+
subject { super().subdomain }
|
203
|
+
it { is_expected.to eq "" }
|
204
|
+
end
|
69
205
|
end
|
70
206
|
end
|
71
207
|
end
|
data/spec/rippersnapper_spec.rb
CHANGED
@@ -1,6 +1,34 @@
|
|
1
1
|
describe Rippersnapper do
|
2
2
|
describe '::parse' do
|
3
3
|
subject { Rippersnapper.parse "www.google.com" }
|
4
|
-
it {
|
4
|
+
it { is_expected.to be_a_kind_of Rippersnapper::Url }
|
5
|
+
end
|
6
|
+
|
7
|
+
describe "::load_suffixes" do
|
8
|
+
subject { described_class.load_suffixes }
|
9
|
+
after { described_class.unload_suffixes }
|
10
|
+
it { is_expected.to be_a_kind_of described_class::SuffixFileReader }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "::suffix_file_reader" do
|
14
|
+
subject { described_class.suffix_file_reader }
|
15
|
+
it { is_expected.to be_nil }
|
16
|
+
|
17
|
+
context "with loaded suffixes" do
|
18
|
+
before { described_class.load_suffixes }
|
19
|
+
after { described_class.unload_suffixes }
|
20
|
+
it { is_expected.to be_a_kind_of described_class::SuffixFileReader }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "::unload_suffixes" do
|
25
|
+
before { described_class.load_suffixes }
|
26
|
+
after { described_class.unload_suffixes }
|
27
|
+
|
28
|
+
it "unloads suffixes" do
|
29
|
+
expect(described_class.suffix_file_reader).to_not be_nil
|
30
|
+
described_class.unload_suffixes
|
31
|
+
expect(described_class.suffix_file_reader).to be_nil
|
32
|
+
end
|
5
33
|
end
|
6
34
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,7 +7,6 @@ require 'rippersnapper'
|
|
7
7
|
#
|
8
8
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
9
9
|
RSpec.configure do |config|
|
10
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
10
|
config.run_all_when_everything_filtered = true
|
12
11
|
config.filter_run :focus
|
13
12
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rippersnapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micah Woods
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '3.3'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '3.3'
|
55
55
|
description: Rip and snap domains using Rippersnappers jaws of steele!
|
56
56
|
email:
|
57
57
|
- micahwoods@gmail.com
|
@@ -100,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
100
|
version: '0'
|
101
101
|
requirements: []
|
102
102
|
rubyforge_project:
|
103
|
-
rubygems_version: 2.
|
103
|
+
rubygems_version: 2.5.1
|
104
104
|
signing_key:
|
105
105
|
specification_version: 4
|
106
106
|
summary: Named after the worst decepticon ever, a shark with T-Rex arms...
|