namelogic 0.0.1 → 0.0.3
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/VERSION +1 -1
- data/lib/name_logic.rb +236 -128
- data/spec/inflection_helper.rb +12 -0
- data/spec/lib/name_logic_spec.rb +136 -79
- data/spec/spec_helper.rb +23 -13
- metadata +16 -15
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
data/lib/name_logic.rb
CHANGED
@@ -1,193 +1,301 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
class NameLogic < String
|
3
2
|
|
4
|
-
|
5
|
-
module ObjectMethods
|
6
|
-
def to_name() NameLogic.new(self) end
|
7
|
-
end
|
8
|
-
|
9
|
-
require 'htmlentities'
|
10
|
-
|
11
|
-
class << self
|
12
|
-
attr_accessor :joint, :banned_array, :banned_re, :var_match,
|
13
|
-
:formal_joint, :uninflect, :name2nameobject
|
14
|
-
end
|
3
|
+
require 'active_support/inflector'
|
15
4
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
else raise end
|
20
|
-
end
|
5
|
+
class Object
|
6
|
+
def to_name() NameLogic.new(self) end
|
7
|
+
end
|
21
8
|
|
9
|
+
class NameLogic < Object
|
10
|
+
require 'htmlentities'
|
22
11
|
|
23
12
|
# Wagny defaults
|
24
|
-
JOINT =
|
25
|
-
BANNED_ARRAY = [
|
13
|
+
JOINT = '+'
|
14
|
+
BANNED_ARRAY = [ '/', '~', '|' ]
|
26
15
|
BANNED_CHARACTERS = BANNED_ARRAY * ' '
|
27
16
|
|
28
17
|
VAR_MATCH = /\{([^\}]*})\}/
|
29
|
-
WORD_RE = RUBY_VERSION =~ /^1\.9/ ? '\p{Word}/' : '/\w/'
|
30
18
|
SINGULAR = :singularize
|
31
19
|
|
32
|
-
|
20
|
+
RUBY19 = RUBY_VERSION =~ /^1\.9/
|
21
|
+
WORD_RE = RUBY19 ? '\p{Word}' : '\w'
|
33
22
|
|
34
23
|
# reset these class instance vars to your system's to customize name syntax
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
24
|
+
@@joint = JOINT
|
25
|
+
@@formal_joint = " <span class=\"wiki-joint\">#{JOINT}</span> "
|
26
|
+
@@banned_array = BANNED_ARRAY
|
27
|
+
@@banned_re = /#{ (['['] + @@banned_array << @@joint )*'\\' }#{ ']' }/
|
28
|
+
@@var_match = VAR_MATCH
|
29
|
+
@@uninflect = SINGULAR
|
30
|
+
@@name_attribute = :cardname
|
31
|
+
@@main_hash = {:main_name=>''}
|
32
|
+
@@code_hash = defined?(Card) ? Card : {}
|
33
|
+
|
34
|
+
@@name2nameobject = {}
|
41
35
|
|
42
36
|
class << self
|
43
37
|
def new obj
|
44
38
|
return obj if NameLogic===obj
|
45
|
-
str = Array===obj ? obj
|
46
|
-
|
47
|
-
|
39
|
+
str = Array===obj ? obj*@@joint : obj.to_s
|
40
|
+
if known_name = @@name2nameobject[str]
|
41
|
+
known_name
|
42
|
+
else
|
43
|
+
super str.strip
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def set_code_hash hash
|
48
|
+
@@code_hash = hash
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_main_hash hash
|
52
|
+
@@main_hash = hash
|
48
53
|
end
|
49
54
|
|
50
|
-
def
|
55
|
+
def unescape uri
|
56
|
+
# can't instantiate because key doesn't resolve correctly in unescaped form
|
57
|
+
# issue is peculiar to plus sign (+), which are interpreted as a space.
|
58
|
+
# if we could make that not happen, we could avoid this (and handle spaces in urls)
|
59
|
+
uri.gsub(' ','+').gsub '_',' '
|
60
|
+
end
|
61
|
+
|
62
|
+
# class var setters to change defaults, consider a config obect?
|
63
|
+
def joint() @@joint end
|
64
|
+
def joint @@joint=(v) = v end
|
65
|
+
def formal_joint() @@formal_joint end
|
66
|
+
def formal_joint=(v) @@formal_joint = v end
|
67
|
+
def banned_array() @@banned_array end
|
68
|
+
def banned_array=(v) @@banned_array = v end
|
69
|
+
def banned_re() @@banned_re end
|
70
|
+
def banned_re=(v) @@banned_re = v end
|
71
|
+
def var_match() @@var_match end
|
72
|
+
def var_match=(v) @@var_match = v end
|
73
|
+
def uninflect() @@uninflect end
|
74
|
+
def uninflect=(v) @@uninflect = v end
|
75
|
+
def name_attribute() @@name_attribute end
|
76
|
+
def name_attribute=(v) @@name_attribute = v end
|
77
|
+
def main_hash() @@main_hash end
|
78
|
+
def main_hash=(v) @@main_hash = v end
|
79
|
+
def code_hash() @@code_hash end
|
80
|
+
def code_hash=(v) @@code_hash = v end
|
51
81
|
end
|
52
82
|
|
53
|
-
|
54
|
-
|
83
|
+
|
84
|
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
85
|
+
#~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
|
86
|
+
|
87
|
+
attr_reader :simple, :parts, :key, :s
|
88
|
+
alias to_s s
|
55
89
|
|
56
90
|
def initialize str
|
57
|
-
|
58
|
-
|
59
|
-
@key = if index
|
60
|
-
@parts =
|
61
|
-
@parts << '' if
|
91
|
+
@s = str.to_s.strip
|
92
|
+
@s = @s.encode('UTF-8') if RUBY19
|
93
|
+
@key = if @s.index(@@joint)
|
94
|
+
@parts = @s.split(/\s*#{Regexp.escape(@@joint)}\s*/)
|
95
|
+
@parts << '' if @s[-1] == @@joint
|
62
96
|
@simple = false
|
63
|
-
@parts.map{|p| p.to_name.key } * joint
|
97
|
+
@parts.map { |p| p.to_name.key } * @@joint
|
64
98
|
else
|
65
99
|
@parts = [str]
|
66
100
|
@simple = true
|
67
|
-
empty? ? '' :
|
101
|
+
str.empty? ? '' : simple_key
|
68
102
|
end
|
69
|
-
name2nameobject[str] = self
|
103
|
+
@@name2nameobject[str] = self
|
70
104
|
end
|
71
|
-
|
72
|
-
def
|
73
|
-
|
105
|
+
|
106
|
+
def to_name() self end
|
107
|
+
def valid?() not parts.find { |pt| pt.match @@banned_re } end
|
108
|
+
def length() parts.length end
|
109
|
+
def size() to_s.size end
|
110
|
+
def blank?() s.blank? end
|
111
|
+
alias empty? blank?
|
112
|
+
|
113
|
+
def inspect
|
114
|
+
"<NameLogic key=#{key}[#{self}]>"
|
74
115
|
end
|
75
|
-
|
76
|
-
def
|
77
|
-
|
116
|
+
|
117
|
+
def == obj
|
118
|
+
object_key = case
|
119
|
+
when obj.respond_to?(:key) ; obj.key
|
120
|
+
when obj.respond_to?(:to_name) ; obj.to_name.key
|
121
|
+
else ; obj.to_s
|
122
|
+
end
|
123
|
+
object_key == key
|
78
124
|
end
|
79
|
-
|
80
|
-
alias simple? simple
|
81
|
-
|
82
|
-
def inspect() "<Name key=#{key}[#{self}, #{parts ? parts.size : 'no size'}]>" end
|
83
125
|
|
84
|
-
def self.unescape(uri) uri.gsub(' ','+').gsub('_',' ') end
|
85
126
|
|
86
|
-
|
87
|
-
str.gsub!(var_match) { |x| (v=hash[var.to_sym]).nil? ? x : v }
|
88
|
-
str
|
89
|
-
end
|
127
|
+
#~~~~~~~~~~~~~~~~~~~ VARIANTS ~~~~~~~~~~~~~~~~~~~
|
90
128
|
|
91
|
-
def
|
92
|
-
|
93
|
-
key == (obj.respond_to?(:to_key) ? obj.to_key :
|
94
|
-
obj.respond_to?(:to_name) ? obj.to_name.key : obj.to_s)
|
129
|
+
def simple_key
|
130
|
+
decoded.underscore.gsub(/[^#{WORD_RE}\*]+/,'_').split(/_+/).reject(&:empty?).map(&@@uninflect)*'_'
|
95
131
|
end
|
96
132
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
133
|
+
def url_key
|
134
|
+
@url_key ||= decoded.gsub(/[^\*#{WORD_RE}\s\+]/,' ').strip.gsub(/[\s\_]+/,'_')
|
135
|
+
end
|
100
136
|
|
101
|
-
def
|
102
|
-
|
103
|
-
newpart = newpart.to_name unless NameLogic===newpart
|
104
|
-
if oldpart.simple?
|
105
|
-
simple? ? (self == oldpart ? newpart : self) :
|
106
|
-
parts.map{ |p| oldpart == p ? newpart : p }.to_name
|
107
|
-
elsif simple?
|
108
|
-
self
|
109
|
-
else
|
110
|
-
oldpart == parts[0, oldpart.size] ?
|
111
|
-
((self.size == oldpart.size) ? newpart :
|
112
|
-
(newpart.parts+(parts[oldpart.size,].lines.to_a)).to_name) : self
|
113
|
-
end
|
137
|
+
def safe_key
|
138
|
+
@safe_key ||= key.gsub('*','X').gsub @@joint, '-'
|
114
139
|
end
|
115
140
|
|
141
|
+
def decoded
|
142
|
+
@decoded ||= (s.index('&') ? HTMLEntities.new.decode(s) : s)
|
143
|
+
end
|
116
144
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
145
|
+
def pre_cgi
|
146
|
+
#why is this necessary?? doesn't real CGI escaping handle this??
|
147
|
+
# hmmm. is this to prevent absolutizing
|
148
|
+
@pre_cgi ||= parts.join '~plus~'
|
149
|
+
end
|
122
150
|
|
123
|
-
|
124
|
-
|
151
|
+
def post_cgi
|
152
|
+
#hmm. this could resolve to the key of some other card. move to class method?
|
153
|
+
@post_cgi ||= s.gsub '~plus~', @@joint
|
154
|
+
end
|
125
155
|
|
126
|
-
|
127
|
-
def star?() simple? and self[0] == ?* end
|
128
|
-
def tag_star?() junction? and ?* == parts[-1][0] end
|
129
|
-
alias rstar? tag_star?
|
130
|
-
def star_rule(star)
|
131
|
-
star = star.to_s
|
132
|
-
[self, star.index(?*) ? star : ?*+star].to_name
|
133
|
-
end
|
156
|
+
#~~~~~~~~~~~~~~~~~~~ PARTS ~~~~~~~~~~~~~~~~~~~
|
134
157
|
|
135
|
-
|
158
|
+
alias simple? simple
|
159
|
+
def junction?() not simple? end
|
136
160
|
|
137
|
-
|
138
|
-
|
161
|
+
def left() @left ||= simple? ? nil : parts[0..-2]*@@joint end
|
162
|
+
def right() @right ||= simple? ? nil : parts[-1] end
|
139
163
|
|
140
|
-
|
141
|
-
@
|
142
|
-
strip.gsub(/[\s\_]+/,'_')
|
143
|
-
end
|
164
|
+
def left_name() @left_name ||= left && self.class.new( left ) end
|
165
|
+
def right_name() @right_name ||= right && self.class.new( right ) end
|
144
166
|
|
145
|
-
|
146
|
-
|
147
|
-
|
167
|
+
# Note that all names have a trunk and tag, but only junctions have left and right
|
168
|
+
|
169
|
+
def trunk() @trunk ||= simple? ? s : left end
|
170
|
+
def tag() @tag ||= simple? ? s : right end
|
148
171
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
172
|
+
def trunk_name() @trunk_name ||= simple? ? self : left_name end
|
173
|
+
def tag_name() @tag_name ||= simple? ? self : right_name end
|
174
|
+
|
175
|
+
def pieces
|
176
|
+
@pieces ||= if simple?
|
177
|
+
[ self ]
|
178
|
+
else
|
179
|
+
trunk_name.pieces + [ tag_name ]
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
#~~~~~~~~~~~~~~~~~~~ TRAITS / STARS ~~~~~~~~~~~~~~~~~~~
|
185
|
+
|
186
|
+
def star?() simple? and '*' == s[0] end
|
187
|
+
def rstar?() right and '*' == right[0] end
|
188
|
+
|
189
|
+
def trait_name? *traitlist
|
190
|
+
junction? && begin
|
191
|
+
right_key = right_name.key
|
192
|
+
!!traitlist.find do |codename|
|
193
|
+
#puts "tn? #{codename}, #{traitlist.inspect}, #{@@code_hash[codename]}\n"
|
194
|
+
codecard = @@code_hash[ codename ] and codecard.send(@@name_attribute).key == right_key
|
195
|
+
end
|
196
|
+
end
|
153
197
|
end
|
154
198
|
|
155
|
-
def
|
156
|
-
|
199
|
+
def trait_name tag_code
|
200
|
+
codecard = @@code_hash[ tag_code ] and
|
201
|
+
[ self, @@code_hash[ tag_code ].name ].to_name
|
157
202
|
end
|
158
203
|
|
159
|
-
def
|
160
|
-
(
|
204
|
+
def trait tag_code
|
205
|
+
trait_name( tag_code ).s
|
161
206
|
end
|
162
207
|
|
163
|
-
|
164
|
-
|
208
|
+
|
209
|
+
|
210
|
+
#~~~~~~~~~~~~~~~~~~~~ SHOW / ABSOLUTE ~~~~~~~~~~~~~~~~~~~~
|
211
|
+
|
212
|
+
def to_show context, args={}
|
213
|
+
# ignore = [ args[:ignore], context.to_name.parts ].flatten.compact.map &:to_name
|
214
|
+
ignore = [ args[:ignore] ].flatten.map &:to_name
|
215
|
+
fullname = parts.to_name.to_absolute_name context, args
|
216
|
+
|
217
|
+
show_parts = fullname.parts.map do |part|
|
218
|
+
reject = ( part.empty? or part =~ /^_/ or ignore.member? part.to_name )
|
219
|
+
reject ? nil : part
|
220
|
+
end
|
221
|
+
|
222
|
+
initial_blank = show_parts[0].nil?
|
223
|
+
show_name = show_parts.compact.to_name.s
|
224
|
+
|
225
|
+
initial_blank ? @@joint + show_name : show_name
|
165
226
|
end
|
166
227
|
|
167
|
-
|
228
|
+
|
229
|
+
def to_absolute context, args={}
|
168
230
|
context = context.to_name
|
169
231
|
parts.map do |part|
|
170
232
|
new_part = case part
|
171
|
-
|
172
|
-
when /^_main$/i;
|
173
|
-
when /^(_self|_whole|_)$/i; context
|
174
|
-
when /^_left$/i; context.
|
175
|
-
when /^_right$/i; context.
|
176
|
-
when /^_(\d+)$/i
|
233
|
+
when /^_user$/i; (user=Session.user_card) ? user.name : part
|
234
|
+
when /^_main$/i; main_hash[:main_name]
|
235
|
+
when /^(_self|_whole|_)$/i; context.s
|
236
|
+
when /^_left$/i; context.trunk #note - inconsistent use of left v. trunk
|
237
|
+
when /^_right$/i; context.tag
|
238
|
+
when /^_(\d+)$/i
|
177
239
|
pos = $~[1].to_i
|
178
|
-
pos = context.
|
240
|
+
pos = context.length if pos > context.length
|
179
241
|
context.parts[pos-1]
|
180
242
|
when /^_(L*)(R?)$/i
|
181
|
-
l_s, r_s = $~[1].size,
|
182
|
-
|
183
|
-
|
243
|
+
l_s, r_s = $~[1].size, !$~[2].empty?
|
244
|
+
l_part = context.nth_left l_s
|
245
|
+
r_s ? l_part.tag : l_part.s
|
184
246
|
when /^_/
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
247
|
+
custom = args[:params] ? args[:params][part] : nil
|
248
|
+
custom ? CGI.escapeHTML(custom) : part #why are we escaping HTML here?
|
249
|
+
else
|
250
|
+
part
|
251
|
+
end.to_s.strip
|
252
|
+
new_part.empty? ? context.to_s : new_part
|
253
|
+
end * @@joint
|
190
254
|
end
|
191
255
|
|
192
|
-
|
256
|
+
def to_absolute_name *args
|
257
|
+
self.class.new to_absolute(*args)
|
258
|
+
end
|
259
|
+
|
260
|
+
def nth_left n
|
261
|
+
# 1 = left; 2= left of left; 3 = left of left of left....
|
262
|
+
( n >= length ? parts[0] : parts[0..-n-1] ).to_name
|
263
|
+
end
|
264
|
+
|
265
|
+
|
266
|
+
#~~~~~~~~~~~~~~~~~~~~ MISC ~~~~~~~~~~~~~~~~~~~~
|
193
267
|
|
268
|
+
def replace_part oldpart, newpart
|
269
|
+
oldpart = oldpart.to_name
|
270
|
+
newpart = newpart.to_name
|
271
|
+
if oldpart.simple?
|
272
|
+
if simple?
|
273
|
+
self == oldpart ? newpart : self
|
274
|
+
else
|
275
|
+
parts.map do |p|
|
276
|
+
oldpart == p ? newpart.to_s : p
|
277
|
+
end.to_name
|
278
|
+
end
|
279
|
+
elsif simple?
|
280
|
+
self
|
281
|
+
else
|
282
|
+
if oldpart == parts[0, oldpart.length]
|
283
|
+
if self.length == oldpart.length
|
284
|
+
newpart
|
285
|
+
else
|
286
|
+
(newpart.parts+(parts[oldpart.length,].lines.to_a)).to_name
|
287
|
+
end
|
288
|
+
else
|
289
|
+
self
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def self.substitute! str, hash
|
295
|
+
hash.keys.each do |var|
|
296
|
+
str.gsub!(@@var_match) { |x| (v=hash[var.to_sym]).nil? ? x : v }
|
297
|
+
end
|
298
|
+
str
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Add new inflection rules using the following format
|
4
|
+
ActiveSupport::Inflector.inflections do |inflect|
|
5
|
+
inflect.irregular 'grave', 'graveyard'
|
6
|
+
inflect.uncountable 'this'
|
7
|
+
# inflect.uncountable 'plus'
|
8
|
+
inflect.uncountable 'anonymous'
|
9
|
+
inflect.uncountable /^s$/
|
10
|
+
inflect.singular(/(ss)$/i, '\1')
|
11
|
+
inflect.plural(/(ss)$/i, '\1')
|
12
|
+
end
|
data/spec/lib/name_logic_spec.rb
CHANGED
@@ -3,55 +3,168 @@ require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
|
3
3
|
|
4
4
|
describe NameLogic do
|
5
5
|
|
6
|
-
describe "#
|
6
|
+
describe "#key" do
|
7
7
|
it "should remove spaces" do
|
8
|
-
"
|
8
|
+
"this Name".to_name.key.should == "this_name"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should have initial _ for initial cap" do
|
12
|
+
"This Name".to_name.key.should == "this_name"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have initial _ for initial cap" do
|
16
|
+
"_This Name".to_name.key.should == "this_name"
|
9
17
|
end
|
10
18
|
|
11
19
|
it "should singularize" do
|
12
|
-
"ethans".to_name.
|
20
|
+
"ethans".to_name.key.should == "ethan"
|
13
21
|
end
|
14
22
|
|
15
23
|
it "should underscore" do
|
16
|
-
"ThisThing".to_name.
|
24
|
+
"ThisThing".to_name.key.should == "this_thing"
|
17
25
|
end
|
18
26
|
|
19
27
|
it "should handle plus cards" do
|
20
|
-
"ThisThing+Ethans".to_name.
|
28
|
+
"ThisThing+Ethans".to_name.key.should == "this_thing+ethan"
|
21
29
|
end
|
22
30
|
|
23
31
|
it "should retain * for star cards" do
|
24
|
-
"*right".to_name.
|
32
|
+
"*right".to_name.key.should == "*right"
|
25
33
|
end
|
26
34
|
|
27
35
|
it "should not singularize double s's" do
|
28
|
-
"grass".to_name.
|
36
|
+
"grass".to_name.key.should == 'grass'
|
29
37
|
end
|
30
38
|
|
31
39
|
it "should not singularize letter 'S'" do
|
32
|
-
'S'.to_name.
|
40
|
+
'S'.to_name.key.should == 's'
|
33
41
|
end
|
34
42
|
|
35
43
|
it "should handle unicode characters" do
|
36
|
-
"Mañana".to_name.
|
44
|
+
"Mañana".to_name.key.should == 'mañana'
|
37
45
|
end
|
38
46
|
|
39
47
|
it "should handle weird initial characters" do
|
40
|
-
'__you motha @#$'.to_name.
|
41
|
-
'?!_you motha @#$'.to_name.
|
48
|
+
'__you motha @#$'.to_name.key.should == 'you_motha'
|
49
|
+
'?!_you motha @#$'.to_name.key.should == 'you_motha'
|
42
50
|
end
|
43
51
|
|
44
52
|
it "should allow numbers" do
|
45
|
-
"3way".to_name.
|
53
|
+
"3way".to_name.key.should == '3way'
|
46
54
|
end
|
47
55
|
|
48
56
|
it "internal plurals" do
|
49
|
-
"cards hooks label foos".to_name.
|
57
|
+
"cards hooks label foos".to_name.key.should == 'card_hook_label_foo'
|
50
58
|
end
|
51
59
|
|
52
60
|
it "should handle html entities" do
|
53
61
|
# This no longer takes off the s, is singularize broken now?
|
54
|
-
"Jean-françois Noubel".to_name.
|
62
|
+
"Jean-françois Noubel".to_name.key.should == 'jean_françoi_noubel'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
describe "#url_key" do
|
71
|
+
cardnames = ["GrassCommons.org", 'Oh you @##', "Alice's Restaurant!", "PB & J", "Mañana"].map(&:to_name)
|
72
|
+
|
73
|
+
cardnames.each do |cardname|
|
74
|
+
it "should have the same key as the name" do
|
75
|
+
k, k2 = cardname.key, cardname.url_key
|
76
|
+
#warn "cn tok #{cardname.inspect}, #{k.inspect}, #{k2.inspect}"
|
77
|
+
k.should == k2.to_name.key
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#valid" do
|
83
|
+
it "accepts valid names" do
|
84
|
+
"this+THAT".to_name.should be_valid
|
85
|
+
"THE*ONE*AND$!ONLY".to_name.should be_valid
|
86
|
+
end
|
87
|
+
|
88
|
+
it "rejects invalide names" do
|
89
|
+
"Tes~sd".to_name.should_not be_valid
|
90
|
+
"TEST/DDER".to_name.should_not be_valid
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "#left_name" do
|
95
|
+
it "returns nil for non junction" do
|
96
|
+
"a".to_name.left_name.should == nil
|
97
|
+
end
|
98
|
+
|
99
|
+
it "returns parent for parent" do
|
100
|
+
"a+b+c+d".to_name.left_name.should == "a+b+c"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#tag_name" do
|
105
|
+
it "returns last part of plus card" do
|
106
|
+
"a+b+c".to_name.tag.should == "c"
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns name of simple card" do
|
110
|
+
"a".to_name.tag.should == "a"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#safe_key" do
|
115
|
+
it "subs pluses & stars" do
|
116
|
+
"Alpha?+*be-ta".to_name.safe_key.should == "alpha-Xbe_tum"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#replace_part" do
|
121
|
+
it "replaces first name part" do
|
122
|
+
'a+b'.to_name.replace_part('a','x').to_s.should == 'x+b'
|
123
|
+
end
|
124
|
+
it "replaces second name part" do
|
125
|
+
'a+b'.to_name.replace_part('b','x').to_s.should == 'a+x'
|
126
|
+
end
|
127
|
+
it "replaces two name parts" do
|
128
|
+
'a+b+c'.to_name.replace_part('a+b','x').to_s.should == 'x+c'
|
129
|
+
end
|
130
|
+
it "doesn't replace two part tag" do
|
131
|
+
'a+b+c'.to_name.replace_part('b+c','x').to_s.should == 'a+b+c'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "Cardnames star handling" do
|
136
|
+
it "recognizes star cards" do
|
137
|
+
'*a'.to_name.star?.should be_true
|
138
|
+
end
|
139
|
+
|
140
|
+
it "doesn't recognize star cards with plusses" do
|
141
|
+
'*a+*b'.to_name.star?.should be_false
|
142
|
+
end
|
143
|
+
|
144
|
+
it "recognizes rstar cards" do
|
145
|
+
'a+*a'.to_name.rstar?.should be_true
|
146
|
+
end
|
147
|
+
|
148
|
+
it "doesn't recognize star cards as rstar" do
|
149
|
+
'*a'.to_name.rstar?.should be_false
|
150
|
+
end
|
151
|
+
|
152
|
+
it "doesn't recognize non-star or star left" do
|
153
|
+
'*a+a'.to_name.rstar?.should be_false
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "trait_name?" do
|
158
|
+
it "returns true for content codename" do
|
159
|
+
"bazoinga+*right+*content".to_name.trait_name?(:content).should be_true
|
160
|
+
end
|
161
|
+
|
162
|
+
it "handles arrays" do
|
163
|
+
"bazoinga+*right+*content".to_name.trait_name?(:content, :default).should be_true
|
164
|
+
end
|
165
|
+
|
166
|
+
it "returns false for non-template" do
|
167
|
+
"bazoinga+*right+nontent".to_name.trait_name?(:content).should be_false
|
55
168
|
end
|
56
169
|
end
|
57
170
|
|
@@ -101,7 +214,7 @@ describe NameLogic do
|
|
101
214
|
end
|
102
215
|
|
103
216
|
context "mismatched requests" do
|
104
|
-
it "returns _self for _left or _right on
|
217
|
+
it "returns _self for _left or _right on simple cards" do
|
105
218
|
"_left+Z".to_name.to_absolute("A").should == "A+Z"
|
106
219
|
"_right+Z".to_name.to_absolute("A").should == "A+Z"
|
107
220
|
end
|
@@ -125,70 +238,14 @@ describe NameLogic do
|
|
125
238
|
end
|
126
239
|
end
|
127
240
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
k, k2 = cardname.to_key, cardname.to_url_key
|
136
|
-
#warn "cn tok #{cardname.inspect}, #{k.inspect}, #{k2.inspect}"
|
137
|
-
k.should == k2.to_name.to_key
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
describe "#valid" do
|
143
|
-
it "accepts valid names" do
|
144
|
-
"this+THAT".to_name.should be_valid
|
145
|
-
"THE*ONE*AND$!ONLY".to_name.should be_valid
|
146
|
-
end
|
147
|
-
|
148
|
-
it "rejects invalide names" do
|
149
|
-
"Tes~sd".to_name.should_not be_valid
|
150
|
-
"TEST/DDER".to_name.should_not be_valid
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
describe "#left_name" do
|
155
|
-
it "returns nil for non junction" do
|
156
|
-
"a".to_name.left_name.should == nil
|
157
|
-
end
|
158
|
-
|
159
|
-
it "returns parent for parent" do
|
160
|
-
"a+b+c+d".to_name.left_name.should == "a+b+c"
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
describe "#tag_name" do
|
165
|
-
it "returns last part of plus card" do
|
166
|
-
"a+b+c".to_name.tag_name.should == "c"
|
167
|
-
end
|
168
|
-
|
169
|
-
it "returns name of simple card" do
|
170
|
-
"a".to_name.tag_name.should == "a"
|
241
|
+
describe "#to_show" do
|
242
|
+
it "ignores ignorables" do
|
243
|
+
'you+awe'.to_name.to_show('A', :ignore=>'you' ).should == '+awe'
|
244
|
+
'me+you+awe'.to_name.to_show('A', :ignore=>'you' ).should == 'me+awe' #HMMM..... what should this do?
|
245
|
+
'me+you+awe'.to_name.to_show('A', :ignore=>['me','you'] ).should == '+awe'
|
246
|
+
'_left+_right+awe'.to_name.to_show('A+B', :ignore=>'A' ).should == '+B+awe'
|
247
|
+
'?a?+awe'.to_name.to_show('B', :ignore=>'A' ).should == '+awe'
|
171
248
|
end
|
172
249
|
end
|
173
|
-
|
174
|
-
describe "#css_name" do
|
175
|
-
it "subs pluses & stars" do
|
176
|
-
"Alpha?+*be-ta".to_name.css_name.should == "alpha-Xbe_tum"
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
describe "#replace_part" do
|
181
|
-
it "replaces first name part" do
|
182
|
-
'a+b'.to_name.replace_part('a','x').to_s.should == 'x+b'
|
183
|
-
end
|
184
|
-
it "replaces second name part" do
|
185
|
-
'a+b'.to_name.replace_part('b','x').to_s.should == 'a+x'
|
186
|
-
end
|
187
|
-
it "replaces two name parts" do
|
188
|
-
'a+b+c'.to_name.replace_part('a+b','x').to_s.should == 'x+c'
|
189
|
-
end
|
190
|
-
it "doesn't replace two part tag" do
|
191
|
-
'a+b+c'.to_name.replace_part('b+c','x').to_s.should == 'a+b+c'
|
192
|
-
end
|
193
|
-
end
|
250
|
+
|
194
251
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,25 @@
|
|
1
|
-
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
|
2
|
+
require 'name_logic'
|
3
|
+
require File.expand_path('./inflection_helper', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
class CardMock < String
|
6
|
+
def name() to_name end
|
7
|
+
end
|
8
|
+
|
9
|
+
NameLogic.name_attribute= :name
|
10
|
+
NameLogic.code_hash= { :content => CardMock.new('*content'), }
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
|
14
|
+
#config.include CustomMatchers
|
15
|
+
#config.include ControllerMacros, :type=>:controllers
|
16
|
+
#config.include AuthenticatedTestHelper, :type=>:controllers
|
17
|
+
#config.include(EmailSpec::Helpers)
|
18
|
+
#config.include(EmailSpec::Matchers)
|
19
|
+
|
20
|
+
# == Mock Framework
|
21
|
+
# If you prefer to mock with mocha, flexmock or RR, uncomment the appropriate symbol:
|
22
|
+
# :mocha, :flexmock, :rr
|
23
|
+
|
13
24
|
end
|
14
25
|
|
15
|
-
Object.send :include, NameLogic::ObjectMethods
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: namelogic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: htmlentities
|
16
|
-
requirement: &
|
16
|
+
requirement: &9300760 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 4.3.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *9300760
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: active_support
|
27
|
-
requirement: &
|
27
|
+
requirement: &9300220 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *9300220
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &9299660 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 2.8.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *9299660
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rdoc
|
49
|
-
requirement: &
|
49
|
+
requirement: &9298960 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '3.12'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *9298960
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: bundler
|
60
|
-
requirement: &
|
60
|
+
requirement: &9314540 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.1.0
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *9314540
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: jeweler
|
71
|
-
requirement: &
|
71
|
+
requirement: &9313820 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: 1.8.3
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *9313820
|
80
80
|
description: Wiki Segmented Name Logic
|
81
81
|
email: gerryg@inbox.com
|
82
82
|
executables: []
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- Rakefile
|
91
91
|
- VERSION
|
92
92
|
- lib/name_logic.rb
|
93
|
+
- spec/inflection_helper.rb
|
93
94
|
- spec/lib/name_logic_spec.rb
|
94
95
|
- spec/spec_helper.rb
|
95
96
|
- test.rb
|
@@ -113,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
114
|
version: '0'
|
114
115
|
segments:
|
115
116
|
- 0
|
116
|
-
hash:
|
117
|
+
hash: 2225341963327626641
|
117
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
119
|
none: false
|
119
120
|
requirements:
|