motion_support 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,322 @@
1
+ # encoding: utf-8
2
+
3
+ module MotionSupport
4
+ # The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
5
+ # and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
6
+ # in inflections.rb.
7
+ #
8
+ # The Rails core team has stated patches for the inflections library will not be accepted
9
+ # in order to avoid breaking legacy applications which may be relying on errant inflections.
10
+ # If you discover an incorrect inflection and require it for your application, you'll need
11
+ # to correct it yourself (explained below).
12
+ module Inflector
13
+ extend self
14
+
15
+ # Returns the plural form of the word in the string.
16
+ #
17
+ # "post".pluralize # => "posts"
18
+ # "octopus".pluralize # => "octopi"
19
+ # "sheep".pluralize # => "sheep"
20
+ # "words".pluralize # => "words"
21
+ # "CamelOctopus".pluralize # => "CamelOctopi"
22
+ def pluralize(word)
23
+ apply_inflections(word, inflections.plurals)
24
+ end
25
+
26
+ # The reverse of +pluralize+, returns the singular form of a word in a string.
27
+ #
28
+ # "posts".singularize # => "post"
29
+ # "octopi".singularize # => "octopus"
30
+ # "sheep".singularize # => "sheep"
31
+ # "word".singularize # => "word"
32
+ # "CamelOctopi".singularize # => "CamelOctopus"
33
+ def singularize(word)
34
+ apply_inflections(word, inflections.singulars)
35
+ end
36
+
37
+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
38
+ # is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
39
+ #
40
+ # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
41
+ #
42
+ # "active_model".camelize # => "ActiveModel"
43
+ # "active_model".camelize(:lower) # => "activeModel"
44
+ # "active_model/errors".camelize # => "ActiveModel::Errors"
45
+ # "active_model/errors".camelize(:lower) # => "activeModel::Errors"
46
+ #
47
+ # As a rule of thumb you can think of +camelize+ as the inverse of +underscore+,
48
+ # though there are cases where that does not hold:
49
+ #
50
+ # "SSLError".underscore.camelize # => "SslError"
51
+ def camelize(term, uppercase_first_letter = true)
52
+ string = term.to_s
53
+ if uppercase_first_letter
54
+ string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
55
+ else
56
+ string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
57
+ end
58
+ string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::')
59
+ end
60
+
61
+ # Makes an underscored, lowercase form from the expression in the string.
62
+ #
63
+ # Changes '::' to '/' to convert namespaces to paths.
64
+ #
65
+ # "ActiveModel".underscore # => "active_model"
66
+ # "ActiveModel::Errors".underscore # => "active_model/errors"
67
+ #
68
+ # As a rule of thumb you can think of +underscore+ as the inverse of +camelize+,
69
+ # though there are cases where that does not hold:
70
+ #
71
+ # "SSLError".underscore.camelize # => "SslError"
72
+ def underscore(camel_cased_word)
73
+ word = camel_cased_word.to_s.dup
74
+ word.gsub!('::', '/')
75
+ word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
76
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
77
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
78
+ word.tr!("-", "_")
79
+ word.downcase!
80
+ word
81
+ end
82
+
83
+ # Capitalizes the first word and turns underscores into spaces and strips a
84
+ # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
85
+ #
86
+ # "employee_salary" # => "Employee salary"
87
+ # "author_id" # => "Author"
88
+ def humanize(lower_case_and_underscored_word)
89
+ result = lower_case_and_underscored_word.to_s.dup
90
+ inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
91
+ result.gsub!(/_id$/, "")
92
+ result.tr!('_', ' ')
93
+ result.gsub(/([a-z\d]*)/i) { |match|
94
+ "#{inflections.acronyms[match] || match.downcase}"
95
+ }.gsub(/^\w/) { $&.upcase }
96
+ end
97
+
98
+ # Capitalizes all the words and replaces some characters in the string to create
99
+ # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
100
+ # used in the Rails internals.
101
+ #
102
+ # +titleize+ is also aliased as +titlecase+.
103
+ #
104
+ # "man from the boondocks".titleize # => "Man From The Boondocks"
105
+ # "x-men: the last stand".titleize # => "X Men: The Last Stand"
106
+ # "TheManWithoutAPast".titleize # => "The Man Without A Past"
107
+ # "raiders_of_the_lost_ark".titleize # => "Raiders Of The Lost Ark"
108
+ def titleize(word)
109
+ humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { $&.capitalize }
110
+ end
111
+
112
+ # Create the name of a table like Rails does for models to table names. This method
113
+ # uses the +pluralize+ method on the last word in the string.
114
+ #
115
+ # "RawScaledScorer".tableize # => "raw_scaled_scorers"
116
+ # "egg_and_ham".tableize # => "egg_and_hams"
117
+ # "fancyCategory".tableize # => "fancy_categories"
118
+ def tableize(class_name)
119
+ pluralize(underscore(class_name))
120
+ end
121
+
122
+ # Create a class name from a plural table name like Rails does for table names to models.
123
+ # Note that this returns a string and not a Class. (To convert to an actual class
124
+ # follow +classify+ with +constantize+.)
125
+ #
126
+ # "egg_and_hams".classify # => "EggAndHam"
127
+ # "posts".classify # => "Post"
128
+ #
129
+ # Singular names are not handled correctly:
130
+ # "business".classify # => "Busines"
131
+ def classify(table_name)
132
+ # strip out any leading schema name
133
+ camelize(singularize(table_name.to_s.sub(/.*\./, '')))
134
+ end
135
+
136
+ # Replaces underscores with dashes in the string.
137
+ #
138
+ # "puni_puni".dasherize # => "puni-puni"
139
+ def dasherize(underscored_word)
140
+ underscored_word.tr('_', '-')
141
+ end
142
+
143
+ # Removes the module part from the expression in the string:
144
+ #
145
+ # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
146
+ # "Inflections".demodulize # => "Inflections"
147
+ #
148
+ # See also +deconstantize+.
149
+ def demodulize(path)
150
+ path = path.to_s
151
+ if i = path.rindex('::')
152
+ path[(i+2)..-1]
153
+ else
154
+ path
155
+ end
156
+ end
157
+
158
+ # Removes the rightmost segment from the constant expression in the string:
159
+ #
160
+ # "Net::HTTP".deconstantize # => "Net"
161
+ # "::Net::HTTP".deconstantize # => "::Net"
162
+ # "String".deconstantize # => ""
163
+ # "::String".deconstantize # => ""
164
+ # "".deconstantize # => ""
165
+ #
166
+ # See also +demodulize+.
167
+ def deconstantize(path)
168
+ path.to_s[0...(path.rindex('::') || 0)] # implementation based on the one in facets' Module#spacename
169
+ end
170
+
171
+ # Creates a foreign key name from a class name.
172
+ # +separate_class_name_and_id_with_underscore+ sets whether
173
+ # the method should put '_' between the name and 'id'.
174
+ #
175
+ # "Message".foreign_key # => "message_id"
176
+ # "Message".foreign_key(false) # => "messageid"
177
+ # "Admin::Post".foreign_key # => "post_id"
178
+ def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
179
+ underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
180
+ end
181
+
182
+ # Tries to find a constant with the name specified in the argument string:
183
+ #
184
+ # "Module".constantize # => Module
185
+ # "Test::Unit".constantize # => Test::Unit
186
+ #
187
+ # The name is assumed to be the one of a top-level constant, no matter whether
188
+ # it starts with "::" or not. No lexical context is taken into account:
189
+ #
190
+ # C = 'outside'
191
+ # module M
192
+ # C = 'inside'
193
+ # C # => 'inside'
194
+ # "C".constantize # => 'outside', same as ::C
195
+ # end
196
+ #
197
+ # NameError is raised when the name is not in CamelCase or the constant is
198
+ # unknown.
199
+ def constantize(camel_cased_word)
200
+ names = camel_cased_word.split('::')
201
+ names.shift if names.empty? || names.first.empty?
202
+
203
+ names.inject(Object) do |constant, name|
204
+ if constant == Object
205
+ constant.const_get(name)
206
+ else
207
+ candidate = constant.const_get(name)
208
+ next candidate if constant.const_defined?(name, false)
209
+ next candidate unless Object.const_defined?(name)
210
+
211
+ # Go down the ancestors to check it it's owned
212
+ # directly before we reach Object or the end of ancestors.
213
+ constant = constant.ancestors.inject do |const, ancestor|
214
+ break const if ancestor == Object
215
+ break ancestor if ancestor.const_defined?(name, false)
216
+ const
217
+ end
218
+
219
+ # owner is in Object, so raise
220
+ constant.const_get(name, false)
221
+ end
222
+ end
223
+ end
224
+
225
+ # Tries to find a constant with the name specified in the argument string:
226
+ #
227
+ # "Module".safe_constantize # => Module
228
+ # "Test::Unit".safe_constantize # => Test::Unit
229
+ #
230
+ # The name is assumed to be the one of a top-level constant, no matter whether
231
+ # it starts with "::" or not. No lexical context is taken into account:
232
+ #
233
+ # C = 'outside'
234
+ # module M
235
+ # C = 'inside'
236
+ # C # => 'inside'
237
+ # "C".safe_constantize # => 'outside', same as ::C
238
+ # end
239
+ #
240
+ # nil is returned when the name is not in CamelCase or the constant (or part of it) is
241
+ # unknown.
242
+ #
243
+ # "blargle".safe_constantize # => nil
244
+ # "UnknownModule".safe_constantize # => nil
245
+ # "UnknownModule::Foo::Bar".safe_constantize # => nil
246
+ #
247
+ def safe_constantize(camel_cased_word)
248
+ begin
249
+ constantize(camel_cased_word)
250
+ rescue NameError => e
251
+ raise unless e.message =~ /(uninitialized constant|wrong constant name) #{const_regexp(camel_cased_word)}$/ ||
252
+ e.name.to_s == camel_cased_word.to_s
253
+ rescue ArgumentError => e
254
+ raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
255
+ end
256
+ end
257
+
258
+ # Returns the suffix that should be added to a number to denote the position
259
+ # in an ordered sequence such as 1st, 2nd, 3rd, 4th.
260
+ #
261
+ # ordinal(1) # => "st"
262
+ # ordinal(2) # => "nd"
263
+ # ordinal(1002) # => "nd"
264
+ # ordinal(1003) # => "rd"
265
+ # ordinal(-11) # => "th"
266
+ # ordinal(-1021) # => "st"
267
+ def ordinal(number)
268
+ if (11..13).include?(number.to_i.abs % 100)
269
+ "th"
270
+ else
271
+ case number.to_i.abs % 10
272
+ when 1; "st"
273
+ when 2; "nd"
274
+ when 3; "rd"
275
+ else "th"
276
+ end
277
+ end
278
+ end
279
+
280
+ # Turns a number into an ordinal string used to denote the position in an
281
+ # ordered sequence such as 1st, 2nd, 3rd, 4th.
282
+ #
283
+ # ordinalize(1) # => "1st"
284
+ # ordinalize(2) # => "2nd"
285
+ # ordinalize(1002) # => "1002nd"
286
+ # ordinalize(1003) # => "1003rd"
287
+ # ordinalize(-11) # => "-11th"
288
+ # ordinalize(-1021) # => "-1021st"
289
+ def ordinalize(number)
290
+ "#{number}#{ordinal(number)}"
291
+ end
292
+
293
+ private
294
+
295
+ # Mount a regular expression that will match part by part of the constant.
296
+ # For instance, Foo::Bar::Baz will generate Foo(::Bar(::Baz)?)?
297
+ def const_regexp(camel_cased_word) #:nodoc:
298
+ parts = camel_cased_word.split("::")
299
+ last = parts.pop
300
+
301
+ parts.reverse.inject(last) do |acc, part|
302
+ part.empty? ? acc : "#{part}(::#{acc})?"
303
+ end
304
+ end
305
+
306
+ # Applies inflection rules for +singularize+ and +pluralize+.
307
+ #
308
+ # apply_inflections("post", inflections.plurals) # => "posts"
309
+ # apply_inflections("posts", inflections.singulars) # => "post"
310
+ def apply_inflections(word, rules)
311
+ result = word.to_s.dup
312
+
313
+ if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/])
314
+ result
315
+ else
316
+ rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
317
+ result
318
+ end
319
+ end
320
+ end
321
+ end
322
+
@@ -16,4 +16,5 @@ Gem::Specification.new do |gem|
16
16
  gem.version = MotionSupport::VERSION
17
17
 
18
18
  gem.add_dependency 'bubble-wrap'
19
+ gem.add_development_dependency 'motion-redgreen'
19
20
  end
@@ -0,0 +1,15 @@
1
+ describe "Array" do
2
+
3
+ describe "#append" do
4
+ it "should prepend elements on the array" do
5
+ [1].append(2).should.equal([1,2])
6
+ end
7
+ end
8
+
9
+ describe "#prepend" do
10
+ it "should prepend elements on the array" do
11
+ [1].prepend(2).should.equal([2,1])
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,76 @@
1
+ #module Ace
2
+ #module Base
3
+ #class Case
4
+ #class Dice
5
+ #end
6
+ #end
7
+ #class Fase < Case
8
+ #end
9
+ #end
10
+ #class Gas
11
+ #include Base
12
+ #end
13
+ #end
14
+
15
+ #class Object
16
+ #module AddtlGlobalConstants
17
+ #class Case
18
+ #class Dice
19
+ #end
20
+ #end
21
+ #end
22
+ #include AddtlGlobalConstants
23
+ #end
24
+
25
+ #module ConstantizeTestCases
26
+ #def run_constantize_tests_on
27
+ #assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") }
28
+ #assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") }
29
+ #assert_nothing_raised { assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") }
30
+ #assert_nothing_raised { assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") }
31
+ #assert_nothing_raised { assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") }
32
+ #assert_nothing_raised { assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice") }
33
+ #assert_nothing_raised { assert_equal Case::Dice, yield("Case::Dice") }
34
+ #assert_nothing_raised { assert_equal Case::Dice, yield("Object::Case::Dice") }
35
+ #assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") }
36
+ #assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") }
37
+ #assert_nothing_raised { assert_equal Object, yield("") }
38
+ #assert_nothing_raised { assert_equal Object, yield("::") }
39
+ #assert_raise(NameError) { yield("UnknownClass") }
40
+ #assert_raise(NameError) { yield("UnknownClass::Ace") }
41
+ #assert_raise(NameError) { yield("UnknownClass::Ace::Base") }
42
+ #assert_raise(NameError) { yield("An invalid string") }
43
+ #assert_raise(NameError) { yield("InvalidClass\n") }
44
+ #assert_raise(NameError) { yield("Ace::ConstantizeTestCases") }
45
+ #assert_raise(NameError) { yield("Ace::Base::ConstantizeTestCases") }
46
+ #assert_raise(NameError) { yield("Ace::Gas::Base") }
47
+ #assert_raise(NameError) { yield("Ace::Gas::ConstantizeTestCases") }
48
+ #end
49
+
50
+ #def run_safe_constantize_tests_on
51
+ #assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") }
52
+ #assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") }
53
+ #assert_nothing_raised { assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") }
54
+ #assert_nothing_raised { assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") }
55
+ #assert_nothing_raised { assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") }
56
+ #assert_nothing_raised { assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice") }
57
+ #assert_nothing_raised { assert_equal Case::Dice, yield("Case::Dice") }
58
+ #assert_nothing_raised { assert_equal Case::Dice, yield("Object::Case::Dice") }
59
+ #assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") }
60
+ #assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") }
61
+ #assert_nothing_raised { assert_equal Object, yield("") }
62
+ #assert_nothing_raised { assert_equal Object, yield("::") }
63
+ #assert_nothing_raised { assert_equal nil, yield("UnknownClass") }
64
+ #assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace") }
65
+ #assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace::Base") }
66
+ #assert_nothing_raised { assert_equal nil, yield("An invalid string") }
67
+ #assert_nothing_raised { assert_equal nil, yield("InvalidClass\n") }
68
+ #assert_nothing_raised { assert_equal nil, yield("blargle") }
69
+ #assert_nothing_raised { assert_equal nil, yield("Ace::ConstantizeTestCases") }
70
+ #assert_nothing_raised { assert_equal nil, yield("Ace::Base::ConstantizeTestCases") }
71
+ #assert_nothing_raised { assert_equal nil, yield("Ace::Gas::Base") }
72
+ #assert_nothing_raised { assert_equal nil, yield("Ace::Gas::ConstantizeTestCases") }
73
+ #assert_nothing_raised { assert_equal nil, yield("#<Class:0x7b8b718b>::Nested_1") }
74
+ #end
75
+ #end
76
+
@@ -0,0 +1,13 @@
1
+ ## Dups the singleton and yields, restoring the original inflections later.
2
+ ## Use this in tests what modify the state of the singleton.
3
+ ##
4
+ ## This helper is implemented by setting @__instance__ because in some tests
5
+ ## there are module functions that access MotionSupport::Inflector.inflections,
6
+ ## so we need to replace the singleton itself.
7
+ def with_dup(&block)
8
+ original = MotionSupport::Inflector.inflections
9
+ MotionSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original.dup)
10
+ block.call
11
+ MotionSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original)
12
+ end
13
+
@@ -0,0 +1,315 @@
1
+ # encoding: utf-8
2
+
3
+ module InflectorTestCases
4
+ SingularToPlural = {
5
+ "search" => "searches",
6
+ "switch" => "switches",
7
+ "fix" => "fixes",
8
+ "box" => "boxes",
9
+ "process" => "processes",
10
+ "address" => "addresses",
11
+ "case" => "cases",
12
+ "stack" => "stacks",
13
+ "wish" => "wishes",
14
+ "fish" => "fish",
15
+ "jeans" => "jeans",
16
+ "funky jeans" => "funky jeans",
17
+ "my money" => "my money",
18
+
19
+ "category" => "categories",
20
+ "query" => "queries",
21
+ "ability" => "abilities",
22
+ "agency" => "agencies",
23
+ "movie" => "movies",
24
+
25
+ "archive" => "archives",
26
+
27
+ "index" => "indices",
28
+
29
+ "wife" => "wives",
30
+ "safe" => "saves",
31
+ "half" => "halves",
32
+
33
+ "move" => "moves",
34
+
35
+ "salesperson" => "salespeople",
36
+ "person" => "people",
37
+
38
+ "spokesman" => "spokesmen",
39
+ "man" => "men",
40
+ "woman" => "women",
41
+
42
+ "basis" => "bases",
43
+ "diagnosis" => "diagnoses",
44
+ "diagnosis_a" => "diagnosis_as",
45
+
46
+ "datum" => "data",
47
+ "medium" => "media",
48
+ "stadium" => "stadia",
49
+ "analysis" => "analyses",
50
+ "my_analysis" => "my_analyses",
51
+
52
+ "node_child" => "node_children",
53
+ "child" => "children",
54
+
55
+ "experience" => "experiences",
56
+ "day" => "days",
57
+
58
+ "comment" => "comments",
59
+ "foobar" => "foobars",
60
+ "newsletter" => "newsletters",
61
+
62
+ "old_news" => "old_news",
63
+ "news" => "news",
64
+
65
+ "series" => "series",
66
+ "species" => "species",
67
+
68
+ "quiz" => "quizzes",
69
+
70
+ "perspective" => "perspectives",
71
+
72
+ "ox" => "oxen",
73
+ "photo" => "photos",
74
+ "buffalo" => "buffaloes",
75
+ "tomato" => "tomatoes",
76
+ "dwarf" => "dwarves",
77
+ "elf" => "elves",
78
+ "information" => "information",
79
+ "equipment" => "equipment",
80
+ "bus" => "buses",
81
+ "status" => "statuses",
82
+ "status_code" => "status_codes",
83
+ "mouse" => "mice",
84
+
85
+ "louse" => "lice",
86
+ "house" => "houses",
87
+ "octopus" => "octopi",
88
+ "virus" => "viri",
89
+ "alias" => "aliases",
90
+ "portfolio" => "portfolios",
91
+
92
+ "vertex" => "vertices",
93
+ "matrix" => "matrices",
94
+ "matrix_fu" => "matrix_fus",
95
+
96
+ "axis" => "axes",
97
+ "taxi" => "taxis", # prevents regression
98
+ "testis" => "testes",
99
+ "crisis" => "crises",
100
+
101
+ "rice" => "rice",
102
+ "shoe" => "shoes",
103
+
104
+ "horse" => "horses",
105
+ "prize" => "prizes",
106
+ "edge" => "edges",
107
+
108
+ "cow" => "kine",
109
+ "database" => "databases",
110
+
111
+ # regression tests against improper inflection regexes
112
+ "|ice" => "|ices",
113
+ "|ouse" => "|ouses",
114
+ "slice" => "slices",
115
+ "police" => "police"
116
+ }
117
+
118
+ CamelToUnderscore = {
119
+ "Product" => "product",
120
+ "SpecialGuest" => "special_guest",
121
+ "ApplicationController" => "application_controller",
122
+ "Area51Controller" => "area51_controller"
123
+ }
124
+
125
+ UnderscoreToLowerCamel = {
126
+ "product" => "product",
127
+ "special_guest" => "specialGuest",
128
+ "application_controller" => "applicationController",
129
+ "area51_controller" => "area51Controller"
130
+ }
131
+
132
+ SymbolToLowerCamel = {
133
+ :product => 'product',
134
+ :special_guest => 'specialGuest',
135
+ :application_controller => 'applicationController',
136
+ :area51_controller => 'area51Controller'
137
+ }
138
+
139
+ CamelToUnderscoreWithoutReverse = {
140
+ "HTMLTidy" => "html_tidy",
141
+ "HTMLTidyGenerator" => "html_tidy_generator",
142
+ "FreeBSD" => "free_bsd",
143
+ "HTML" => "html",
144
+ }
145
+
146
+ CamelWithModuleToUnderscoreWithSlash = {
147
+ "Admin::Product" => "admin/product",
148
+ "Users::Commission::Department" => "users/commission/department",
149
+ "UsersSection::CommissionDepartment" => "users_section/commission_department",
150
+ }
151
+
152
+ ClassNameToForeignKeyWithUnderscore = {
153
+ "Person" => "person_id",
154
+ "MyApplication::Billing::Account" => "account_id"
155
+ }
156
+
157
+ ClassNameToForeignKeyWithoutUnderscore = {
158
+ "Person" => "personid",
159
+ "MyApplication::Billing::Account" => "accountid"
160
+ }
161
+
162
+ ClassNameToTableName = {
163
+ "PrimarySpokesman" => "primary_spokesmen",
164
+ "NodeChild" => "node_children"
165
+ }
166
+
167
+ StringToParameterized = {
168
+ "Donald E. Knuth" => "donald-e-knuth",
169
+ "Random text with *(bad)* characters" => "random-text-with-bad-characters",
170
+ "Allow_Under_Scores" => "allow_under_scores",
171
+ "Trailing bad characters!@#" => "trailing-bad-characters",
172
+ "!@#Leading bad characters" => "leading-bad-characters",
173
+ "Squeeze separators" => "squeeze-separators",
174
+ "Test with + sign" => "test-with-sign",
175
+ "Test with malformed utf8 \251" => "test-with-malformed-utf8"
176
+ }
177
+
178
+ StringToParameterizeWithNoSeparator = {
179
+ "Donald E. Knuth" => "donaldeknuth",
180
+ "With-some-dashes" => "with-some-dashes",
181
+ "Random text with *(bad)* characters" => "randomtextwithbadcharacters",
182
+ "Trailing bad characters!@#" => "trailingbadcharacters",
183
+ "!@#Leading bad characters" => "leadingbadcharacters",
184
+ "Squeeze separators" => "squeezeseparators",
185
+ "Test with + sign" => "testwithsign",
186
+ "Test with malformed utf8 \251" => "testwithmalformedutf8"
187
+ }
188
+
189
+ StringToParameterizeWithUnderscore = {
190
+ "Donald E. Knuth" => "donald_e_knuth",
191
+ "Random text with *(bad)* characters" => "random_text_with_bad_characters",
192
+ "With-some-dashes" => "with-some-dashes",
193
+ "Retain_underscore" => "retain_underscore",
194
+ "Trailing bad characters!@#" => "trailing_bad_characters",
195
+ "!@#Leading bad characters" => "leading_bad_characters",
196
+ "Squeeze separators" => "squeeze_separators",
197
+ "Test with + sign" => "test_with_sign",
198
+ "Test with malformed utf8 \251" => "test_with_malformed_utf8"
199
+ }
200
+
201
+ StringToParameterizedAndNormalized = {
202
+ "Malmö" => "malmo",
203
+ "Garçons" => "garcons",
204
+ "Ops\331" => "opsu",
205
+ "Ærøskøbing" => "aeroskobing",
206
+ "Aßlar" => "asslar",
207
+ "Japanese: 日本語" => "japanese"
208
+ }
209
+
210
+ UnderscoreToHuman = {
211
+ "employee_salary" => "Employee salary",
212
+ "employee_id" => "Employee",
213
+ "underground" => "Underground"
214
+ }
215
+
216
+ MixtureToTitleCase = {
217
+ 'active_record' => 'Active Record',
218
+ 'ActiveRecord' => 'Active Record',
219
+ 'action web service' => 'Action Web Service',
220
+ 'Action Web Service' => 'Action Web Service',
221
+ 'Action web service' => 'Action Web Service',
222
+ 'actionwebservice' => 'Actionwebservice',
223
+ 'Actionwebservice' => 'Actionwebservice',
224
+ "david's code" => "David's Code",
225
+ "David's code" => "David's Code",
226
+ "david's Code" => "David's Code",
227
+ "sgt. pepper's" => "Sgt. Pepper's",
228
+ "i've just seen a face" => "I've Just Seen A Face",
229
+ "maybe you'll be there" => "Maybe You'll Be There",
230
+ "¿por qué?" => '¿Por Qué?',
231
+ "Fred’s" => "Fred’s",
232
+ "Fred`s" => "Fred`s"
233
+ }
234
+
235
+ OrdinalNumbers = {
236
+ "-1" => "-1st",
237
+ "-2" => "-2nd",
238
+ "-3" => "-3rd",
239
+ "-4" => "-4th",
240
+ "-5" => "-5th",
241
+ "-6" => "-6th",
242
+ "-7" => "-7th",
243
+ "-8" => "-8th",
244
+ "-9" => "-9th",
245
+ "-10" => "-10th",
246
+ "-11" => "-11th",
247
+ "-12" => "-12th",
248
+ "-13" => "-13th",
249
+ "-14" => "-14th",
250
+ "-20" => "-20th",
251
+ "-21" => "-21st",
252
+ "-22" => "-22nd",
253
+ "-23" => "-23rd",
254
+ "-24" => "-24th",
255
+ "-100" => "-100th",
256
+ "-101" => "-101st",
257
+ "-102" => "-102nd",
258
+ "-103" => "-103rd",
259
+ "-104" => "-104th",
260
+ "-110" => "-110th",
261
+ "-111" => "-111th",
262
+ "-112" => "-112th",
263
+ "-113" => "-113th",
264
+ "-1000" => "-1000th",
265
+ "-1001" => "-1001st",
266
+ "0" => "0th",
267
+ "1" => "1st",
268
+ "2" => "2nd",
269
+ "3" => "3rd",
270
+ "4" => "4th",
271
+ "5" => "5th",
272
+ "6" => "6th",
273
+ "7" => "7th",
274
+ "8" => "8th",
275
+ "9" => "9th",
276
+ "10" => "10th",
277
+ "11" => "11th",
278
+ "12" => "12th",
279
+ "13" => "13th",
280
+ "14" => "14th",
281
+ "20" => "20th",
282
+ "21" => "21st",
283
+ "22" => "22nd",
284
+ "23" => "23rd",
285
+ "24" => "24th",
286
+ "100" => "100th",
287
+ "101" => "101st",
288
+ "102" => "102nd",
289
+ "103" => "103rd",
290
+ "104" => "104th",
291
+ "110" => "110th",
292
+ "111" => "111th",
293
+ "112" => "112th",
294
+ "113" => "113th",
295
+ "1000" => "1000th",
296
+ "1001" => "1001st"
297
+ }
298
+
299
+ UnderscoresToDashes = {
300
+ "street" => "street",
301
+ "street_address" => "street-address",
302
+ "person_street_address" => "person-street-address"
303
+ }
304
+
305
+ Irregularities = {
306
+ 'person' => 'people',
307
+ 'man' => 'men',
308
+ 'child' => 'children',
309
+ 'sex' => 'sexes',
310
+ 'move' => 'moves',
311
+ 'cow' => 'kine',
312
+ 'zombie' => 'zombies',
313
+ }
314
+ end
315
+