truncator 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|