stringex 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +7 -2
- data/init.rb +2 -1
- data/lib/lucky_sneaks/acts_as_url.rb +15 -11
- data/lib/lucky_sneaks/string_extensions.rb +31 -34
- data/lib/lucky_sneaks/unidecoder.rb +11 -10
- data/lib/lucky_sneaks/unidecoder_data/x00.yml +5 -5
- data/lib/stringex.rb +1 -0
- data/stringex.gemspec +7 -6
- data/test/acts_as_url_test.rb +19 -18
- data/test/string_extensions_test.rb +28 -32
- data/test/unidecoder_test.rb +7 -7
- metadata +20 -5
data/Rakefile
CHANGED
@@ -214,7 +214,12 @@ begin
|
|
214
214
|
gem.rdoc_options = %w{--main README.rdoc --charset utf-8 --line-numbers}
|
215
215
|
gem.extra_rdoc_files = %w{MIT-LICENSE README.rdoc}
|
216
216
|
end
|
217
|
-
|
217
|
+
|
218
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
219
|
+
rubyforge.doc_task = "rdoc"
|
220
|
+
end
|
221
|
+
|
222
|
+
Jeweler::GemcutterTasks.new
|
218
223
|
rescue LoadError
|
219
224
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
220
225
|
end
|
@@ -243,7 +248,7 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
243
248
|
version = ""
|
244
249
|
end
|
245
250
|
|
246
|
-
rdoc.rdoc_dir = '
|
251
|
+
rdoc.rdoc_dir = 'rdoc'
|
247
252
|
rdoc.title = 'Stringex: A String Extension Pack [#{version}]'
|
248
253
|
rdoc.options << '--line-numbers' << '--inline-source'
|
249
254
|
rdoc.options << '--charset' << 'utf-8'
|
data/init.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
# encoding: UTF-8
|
2
|
+
require "stringex"
|
@@ -1,27 +1,28 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module LuckySneaks
|
2
3
|
module ActsAsUrl # :nodoc:
|
3
4
|
def self.included(base)
|
4
5
|
base.extend ClassMethods
|
5
6
|
end
|
6
|
-
|
7
|
+
|
7
8
|
module ClassMethods # :doc:
|
8
9
|
# Creates a callback to automatically create an url-friendly representation
|
9
10
|
# of the <tt>attribute</tt> argument. Example:
|
10
|
-
#
|
11
|
+
#
|
11
12
|
# act_as_url :title
|
12
|
-
#
|
13
|
+
#
|
13
14
|
# will use the string contents of the <tt>title</tt> attribute
|
14
15
|
# to create the permalink. <strong>Note:</strong> you can also use a non-database-backed
|
15
16
|
# method to supply the string contents for the permalink. Just use that method's name
|
16
17
|
# as the argument as you would an attribute.
|
17
|
-
#
|
18
|
+
#
|
18
19
|
# The default attribute <tt>acts_as_url</tt> uses to save the permalink is <tt>url</tt>
|
19
20
|
# but this can be changed in the options hash. Available options are:
|
20
|
-
#
|
21
|
+
#
|
21
22
|
# <tt>:url_attribute</tt>:: The name of the attribute to use for storing the generated url string.
|
22
23
|
# Default is <tt>:url</tt>
|
23
24
|
# <tt>:scope</tt>:: The name of model attribute to scope unique urls to. There is no default here.
|
24
|
-
# <tt>:only_when_blank</tt>:: If true, the url generation will only happen when <tt>:url_attribute</tt> is
|
25
|
+
# <tt>:only_when_blank</tt>:: If true, the url generation will only happen when <tt>:url_attribute</tt> is
|
25
26
|
# blank. Default is false (meaning url generation will happen always)
|
26
27
|
# <tt>:sync_url</tt>:: If set to true, the url field will be updated when changes are made to the
|
27
28
|
# attribute it is based on. Default is false.
|
@@ -31,12 +32,15 @@ module LuckySneaks
|
|
31
32
|
cattr_accessor :url_attribute # The attribute on the DB
|
32
33
|
cattr_accessor :only_when_blank
|
33
34
|
cattr_accessor :duplicate_count_separator
|
34
|
-
|
35
|
+
|
35
36
|
if options[:sync_url]
|
36
37
|
before_validation :ensure_unique_url
|
37
38
|
else
|
38
|
-
|
39
|
-
|
39
|
+
if defined?(ActiveModel::Callbacks)
|
40
|
+
before_validation(:ensure_unique_url, :on => :create)
|
41
|
+
else
|
42
|
+
before_validation_on_create(:ensure_unique_url)
|
43
|
+
end
|
40
44
|
end
|
41
45
|
|
42
46
|
self.attribute_to_urlify = attribute
|
@@ -49,7 +53,7 @@ module LuckySneaks
|
|
49
53
|
# Initialize the url fields for the records that need it. Designed for people who add
|
50
54
|
# <tt>acts_as_url</tt> support once there's already development/production data they'd
|
51
55
|
# like to keep around.
|
52
|
-
#
|
56
|
+
#
|
53
57
|
# Note: This method can get very expensive, very fast. If you're planning on using this
|
54
58
|
# on a large selection, you will get much better results writing your own version with
|
55
59
|
# using pagination.
|
@@ -60,7 +64,7 @@ module LuckySneaks
|
|
60
64
|
end
|
61
65
|
end
|
62
66
|
end
|
63
|
-
|
67
|
+
|
64
68
|
private
|
65
69
|
def ensure_unique_url
|
66
70
|
url_attribute = self.class.url_attribute
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
3
|
module LuckySneaks
|
4
4
|
# These methods are all added on String class.
|
@@ -6,10 +6,10 @@ module LuckySneaks
|
|
6
6
|
def self.included(base) # :nodoc:
|
7
7
|
base.extend(ClassMethods)
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
# Returns the string converted (via Textile/RedCloth) to HTML format
|
11
11
|
# or self [with a friendly warning] if Redcloth is not available.
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# Using <tt>:lite</tt> argument will cause RedCloth to not wrap the HTML in a container
|
14
14
|
# P element, which is useful behavior for generating header element text, etc.
|
15
15
|
# This is roughly equivalent to ActionView's <tt>textilize_without_paragraph</tt>
|
@@ -31,23 +31,18 @@ module LuckySneaks
|
|
31
31
|
self
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
35
|
-
# Create a URI-friendly representation of the string. This is used internally by
|
34
|
+
|
35
|
+
# Create a URI-friendly representation of the string. This is used internally by
|
36
36
|
# acts_as_url[link:classes/LuckySneaks/ActsAsUrl/ClassMethods.html#M000012]
|
37
37
|
# but can be called manually in order to generate an URI-friendly version of any string.
|
38
38
|
def to_url
|
39
39
|
remove_formatting.downcase.replace_whitespace("-").collapse("-")
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# Performs multiple text manipulations. Essentially a shortcut for typing them all. View source
|
43
43
|
# below to see which methods are run.
|
44
44
|
def remove_formatting
|
45
|
-
strip_html_tags.
|
46
|
-
convert_german_umlauts.
|
47
|
-
convert_accented_entities.
|
48
|
-
convert_misc_entities.
|
49
|
-
convert_misc_characters.
|
50
|
-
to_ascii.collapse
|
45
|
+
strip_html_tags.convert_accented_entities.convert_misc_entities.convert_misc_characters.to_ascii.collapse
|
51
46
|
end
|
52
47
|
|
53
48
|
# Removes HTML tags from text. This code is simplified from Tobias Luettke's regular expression
|
@@ -61,36 +56,22 @@ module LuckySneaks
|
|
61
56
|
end
|
62
57
|
|
63
58
|
# Converts HTML entities into the respective non-accented letters. Examples:
|
64
|
-
#
|
59
|
+
#
|
65
60
|
# "á".convert_accented_entities # => "a"
|
66
61
|
# "ç".convert_accented_entities # => "c"
|
67
62
|
# "è".convert_accented_entities # => "e"
|
68
63
|
# "î".convert_accented_entities # => "i"
|
69
64
|
# "ø".convert_accented_entities # => "o"
|
70
65
|
# "ü".convert_accented_entities # => "u"
|
71
|
-
#
|
66
|
+
#
|
72
67
|
# Note: This does not do any conversion of Unicode/Ascii accented-characters. For that
|
73
68
|
# functionality please use <tt>to_ascii</tt>.
|
74
69
|
def convert_accented_entities
|
75
70
|
gsub(/&([A-Za-z])(grave|acute|circ|tilde|uml|ring|cedil|slash);/, '\1')
|
76
71
|
end
|
77
72
|
|
78
|
-
# Converts German Umlauts to their transliteration according to German conventions.
|
79
|
-
def convert_german_umlauts
|
80
|
-
map = {
|
81
|
-
"Ä" => "ae",
|
82
|
-
"Ö" => "oe",
|
83
|
-
"Ü" => "ue",
|
84
|
-
"ä" => "ae",
|
85
|
-
"ö" => "oe",
|
86
|
-
"ü" => "ue",
|
87
|
-
"ß" => "ss"
|
88
|
-
}
|
89
|
-
gsub(/#{map.keys.join('|')}/) { |match| map[match] }
|
90
|
-
end
|
91
|
-
|
92
73
|
# Converts HTML entities (taken from common Textile/RedCloth formattings) into plain text formats.
|
93
|
-
#
|
74
|
+
#
|
94
75
|
# Note: This isn't an attempt at complete conversion of HTML entities, just those most likely
|
95
76
|
# to be generated by Textile.
|
96
77
|
def convert_misc_entities
|
@@ -121,9 +102,24 @@ module LuckySneaks
|
|
121
102
|
dummy.gsub(/&[^;]+;/, "")
|
122
103
|
end
|
123
104
|
|
105
|
+
# Converts MS Word 'smart punctuation' to ASCII
|
106
|
+
#
|
107
|
+
def convert_smart_punctuation
|
108
|
+
dummy = dup
|
109
|
+
{
|
110
|
+
|
111
|
+
"(“|”|\302\223|\302\224)" => '"',
|
112
|
+
"(‘|’|\302\221|\302\222)" => "'",
|
113
|
+
"…" => "...",
|
114
|
+
}.each do |smart, normal|
|
115
|
+
dummy.gsub!(/#{smart}/, normal)
|
116
|
+
end
|
117
|
+
dummy
|
118
|
+
end
|
119
|
+
|
124
120
|
# Converts various common plaintext characters to a more URI-friendly representation.
|
125
121
|
# Examples:
|
126
|
-
#
|
122
|
+
#
|
127
123
|
# "foo & bar".convert_misc_characters # => "foo and bar"
|
128
124
|
# "Chanel #9".convert_misc_characters # => "Chanel number nine"
|
129
125
|
# "user@host".convert_misc_characters # => "user at host"
|
@@ -132,7 +128,7 @@ module LuckySneaks
|
|
132
128
|
# "*69".convert_misc_characters # => "star 69"
|
133
129
|
# "100%".convert_misc_characters # => "100 percent"
|
134
130
|
# "windows/mac/linux".convert_misc_characters # => "windows slash mac slash linux"
|
135
|
-
#
|
131
|
+
#
|
136
132
|
# Note: Because this method will convert any & symbols to the string "and",
|
137
133
|
# you should run any methods which convert HTML entities (convert_html_entities and convert_misc_entities)
|
138
134
|
# before running this method.
|
@@ -158,6 +154,7 @@ module LuckySneaks
|
|
158
154
|
/\s*\*\s*/ => "star",
|
159
155
|
/\s*%\s*/ => "percent",
|
160
156
|
/\s*(\\|\/)\s*/ => "slash",
|
157
|
+
/(\s*=\s*)/ => " equals "
|
161
158
|
}.each do |found, replaced|
|
162
159
|
replaced = " #{replaced} " unless replaced =~ /\\1/
|
163
160
|
dummy.gsub!(found, replaced)
|
@@ -167,7 +164,7 @@ module LuckySneaks
|
|
167
164
|
|
168
165
|
# Replace runs of whitespace in string. Defaults to a single space but any replacement
|
169
166
|
# string may be specified as an argument. Examples:
|
170
|
-
#
|
167
|
+
#
|
171
168
|
# "Foo bar".replace_whitespace # => "Foo bar"
|
172
169
|
# "Foo bar".replace_whitespace("-") # => "Foo-bar"
|
173
170
|
def replace_whitespace(replace = " ")
|
@@ -176,12 +173,12 @@ module LuckySneaks
|
|
176
173
|
|
177
174
|
# Removes specified character from the beginning and/or end of the string and then performs
|
178
175
|
# <tt>String#squeeze(character)</tt>, condensing runs of the character within the string.
|
179
|
-
#
|
176
|
+
#
|
180
177
|
# Note: This method has been superceded by ActiveSupport's squish method.
|
181
178
|
def collapse(character = " ")
|
182
179
|
sub(/^#{character}*/, "").sub(/#{character}*$/, "").squeeze(character)
|
183
180
|
end
|
184
|
-
|
181
|
+
|
185
182
|
module ClassMethods
|
186
183
|
# Returns string of random characters with a length matching the specified limit. Excludes 0
|
187
184
|
# to avoid confusion between 0 and O.
|
@@ -1,15 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
require "yaml"
|
2
3
|
|
3
4
|
module LuckySneaks
|
4
5
|
module Unidecoder
|
5
6
|
# Contains Unicode codepoints, loading as needed from YAML files
|
6
7
|
CODEPOINTS = Hash.new { |h, k|
|
7
|
-
h[k] = YAML::load_file(File.join(File.dirname(__FILE__), "unidecoder_data", "#{k}.yml"))
|
8
|
+
h[k] = YAML::load_file(File.join(File.expand_path(File.dirname(__FILE__)), "unidecoder_data", "#{k}.yml"))
|
8
9
|
} unless defined?(CODEPOINTS)
|
9
|
-
|
10
|
+
|
10
11
|
class << self
|
11
12
|
# Returns string with its UTF-8 characters transliterated to ASCII ones
|
12
|
-
#
|
13
|
+
#
|
13
14
|
# You're probably better off just using the added String#to_ascii
|
14
15
|
def decode(string)
|
15
16
|
string.gsub(/[^\x00-\x7f]/u) do |codepoint|
|
@@ -22,25 +23,25 @@ module LuckySneaks
|
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
25
|
-
|
26
|
+
|
26
27
|
# Returns character for the given Unicode codepoint
|
27
28
|
def encode(codepoint)
|
28
29
|
["0x#{codepoint}".to_i(16)].pack("U")
|
29
30
|
end
|
30
|
-
|
31
|
+
|
31
32
|
# Returns string indicating which file (and line) contains the
|
32
33
|
# transliteration value for the character
|
33
34
|
def in_yaml_file(character)
|
34
35
|
unpacked = character.unpack("U")[0]
|
35
36
|
"#{code_group(unpacked)}.yml (line #{grouped_point(unpacked) + 2})"
|
36
37
|
end
|
37
|
-
|
38
|
+
|
38
39
|
private
|
39
40
|
# Returns the Unicode codepoint grouping for the given character
|
40
41
|
def code_group(unpacked_character)
|
41
42
|
"x%02x" % (unpacked_character >> 8)
|
42
43
|
end
|
43
|
-
|
44
|
+
|
44
45
|
# Returns the index of the given character in the YAML file for its codepoint group
|
45
46
|
def grouped_point(unpacked_character)
|
46
47
|
unpacked_character & 255
|
@@ -51,11 +52,11 @@ end
|
|
51
52
|
|
52
53
|
module LuckySneaks
|
53
54
|
module StringExtensions
|
54
|
-
# Returns string with its UTF-8 characters transliterated to ASCII ones. Example:
|
55
|
-
#
|
55
|
+
# Returns string with its UTF-8 characters transliterated to ASCII ones. Example:
|
56
|
+
#
|
56
57
|
# "⠋⠗⠁⠝⠉⠑".to_ascii #=> "braille"
|
57
58
|
def to_ascii
|
58
59
|
LuckySneaks::Unidecoder.decode(self)
|
59
60
|
end
|
60
61
|
end
|
61
|
-
end
|
62
|
+
end
|
@@ -8,7 +8,7 @@
|
|
8
8
|
- "\x06"
|
9
9
|
- "\a"
|
10
10
|
- "\x08"
|
11
|
-
- '
|
11
|
+
- ' '
|
12
12
|
- "\n"
|
13
13
|
- "\v"
|
14
14
|
- "\f"
|
@@ -144,10 +144,10 @@
|
|
144
144
|
- ''
|
145
145
|
- ''
|
146
146
|
- ''
|
147
|
-
- '
|
148
|
-
- '
|
149
|
-
- ''
|
150
|
-
- ''
|
147
|
+
- "'"
|
148
|
+
- "'"
|
149
|
+
- '"'
|
150
|
+
- '"'
|
151
151
|
- ''
|
152
152
|
- ''
|
153
153
|
- ''
|
data/lib/stringex.rb
CHANGED
data/stringex.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{stringex}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Russell Norris"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-10-20}
|
13
13
|
s.description = %q{Some [hopefully] useful extensions to Ruby’s String class. Stringex is made up of three libraries: ActsAsUrl [permalink solution with better character translation], Unidecoder [Unicode to Ascii transliteration], and StringExtensions [miscellaneous helper methods for the String class].}
|
14
14
|
s.email = %q{rsl@luckysneaks.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -211,7 +211,7 @@ Gem::Specification.new do |s|
|
|
211
211
|
s.rdoc_options = ["--main", "README.rdoc", "--charset", "utf-8", "--line-numbers"]
|
212
212
|
s.require_paths = ["lib"]
|
213
213
|
s.rubyforge_project = %q{stringex}
|
214
|
-
s.rubygems_version = %q{1.3.
|
214
|
+
s.rubygems_version = %q{1.3.7}
|
215
215
|
s.summary = %q{Some [hopefully] useful extensions to Ruby’s String class}
|
216
216
|
s.test_files = [
|
217
217
|
"test/acts_as_url_test.rb",
|
@@ -223,9 +223,10 @@ Gem::Specification.new do |s|
|
|
223
223
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
224
224
|
s.specification_version = 3
|
225
225
|
|
226
|
-
if Gem::Version.new(Gem::
|
226
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
227
227
|
else
|
228
228
|
end
|
229
229
|
else
|
230
230
|
end
|
231
231
|
end
|
232
|
+
|
data/test/acts_as_url_test.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
require 'test/unit'
|
2
3
|
|
3
4
|
begin
|
4
|
-
require File.dirname(__FILE__) + '/../../../config/environment'
|
5
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../../../config/environment'
|
5
6
|
rescue LoadError
|
6
7
|
require 'rubygems'
|
7
8
|
gem 'activerecord'
|
8
9
|
require 'active_record'
|
9
|
-
|
10
|
-
RAILS_ROOT = File.dirname(__FILE__)
|
11
|
-
$: << File.join(File.dirname(__FILE__), '../lib')
|
10
|
+
|
11
|
+
RAILS_ROOT = File.expand_path(File.dirname(__FILE__))
|
12
|
+
$: << File.join(File.expand_path(File.dirname(__FILE__)), '../lib')
|
12
13
|
end
|
13
14
|
|
14
|
-
require File.join(File.dirname(__FILE__), '../init')
|
15
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '../init.rb')
|
15
16
|
|
16
17
|
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "acts_as_url.sqlite3")
|
17
18
|
|
@@ -28,7 +29,7 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
28
29
|
create_table :mocuments, :force => true do |t|
|
29
30
|
t.string :title, :url, :other
|
30
31
|
end
|
31
|
-
|
32
|
+
|
32
33
|
create_table :permuments, :force => true do |t|
|
33
34
|
t.string :title, :permalink, :other
|
34
35
|
end
|
@@ -65,7 +66,7 @@ end
|
|
65
66
|
|
66
67
|
class Procument < ActiveRecord::Base
|
67
68
|
acts_as_url :non_attribute_method
|
68
|
-
|
69
|
+
|
69
70
|
def non_attribute_method
|
70
71
|
"#{title} got massaged"
|
71
72
|
end
|
@@ -84,7 +85,7 @@ class ActsAsUrlTest < Test::Unit::TestCase
|
|
84
85
|
@doc = Document.create(:title => "Let's Make a Test Title, <em>Okay</em>?")
|
85
86
|
assert_equal "lets-make-a-test-title-okay", @doc.url
|
86
87
|
end
|
87
|
-
|
88
|
+
|
88
89
|
def test_should_create_unique_url
|
89
90
|
@doc = Document.create!(:title => "Unique")
|
90
91
|
@other_doc = Document.create!(:title => "Unique")
|
@@ -116,7 +117,7 @@ class ActsAsUrlTest < Test::Unit::TestCase
|
|
116
117
|
assert_equal "foo", @doc2.other
|
117
118
|
assert_equal "twonique-1", @other_doc2.url
|
118
119
|
end
|
119
|
-
|
120
|
+
|
120
121
|
def test_should_create_unique_url_when_partial_url_already_exists
|
121
122
|
@doc = Document.create!(:title => "House Farms")
|
122
123
|
@other_doc = Document.create!(:title => "House Farm")
|
@@ -124,38 +125,38 @@ class ActsAsUrlTest < Test::Unit::TestCase
|
|
124
125
|
assert_equal "house-farms", @doc.url
|
125
126
|
assert_equal "house-farm", @other_doc.url
|
126
127
|
end
|
127
|
-
|
128
|
+
|
128
129
|
def test_should_scope_uniqueness
|
129
130
|
@moc = Mocument.create!(:title => "Mocumentary", :other => "I dunno why but I don't care if I'm unique")
|
130
131
|
@other_moc = Mocument.create!(:title => "Mocumentary")
|
131
132
|
assert_equal @moc.url, @other_moc.url
|
132
133
|
end
|
133
|
-
|
134
|
+
|
134
135
|
def test_should_still_create_unique_if_in_same_scope
|
135
136
|
@moc = Mocument.create!(:title => "Mocumentary", :other => "Suddenly, I care if I'm unique")
|
136
137
|
@other_moc = Mocument.create!(:title => "Mocumentary", :other => "Suddenly, I care if I'm unique")
|
137
138
|
assert_not_equal @moc.url, @other_moc.url
|
138
139
|
end
|
139
|
-
|
140
|
+
|
140
141
|
def test_should_use_alternate_field_name
|
141
142
|
@perm = Permument.create!(:title => "Anything at This Point")
|
142
143
|
assert_equal "anything-at-this-point", @perm.permalink
|
143
144
|
end
|
144
|
-
|
145
|
+
|
145
146
|
def test_should_not_update_url_by_default
|
146
147
|
@doc = Document.create!(:title => "Stable as Stone")
|
147
148
|
@original_url = @doc.url
|
148
149
|
@doc.update_attributes :title => "New Unstable Madness"
|
149
150
|
assert_equal @original_url, @doc.url
|
150
151
|
end
|
151
|
-
|
152
|
+
|
152
153
|
def test_should_update_url_if_asked
|
153
154
|
@moc = Mocument.create!(:title => "Original")
|
154
155
|
@original_url = @moc.url
|
155
156
|
@moc.update_attributes :title => "New and Improved"
|
156
157
|
assert_not_equal @original_url, @moc.url
|
157
158
|
end
|
158
|
-
|
159
|
+
|
159
160
|
def test_should_update_url_only_when_blank_if_asked
|
160
161
|
@original_url = 'the-url-of-concrete'
|
161
162
|
@blank = Blankument.create!(:title => "Stable as Stone", :url => @original_url)
|
@@ -163,7 +164,7 @@ class ActsAsUrlTest < Test::Unit::TestCase
|
|
163
164
|
@blank = Blankument.create!(:title => "Stable as Stone")
|
164
165
|
assert_equal 'stable-as-stone', @blank.url
|
165
166
|
end
|
166
|
-
|
167
|
+
|
167
168
|
def test_should_mass_initialize_urls
|
168
169
|
@doc_1 = Document.create!(:title => "Initial")
|
169
170
|
@doc_2 = Document.create!(:title => "Subsequent")
|
@@ -177,7 +178,7 @@ class ActsAsUrlTest < Test::Unit::TestCase
|
|
177
178
|
assert_equal "initial", @doc_1.url
|
178
179
|
assert_equal "subsequent", @doc_2.url
|
179
180
|
end
|
180
|
-
|
181
|
+
|
181
182
|
def test_should_mass_initialize_urls_with_custom_url_attribute
|
182
183
|
@doc_1 = Permument.create!(:title => "Initial")
|
183
184
|
@doc_2 = Permument.create!(:title => "Subsequent")
|
@@ -191,7 +192,7 @@ class ActsAsUrlTest < Test::Unit::TestCase
|
|
191
192
|
assert_equal "initial", @doc_1.permalink
|
192
193
|
assert_equal "subsequent", @doc_2.permalink
|
193
194
|
end
|
194
|
-
|
195
|
+
|
195
196
|
def test_should_utilize_block_if_given
|
196
197
|
@doc = Procument.create!(:title => "Title String")
|
197
198
|
assert_equal "title-string-got-massaged", @doc.url
|
@@ -1,9 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
3
|
require "test/unit"
|
4
4
|
|
5
|
-
$: << File.join(File.dirname(__FILE__), '../lib')
|
6
|
-
require File.join(File.dirname(__FILE__), "../init")
|
5
|
+
$: << File.join(File.expand_path(File.dirname(__FILE__)), '../lib')
|
6
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "../init.rb")
|
7
7
|
|
8
8
|
class StringExtensionsTest < Test::Unit::TestCase
|
9
9
|
def test_to_html
|
@@ -21,7 +21,7 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
21
21
|
rescue LoadError
|
22
22
|
puts "\n>> Could not load RedCloth. String#to_html was not tested.\n>> Please gem install RedCloth if you'd like to use this functionality."
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def test_to_html_lite
|
26
26
|
require "rubygems"
|
27
27
|
require "RedCloth"
|
@@ -34,12 +34,12 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
34
34
|
rescue LoadError
|
35
35
|
puts "\n>> Could not load RedCloth. String#to_html (with :lite argument) was not tested.\n>> Please gem install RedCloth if you'd like to use this functionality."
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def test_to_url
|
39
39
|
{
|
40
40
|
"<p>This has 100% too much <em>formatting</em></p>" =>
|
41
41
|
"this-has-100-percent-too-much-formatting",
|
42
|
-
"Tea & crumpets & <strong>crêpes</strong> for me!" =>
|
42
|
+
"Tea & crumpets & <strong>crêpes</strong> for me!" =>
|
43
43
|
"tea-and-crumpets-and-crepes-for-me",
|
44
44
|
"The Suspense... Is... Killing Me" =>
|
45
45
|
"the-suspense-dot-dot-dot-is-dot-dot-dot-killing-me",
|
@@ -47,24 +47,24 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
47
47
|
"how-to-use-attr-accessible-and-attr-protected",
|
48
48
|
"I'm just making sure there's nothing wrong with things!" =>
|
49
49
|
"im-just-making-sure-theres-nothing-wrong-with-things",
|
50
|
-
"
|
51
|
-
"
|
50
|
+
"foo = bar and bar=foo" =>
|
51
|
+
"foo-equals-bar-and-bar-equals-foo"
|
52
52
|
}.each do |html, plain|
|
53
53
|
assert_equal plain, html.to_url
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def test_remove_formatting
|
58
58
|
{
|
59
59
|
"<p>This has 100% too much <em>formatting</em></p>" =>
|
60
60
|
"This has 100 percent too much formatting",
|
61
|
-
"Tea & crumpets & <strong>crêpes</strong> for me!" =>
|
61
|
+
"Tea & crumpets & <strong>crêpes</strong> for me!" =>
|
62
62
|
"Tea and crumpets and crepes for me"
|
63
63
|
}.each do |html, plain|
|
64
64
|
assert_equal plain, html.remove_formatting
|
65
65
|
end
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
def test_strip_html_tags
|
69
69
|
{
|
70
70
|
"<h1><em>This</em> is good but <strong>that</strong> is better</h1>" =>
|
@@ -78,7 +78,7 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
78
78
|
assert_equal plain, html.strip_html_tags
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
def test_convert_accented_entities
|
83
83
|
{
|
84
84
|
"å" => "a",
|
@@ -92,21 +92,7 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
92
92
|
assert_equal plain, entitied.convert_accented_entities
|
93
93
|
end
|
94
94
|
end
|
95
|
-
|
96
|
-
def test_convert_german_umlauts
|
97
|
-
{
|
98
|
-
"Ä" => "ae",
|
99
|
-
"Ö" => "oe",
|
100
|
-
"Ü" => "ue",
|
101
|
-
"ä" => "ae",
|
102
|
-
"ö" => "oe",
|
103
|
-
"ü" => "ue",
|
104
|
-
"ß" => "ss"
|
105
|
-
}.each do |entitied, plain|
|
106
|
-
assert_equal plain, entitied.convert_german_umlauts
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
95
|
+
|
110
96
|
def test_convert_misc_entities
|
111
97
|
{
|
112
98
|
"America™" => "America(tm)",
|
@@ -120,7 +106,17 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
120
106
|
assert_equal plain, entitied.convert_misc_entities
|
121
107
|
end
|
122
108
|
end
|
123
|
-
|
109
|
+
|
110
|
+
def test_convert_smart_punctuation
|
111
|
+
{
|
112
|
+
"“smart quotes”" => '"smart quotes"',
|
113
|
+
"‘dumb quotes’" => "'dumb quotes'",
|
114
|
+
"I love you, but…" => "I love you, but...",
|
115
|
+
}.each do |smart, plain|
|
116
|
+
assert_equal plain, smart.convert_smart_punctuation
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
124
120
|
def test_convert_misc_characters
|
125
121
|
{
|
126
122
|
"Foo & bar make foobar" => "Foo and bar make foobar",
|
@@ -134,7 +130,7 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
134
130
|
assert_equal plain, misc.convert_misc_characters
|
135
131
|
end
|
136
132
|
end
|
137
|
-
|
133
|
+
|
138
134
|
def test_replace_whitespace
|
139
135
|
{
|
140
136
|
"this has too much space" => "this has too much space",
|
@@ -143,10 +139,10 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
143
139
|
}.each do |whitespaced, plain|
|
144
140
|
assert_equal plain, whitespaced.replace_whitespace
|
145
141
|
end
|
146
|
-
|
142
|
+
|
147
143
|
assert_equal "now-with-more-hyphens", "now with more hyphens".replace_whitespace("-")
|
148
144
|
end
|
149
|
-
|
145
|
+
|
150
146
|
def test_collapse
|
151
147
|
{
|
152
148
|
"too much space" => "too much space",
|
@@ -154,7 +150,7 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
154
150
|
}.each do |uncollapsed, plain|
|
155
151
|
assert_equal plain, uncollapsed.collapse
|
156
152
|
end
|
157
|
-
|
153
|
+
|
158
154
|
assert_equal "now-with-hyphens", "----now---------with-hyphens--------".collapse("-")
|
159
155
|
end
|
160
156
|
end
|
data/test/unidecoder_test.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# encoding: UTF-8
|
2
2
|
|
3
3
|
require "test/unit"
|
4
4
|
|
5
|
-
$: << File.join(File.dirname(__FILE__), '../lib')
|
6
|
-
require File.join(File.dirname(__FILE__), "../init")
|
5
|
+
$: << File.join(File.expand_path(File.dirname(__FILE__)), '../lib')
|
6
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "../init.rb")
|
7
7
|
|
8
8
|
class UnidecoderTest < Test::Unit::TestCase
|
9
9
|
# Silly phrases courtesy of Frank da Cruz
|
@@ -50,7 +50,7 @@ class UnidecoderTest < Test::Unit::TestCase
|
|
50
50
|
"私はガラスを食べられます。それは私を傷つけません。" => # Japanese
|
51
51
|
"Si hagarasuwoShi beraremasu. sorehaSi woShang tukemasen. "
|
52
52
|
}
|
53
|
-
|
53
|
+
|
54
54
|
def test_unidecoder_decode
|
55
55
|
DONT_CONVERT.each do |ascii|
|
56
56
|
assert_equal ascii, LuckySneaks::Unidecoder.decode(ascii)
|
@@ -59,7 +59,7 @@ class UnidecoderTest < Test::Unit::TestCase
|
|
59
59
|
assert_equal ascii, LuckySneaks::Unidecoder.decode(unicode)
|
60
60
|
end
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
def test_to_ascii
|
64
64
|
DONT_CONVERT.each do |ascii|
|
65
65
|
assert_equal ascii, ascii.to_ascii
|
@@ -68,7 +68,7 @@ class UnidecoderTest < Test::Unit::TestCase
|
|
68
68
|
assert_equal ascii, unicode.to_ascii
|
69
69
|
end
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def test_unidecoder_encode
|
73
73
|
{
|
74
74
|
# Strings
|
@@ -79,7 +79,7 @@ class UnidecoderTest < Test::Unit::TestCase
|
|
79
79
|
assert_equal unicode, LuckySneaks::Unidecoder.encode(codepoint)
|
80
80
|
end
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
def test_unidecoder_in_yaml_file
|
84
84
|
{
|
85
85
|
"A" => "x00.yml (line 67)",
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stringex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 31
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 1.2.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Russell Norris
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-10-20 00:00:00 -04:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -212,6 +218,9 @@ files:
|
|
212
218
|
- lib/lucky_sneaks/unidecoder_data/xff.yml
|
213
219
|
- lib/stringex.rb
|
214
220
|
- stringex.gemspec
|
221
|
+
- test/acts_as_url_test.rb
|
222
|
+
- test/string_extensions_test.rb
|
223
|
+
- test/unidecoder_test.rb
|
215
224
|
has_rdoc: true
|
216
225
|
homepage: http://github.com/rsl/stringex
|
217
226
|
licenses: []
|
@@ -226,21 +235,27 @@ rdoc_options:
|
|
226
235
|
require_paths:
|
227
236
|
- lib
|
228
237
|
required_ruby_version: !ruby/object:Gem::Requirement
|
238
|
+
none: false
|
229
239
|
requirements:
|
230
240
|
- - ">="
|
231
241
|
- !ruby/object:Gem::Version
|
242
|
+
hash: 3
|
243
|
+
segments:
|
244
|
+
- 0
|
232
245
|
version: "0"
|
233
|
-
version:
|
234
246
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
247
|
+
none: false
|
235
248
|
requirements:
|
236
249
|
- - ">="
|
237
250
|
- !ruby/object:Gem::Version
|
251
|
+
hash: 3
|
252
|
+
segments:
|
253
|
+
- 0
|
238
254
|
version: "0"
|
239
|
-
version:
|
240
255
|
requirements: []
|
241
256
|
|
242
257
|
rubyforge_project: stringex
|
243
|
-
rubygems_version: 1.3.
|
258
|
+
rubygems_version: 1.3.7
|
244
259
|
signing_key:
|
245
260
|
specification_version: 3
|
246
261
|
summary: "Some [hopefully] useful extensions to Ruby\xE2\x80\x99s String class"
|