smartname 0.1.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/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Add dependencies to develop your gem here.
4
+ # Include everything needed to run rake, tests, features, etc.
5
+ group :development do
6
+ gem "rspec", "~> 2.8.0"
7
+ gem "rdoc", "~> 3.12"
8
+ gem "bundler", "~> 1.1.0"
9
+ gem "jeweler", "~> 1.8.3"
10
+ #gem "rcov", ">= 0"
11
+ end
12
+
13
+ gem "activesupport"
14
+ gem 'htmlentities', '~>4.3.0'
data/Gemfile.lock ADDED
@@ -0,0 +1,39 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.2.8)
5
+ i18n (~> 0.6)
6
+ multi_json (~> 1.0)
7
+ diff-lcs (1.1.3)
8
+ git (1.2.5)
9
+ htmlentities (4.3.1)
10
+ i18n (0.6.1)
11
+ jeweler (1.8.3)
12
+ bundler (~> 1.0)
13
+ git (>= 1.2.5)
14
+ rake
15
+ rdoc
16
+ json (1.7.5)
17
+ multi_json (1.3.6)
18
+ rake (0.9.2.2)
19
+ rdoc (3.12)
20
+ json (~> 1.4)
21
+ rspec (2.8.0)
22
+ rspec-core (~> 2.8.0)
23
+ rspec-expectations (~> 2.8.0)
24
+ rspec-mocks (~> 2.8.0)
25
+ rspec-core (2.8.0)
26
+ rspec-expectations (2.8.0)
27
+ diff-lcs (~> 1.1.2)
28
+ rspec-mocks (2.8.0)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ activesupport
35
+ bundler (~> 1.1.0)
36
+ htmlentities (~> 4.3.0)
37
+ jeweler (~> 1.8.3)
38
+ rdoc (~> 3.12)
39
+ rspec (~> 2.8.0)
data/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+
2
+ == SmartName
3
+
4
+ Wiki Segmented Name Logic
5
+
6
+ == Abstract
7
+
data/Rakefile ADDED
@@ -0,0 +1,66 @@
1
+
2
+ # encoding: utf-8
3
+
4
+ require 'rubygems'
5
+ require 'bundler'
6
+
7
+ VERSION = File.exist?('VERSION') ? File.read('VERSION') : ""
8
+
9
+ begin
10
+ Bundler.setup(:default, :development)
11
+ rescue Bundler::BundlerError => e
12
+ $stderr.puts e.message
13
+ $stderr.puts "Run `bundle install` to install missing gems"
14
+ exit e.status_code
15
+ end
16
+
17
+ require 'rake'
18
+
19
+ begin
20
+ require 'jeweler'
21
+ Jeweler::Tasks.new do |gem|
22
+ gem.name = 'smartname'
23
+ gem.version = VERSION
24
+ gem.license = "GPL-2"
25
+ gem.summary = "Wagn names without all the wagn"
26
+ gem.email = "gerryg@inbox.com"
27
+ gem.homepage = "https://github.com/wagn/smartname"
28
+ gem.description = "Wagn names without all the wagn"
29
+ gem.authors = ["Gerry Gleason <gerryg@inbox.com>", "Ethan McCutchen <ethan@wagn.org>"]
30
+ gem.files = FileList[
31
+ '[A-Z]*',
32
+ '*.rb',
33
+ 'lib/**/*.rb',
34
+ 'spec/**/*.rb' ].to_a
35
+ gem.test_files = Dir.glob('spec/*_spec.rb')
36
+ gem.has_rdoc = true
37
+ gem.extra_rdoc_files = [ "README.rdoc", "CHANGES" ]
38
+ gem.rdoc_options = ["--main", "README.rdoc", "--inline-source", "--line-numbers"]
39
+ end
40
+ rescue LoadError
41
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
42
+ end
43
+
44
+ Jeweler::RubygemsDotOrgTasks.new
45
+
46
+ require 'rspec/core'
47
+ require 'rspec/core/rake_task'
48
+ RSpec::Core::RakeTask.new(:spec) do |spec|
49
+ spec.pattern = FileList['spec/**/*_spec.rb']
50
+ end
51
+
52
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
53
+ spec.pattern = 'spec/**/*_spec.rb'
54
+ spec.rcov = true
55
+ end
56
+
57
+ task :default => :spec
58
+
59
+ require 'rdoc/task'
60
+ Rake::RDocTask.new do |rdoc|
61
+
62
+ rdoc.rdoc_dir = 'rdoc'
63
+ rdoc.title = "smartname #{VERSION}"
64
+ rdoc.rdoc_files.include('README*')
65
+ rdoc.rdoc_files.include('lib/**/*.rb')
66
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/smart_name.rb ADDED
@@ -0,0 +1,274 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ require 'active_support/configurable'
4
+ require 'active_support/inflector'
5
+
6
+ class Object
7
+ def to_name() SmartName.new(self) end
8
+ end
9
+
10
+ class SmartName < Object
11
+ require 'htmlentities'
12
+ RUBY19 = RUBY_VERSION =~ /^1\.9/
13
+ WORD_RE = RUBY19 ? '\p{Word}' : '\w'
14
+
15
+ include ActiveSupport::Configurable
16
+
17
+ config_accessor :joint, :formal_joint, :name_attribute, :banned_array,
18
+ :var_re, :uninflect, :params, :codes, :lookup
19
+
20
+ # Wagny defaults:
21
+ JOINT = '+'
22
+ SmartName.joint = JOINT
23
+ SmartName.formal_joint = " <span class=\"wiki-joint\">#{JOINT}</span> "
24
+ SmartName.banned_array = [ '/', '~', '|' ]
25
+ SmartName.name_attribute = :cardname
26
+ SmartName.var_re = /\{([^\}]*})\}/
27
+ SmartName.uninflect = :singularize
28
+
29
+ @@name2nameobject = {}
30
+
31
+ class << self
32
+ def new obj
33
+ return obj if SmartName===obj
34
+ str = Array===obj ? obj*SmartName.joint : obj.to_s
35
+ if known_name = @@name2nameobject[str]
36
+ known_name
37
+ else
38
+ super str.strip
39
+ end
40
+ end
41
+
42
+ def unescape uri
43
+ # can't instantiate because key doesn't resolve correctly in unescaped form
44
+ # issue is peculiar to plus sign (+), which are interpreted as a space.
45
+ # if we could make that not happen, we could avoid this (and handle spaces in urls)
46
+ uri.gsub(' ','+').gsub '_',' '
47
+ end
48
+
49
+ def banned_re
50
+ %r{#{ (['['] + SmartName.banned_array << SmartName.joint )*'\\' + ']' }}
51
+ end
52
+ end
53
+
54
+
55
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56
+ #~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
57
+
58
+ attr_reader :simple, :parts, :key, :s
59
+ alias to_s s
60
+
61
+ def initialize str
62
+ @s = str.to_s.strip
63
+ @s = @s.encode('UTF-8') if RUBY19
64
+ @key = if @s.index(SmartName.joint)
65
+ @parts = @s.split(/\s*#{Regexp.escape(SmartName.joint)}\s*/)
66
+ @parts << '' if @s[-1] == SmartName.joint
67
+ @simple = false
68
+ @parts.map { |p| p.to_name.key } * SmartName.joint
69
+ else
70
+ @parts = [str]
71
+ @simple = true
72
+ str.empty? ? '' : simple_key
73
+ end
74
+ @@name2nameobject[str] = self
75
+ end
76
+
77
+ def valid?()
78
+ not parts.find { |pt| pt.match SmartName.banned_re }
79
+ end
80
+ def to_name() self end
81
+ def length() parts.length end
82
+ def size() to_s.size end
83
+ def blank?() s.blank? end
84
+ alias empty? blank?
85
+
86
+ def inspect
87
+ "<SmartName key=#{key}[#{self}]>"
88
+ end
89
+
90
+ def == obj
91
+ object_key = case
92
+ when obj.respond_to?(:key) ; obj.key
93
+ when obj.respond_to?(:to_name) ; obj.to_name.key
94
+ else ; obj.to_s
95
+ end
96
+ object_key == key
97
+ end
98
+
99
+
100
+ #~~~~~~~~~~~~~~~~~~~ VARIANTS ~~~~~~~~~~~~~~~~~~~
101
+
102
+ def simple_key
103
+ decoded.underscore.gsub(/[^#{WORD_RE}\*]+/,'_').split(/_+/).reject(&:empty?).map(&(SmartName.uninflect))*'_'
104
+ end
105
+
106
+ def url_key
107
+ @url_key ||= decoded.gsub(/[^\*#{WORD_RE}\s\+]/,' ').strip.gsub(/[\s\_]+/,'_')
108
+ end
109
+
110
+ def safe_key
111
+ @safe_key ||= key.gsub('*','X').gsub SmartName.joint, '-'
112
+ end
113
+
114
+ def decoded
115
+ @decoded ||= (s.index('&') ? HTMLEntities.new.decode(s) : s)
116
+ end
117
+
118
+ def pre_cgi
119
+ #why is this necessary?? doesn't real CGI escaping handle this??
120
+ # hmmm. is this to prevent absolutizing
121
+ @pre_cgi ||= parts.join '~plus~'
122
+ end
123
+
124
+ def post_cgi
125
+ #hmm. this could resolve to the key of some other card. move to class method?
126
+ @post_cgi ||= s.gsub '~plus~', SmartName.joint
127
+ end
128
+
129
+ #~~~~~~~~~~~~~~~~~~~ PARTS ~~~~~~~~~~~~~~~~~~~
130
+
131
+ alias simple? simple
132
+ def junction?() not simple? end
133
+
134
+ def left() @left ||= simple? ? nil : parts[0..-2]*SmartName.joint end
135
+ def right() @right ||= simple? ? nil : parts[-1] end
136
+
137
+ def left_name() @left_name ||= left && SmartName.new( left ) end
138
+ def right_name() @right_name ||= right && SmartName.new( right ) end
139
+
140
+ # Note that all names have a trunk and tag, but only junctions have left and right
141
+
142
+ def trunk() @trunk ||= simple? ? s : left end
143
+ def tag() @tag ||= simple? ? s : right end
144
+
145
+ def trunk_name() @trunk_name ||= simple? ? self : left_name end
146
+ def tag_name() @tag_name ||= simple? ? self : right_name end
147
+
148
+ def pieces
149
+ @pieces ||= if simple?
150
+ [ self ]
151
+ else
152
+ trunk_name.pieces + [ tag_name ]
153
+ end
154
+ end
155
+
156
+
157
+ #~~~~~~~~~~~~~~~~~~~ TRAITS / STARS ~~~~~~~~~~~~~~~~~~~
158
+
159
+ def star?() simple? and '*' == s[0] end
160
+ def rstar?() right and '*' == right[0] end
161
+
162
+ def trait_name? *traitlist
163
+ junction? && begin
164
+ right_key = right_name.key
165
+ !!traitlist.find do |codename|
166
+ codecard = SmartName.codes[ codename ] and codecard = SmartName.lookup[ codecard ] and
167
+ codecard.send(SmartName.name_attribute).key == right_key
168
+ end
169
+ end
170
+ end
171
+
172
+ def trait_name tag_code
173
+ codecard = SmartName.codes[ tag_code ] and codecard = SmartName.lookup[ codecard ] and
174
+ [ self, codecard.send(SmartName.name_attribute) ].to_name
175
+ end
176
+
177
+ def trait tag_code
178
+ trait_name( tag_code ).s
179
+ end
180
+
181
+
182
+
183
+ #~~~~~~~~~~~~~~~~~~~~ SHOW / ABSOLUTE ~~~~~~~~~~~~~~~~~~~~
184
+
185
+ def to_show context, args={}
186
+ # ignore = [ args[:ignore], context.to_name.parts ].flatten.compact.map &:to_name
187
+ ignore = [ args[:ignore] ].flatten.map &:to_name
188
+ fullname = parts.to_name.to_absolute_name context, args
189
+
190
+ show_parts = fullname.parts.map do |part|
191
+ reject = ( part.empty? or part =~ /^_/ or ignore.member? part.to_name )
192
+ reject ? nil : part
193
+ end
194
+
195
+ initial_blank = show_parts[0].nil?
196
+ show_name = show_parts.compact.to_name.s
197
+
198
+ initial_blank ? SmartName.joint + show_name : show_name
199
+ end
200
+
201
+
202
+ def to_absolute context, args={}
203
+ context = context.to_name
204
+ parts.map do |part|
205
+ new_part = case part
206
+ when /^_user$/i; (user=Session.user_card) ? user.name : part
207
+ when /^_main$/i; SmartName.params[:main_name]
208
+ when /^(_self|_whole|_)$/i; context.s
209
+ when /^_left$/i; context.trunk #note - inconsistent use of left v. trunk
210
+ when /^_right$/i; context.tag
211
+ when /^_(\d+)$/i
212
+ pos = $~[1].to_i
213
+ pos = context.length if pos > context.length
214
+ context.parts[pos-1]
215
+ when /^_(L*)(R?)$/i
216
+ l_s, r_s = $~[1].size, !$~[2].empty?
217
+ l_part = context.nth_left l_s
218
+ r_s ? l_part.tag : l_part.s
219
+ when /^_/
220
+ custom = args[:params] ? args[:params][part] : nil
221
+ custom ? CGI.escapeHTML(custom) : part #why are we escaping HTML here?
222
+ else
223
+ part
224
+ end.to_s.strip
225
+ new_part.empty? ? context.to_s : new_part
226
+ end * SmartName.joint
227
+ end
228
+
229
+ def to_absolute_name *args
230
+ SmartName.new to_absolute(*args)
231
+ end
232
+
233
+ def nth_left n
234
+ # 1 = left; 2= left of left; 3 = left of left of left....
235
+ ( n >= length ? parts[0] : parts[0..-n-1] ).to_name
236
+ end
237
+
238
+
239
+ #~~~~~~~~~~~~~~~~~~~~ MISC ~~~~~~~~~~~~~~~~~~~~
240
+
241
+ def replace_part oldpart, newpart
242
+ oldpart = oldpart.to_name
243
+ newpart = newpart.to_name
244
+ if oldpart.simple?
245
+ if simple?
246
+ self == oldpart ? newpart : self
247
+ else
248
+ parts.map do |p|
249
+ oldpart == p ? newpart.to_s : p
250
+ end.to_name
251
+ end
252
+ elsif simple?
253
+ self
254
+ else
255
+ if oldpart == parts[0, oldpart.length]
256
+ if self.length == oldpart.length
257
+ newpart
258
+ else
259
+ (newpart.parts+(parts[oldpart.length,].lines.to_a)).to_name
260
+ end
261
+ else
262
+ self
263
+ end
264
+ end
265
+ end
266
+
267
+ def self.substitute! str, hash
268
+ hash.keys.each do |var|
269
+ str.gsub!(SmartName.var_re) { |x| (v=hash[var.to_sym]).nil? ? x : v }
270
+ end
271
+ str
272
+ end
273
+
274
+ 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
@@ -0,0 +1,251 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
3
+
4
+ describe SmartName do
5
+
6
+ describe "#key" do
7
+ it "should remove spaces" do
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"
17
+ end
18
+
19
+ it "should singularize" do
20
+ "ethans".to_name.key.should == "ethan"
21
+ end
22
+
23
+ it "should underscore" do
24
+ "ThisThing".to_name.key.should == "this_thing"
25
+ end
26
+
27
+ it "should handle plus cards" do
28
+ "ThisThing+Ethans".to_name.key.should == "this_thing+ethan"
29
+ end
30
+
31
+ it "should retain * for star cards" do
32
+ "*right".to_name.key.should == "*right"
33
+ end
34
+
35
+ it "should not singularize double s's" do
36
+ "grass".to_name.key.should == 'grass'
37
+ end
38
+
39
+ it "should not singularize letter 'S'" do
40
+ 'S'.to_name.key.should == 's'
41
+ end
42
+
43
+ it "should handle unicode characters" do
44
+ "Mañana".to_name.key.should == 'mañana'
45
+ end
46
+
47
+ it "should handle weird initial characters" do
48
+ '__you motha @#$'.to_name.key.should == 'you_motha'
49
+ '?!_you motha @#$'.to_name.key.should == 'you_motha'
50
+ end
51
+
52
+ it "should allow numbers" do
53
+ "3way".to_name.key.should == '3way'
54
+ end
55
+
56
+ it "internal plurals" do
57
+ "cards hooks label foos".to_name.key.should == 'card_hook_label_foo'
58
+ end
59
+
60
+ it "should handle html entities" do
61
+ # This no longer takes off the s, is singularize broken now?
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
168
+ end
169
+ end
170
+
171
+ describe "#to_absolute" do
172
+ it "handles _self, _whole, _" do
173
+ "_self".to_name.to_absolute("foo").should == "foo"
174
+ "_whole".to_name.to_absolute("foo").should == "foo"
175
+ "_".to_name.to_absolute("foo").should == "foo"
176
+ end
177
+
178
+ it "handles _left" do
179
+ "_left+Z".to_name.to_absolute("A+B+C").should == "A+B+Z"
180
+ end
181
+
182
+ it "handles white space" do
183
+ "_left + Z".to_name.to_absolute("A+B+C").should == "A+B+Z"
184
+ end
185
+
186
+ it "handles _right" do
187
+ "_right+bang".to_name.to_absolute("nutter+butter").should == "butter+bang"
188
+ "C+_right".to_name.to_absolute("B+A").should == "C+A"
189
+ end
190
+
191
+ it "handles leading +" do
192
+ "+bug".to_name.to_absolute("hum").should == "hum+bug"
193
+ end
194
+
195
+ it "handles trailing +" do
196
+ "bug+".to_name.to_absolute("tracks").should == "bug+tracks"
197
+ end
198
+
199
+ it "handles _(numbers)" do
200
+ "_1".to_name.to_absolute("A+B+C").should == "A"
201
+ "_1+_2".to_name.to_absolute("A+B+C").should == "A+B"
202
+ "_2+_3".to_name.to_absolute("A+B+C").should == "B+C"
203
+ end
204
+
205
+ it "handles _LLR etc" do
206
+ "_R".to_name.to_absolute("A+B+C+D+E").should == "E"
207
+ "_L".to_name.to_absolute("A+B+C+D+E").should == "A+B+C+D"
208
+ "_LR".to_name.to_absolute("A+B+C+D+E").should == "D"
209
+ "_LL".to_name.to_absolute("A+B+C+D+E").should == "A+B+C"
210
+ "_LLR".to_name.to_absolute("A+B+C+D+E").should == "C"
211
+ "_LLL".to_name.to_absolute("A+B+C+D+E").should == "A+B"
212
+ "_LLLR".to_name.to_absolute("A+B+C+D+E").should == "B"
213
+ "_LLLL".to_name.to_absolute("A+B+C+D+E").should == "A"
214
+ end
215
+
216
+ context "mismatched requests" do
217
+ it "returns _self for _left or _right on simple cards" do
218
+ "_left+Z".to_name.to_absolute("A").should == "A+Z"
219
+ "_right+Z".to_name.to_absolute("A").should == "A+Z"
220
+ end
221
+
222
+ it "handles bogus numbers" do
223
+ "_1".to_name.to_absolute("A").should == "A"
224
+ "_1+_2".to_name.to_absolute("A").should == "A+A"
225
+ "_2+_3".to_name.to_absolute("A").should == "A+A"
226
+ end
227
+
228
+ it "handles bogus _llr requests" do
229
+ "_R".to_name.to_absolute("A").should == "A"
230
+ "_L".to_name.to_absolute("A").should == "A"
231
+ "_LR".to_name.to_absolute("A").should == "A"
232
+ "_LL".to_name.to_absolute("A").should == "A"
233
+ "_LLR".to_name.to_absolute("A").should == "A"
234
+ "_LLL".to_name.to_absolute("A").should == "A"
235
+ "_LLLR".to_name.to_absolute("A").should == "A"
236
+ "_LLLL".to_name.to_absolute("A").should == "A"
237
+ end
238
+ end
239
+ end
240
+
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'
248
+ end
249
+ end
250
+
251
+ end
@@ -0,0 +1,26 @@
1
+
2
+ require 'smart_name'
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
+ SmartName.name_attribute= :name
10
+ SmartName.codes= { :content => 1 }
11
+ SmartName.lookup= { 1 => CardMock.new('*content'), }
12
+
13
+ RSpec.configure do |config|
14
+
15
+ #config.include CustomMatchers
16
+ #config.include ControllerMacros, :type=>:controllers
17
+ #config.include AuthenticatedTestHelper, :type=>:controllers
18
+ #config.include(EmailSpec::Helpers)
19
+ #config.include(EmailSpec::Matchers)
20
+
21
+ # == Mock Framework
22
+ # If you prefer to mock with mocha, flexmock or RR, uncomment the appropriate symbol:
23
+ # :mocha, :flexmock, :rr
24
+
25
+ end
26
+
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smartname
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gerry Gleason <gerryg@inbox.com>
9
+ - Ethan McCutchen <ethan@wagn.org>
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-11-20 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: htmlentities
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 4.3.0
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 4.3.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.8.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 2.8.0
63
+ - !ruby/object:Gem::Dependency
64
+ name: rdoc
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: '3.12'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: '3.12'
79
+ - !ruby/object:Gem::Dependency
80
+ name: bundler
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ version: 1.1.0
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: 1.1.0
95
+ - !ruby/object:Gem::Dependency
96
+ name: jeweler
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: 1.8.3
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.8.3
111
+ description: Wagn names without all the wagn
112
+ email: gerryg@inbox.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files:
116
+ - README.rdoc
117
+ files:
118
+ - Gemfile
119
+ - Gemfile.lock
120
+ - README.rdoc
121
+ - Rakefile
122
+ - VERSION
123
+ - lib/smart_name.rb
124
+ - spec/inflection_helper.rb
125
+ - spec/lib/smart_name_spec.rb
126
+ - spec/spec_helper.rb
127
+ homepage: https://github.com/wagn/smartname
128
+ licenses:
129
+ - GPL-2
130
+ post_install_message:
131
+ rdoc_options:
132
+ - --main
133
+ - README.rdoc
134
+ - --inline-source
135
+ - --line-numbers
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ segments:
145
+ - 0
146
+ hash: 239023093442111674
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 1.8.24
156
+ signing_key:
157
+ specification_version: 3
158
+ summary: Wagn names without all the wagn
159
+ test_files: []