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 CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.3
@@ -1,193 +1,301 @@
1
1
  # -*- encoding : utf-8 -*-
2
- class NameLogic < String
3
2
 
4
- # do: Object.send :include, NameLogic::ObjectMethods to enable x.to_name
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
- def method_missing meth, *args
17
- if self.class.respond_to? meth
18
- self.class.send meth, *args
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
- @name2nameobject = {}
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
- @joint = JOINT
36
- @formal_joint = " <span class=\"wiki-joint\">#{JOINT}</span> "
37
- @banned_array = BANNED_ARRAY
38
- @banned_re = /#{ ([?[] + @banned_array << @joint )*?\\ }#{ ?] }/
39
- @var_match = VAR_MATCH
40
- @uninflect = SINGULAR
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*joint : obj.to_s
46
- return obj if obj = name2nameobject[str]
47
- super str.strip
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 user() '' end # override to fetch your user string for _user subs
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
- attr_reader :simple, :parts, :key
54
- alias to_key key
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
- super str
58
- #warn "init #{str.inspect}, #{inspect}, #{self.class.joint}, #{joint}"
59
- @key = if index joint
60
- @parts = str.split(/\s*#{Regexp.escape(joint)}\s*/)
61
- @parts << '' if str[-1] == joint
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? ? '' : generate_simple_key
101
+ str.empty? ? '' : simple_key
68
102
  end
69
- name2nameobject[str] = self
103
+ @@name2nameobject[str] = self
70
104
  end
71
-
72
- def generate_simple_key
73
- decode_html.underscore.gsub(/[^#{WORD_RE}\*]+/,'_').split(/_+/).reject(&:empty?).map(&uninflect)*?_
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 decode_html
77
- @decoded ||= (index(?&) ? HTMLEntities.new.decode(to_s) : to_s)
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
- def self.substitute!( str, hash )
87
- str.gsub!(var_match) { |x| (v=hash[var.to_sym]).nil? ? x : v }
88
- str
89
- end
127
+ #~~~~~~~~~~~~~~~~~~~ VARIANTS ~~~~~~~~~~~~~~~~~~~
90
128
 
91
- def ==(obj)
92
- obj.nil? ? false :
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 size() parts.size end
98
- def to_name() self end
99
- def valid?() not parts.find {|pt| pt.match(banned_re)} end
133
+ def url_key
134
+ @url_key ||= decoded.gsub(/[^\*#{WORD_RE}\s\+]/,' ').strip.gsub(/[\s\_]+/,'_')
135
+ end
100
136
 
101
- def replace_part( oldpart, newpart )
102
- oldpart = oldpart.to_name unless NameLogic===oldpart
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
- def tag_name() simple? ? self : parts[-1] end
118
- def left_name() simple? ? nil : self.class.new(parts[0..-2]) end
119
- def trunk_name() simple? ? self : self.class.new(parts[0..-2]) end
120
- def junction?() not simple? end
121
- alias particle_names parts
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
- def module_name() gsub(/^\*/,'X_').gsub(/[\b\s]+/,'_').camelcase end
124
- def css_name() @css_name ||= key.gsub('*','X').gsub('+','-') end
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
- def to_star() star? ? self : ?*+self end
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
- alias blank? empty?
158
+ alias simple? simple
159
+ def junction?() not simple? end
136
160
 
137
- def pre_cgi() parts * '~plus~' end
138
- def escape() gsub(' ','_') end
161
+ def left() @left ||= simple? ? nil : parts[0..-2]*@@joint end
162
+ def right() @right ||= simple? ? nil : parts[-1] end
139
163
 
140
- def to_url_key()
141
- @url_key ||= decode_html.gsub(/[^\*#{WORD_RE}\s\+]/,' ').
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
- def piece_names()
146
- simple? ? [self] : ([self] + trunk_name.piece_names + [tag_name]).uniq
147
- end
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
- def to_show(context)
150
- # FIXME this is not quite right. distinction is that is leaves blank parts blank.
151
- (self =~/\b_(left|right|whole|self|user|main|\d+|L*R?)\b/) ?
152
- to_absolute(context) : self
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 escapeHTML(args)
156
- args ? parts.map { |p| p =~ /^_/ and args[p] ? args[p] : p }*joint : self
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 to_absolute_name(rel_name=nil)
160
- (rel_name || self).to_name.to_absolute(self)
204
+ def trait tag_code
205
+ trait_name( tag_code ).s
161
206
  end
162
207
 
163
- def nth_left(n)
164
- (n >= size ? parts[0] : parts[0..-n-1]).to_name
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
- def to_absolute(context, params=nil)
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
- #when /^_user$/i; user || part
172
- when /^_main$/i; Wagn::Conf[:main_name]
173
- when /^(_self|_whole|_)$/i; context
174
- when /^_left$/i; context.trunk_name
175
- when /^_right$/i; context.tag_name
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.size if pos > context.size
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, $~[2].empty?
182
- trunk = context.nth_left(l_s)
183
- r= r_s ? trunk.to_s : trunk.tag_name
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
- (params && ppart = params[part]) ? CGI.escapeHTML( ppart ) : part
186
- else part
187
- end.strip
188
- new_part.empty? ? context : new_part
189
- end * joint
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
- end
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
@@ -3,55 +3,168 @@ require File.expand_path('../spec_helper', File.dirname(__FILE__))
3
3
 
4
4
  describe NameLogic do
5
5
 
6
- describe "#to_key" do
6
+ describe "#key" do
7
7
  it "should remove spaces" do
8
- "This Name".to_name.to_key.should == "this_name"
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.to_key.should == "ethan"
20
+ "ethans".to_name.key.should == "ethan"
13
21
  end
14
22
 
15
23
  it "should underscore" do
16
- "ThisThing".to_name.to_key.should == "this_thing"
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.to_key.should == "this_thing+ethan"
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.to_key.should == "*right"
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.to_key.should == 'grass'
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.to_key.should == 's'
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.to_key.should == 'mañana'
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.to_key.should == 'you_motha'
41
- '?!_you motha @#$'.to_name.to_key.should == 'you_motha'
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.to_key.should == '3way'
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.to_key.should == 'card_hook_label_foo'
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&ccedil;ois Noubel".to_name.to_key.should == 'jean_françoi_noubel'
62
+ "Jean-fran&ccedil;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 &amp; 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 non-junctions" do
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
- describe "#to_url_key" do
131
- cardnames = ["GrassCommons.org", 'Oh you @##', "Alice's Restaurant!", "PB &amp; J", "Mañana"].map(&:to_name)
132
-
133
- cardnames.each do |cardname|
134
- it "should have the same key as the name" do
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
@@ -1,15 +1,25 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/../lib/name_logic")
2
- require 'active_support/inflector'
3
-
4
- # Add new inflection rules using the following format
5
- ActiveSupport::Inflector.inflections do |inflect|
6
- inflect.irregular 'grave', 'graveyard'
7
- inflect.uncountable 'this'
8
- # inflect.uncountable 'plus'
9
- inflect.uncountable 'anonymous'
10
- inflect.uncountable /^s$/
11
- inflect.singular(/(ss)$/i, '\1')
12
- inflect.plural(/(ss)$/i, '\1')
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.1
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-03-24 00:00:00.000000000 Z
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: &9304420 !ruby/object:Gem::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: *9304420
24
+ version_requirements: *9300760
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: active_support
27
- requirement: &9303140 !ruby/object:Gem::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: *9303140
35
+ version_requirements: *9300220
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &9318660 !ruby/object:Gem::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: *9318660
46
+ version_requirements: *9299660
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rdoc
49
- requirement: &9317780 !ruby/object:Gem::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: *9317780
57
+ version_requirements: *9298960
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: bundler
60
- requirement: &9317080 !ruby/object:Gem::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: *9317080
68
+ version_requirements: *9314540
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: jeweler
71
- requirement: &9314980 !ruby/object:Gem::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: *9314980
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: 4038131039544687550
117
+ hash: 2225341963327626641
117
118
  required_rubygems_version: !ruby/object:Gem::Requirement
118
119
  none: false
119
120
  requirements: