truncator 0.0.1 → 0.1.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/Gemfile +0 -3
- data/lib/truncator.rb +3 -0
- data/lib/truncator/extended_array.rb +12 -0
- data/lib/truncator/extended_string.rb +32 -0
- data/lib/truncator/extended_uri.rb +78 -0
- data/lib/truncator/url_parser.rb +73 -136
- data/lib/truncator/version.rb +1 -1
- data/spec/url_parser_spec.rb +25 -25
- data/truncator.gemspec +3 -0
- metadata +33 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50aa3fe4a5e7f94318128cad88fa00d37c118b01
|
4
|
+
data.tar.gz: 1e74abed03fc0af9dd4a1f1b248d3a772b5015c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8651a8088c7e57b183b3320551b890e0678bfb7b65d6d6e30e5d7e027877fec47ae787bf49b16fc0837fc7c4da2a0a0d32dc87d5ccd36532d1c74f2d5eb5215b
|
7
|
+
data.tar.gz: 6c3e960903c5ed73e291eb42a92fde49cba0392021ae86d9da1d59d4cb0db68471a70743c8aed86675b97a66d402a58989cc7edf71b15f6f39618bcd7f2609ab
|
data/Gemfile
CHANGED
data/lib/truncator.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Truncator
|
2
|
+
module ExtendedArray
|
3
|
+
refine Array do
|
4
|
+
|
5
|
+
# Generate all possible combinations of sequential elements
|
6
|
+
# Example: [1, 2, 3].sequences #=> [[1], [2], [3], [1, 2], [2, 3], [1, 2, 3]]
|
7
|
+
def sequences
|
8
|
+
self.each_index.inject([]) { |result, i| self.each_cons(i + 1) { |cons| result << cons }; result }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
2
|
+
|
3
|
+
class String
|
4
|
+
cattr_accessor :separator
|
5
|
+
end
|
6
|
+
|
7
|
+
module Truncator
|
8
|
+
module ExtendedString
|
9
|
+
refine String do
|
10
|
+
def truncate!(length, separator = nil)
|
11
|
+
separator ||= self.separator
|
12
|
+
fail ArgumentError, 'Separator should be present. Pass it via last argument or set globally String.separator=' unless separator
|
13
|
+
if self.length > length
|
14
|
+
self[(length - separator.length)..-1] = separator
|
15
|
+
end
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def truncate(*args)
|
20
|
+
self.dup.truncate!(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_length?(valid_length)
|
24
|
+
self.length <= valid_length
|
25
|
+
end
|
26
|
+
|
27
|
+
def invalid_length?(*args)
|
28
|
+
not valid_length?(*args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Truncator
|
4
|
+
module ExtendedURI
|
5
|
+
refine URI::Generic do
|
6
|
+
def ordinary_hostname?
|
7
|
+
if %w(https ftp).include?(self.scheme) || self.userinfo || self.port_defined?
|
8
|
+
false
|
9
|
+
else
|
10
|
+
true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def path_blank?
|
15
|
+
['', nil, '/'].include? self.path
|
16
|
+
end
|
17
|
+
|
18
|
+
def paths
|
19
|
+
self.path.split('/').delete_if(&:empty?)
|
20
|
+
end
|
21
|
+
|
22
|
+
def paths=(paths_array)
|
23
|
+
_path = paths_array.join('/')
|
24
|
+
# We should insure that we have leading '/'
|
25
|
+
_path.prepend('/') unless _path[0] == '/'
|
26
|
+
self.path = _path
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def last_path_with_query
|
31
|
+
str = "#{self.paths.last}"
|
32
|
+
if self.query
|
33
|
+
str += "?#{self.query}"
|
34
|
+
end
|
35
|
+
str
|
36
|
+
end
|
37
|
+
|
38
|
+
def last_path_with_query=(str)
|
39
|
+
last_path, query = str.split('?')
|
40
|
+
_paths = self.paths
|
41
|
+
_paths[-1] = last_path.to_s if _paths.last
|
42
|
+
self.paths = _paths
|
43
|
+
self.query = query
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def query_parameters
|
48
|
+
URI.decode_www_form(self.query)
|
49
|
+
end
|
50
|
+
|
51
|
+
def query_parameters=(params)
|
52
|
+
self.query = URI.encode_www_form(params)
|
53
|
+
end
|
54
|
+
|
55
|
+
##App specific
|
56
|
+
def special_format
|
57
|
+
str = self.to_s
|
58
|
+
if ordinary_hostname?
|
59
|
+
str.sub!(/\Ahttp:\/\//, '') # remove http protocol
|
60
|
+
str.gsub(/\/{2,}/, '/') # replace multiple slashes by one
|
61
|
+
str.chomp!('/') # remove slash from the end
|
62
|
+
end
|
63
|
+
str
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def port_defined?
|
68
|
+
port = self.port
|
69
|
+
self.to_s.include? ":#{port}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.insure_leading_slash!(str)
|
73
|
+
str.prepend('/') unless str[0] == '/'
|
74
|
+
str
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/truncator/url_parser.rb
CHANGED
@@ -1,155 +1,92 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
if !has_path?(url)
|
22
|
-
url = truncate(url, truncation_length)
|
23
|
-
return url
|
24
|
-
end
|
25
|
-
|
26
|
-
if params_exists?(url)
|
27
|
-
if invalid_length?(hostname(url).length, truncation_length) and last_directory(url).length > truncation_length
|
28
|
-
url = truncate_last_directory(url, truncation_length)
|
29
|
-
elsif valid_length?(url.length - last_directory(url).length, truncation_length) or !has_dirs?(url)
|
30
|
-
url = truncate(url, truncation_length)
|
31
|
-
end
|
32
|
-
else
|
33
|
-
if valid_length?(hostname(url).length, truncation_length)
|
34
|
-
url = truncate_by_shortest(url, truncation_length)
|
35
|
-
else
|
36
|
-
url = truncate_all_directories(url)
|
37
|
-
url = truncate_last_directory(url, truncation_length)
|
1
|
+
using Truncator::ExtendedURI
|
2
|
+
using Truncator::ExtendedString
|
3
|
+
using Truncator::ExtendedArray
|
4
|
+
|
5
|
+
module Truncator
|
6
|
+
class UrlParser
|
7
|
+
class << self
|
8
|
+
SEPARATOR = '...'
|
9
|
+
String.separator = SEPARATOR
|
10
|
+
|
11
|
+
def shorten_url(uri, truncation_length = 42)
|
12
|
+
uri = URI(uri)
|
13
|
+
|
14
|
+
if not uri.ordinary_hostname?
|
15
|
+
if uri.query
|
16
|
+
uri.query_parameters = [uri.query_parameters.first]
|
17
|
+
return uri.to_s + SEPARATOR
|
18
|
+
else
|
19
|
+
return uri.to_s
|
20
|
+
end
|
38
21
|
end
|
39
|
-
end
|
40
22
|
|
41
|
-
|
42
|
-
end
|
23
|
+
return uri.special_format if uri.special_format.valid_length?(truncation_length)
|
43
24
|
|
44
|
-
|
45
|
-
|
46
|
-
def truncate(str, length)
|
47
|
-
str = str.dup
|
48
|
-
if str.length > length
|
49
|
-
str[(length - SEPARATOR.length)..-1] = SEPARATOR
|
25
|
+
if uri.path_blank? and not uri.query
|
26
|
+
return uri.special_format.truncate!(truncation_length)
|
50
27
|
end
|
51
|
-
str
|
52
|
-
end
|
53
28
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
false
|
61
|
-
elsif url.start_with?('ftp://')
|
62
|
-
# ftp
|
63
|
-
false
|
64
|
-
elsif url =~ /^http:\/\/[a-zA-Z\d]+:[a-zA-Z\d]+@[a-zA-Z\d.]+\//
|
65
|
-
# with credentials
|
66
|
-
false
|
29
|
+
if uri.query
|
30
|
+
if uri.host.invalid_length?(truncation_length) and uri.last_path_with_query.length > truncation_length
|
31
|
+
uri = truncate_last_path_segment(uri, truncation_length)
|
32
|
+
elsif uri.special_format.valid_length?(truncation_length + uri.last_path_with_query.length) or not uri.path_blank?
|
33
|
+
return uri.special_format.truncate!(truncation_length)
|
34
|
+
end
|
67
35
|
else
|
68
|
-
|
36
|
+
if uri.host.valid_length?(truncation_length)
|
37
|
+
uri = truncate_by_shortest(uri, truncation_length)
|
38
|
+
else
|
39
|
+
uri = truncate_all_paths_except_last(uri)
|
40
|
+
uri = truncate_last_path_segment(uri, truncation_length)
|
41
|
+
end
|
69
42
|
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def hostname(url)
|
73
|
-
url[0..(url.index('/') - 1)]
|
74
|
-
end
|
75
|
-
|
76
|
-
def valid_length?(url_length, truncation_length)
|
77
|
-
url_length <= truncation_length
|
78
|
-
end
|
79
|
-
|
80
|
-
def invalid_length?(url_length, truncation_length)
|
81
|
-
!valid_length?(url_length, truncation_length)
|
82
|
-
end
|
83
43
|
|
84
|
-
|
85
|
-
def params_exists?(url)
|
86
|
-
valid_symbols_before_params = URL_VALID_SYMBOLS.dup.tap { |r| r[-1] = '.\/]' }
|
87
|
-
!!(url =~ /^#{valid_symbols_before_params}+\?(#{URL_VALID_SYMBOLS}+)/)
|
44
|
+
uri.special_format
|
88
45
|
end
|
89
46
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
def truncate_all_directories(url)
|
101
|
-
first_slash = url.index('/')
|
102
|
-
last_slash = url.rindex('/')
|
103
|
-
url = url.dup
|
104
|
-
url[first_slash..last_slash] = "/#{SEPARATOR}/"
|
105
|
-
url
|
106
|
-
end
|
107
|
-
|
108
|
-
def last_directory(url)
|
109
|
-
url[(url.rindex('/') + 1)..-1]
|
110
|
-
end
|
111
|
-
|
112
|
-
def truncate_last_directory(url, truncation_length)
|
113
|
-
last_dir_begin = url.rindex('/') + 1
|
114
|
-
last_dir = last_directory(url)
|
115
|
-
url = url.dup
|
116
|
-
url[last_dir_begin..-1] = truncate(last_dir, truncation_length)
|
117
|
-
url
|
118
|
-
end
|
47
|
+
private
|
48
|
+
def truncate_all_paths_except_last(uri)
|
49
|
+
uri = uri.dup
|
50
|
+
paths = uri.paths
|
51
|
+
if paths.size > 1
|
52
|
+
uri.paths = [SEPARATOR, paths.last]
|
53
|
+
end
|
54
|
+
uri
|
55
|
+
end
|
119
56
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
57
|
+
def truncate_last_path_segment(uri, truncation_length)
|
58
|
+
uri = uri.dup
|
59
|
+
last_path_with_query = uri.last_path_with_query
|
60
|
+
uri.last_path_with_query = last_path_with_query.truncate(truncation_length)
|
61
|
+
uri
|
62
|
+
end
|
124
63
|
|
125
|
-
|
126
|
-
|
127
|
-
|
64
|
+
def sort_paths_by_length_and_index!(paths)
|
65
|
+
paths.lazy.with_index.sort_by { |a, i| [a.size, i] }.map(&:first)
|
66
|
+
end
|
128
67
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
68
|
+
# Get the sequences of paths from uri
|
69
|
+
def paths_sequences_from_uri(uri)
|
70
|
+
paths = uri.paths[0..-2]
|
71
|
+
paths.sequences.uniq.map { |i| i.join('/') }
|
72
|
+
end
|
133
73
|
|
134
|
-
#
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
dirs[dirs.index(next_min_dir)..-1].each do |dir|
|
139
|
-
current_dirs_length += dir.to_s.length
|
140
|
-
current_dirs_count += 1
|
141
|
-
current_dirs_length_with_slashes = current_dirs_length + (current_dirs_count - 1) - SEPARATOR.length
|
142
|
-
break if url.length - current_dirs_length_with_slashes <= target_length
|
74
|
+
# Find the appropriate sequence to truncate uri to target length
|
75
|
+
def find_truncated_sequence(uri, sorted_sequences, target_length)
|
76
|
+
sorted_sequences.find do |seq|
|
77
|
+
(uri.special_format.length - seq.length + SEPARATOR.length) <= target_length
|
143
78
|
end
|
144
|
-
|
79
|
+
end
|
145
80
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
81
|
+
# Truncate the uri via truncating the shortest possible path sequence
|
82
|
+
def truncate_by_shortest(uri, target_length)
|
83
|
+
uri = uri.dup
|
84
|
+
sorted_sequences = sort_paths_by_length_and_index!(paths_sequences_from_uri(uri))
|
85
|
+
truncated_part = find_truncated_sequence(uri, sorted_sequences, target_length)
|
86
|
+
|
87
|
+
uri.path = uri.path.sub(truncated_part, SEPARATOR)
|
88
|
+
uri
|
151
89
|
end
|
152
|
-
|
153
|
-
end
|
90
|
+
end
|
154
91
|
end
|
155
92
|
end
|
data/lib/truncator/version.rb
CHANGED
data/spec/url_parser_spec.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'truncator'
|
3
3
|
|
4
|
-
describe UrlParser do
|
4
|
+
describe Truncator::UrlParser do
|
5
5
|
|
6
6
|
describe ".shorten_url" do
|
7
7
|
|
8
8
|
context "when no truncation length is specified, the URL is too long, has sublevels, but no query params" do
|
9
|
-
let(:shortened) { UrlParser.shorten_url "http://www.foo.com/this/is/a/b/c/d/e/f/string.html" }
|
9
|
+
let(:shortened) { Truncator::UrlParser.shorten_url "http://www.foo.com/this/is/a/b/c/d/e/f/string.html" }
|
10
10
|
|
11
11
|
it "should default to truncate at 42 characters" do
|
12
12
|
# shortened.should == "www.foo.com/this/is/a/.../e/f/string.html"
|
@@ -15,7 +15,7 @@ describe UrlParser do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
context 'when URL has a large last folder level' do
|
18
|
-
let(:shortened) { UrlParser.shorten_url "http://m.whitehouse.gov/blog/2013/08/23/check-out-secretary-education-arne-duncans-google-hangout-sal-khan?utm_source=email&utm_medium=email&utm_content=email232-graphic2&utm_campaign=education" }
|
18
|
+
let(:shortened) { Truncator::UrlParser.shorten_url "http://m.whitehouse.gov/blog/2013/08/23/check-out-secretary-education-arne-duncans-google-hangout-sal-khan?utm_source=email&utm_medium=email&utm_content=email232-graphic2&utm_campaign=education" }
|
19
19
|
|
20
20
|
it "should should default to truncate at 42 characters" do
|
21
21
|
shortened.should == "m.whitehouse.gov/blog/2013/08/23/check-..."
|
@@ -24,7 +24,7 @@ describe UrlParser do
|
|
24
24
|
|
25
25
|
context "when URL is too long, has sublevels, but no query params" do
|
26
26
|
it "should ellipse the directories and just show the file" do
|
27
|
-
UrlParser.shorten_url("http://www.foo.com/this/is/a/really/long/url/that/has/no/query/string.html", 30).should == "www.foo.com/.../string.html"
|
27
|
+
Truncator::UrlParser.shorten_url("http://www.foo.com/this/is/a/really/long/url/that/has/no/query/string.html", 30).should == "www.foo.com/.../string.html"
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should replace path segments with ellipses to shorten the path as much as necessary" do
|
@@ -34,7 +34,7 @@ describe UrlParser do
|
|
34
34
|
0.upto(20) do |n|
|
35
35
|
url = url_prefix + url_middle + url_suffix
|
36
36
|
url_middle += "and/on/"
|
37
|
-
shorter_url = UrlParser.shorten_url(url, 30)
|
37
|
+
shorter_url = Truncator::UrlParser.shorten_url(url, 30)
|
38
38
|
#TODO: rewrite this
|
39
39
|
shorter_url.should == if url[7..-1].length <= 30
|
40
40
|
url[7..-1]
|
@@ -51,7 +51,7 @@ describe UrlParser do
|
|
51
51
|
0.upto(20) do |n|
|
52
52
|
url = url_prefix + url_middle + url_suffix
|
53
53
|
url_middle += "nd/on/"
|
54
|
-
shorter_url = UrlParser.shorten_url(url, 30)
|
54
|
+
shorter_url = Truncator::UrlParser.shorten_url(url, 30)
|
55
55
|
#TODO: rewrite this
|
56
56
|
shorter_url.should == if url[7..-1].length <= 30
|
57
57
|
url[7..-1]
|
@@ -63,16 +63,16 @@ describe UrlParser do
|
|
63
63
|
|
64
64
|
# it "should replace path segments with ellipses to shorten the path as much as necessary for various lengths", focus: true do
|
65
65
|
# url = "http://www.foo.com/this/goes/on/and/on/and/on/with/XXX.html"
|
66
|
-
# UrlParser.shorten_url(url, 24).should == "www.foo.com/.../XXX.html"
|
67
|
-
# 32.upto(33) { |n| UrlParser.shorten_url(url, n).should == "www.foo.com/.../on/with/XXX.html" }
|
68
|
-
# 35.upto(39) { |n| UrlParser.shorten_url(url, n).should == "www.foo.com/this/.../with/XXX.html" }
|
69
|
-
# 40.upto(42) { |n| UrlParser.shorten_url(url, n).should == "www.foo.com/this/goes/.../with/XXX.html" }
|
70
|
-
# 43.upto(45) { |n| UrlParser.shorten_url(url, n).should == "www.foo.com/this/goes/.../on/with/XXX.html" }
|
66
|
+
# Truncator::UrlParser.shorten_url(url, 24).should == "www.foo.com/.../XXX.html"
|
67
|
+
# 32.upto(33) { |n| Truncator::UrlParser.shorten_url(url, n).should == "www.foo.com/.../on/with/XXX.html" }
|
68
|
+
# 35.upto(39) { |n| Truncator::UrlParser.shorten_url(url, n).should == "www.foo.com/this/.../with/XXX.html" }
|
69
|
+
# 40.upto(42) { |n| Truncator::UrlParser.shorten_url(url, n).should == "www.foo.com/this/goes/.../with/XXX.html" }
|
70
|
+
# 43.upto(45) { |n| Truncator::UrlParser.shorten_url(url, n).should == "www.foo.com/this/goes/.../on/with/XXX.html" }
|
71
71
|
# end
|
72
72
|
end
|
73
73
|
|
74
74
|
# context "when URL is too long and has at least one sublevel specified as well as a query parameter" do
|
75
|
-
# let(:shortened) { UrlParser.shorten_url("http://www.foo.com/this/goes/on/and/on/and/on/and/on/and/ends/with/XXXX.html?q=1&a=2&b=3", 50) }
|
75
|
+
# let(:shortened) { Truncator::UrlParser.shorten_url("http://www.foo.com/this/goes/on/and/on/and/on/and/on/and/ends/with/XXXX.html?q=1&a=2&b=3", 50) }
|
76
76
|
|
77
77
|
# it "should replace path segments with ellipses to shorten the path as much as necessary, and show only the first param, followed by ellipses" do
|
78
78
|
# shortened.should == "www.foo.com/this/goes/.../with/XXXX.html?q=1..."
|
@@ -80,7 +80,7 @@ describe UrlParser do
|
|
80
80
|
# end
|
81
81
|
|
82
82
|
context "when URL is more than 30 chars long and does not have at least one sublevel specified" do
|
83
|
-
let(:shortened) { UrlParser.shorten_url("http://www.mass.gov/?pageID=trepressrelease&L=4&L0=Home&L1=Media+%26+Publications&L2=Treasury+Press+Releases&L3=2006&sid=Ctre&b=pressrelease&f=2006_032706&csid=Ctre", 30) }
|
83
|
+
let(:shortened) { Truncator::UrlParser.shorten_url("http://www.mass.gov/?pageID=trepressrelease&L=4&L0=Home&L1=Media+%26+Publications&L2=Treasury+Press+Releases&L3=2006&sid=Ctre&b=pressrelease&f=2006_032706&csid=Ctre", 30) }
|
84
84
|
|
85
85
|
it "should truncate to 30 chars with ellipses" do
|
86
86
|
shortened.should == "www.mass.gov/?pageID=trepre..."
|
@@ -88,7 +88,7 @@ describe UrlParser do
|
|
88
88
|
end
|
89
89
|
|
90
90
|
context "when the URL contains a really long host name and a long trailing filename" do
|
91
|
-
let(:shortened) { UrlParser.shorten_url("http://www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/some/path/1234567890123456789012345678901234test_of_the_mergency_broadcastingnet_work.html", 30) }
|
91
|
+
let(:shortened) { Truncator::UrlParser.shorten_url("http://www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/some/path/1234567890123456789012345678901234test_of_the_mergency_broadcastingnet_work.html", 30) }
|
92
92
|
|
93
93
|
it "should not truncate the host name and truncated the last part of the path to truncation length and all dirs" do
|
94
94
|
shortened.should == "www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/.../123456789012345678901234567..."
|
@@ -97,7 +97,7 @@ describe UrlParser do
|
|
97
97
|
|
98
98
|
#TODO: this and the next spec can be merged
|
99
99
|
context "when the URL contains a really long host name and is an http url and has an empty path" do
|
100
|
-
let(:shortened) { UrlParser.shorten_url("http://www128376218.skjdhfskdj.lqdkwjqlkwjdqlqwkjd.com/", 30) }
|
100
|
+
let(:shortened) { Truncator::UrlParser.shorten_url("http://www128376218.skjdhfskdj.lqdkwjqlkwjdqlqwkjd.com/", 30) }
|
101
101
|
|
102
102
|
it "should truncate the host name and have no trailing /" do
|
103
103
|
shortened.should == "www128376218.skjdhfskdj.lqd..."
|
@@ -105,7 +105,7 @@ describe UrlParser do
|
|
105
105
|
end
|
106
106
|
|
107
107
|
context "when the URL contains a really long host name and is an http url and has an empty path and no trailing /" do
|
108
|
-
let(:shortened) { UrlParser.shorten_url("http://www128376218.skjdhfskdj.lqdkwjqlkwjdqlqwkjd.com", 30) }
|
108
|
+
let(:shortened) { Truncator::UrlParser.shorten_url("http://www128376218.skjdhfskdj.lqdkwjqlkwjdqlqwkjd.com", 30) }
|
109
109
|
|
110
110
|
it "should truncate the URL and have no trailing /" do
|
111
111
|
shortened.should == "www128376218.skjdhfskdj.lqd..."
|
@@ -113,7 +113,7 @@ describe UrlParser do
|
|
113
113
|
end
|
114
114
|
|
115
115
|
context "when the URL contains a really long host name and has a really long query parameter" do
|
116
|
-
let(:shortened) { UrlParser.shorten_url("http://www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/?cmd=1234567890123456789012345678901234&api_key=1234567890123456789012345678901234", 30) }
|
116
|
+
let(:shortened) { Truncator::UrlParser.shorten_url("http://www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/?cmd=1234567890123456789012345678901234&api_key=1234567890123456789012345678901234", 30) }
|
117
117
|
|
118
118
|
it "should not truncate the host name but truncate the query parameter" do
|
119
119
|
shortened.should == "www128376218.skjdhfskdjfhs.lqdkwjqlkwjdqlqwkjd.com/?cmd=1234567890123456789012..."
|
@@ -121,7 +121,7 @@ describe UrlParser do
|
|
121
121
|
end
|
122
122
|
|
123
123
|
context "when URL is really short and contains only the protocol http and hostname" do
|
124
|
-
let(:shortened) { UrlParser.shorten_url("http://bit.ly/") }
|
124
|
+
let(:shortened) { Truncator::UrlParser.shorten_url("http://bit.ly/") }
|
125
125
|
|
126
126
|
it "should omit the protocol as well as trailing slash" do
|
127
127
|
shortened.should == "bit.ly"
|
@@ -129,7 +129,7 @@ describe UrlParser do
|
|
129
129
|
end
|
130
130
|
|
131
131
|
context "when URL is really short and contains only the protocol http and hostname and a long query parameter" do
|
132
|
-
let(:shortened) { UrlParser.shorten_url("http://api.bit.ly/?cmd=boom&t=now&auth_token=f886c1c02896492577e92b550cd22b3c83b062") }
|
132
|
+
let(:shortened) { Truncator::UrlParser.shorten_url("http://api.bit.ly/?cmd=boom&t=now&auth_token=f886c1c02896492577e92b550cd22b3c83b062") }
|
133
133
|
|
134
134
|
it "should omit the protocol as well as trailing slash" do
|
135
135
|
shortened.should == "api.bit.ly/?cmd=boom&t=now&auth_token=f..."
|
@@ -137,7 +137,7 @@ describe UrlParser do
|
|
137
137
|
end
|
138
138
|
|
139
139
|
context "when URL is really short and contains only the protocol http and hostname and a short query parameter" do
|
140
|
-
let(:shortened) { UrlParser.shorten_url("http://api.bit.ly/?cmd=boom&t=now") }
|
140
|
+
let(:shortened) { Truncator::UrlParser.shorten_url("http://api.bit.ly/?cmd=boom&t=now") }
|
141
141
|
|
142
142
|
it "should omit the protocol as well as trailing slash" do
|
143
143
|
shortened.should == "api.bit.ly/?cmd=boom&t=now"
|
@@ -148,19 +148,19 @@ describe UrlParser do
|
|
148
148
|
before do
|
149
149
|
@long_urls = [
|
150
150
|
"https://www.mass.gov/",
|
151
|
-
"http://www.mass.gov:
|
151
|
+
"http://www.mass.gov:81/",
|
152
152
|
"http://user:secret@www.mass.gov/",
|
153
153
|
"https://www.mass.gov/?pageID=trepressrelease&L=4&L0=Home&L1=Media+%26+Publications&L2=Treasury+Press+Releases&L3=2006&sid=Ctre&b=pressrelease&f=2006_032706&csid=Ctre",
|
154
|
-
"http://www.mass.gov:
|
154
|
+
"http://www.mass.gov:81/?pageID=trepressrelease&L=4&L0=Home&L1=Media+%26+Publications&L2=Treasury+Press+Releases&L3=2006&sid=Ctre&b=pressrelease&f=2006_032706&csid=Ctre",
|
155
155
|
"http://user:secret@www.mass.gov/?pageID=trepressrelease&L=4&L0=Home&L1=Media+%26+Publications&L2=Treasury+Press+Releases&L3=2006&sid=Ctre&b=pressrelease&f=2006_032706&csid=Ctre",
|
156
156
|
"ftp://www.mass.gov/"
|
157
157
|
]
|
158
158
|
@short_urls = [
|
159
159
|
"https://www.mass.gov/",
|
160
|
-
"http://www.mass.gov:
|
160
|
+
"http://www.mass.gov:81/",
|
161
161
|
"http://user:secret@www.mass.gov/",
|
162
162
|
"https://www.mass.gov/?pageID=trepressrelease...",
|
163
|
-
"http://www.mass.gov:
|
163
|
+
"http://www.mass.gov:81/?pageID=trepressrelease...",
|
164
164
|
"http://user:secret@www.mass.gov/?pageID=trepressrelease...",
|
165
165
|
"ftp://www.mass.gov/"
|
166
166
|
]
|
@@ -168,7 +168,7 @@ describe UrlParser do
|
|
168
168
|
|
169
169
|
it "should truncate to 30 chars with ellipses" do
|
170
170
|
@long_urls.each_with_index do |url, x|
|
171
|
-
UrlParser.shorten_url(url, 30).should == @short_urls[x]
|
171
|
+
Truncator::UrlParser.shorten_url(url, 30).should == @short_urls[x]
|
172
172
|
end
|
173
173
|
end
|
174
174
|
end
|
data/truncator.gemspec
CHANGED
@@ -15,7 +15,10 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.files = `git ls-files`.split($/)
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
|
18
|
+
spec.add_dependency "activesupport", "~> 4.0.1"
|
19
|
+
|
18
20
|
spec.add_development_dependency "bundler", "~> 1.3"
|
19
21
|
spec.add_development_dependency "rake"
|
20
22
|
spec.add_development_dependency "rspec", "~> 2.13"
|
23
|
+
spec.add_development_dependency "byebug"
|
21
24
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: truncator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- freemanoid
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.0.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.0.1
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - ~>
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '2.13'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: url truncator
|
56
84
|
email:
|
57
85
|
- freemanoid321@gmail.com
|
@@ -65,6 +93,9 @@ files:
|
|
65
93
|
- README.md
|
66
94
|
- Rakefile
|
67
95
|
- lib/truncator.rb
|
96
|
+
- lib/truncator/extended_array.rb
|
97
|
+
- lib/truncator/extended_string.rb
|
98
|
+
- lib/truncator/extended_uri.rb
|
68
99
|
- lib/truncator/url_parser.rb
|
69
100
|
- lib/truncator/version.rb
|
70
101
|
- spec/spec_helper.rb
|