smartname 0.3.0 → 0.3.1
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.lock +48 -10
- data/VERSION +1 -1
- data/lib/smart_name.rb +138 -105
- data/spec/inflection_helper.rb +2 -2
- data/spec/lib/smart_name_spec.rb +127 -126
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa282b70e290a7ba8992394815a56a59a82a725e
|
4
|
+
data.tar.gz: 4eca49b980ee540634174c58bb21ad478d94ead6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f740e5c97e12c676d329c7c8da7c0ec4cbd2782ed8b034748bdb5b907e091a28ef150469f20c621e64650081ca01a01253e99f72592896cee097254277ce28ef
|
7
|
+
data.tar.gz: ba9b593644295fdb93de0db2b123f38bfd608a6b54dc6fcdf78d2cd62c6290f6ae9f12804e5ee2dda17a28ad61a90992fece91a95cbf8b3de228c84c49df84f2
|
data/Gemfile.lock
CHANGED
@@ -1,21 +1,53 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activesupport (
|
5
|
-
i18n (
|
6
|
-
|
4
|
+
activesupport (4.2.6)
|
5
|
+
i18n (~> 0.7)
|
6
|
+
json (~> 1.7, >= 1.7.7)
|
7
|
+
minitest (~> 5.1)
|
8
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
9
|
+
tzinfo (~> 1.1)
|
10
|
+
addressable (2.4.0)
|
11
|
+
builder (3.2.2)
|
7
12
|
diff-lcs (1.1.3)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
13
|
+
faraday (0.8.11)
|
14
|
+
multipart-post (~> 1.2.0)
|
15
|
+
git (1.3.0)
|
16
|
+
github_api (0.10.1)
|
17
|
+
addressable
|
18
|
+
faraday (~> 0.8.1)
|
19
|
+
hashie (>= 1.2)
|
20
|
+
multi_json (~> 1.4)
|
21
|
+
nokogiri (~> 1.5.2)
|
22
|
+
oauth2
|
23
|
+
hashie (3.4.4)
|
24
|
+
highline (1.7.8)
|
25
|
+
htmlentities (4.3.4)
|
26
|
+
i18n (0.7.0)
|
27
|
+
jeweler (1.8.8)
|
28
|
+
builder
|
12
29
|
bundler (~> 1.0)
|
13
30
|
git (>= 1.2.5)
|
31
|
+
github_api (= 0.10.1)
|
32
|
+
highline (>= 1.6.15)
|
33
|
+
nokogiri (= 1.5.10)
|
14
34
|
rake
|
15
35
|
rdoc
|
16
|
-
json (1.
|
17
|
-
|
18
|
-
|
36
|
+
json (1.8.3)
|
37
|
+
jwt (1.5.1)
|
38
|
+
minitest (5.8.4)
|
39
|
+
multi_json (1.12.0)
|
40
|
+
multi_xml (0.5.5)
|
41
|
+
multipart-post (1.2.0)
|
42
|
+
nokogiri (1.5.10)
|
43
|
+
oauth2 (1.1.0)
|
44
|
+
faraday (>= 0.8, < 0.10)
|
45
|
+
jwt (~> 1.0, < 1.5.2)
|
46
|
+
multi_json (~> 1.3)
|
47
|
+
multi_xml (~> 0.5)
|
48
|
+
rack (>= 1.2, < 3)
|
49
|
+
rack (1.6.4)
|
50
|
+
rake (11.1.2)
|
19
51
|
rdoc (3.12.2)
|
20
52
|
json (~> 1.4)
|
21
53
|
rspec (2.8.0)
|
@@ -26,6 +58,9 @@ GEM
|
|
26
58
|
rspec-expectations (2.8.0)
|
27
59
|
diff-lcs (~> 1.1.2)
|
28
60
|
rspec-mocks (2.8.0)
|
61
|
+
thread_safe (0.3.5)
|
62
|
+
tzinfo (1.2.2)
|
63
|
+
thread_safe (~> 0.1)
|
29
64
|
|
30
65
|
PLATFORMS
|
31
66
|
ruby
|
@@ -37,3 +72,6 @@ DEPENDENCIES
|
|
37
72
|
jeweler (~> 1.8.3)
|
38
73
|
rdoc (~> 3.12)
|
39
74
|
rspec (~> 2.8.0)
|
75
|
+
|
76
|
+
BUNDLED WITH
|
77
|
+
1.11.2
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.1
|
data/lib/smart_name.rb
CHANGED
@@ -9,14 +9,11 @@ class SmartName < Object
|
|
9
9
|
OK4KEY_RE = RUBYENCODING ? '\p{Word}\*' : '\w\*'
|
10
10
|
|
11
11
|
include ActiveSupport::Configurable
|
12
|
-
|
13
|
-
config_accessor :joint, :
|
14
|
-
|
15
|
-
# Wagny defaults:
|
16
|
-
#config_accessor :joint, :default => '+'
|
12
|
+
|
13
|
+
config_accessor :joint, :banned_array, :var_re, :uninflect, :params, :session
|
14
|
+
|
17
15
|
SmartName.joint = '+'
|
18
|
-
SmartName.banned_array = [
|
19
|
-
SmartName.name_attribute = :cardname
|
16
|
+
SmartName.banned_array = ['/', '~', '|']
|
20
17
|
SmartName.var_re = /\{([^\}]*\})\}/
|
21
18
|
SmartName.uninflect = :singularize
|
22
19
|
|
@@ -26,9 +23,9 @@ class SmartName < Object
|
|
26
23
|
|
27
24
|
class << self
|
28
25
|
def new obj
|
29
|
-
return obj if self.class
|
30
|
-
str = Array
|
31
|
-
if known_name = @@name2nameobject[str]
|
26
|
+
return obj if obj.is_a? self.class
|
27
|
+
str = obj.is_a?(Array) ? obj * joint : obj.to_s
|
28
|
+
if (known_name = @@name2nameobject[str])
|
32
29
|
known_name
|
33
30
|
else
|
34
31
|
super str.strip
|
@@ -36,13 +33,12 @@ class SmartName < Object
|
|
36
33
|
end
|
37
34
|
|
38
35
|
def banned_re
|
39
|
-
%r{#{ (['['] + banned_array << joint
|
36
|
+
%r{#{ (['['] + banned_array << joint) * '\\' + ']' }}
|
40
37
|
end
|
41
38
|
end
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
#~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
|
40
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
41
|
+
# ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
|
46
42
|
|
47
43
|
attr_reader :simple, :parts, :key, :s
|
48
44
|
alias to_s s
|
@@ -51,27 +47,38 @@ class SmartName < Object
|
|
51
47
|
@s = str.to_s.strip
|
52
48
|
@s = @s.encode('UTF-8') if RUBYENCODING
|
53
49
|
@key = if @s.index(self.class.joint)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
50
|
+
@parts = @s.split(/\s*#{JOINT_RE}\s*/)
|
51
|
+
@parts << '' if @s[-1, 1] == self.class.joint
|
52
|
+
@simple = false
|
53
|
+
@parts.map { |p| p.to_name.key } * self.class.joint
|
54
|
+
else
|
55
|
+
@parts = [str]
|
56
|
+
@simple = true
|
57
|
+
str.empty? ? '' : simple_key
|
58
|
+
end
|
63
59
|
@@name2nameobject[str] = self
|
64
60
|
end
|
65
61
|
|
66
|
-
def to_name
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
def to_name
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def length
|
67
|
+
parts.length
|
68
|
+
end
|
69
|
+
|
70
|
+
def size
|
71
|
+
to_s.size
|
72
|
+
end
|
73
|
+
|
74
|
+
def blank?
|
75
|
+
s.blank?
|
76
|
+
end
|
70
77
|
alias empty? blank?
|
71
78
|
|
72
79
|
def valid?
|
73
|
-
|
74
|
-
pt.match self.class.banned_re
|
80
|
+
!parts.find do |pt|
|
81
|
+
pt.match self.class.banned_re
|
75
82
|
end
|
76
83
|
end
|
77
84
|
|
@@ -79,123 +86,151 @@ class SmartName < Object
|
|
79
86
|
"<#{self.class.name} key=#{key}[#{self}]>"
|
80
87
|
end
|
81
88
|
|
82
|
-
def ==
|
83
|
-
|
84
|
-
|
85
|
-
when
|
86
|
-
|
89
|
+
def == other
|
90
|
+
other_key =
|
91
|
+
case
|
92
|
+
when other.respond_to?(:key) then other.key
|
93
|
+
when other.respond_to?(:to_name) then other.to_name.key
|
94
|
+
else other.to_s
|
87
95
|
end
|
88
|
-
|
96
|
+
other_key == key
|
89
97
|
end
|
90
98
|
|
91
|
-
|
92
|
-
#~~~~~~~~~~~~~~~~~~~ VARIANTS ~~~~~~~~~~~~~~~~~~~
|
99
|
+
# ~~~~~~~~~~~~~~~~~~~ VARIANTS ~~~~~~~~~~~~~~~~~~~
|
93
100
|
|
94
101
|
def simple_key
|
95
|
-
decoded
|
102
|
+
decoded
|
103
|
+
.underscore
|
104
|
+
.gsub(/[^#{OK4KEY_RE}]+/, '_')
|
105
|
+
.split(/_+/)
|
106
|
+
.reject(&:empty?)
|
107
|
+
.map(&self.class.uninflect) * '_'
|
96
108
|
end
|
97
109
|
|
98
110
|
def url_key
|
99
|
-
@url_key ||=
|
111
|
+
@url_key ||= part_names.map do |part_name|
|
112
|
+
stripped = part_name.decoded.gsub(/[^#{OK4KEY_RE}]+/, ' ').strip
|
113
|
+
stripped.gsub(/[\s\_]+/, '_')
|
114
|
+
end * self.class.joint
|
100
115
|
end
|
101
116
|
|
102
117
|
def safe_key
|
103
|
-
@safe_key ||= key.
|
118
|
+
@safe_key ||= key.tr('*', 'X').tr self.class.joint, '-'
|
104
119
|
end
|
105
120
|
|
106
121
|
def decoded
|
107
|
-
@decoded ||=
|
122
|
+
@decoded ||= s.index('&') ? HTMLEntities.new.decode(s) : s
|
108
123
|
end
|
109
124
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
125
|
+
# ~~~~~~~~~~~~~~~~~~~ PARTS ~~~~~~~~~~~~~~~~~~~
|
126
|
+
|
127
|
+
alias simple? simple
|
128
|
+
def junction?
|
129
|
+
!simple?
|
114
130
|
end
|
115
131
|
|
116
|
-
def
|
117
|
-
|
118
|
-
@post_cgi ||= s.gsub '~plus~', self.class.joint
|
132
|
+
def left
|
133
|
+
@left ||= simple? ? nil : parts[0..-2] * self.class.joint
|
119
134
|
end
|
120
135
|
|
121
|
-
|
136
|
+
def right
|
137
|
+
@right ||= simple? ? nil : parts[-1]
|
138
|
+
end
|
122
139
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
def
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
#
|
133
|
-
|
134
|
-
def trunk
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
def
|
139
|
-
|
140
|
-
def part_names() @part_names ||= parts.map &:to_name end
|
141
|
-
def piece_names() @piece_names ||= pieces.map &:to_name end
|
142
|
-
|
143
|
-
def pieces
|
144
|
-
@pieces ||= if simple?
|
145
|
-
[ self ]
|
146
|
-
else
|
147
|
-
junction_pieces = []
|
148
|
-
parts[1..-1].inject parts[0] do |left, right|
|
149
|
-
piece = [left, right] * self.class.joint
|
150
|
-
junction_pieces << piece
|
151
|
-
piece
|
152
|
-
end
|
153
|
-
parts + junction_pieces
|
154
|
-
end
|
140
|
+
def left_name
|
141
|
+
@left_name ||= left && self.class.new(left)
|
142
|
+
end
|
143
|
+
|
144
|
+
def right_name
|
145
|
+
@right_name ||= right && self.class.new(right)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Note that all names have a trunk and tag,
|
149
|
+
# but only junctions have left and right
|
150
|
+
|
151
|
+
def trunk
|
152
|
+
@trunk ||= simple? ? s : left
|
153
|
+
end
|
154
|
+
|
155
|
+
def tag
|
156
|
+
@tag ||= simple? ? s : right
|
155
157
|
end
|
156
158
|
|
159
|
+
def trunk_name
|
160
|
+
@trunk_name ||= simple? ? self : left_name
|
161
|
+
end
|
162
|
+
|
163
|
+
def tag_name
|
164
|
+
@tag_name ||= simple? ? self : right_name
|
165
|
+
end
|
157
166
|
|
167
|
+
def part_names
|
168
|
+
@part_names ||= parts.map(&:to_name)
|
169
|
+
end
|
158
170
|
|
159
|
-
|
171
|
+
def piece_names
|
172
|
+
@piece_names ||= pieces.map(&:to_name)
|
173
|
+
end
|
174
|
+
|
175
|
+
def pieces
|
176
|
+
@pieces ||=
|
177
|
+
if simple?
|
178
|
+
[self]
|
179
|
+
else
|
180
|
+
junction_pieces = []
|
181
|
+
parts[1..-1].inject parts[0] do |left, right|
|
182
|
+
piece = [left, right] * self.class.joint
|
183
|
+
junction_pieces << piece
|
184
|
+
piece
|
185
|
+
end
|
186
|
+
parts + junction_pieces
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# ~~~~~~~~~~~~~~~~~~~~ SHOW / ABSOLUTE ~~~~~~~~~~~~~~~~~~~~
|
160
191
|
|
161
192
|
def to_show *ignore
|
162
|
-
ignore.map!
|
193
|
+
ignore.map!(&:to_name)
|
163
194
|
|
164
195
|
show_parts = parts.map do |part|
|
165
|
-
reject = (
|
196
|
+
reject = (part.empty? || (part =~ /^_/) || ignore.member?(part.to_name))
|
166
197
|
reject ? nil : part
|
167
198
|
end
|
168
199
|
|
169
200
|
show_name = show_parts.compact.to_name.s
|
170
|
-
|
201
|
+
|
171
202
|
case
|
172
|
-
when show_parts.compact.empty
|
173
|
-
when show_parts[0].nil?
|
203
|
+
when show_parts.compact.empty? then self
|
204
|
+
when show_parts[0].nil? then self.class.joint + show_name
|
174
205
|
else show_name
|
175
206
|
end
|
176
207
|
end
|
177
208
|
|
178
|
-
|
179
209
|
def to_absolute context, args={}
|
180
210
|
context = context.to_name
|
181
211
|
parts.map do |part|
|
182
|
-
new_part =
|
183
|
-
|
184
|
-
when /^
|
185
|
-
|
186
|
-
|
187
|
-
when /^
|
212
|
+
new_part =
|
213
|
+
case part
|
214
|
+
when /^_user$/i
|
215
|
+
name_proc = self.class.session
|
216
|
+
name_proc ? name_proc.call : part
|
217
|
+
when /^_main$/i then self.class.params[:main_name]
|
218
|
+
when /^(_self|_whole|_)$/i then context.s
|
219
|
+
when /^_left$/i then context.trunk
|
220
|
+
# note - inconsistent use of left v. trunk
|
221
|
+
when /^_right$/i then context.tag
|
188
222
|
when /^_(\d+)$/i
|
189
223
|
pos = $~[1].to_i
|
190
224
|
pos = context.length if pos > context.length
|
191
|
-
context.parts[pos-1]
|
225
|
+
context.parts[pos - 1]
|
192
226
|
when /^_(L*)(R?)$/i
|
193
227
|
l_s, r_s = $~[1].size, !$~[2].empty?
|
194
228
|
l_part = context.nth_left l_s
|
195
229
|
r_s ? l_part.tag : l_part.s
|
196
|
-
when /^_/
|
197
|
-
|
198
|
-
|
230
|
+
# when /^_/
|
231
|
+
# custom = args[:params] ? args[:params][part] : nil
|
232
|
+
# custom ? CGI.escapeHTML(custom) : part
|
233
|
+
# why are we escaping HTML here?
|
199
234
|
else
|
200
235
|
part
|
201
236
|
end.to_s.strip
|
@@ -209,11 +244,10 @@ class SmartName < Object
|
|
209
244
|
|
210
245
|
def nth_left n
|
211
246
|
# 1 = left; 2= left of left; 3 = left of left of left....
|
212
|
-
(
|
247
|
+
(n >= length ? parts[0] : parts[0..-n - 1]).to_name
|
213
248
|
end
|
214
249
|
|
215
|
-
|
216
|
-
#~~~~~~~~~~~~~~~~~~~~ MISC ~~~~~~~~~~~~~~~~~~~~
|
250
|
+
# ~~~~~~~~~~~~~~~~~~~~ MISC ~~~~~~~~~~~~~~~~~~~~
|
217
251
|
|
218
252
|
def replace_part oldpart, newpart
|
219
253
|
oldpart = oldpart.to_name
|
@@ -230,10 +264,10 @@ class SmartName < Object
|
|
230
264
|
self
|
231
265
|
else
|
232
266
|
if oldpart == parts[0, oldpart.length]
|
233
|
-
if
|
267
|
+
if length == oldpart.length
|
234
268
|
newpart
|
235
269
|
else
|
236
|
-
(
|
270
|
+
(newpart.parts + parts[oldpart.length..-1]).to_name
|
237
271
|
end
|
238
272
|
else
|
239
273
|
self
|
@@ -245,11 +279,10 @@ class SmartName < Object
|
|
245
279
|
# shouldn't it use inclusions???
|
246
280
|
def self.substitute! str, hash
|
247
281
|
hash.keys.each do |var|
|
248
|
-
str.gsub! var_re do |x|
|
282
|
+
str.gsub! var_re do |x|
|
249
283
|
hash[var.to_sym]
|
250
284
|
end
|
251
285
|
end
|
252
286
|
str
|
253
287
|
end
|
254
|
-
|
255
288
|
end
|
data/spec/inflection_helper.rb
CHANGED
@@ -4,9 +4,9 @@
|
|
4
4
|
ActiveSupport::Inflector.inflections do |inflect|
|
5
5
|
inflect.irregular 'grave', 'graveyard'
|
6
6
|
inflect.uncountable 'this'
|
7
|
-
# inflect.uncountable 'plus'
|
7
|
+
# inflect.uncountable 'plus'
|
8
8
|
inflect.uncountable 'anonymous'
|
9
|
-
inflect.uncountable
|
9
|
+
inflect.uncountable 's'
|
10
10
|
inflect.singular(/(ss)$/i, '\1')
|
11
11
|
inflect.plural(/(ss)$/i, '\1')
|
12
12
|
end
|
data/spec/lib/smart_name_spec.rb
CHANGED
@@ -2,231 +2,232 @@
|
|
2
2
|
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
3
3
|
require 'core_ext'
|
4
4
|
|
5
|
-
|
6
5
|
describe SmartName do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
"this Name".to_name.key.should == "this_name"
|
6
|
+
describe '#key' do
|
7
|
+
it 'should remove spaces' do
|
8
|
+
'this Name'.to_name.key.should == 'this_name'
|
11
9
|
end
|
12
10
|
|
13
|
-
it
|
14
|
-
|
11
|
+
it 'should have initial _ for initial cap' do
|
12
|
+
'This Name'.to_name.key.should == 'this_name'
|
15
13
|
end
|
16
14
|
|
17
|
-
it
|
18
|
-
|
15
|
+
it 'should have initial _ for initial cap' do
|
16
|
+
'_This Name'.to_name.key.should == 'this_name'
|
19
17
|
end
|
20
18
|
|
21
|
-
it
|
22
|
-
|
19
|
+
it 'should singularize' do
|
20
|
+
'ethans'.to_name.key.should == 'ethan'
|
23
21
|
end
|
24
22
|
|
25
|
-
it
|
26
|
-
|
23
|
+
it 'should underscore' do
|
24
|
+
'ThisThing'.to_name.key.should == 'this_thing'
|
27
25
|
end
|
28
26
|
|
29
|
-
it
|
30
|
-
|
27
|
+
it 'should handle plus cards' do
|
28
|
+
'ThisThing+Ethans'.to_name.key.should == 'this_thing+ethan'
|
31
29
|
end
|
32
30
|
|
33
|
-
it
|
34
|
-
|
31
|
+
it 'should retain * for star cards' do
|
32
|
+
'*right'.to_name.key.should == '*right'
|
35
33
|
end
|
36
34
|
|
37
35
|
it "should not singularize double s's" do
|
38
|
-
|
36
|
+
'grass'.to_name.key.should == 'grass'
|
39
37
|
end
|
40
38
|
|
41
39
|
it "should not singularize letter 'S'" do
|
42
40
|
'S'.to_name.key.should == 's'
|
43
41
|
end
|
44
42
|
|
45
|
-
it
|
46
|
-
|
43
|
+
it 'should handle unicode characters' do
|
44
|
+
'Mañana'.to_name.key.should == 'mañana'
|
47
45
|
end
|
48
46
|
|
49
|
-
it
|
47
|
+
it 'should handle weird initial characters' do
|
50
48
|
'__you motha @#$'.to_name.key.should == 'you_motha'
|
51
49
|
'?!_you motha @#$'.to_name.key.should == 'you_motha'
|
52
50
|
end
|
53
51
|
|
54
|
-
it
|
55
|
-
|
52
|
+
it 'should allow numbers' do
|
53
|
+
'3way'.to_name.key.should == '3way'
|
56
54
|
end
|
57
55
|
|
58
|
-
it
|
59
|
-
|
56
|
+
it 'internal plurals' do
|
57
|
+
'cards hooks label foos'.to_name.key.should == 'card_hook_label_foo'
|
60
58
|
end
|
61
59
|
|
62
|
-
it
|
60
|
+
it 'should handle html entities' do
|
63
61
|
# This no longer takes off the s, is singularize broken now?
|
64
|
-
|
62
|
+
'Jean-françois Noubel'.to_name.key.should == 'jean_françoi_noubel'
|
65
63
|
end
|
66
64
|
end
|
67
65
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
"A+B+C+D".to_name.parts.should == %w{ A B C D }
|
66
|
+
describe 'parts and pieces' do
|
67
|
+
it 'should produce simple strings for parts' do
|
68
|
+
'A+B+C+D'.to_name.parts.should == %w( A B C D )
|
72
69
|
end
|
73
70
|
|
74
|
-
it
|
75
|
-
|
71
|
+
it 'should produce simple name objects for part_names' do
|
72
|
+
'A+B+C+D'.to_name.part_names.should == %w( A B C D ).map(&:to_name)
|
76
73
|
end
|
77
|
-
|
78
|
-
it
|
79
|
-
|
74
|
+
|
75
|
+
it 'should produce compound strings for pieces' do
|
76
|
+
'A+B+C+D'.to_name.pieces.should == %w( A B C D A+B A+B+C A+B+C+D )
|
80
77
|
end
|
81
|
-
|
82
|
-
it
|
83
|
-
|
78
|
+
|
79
|
+
it 'should produce compound name objects for piece_names' do
|
80
|
+
'A+B+C+D'.to_name.piece_names.should ==
|
81
|
+
%w( A B C D A+B A+B+C A+B+C+D ).map(&:to_name)
|
84
82
|
end
|
85
83
|
end
|
86
|
-
|
87
|
-
|
88
84
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
85
|
+
describe '#url_key' do
|
86
|
+
cardnames = [
|
87
|
+
'GrassCommons.org',
|
88
|
+
'Oh you @##',
|
89
|
+
"Alice's Restaurant!",
|
90
|
+
'PB & J',
|
91
|
+
'Mañana'
|
92
|
+
].map(&:to_name)
|
93
93
|
|
94
94
|
cardnames.each do |cardname|
|
95
|
-
it
|
96
|
-
|
97
|
-
#warn "cn tok #{cardname.inspect}, #{k.inspect}, #{k2.inspect}"
|
98
|
-
k.should == k2.to_name.key
|
95
|
+
it 'should have the same key as the name' do
|
96
|
+
cardname.key.should == cardname.url_key.to_name.key
|
99
97
|
end
|
100
98
|
end
|
99
|
+
|
100
|
+
it 'should handle compound names cleanly' do
|
101
|
+
'What?+the!+heck$'.to_name.url_key.should == 'What+the+heck'
|
102
|
+
end
|
101
103
|
end
|
102
104
|
|
103
|
-
describe
|
104
|
-
it
|
105
|
-
|
106
|
-
|
105
|
+
describe '#valid' do
|
106
|
+
it 'accepts valid names' do
|
107
|
+
'this+THAT'.to_name.should be_valid
|
108
|
+
'THE*ONE*AND$!ONLY'.to_name.should be_valid
|
107
109
|
end
|
108
110
|
|
109
|
-
it
|
110
|
-
|
111
|
-
|
111
|
+
it 'rejects invalide names' do
|
112
|
+
'Tes~sd'.to_name.should_not be_valid
|
113
|
+
'TEST/DDER'.to_name.should_not be_valid
|
112
114
|
end
|
113
115
|
end
|
114
116
|
|
115
|
-
describe
|
116
|
-
it
|
117
|
-
|
117
|
+
describe '#left_name' do
|
118
|
+
it 'returns nil for non junction' do
|
119
|
+
'a'.to_name.left_name.should == nil
|
118
120
|
end
|
119
121
|
|
120
|
-
it
|
121
|
-
|
122
|
+
it 'returns parent for parent' do
|
123
|
+
'a+b+c+d'.to_name.left_name.should == 'a+b+c'
|
122
124
|
end
|
123
125
|
end
|
124
126
|
|
125
|
-
describe
|
126
|
-
it
|
127
|
-
|
127
|
+
describe '#tag_name' do
|
128
|
+
it 'returns last part of plus card' do
|
129
|
+
'a+b+c'.to_name.tag.should == 'c'
|
128
130
|
end
|
129
131
|
|
130
|
-
it
|
131
|
-
|
132
|
+
it 'returns name of simple card' do
|
133
|
+
'a'.to_name.tag.should == 'a'
|
132
134
|
end
|
133
135
|
end
|
134
136
|
|
135
|
-
describe
|
136
|
-
it
|
137
|
-
|
137
|
+
describe '#safe_key' do
|
138
|
+
it 'subs pluses & stars' do
|
139
|
+
'Alpha?+*be-ta'.to_name.safe_key.should == 'alpha-Xbe_tum'
|
138
140
|
end
|
139
141
|
end
|
140
142
|
|
141
|
-
describe
|
142
|
-
it
|
143
|
-
'a+b'.to_name.replace_part('a','x').to_s.should == 'x+b'
|
143
|
+
describe '#replace_part' do
|
144
|
+
it 'replaces first name part' do
|
145
|
+
'a+b'.to_name.replace_part('a', 'x').to_s.should == 'x+b'
|
144
146
|
end
|
145
|
-
it
|
146
|
-
'a+b'.to_name.replace_part('b','x').to_s.should == 'a+x'
|
147
|
+
it 'replaces second name part' do
|
148
|
+
'a+b'.to_name.replace_part('b', 'x').to_s.should == 'a+x'
|
147
149
|
end
|
148
|
-
it
|
149
|
-
'a+b+c' .to_name.replace_part('a+b', 'x'
|
150
|
+
it 'replaces two name parts' do
|
151
|
+
'a+b+c' .to_name.replace_part('a+b', 'x').to_s.should == 'x+c'
|
150
152
|
'a+b+c+d'.to_name.replace_part('a+b', 'e+f').to_s.should == 'e+f+c+d'
|
151
153
|
end
|
152
154
|
it "doesn't replace two part tag" do
|
153
|
-
'a+b+c'.to_name.replace_part('b+c','x').to_s.should == 'a+b+c'
|
155
|
+
'a+b+c'.to_name.replace_part('b+c', 'x').to_s.should == 'a+b+c'
|
154
156
|
end
|
155
157
|
end
|
156
158
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
"_".to_name.to_absolute("foo").should == "foo"
|
159
|
+
describe '#to_absolute' do
|
160
|
+
it 'handles _self, _whole, _' do
|
161
|
+
'_self'.to_name.to_absolute('foo').should == 'foo'
|
162
|
+
'_whole'.to_name.to_absolute('foo').should == 'foo'
|
163
|
+
'_'.to_name.to_absolute('foo').should == 'foo'
|
163
164
|
end
|
164
165
|
|
165
|
-
it
|
166
|
-
|
166
|
+
it 'handles _left' do
|
167
|
+
'_left+Z'.to_name.to_absolute('A+B+C').should == 'A+B+Z'
|
167
168
|
end
|
168
169
|
|
169
|
-
it
|
170
|
-
|
170
|
+
it 'handles white space' do
|
171
|
+
'_left + Z'.to_name.to_absolute('A+B+C').should == 'A+B+Z'
|
171
172
|
end
|
172
173
|
|
173
|
-
it
|
174
|
-
|
175
|
-
|
174
|
+
it 'handles _right' do
|
175
|
+
'_right+bang'.to_name.to_absolute('nutter+butter').should == 'butter+bang'
|
176
|
+
'C+_right'.to_name.to_absolute('B+A').should == 'C+A'
|
176
177
|
end
|
177
178
|
|
178
|
-
it
|
179
|
-
|
179
|
+
it 'handles leading +' do
|
180
|
+
'+bug'.to_name.to_absolute('hum').should == 'hum+bug'
|
180
181
|
end
|
181
182
|
|
182
|
-
it
|
183
|
-
|
183
|
+
it 'handles trailing +' do
|
184
|
+
'bug+'.to_name.to_absolute('tracks').should == 'bug+tracks'
|
184
185
|
end
|
185
186
|
|
186
|
-
it
|
187
|
-
|
188
|
-
|
189
|
-
|
187
|
+
it 'handles _(numbers)' do
|
188
|
+
'_1'.to_name.to_absolute('A+B+C').should == 'A'
|
189
|
+
'_1+_2'.to_name.to_absolute('A+B+C').should == 'A+B'
|
190
|
+
'_2+_3'.to_name.to_absolute('A+B+C').should == 'B+C'
|
190
191
|
end
|
191
192
|
|
192
|
-
it
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
193
|
+
it 'handles _LLR etc' do
|
194
|
+
'_R'.to_name.to_absolute('A+B+C+D+E').should == 'E'
|
195
|
+
'_L'.to_name.to_absolute('A+B+C+D+E').should == 'A+B+C+D'
|
196
|
+
'_LR'.to_name.to_absolute('A+B+C+D+E').should == 'D'
|
197
|
+
'_LL'.to_name.to_absolute('A+B+C+D+E').should == 'A+B+C'
|
198
|
+
'_LLR'.to_name.to_absolute('A+B+C+D+E').should == 'C'
|
199
|
+
'_LLL'.to_name.to_absolute('A+B+C+D+E').should == 'A+B'
|
200
|
+
'_LLLR'.to_name.to_absolute('A+B+C+D+E').should == 'B'
|
201
|
+
'_LLLL'.to_name.to_absolute('A+B+C+D+E').should == 'A'
|
201
202
|
end
|
202
203
|
|
203
|
-
context
|
204
|
-
it
|
205
|
-
|
206
|
-
|
204
|
+
context 'mismatched requests' do
|
205
|
+
it 'returns _self for _left or _right on simple cards' do
|
206
|
+
'_left+Z'.to_name.to_absolute('A').should == 'A+Z'
|
207
|
+
'_right+Z'.to_name.to_absolute('A').should == 'A+Z'
|
207
208
|
end
|
208
209
|
|
209
|
-
it
|
210
|
-
|
211
|
-
|
212
|
-
|
210
|
+
it 'handles bogus numbers' do
|
211
|
+
'_1'.to_name.to_absolute('A').should == 'A'
|
212
|
+
'_1+_2'.to_name.to_absolute('A').should == 'A+A'
|
213
|
+
'_2+_3'.to_name.to_absolute('A').should == 'A+A'
|
213
214
|
end
|
214
215
|
|
215
|
-
it
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
216
|
+
it 'handles bogus _llr requests' do
|
217
|
+
'_R'.to_name.to_absolute('A').should == 'A'
|
218
|
+
'_L'.to_name.to_absolute('A').should == 'A'
|
219
|
+
'_LR'.to_name.to_absolute('A').should == 'A'
|
220
|
+
'_LL'.to_name.to_absolute('A').should == 'A'
|
221
|
+
'_LLR'.to_name.to_absolute('A').should == 'A'
|
222
|
+
'_LLL'.to_name.to_absolute('A').should == 'A'
|
223
|
+
'_LLLR'.to_name.to_absolute('A').should == 'A'
|
224
|
+
'_LLLL'.to_name.to_absolute('A').should == 'A'
|
224
225
|
end
|
225
226
|
end
|
226
227
|
end
|
227
228
|
|
228
|
-
describe
|
229
|
-
it
|
229
|
+
describe '#to_show' do
|
230
|
+
it 'ignores ignorables' do
|
230
231
|
'you+awe'.to_name.to_show('you').should == '+awe'
|
231
232
|
'me+you+awe'.to_name.to_show('you').should == 'me+awe' #HMMM..... what should this do?
|
232
233
|
'me+you+awe'.to_name.to_show('me' ).should == '+you+awe'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smartname
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerry Gleason
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-05-
|
12
|
+
date: 2016-05-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|