stringex 1.1.0 → 1.2.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.
- 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"
|