motion_blender-support 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +4 -0
  5. data/HACKS.md +7 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +359 -0
  8. data/Rakefile +14 -0
  9. data/app/app_delegate.rb +5 -0
  10. data/examples/Inflector/.gitignore +16 -0
  11. data/examples/Inflector/Gemfile +5 -0
  12. data/examples/Inflector/Rakefile +13 -0
  13. data/examples/Inflector/app/app_delegate.rb +8 -0
  14. data/examples/Inflector/app/inflections.rb +5 -0
  15. data/examples/Inflector/app/inflector_view_controller.rb +109 -0
  16. data/examples/Inflector/app/words_view_controller.rb +101 -0
  17. data/examples/Inflector/resources/Default-568h@2x.png +0 -0
  18. data/examples/Inflector/spec/main_spec.rb +9 -0
  19. data/lib/motion-support/callbacks.rb +8 -0
  20. data/lib/motion-support/concern.rb +4 -0
  21. data/lib/motion-support/core_ext/array.rb +10 -0
  22. data/lib/motion-support/core_ext/class.rb +5 -0
  23. data/lib/motion-support/core_ext/hash.rb +13 -0
  24. data/lib/motion-support/core_ext/integer.rb +6 -0
  25. data/lib/motion-support/core_ext/module.rb +11 -0
  26. data/lib/motion-support/core_ext/numeric.rb +6 -0
  27. data/lib/motion-support/core_ext/object.rb +12 -0
  28. data/lib/motion-support/core_ext/range.rb +5 -0
  29. data/lib/motion-support/core_ext/string.rb +13 -0
  30. data/lib/motion-support/core_ext/time.rb +16 -0
  31. data/lib/motion-support/core_ext.rb +13 -0
  32. data/lib/motion-support/inflector.rb +8 -0
  33. data/lib/motion-support.rb +81 -0
  34. data/motion/_stdlib/array.rb +13 -0
  35. data/motion/_stdlib/cgi.rb +22 -0
  36. data/motion/_stdlib/date.rb +81 -0
  37. data/motion/_stdlib/enumerable.rb +9 -0
  38. data/motion/_stdlib/time.rb +19 -0
  39. data/motion/callbacks.rb +511 -0
  40. data/motion/concern.rb +122 -0
  41. data/motion/core_ext/array/access.rb +28 -0
  42. data/motion/core_ext/array/conversions.rb +86 -0
  43. data/motion/core_ext/array/extract_options.rb +11 -0
  44. data/motion/core_ext/array/grouping.rb +99 -0
  45. data/motion/core_ext/array/prepend_and_append.rb +7 -0
  46. data/motion/core_ext/array/wrap.rb +45 -0
  47. data/motion/core_ext/array.rb +19 -0
  48. data/motion/core_ext/class/attribute.rb +119 -0
  49. data/motion/core_ext/class/attribute_accessors.rb +168 -0
  50. data/motion/core_ext/date/acts_like.rb +8 -0
  51. data/motion/core_ext/date/calculations.rb +117 -0
  52. data/motion/core_ext/date/conversions.rb +56 -0
  53. data/motion/core_ext/date_and_time/calculations.rb +232 -0
  54. data/motion/core_ext/enumerable.rb +90 -0
  55. data/motion/core_ext/hash/deep_delete_if.rb +23 -0
  56. data/motion/core_ext/hash/deep_merge.rb +27 -0
  57. data/motion/core_ext/hash/except.rb +15 -0
  58. data/motion/core_ext/hash/indifferent_access.rb +19 -0
  59. data/motion/core_ext/hash/keys.rb +150 -0
  60. data/motion/core_ext/hash/reverse_merge.rb +22 -0
  61. data/motion/core_ext/hash/slice.rb +40 -0
  62. data/motion/core_ext/integer/inflections.rb +27 -0
  63. data/motion/core_ext/integer/multiple.rb +10 -0
  64. data/motion/core_ext/integer/time.rb +41 -0
  65. data/motion/core_ext/kernel/singleton_class.rb +6 -0
  66. data/motion/core_ext/metaclass.rb +8 -0
  67. data/motion/core_ext/module/aliasing.rb +69 -0
  68. data/motion/core_ext/module/anonymous.rb +19 -0
  69. data/motion/core_ext/module/attr_internal.rb +38 -0
  70. data/motion/core_ext/module/attribute_accessors.rb +64 -0
  71. data/motion/core_ext/module/delegation.rb +175 -0
  72. data/motion/core_ext/module/introspection.rb +60 -0
  73. data/motion/core_ext/module/reachable.rb +5 -0
  74. data/motion/core_ext/module/remove_method.rb +12 -0
  75. data/motion/core_ext/ns_dictionary.rb +14 -0
  76. data/motion/core_ext/ns_string.rb +14 -0
  77. data/motion/core_ext/numeric/bytes.rb +44 -0
  78. data/motion/core_ext/numeric/conversions.rb +49 -0
  79. data/motion/core_ext/numeric/time.rb +75 -0
  80. data/motion/core_ext/object/acts_like.rb +10 -0
  81. data/motion/core_ext/object/blank.rb +105 -0
  82. data/motion/core_ext/object/deep_dup.rb +44 -0
  83. data/motion/core_ext/object/duplicable.rb +87 -0
  84. data/motion/core_ext/object/inclusion.rb +15 -0
  85. data/motion/core_ext/object/instance_variables.rb +28 -0
  86. data/motion/core_ext/object/to_param.rb +58 -0
  87. data/motion/core_ext/object/to_query.rb +26 -0
  88. data/motion/core_ext/object/try.rb +78 -0
  89. data/motion/core_ext/range/include_range.rb +23 -0
  90. data/motion/core_ext/range/overlaps.rb +8 -0
  91. data/motion/core_ext/regexp.rb +5 -0
  92. data/motion/core_ext/string/access.rb +104 -0
  93. data/motion/core_ext/string/behavior.rb +6 -0
  94. data/motion/core_ext/string/exclude.rb +11 -0
  95. data/motion/core_ext/string/filters.rb +55 -0
  96. data/motion/core_ext/string/indent.rb +43 -0
  97. data/motion/core_ext/string/inflections.rb +178 -0
  98. data/motion/core_ext/string/starts_ends_with.rb +4 -0
  99. data/motion/core_ext/string/strip.rb +24 -0
  100. data/motion/core_ext/time/acts_like.rb +8 -0
  101. data/motion/core_ext/time/calculations.rb +215 -0
  102. data/motion/core_ext/time/conversions.rb +52 -0
  103. data/motion/descendants_tracker.rb +50 -0
  104. data/motion/duration.rb +104 -0
  105. data/motion/hash_with_indifferent_access.rb +253 -0
  106. data/motion/inflections.rb +67 -0
  107. data/motion/inflector/inflections.rb +203 -0
  108. data/motion/inflector/methods.rb +321 -0
  109. data/motion/logger.rb +47 -0
  110. data/motion/number_helper.rb +54 -0
  111. data/motion/version.rb +3 -0
  112. data/motion_blender-support.gemspec +21 -0
  113. data/spec/motion-support/_helpers/constantize_test_cases.rb +75 -0
  114. data/spec/motion-support/_helpers/inflector_test_cases.rb +270 -0
  115. data/spec/motion-support/callback_spec.rb +702 -0
  116. data/spec/motion-support/concern_spec.rb +93 -0
  117. data/spec/motion-support/core_ext/array/access_spec.rb +29 -0
  118. data/spec/motion-support/core_ext/array/conversion_spec.rb +60 -0
  119. data/spec/motion-support/core_ext/array/extract_options_spec.rb +15 -0
  120. data/spec/motion-support/core_ext/array/grouping_spec.rb +85 -0
  121. data/spec/motion-support/core_ext/array/prepend_and_append_spec.rb +25 -0
  122. data/spec/motion-support/core_ext/array/wrap_spec.rb +19 -0
  123. data/spec/motion-support/core_ext/array_spec.rb +16 -0
  124. data/spec/motion-support/core_ext/class/attribute_accessor_spec.rb +127 -0
  125. data/spec/motion-support/core_ext/class/attribute_spec.rb +92 -0
  126. data/spec/motion-support/core_ext/date/acts_like_spec.rb +11 -0
  127. data/spec/motion-support/core_ext/date/calculation_spec.rb +186 -0
  128. data/spec/motion-support/core_ext/date/conversion_spec.rb +18 -0
  129. data/spec/motion-support/core_ext/date_and_time/calculation_spec.rb +336 -0
  130. data/spec/motion-support/core_ext/enumerable_spec.rb +130 -0
  131. data/spec/motion-support/core_ext/hash/deep_delete_if_spec.rb +19 -0
  132. data/spec/motion-support/core_ext/hash/deep_merge_spec.rb +32 -0
  133. data/spec/motion-support/core_ext/hash/except_spec.rb +43 -0
  134. data/spec/motion-support/core_ext/hash/key_spec.rb +236 -0
  135. data/spec/motion-support/core_ext/hash/reverse_merge_spec.rb +26 -0
  136. data/spec/motion-support/core_ext/hash/slice_spec.rb +61 -0
  137. data/spec/motion-support/core_ext/integer/inflection_spec.rb +23 -0
  138. data/spec/motion-support/core_ext/integer/multiple_spec.rb +19 -0
  139. data/spec/motion-support/core_ext/kernel/singleton_class_spec.rb +9 -0
  140. data/spec/motion-support/core_ext/metaclass_spec.rb +9 -0
  141. data/spec/motion-support/core_ext/module/aliasing_spec.rb +143 -0
  142. data/spec/motion-support/core_ext/module/anonymous_spec.rb +29 -0
  143. data/spec/motion-support/core_ext/module/attr_internal_spec.rb +104 -0
  144. data/spec/motion-support/core_ext/module/attribute_accessor_spec.rb +86 -0
  145. data/spec/motion-support/core_ext/module/delegation_spec.rb +136 -0
  146. data/spec/motion-support/core_ext/module/introspection_spec.rb +70 -0
  147. data/spec/motion-support/core_ext/module/reachable_spec.rb +61 -0
  148. data/spec/motion-support/core_ext/module/remove_method_spec.rb +25 -0
  149. data/spec/motion-support/core_ext/numeric/bytes_spec.rb +43 -0
  150. data/spec/motion-support/core_ext/numeric/conversions_spec.rb +40 -0
  151. data/spec/motion-support/core_ext/object/acts_like_spec.rb +21 -0
  152. data/spec/motion-support/core_ext/object/blank_spec.rb +54 -0
  153. data/spec/motion-support/core_ext/object/deep_dup_spec.rb +54 -0
  154. data/spec/motion-support/core_ext/object/duplicable_spec.rb +31 -0
  155. data/spec/motion-support/core_ext/object/inclusion_spec.rb +34 -0
  156. data/spec/motion-support/core_ext/object/instance_variable_spec.rb +19 -0
  157. data/spec/motion-support/core_ext/object/to_param_spec.rb +75 -0
  158. data/spec/motion-support/core_ext/object/to_query_spec.rb +37 -0
  159. data/spec/motion-support/core_ext/object/try_spec.rb +92 -0
  160. data/spec/motion-support/core_ext/range/include_range_spec.rb +31 -0
  161. data/spec/motion-support/core_ext/range/overlap_spec.rb +43 -0
  162. data/spec/motion-support/core_ext/regexp_spec.rb +7 -0
  163. data/spec/motion-support/core_ext/string/access_spec.rb +53 -0
  164. data/spec/motion-support/core_ext/string/behavior_spec.rb +7 -0
  165. data/spec/motion-support/core_ext/string/exclude_spec.rb +8 -0
  166. data/spec/motion-support/core_ext/string/filter_spec.rb +49 -0
  167. data/spec/motion-support/core_ext/string/indent_spec.rb +56 -0
  168. data/spec/motion-support/core_ext/string/inflection_spec.rb +142 -0
  169. data/spec/motion-support/core_ext/string/starts_end_with_spec.rb +14 -0
  170. data/spec/motion-support/core_ext/string/strip_spec.rb +34 -0
  171. data/spec/motion-support/core_ext/string_spec.rb +88 -0
  172. data/spec/motion-support/core_ext/time/acts_like_spec.rb +11 -0
  173. data/spec/motion-support/core_ext/time/calculation_spec.rb +201 -0
  174. data/spec/motion-support/core_ext/time/conversion_spec.rb +53 -0
  175. data/spec/motion-support/descendants_tracker_spec.rb +58 -0
  176. data/spec/motion-support/duration_spec.rb +107 -0
  177. data/spec/motion-support/hash_with_indifferent_access_spec.rb +605 -0
  178. data/spec/motion-support/inflector_spec.rb +504 -0
  179. data/spec/motion-support/ns_dictionary_spec.rb +89 -0
  180. data/spec/motion-support/ns_string_spec.rb +182 -0
  181. data/spec/motion-support/number_helper_spec.rb +55 -0
  182. metadata +352 -0
@@ -0,0 +1,321 @@
1
+ module MotionSupport
2
+ # The Inflector transforms words from singular to plural, class names to table
3
+ # names, modularized class names to ones without, and class names to foreign
4
+ # keys. The default inflections for pluralization, singularization, and
5
+ # uncountable words are kept in inflections.rb.
6
+ module Inflector
7
+ extend self
8
+
9
+ # Returns the plural form of the word in the string.
10
+ #
11
+ # 'post'.pluralize # => "posts"
12
+ # 'octopus'.pluralize # => "octopi"
13
+ # 'sheep'.pluralize # => "sheep"
14
+ # 'words'.pluralize # => "words"
15
+ # 'CamelOctopus'.pluralize # => "CamelOctopi"
16
+ def pluralize(word)
17
+ apply_inflections(word, inflections.plurals)
18
+ end
19
+
20
+ # The reverse of +pluralize+, returns the singular form of a word in a
21
+ # string.
22
+ #
23
+ # 'posts'.singularize # => "post"
24
+ # 'octopi'.singularize # => "octopus"
25
+ # 'sheep'.singularize # => "sheep"
26
+ # 'word'.singularize # => "word"
27
+ # 'CamelOctopi'.singularize # => "CamelOctopus"
28
+ def singularize(word)
29
+ apply_inflections(word, inflections.singulars)
30
+ end
31
+
32
+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument
33
+ # to +camelize+ is set to <tt>:lower</tt> then +camelize+ produces
34
+ # lowerCamelCase.
35
+ #
36
+ # +camelize+ will also convert '/' to '::' which is useful for converting
37
+ # paths to namespaces.
38
+ #
39
+ # 'active_model'.camelize # => "ActiveModel"
40
+ # 'active_model'.camelize(:lower) # => "activeModel"
41
+ # 'active_model/errors'.camelize # => "ActiveModel::Errors"
42
+ # 'active_model/errors'.camelize(:lower) # => "activeModel::Errors"
43
+ #
44
+ # As a rule of thumb you can think of +camelize+ as the inverse of
45
+ # +underscore+, though there are cases where that does not hold:
46
+ #
47
+ # 'SSLError'.underscore.camelize # => "SslError"
48
+ def camelize(term, uppercase_first_letter = true)
49
+ string = term.to_s
50
+ if uppercase_first_letter
51
+ string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
52
+ else
53
+ string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
54
+ end
55
+ string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::')
56
+ end
57
+
58
+ # Makes an underscored, lowercase form from the expression in the string.
59
+ #
60
+ # Changes '::' to '/' to convert namespaces to paths.
61
+ #
62
+ # 'ActiveModel'.underscore # => "active_model"
63
+ # 'ActiveModel::Errors'.underscore # => "active_model/errors"
64
+ #
65
+ # As a rule of thumb you can think of +underscore+ as the inverse of
66
+ # +camelize+, though there are cases where that does not hold:
67
+ #
68
+ # 'SSLError'.underscore.camelize # => "SslError"
69
+ def underscore(camel_cased_word)
70
+ word = camel_cased_word.to_s.dup
71
+ word.gsub!('::', '/')
72
+ word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
73
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
74
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
75
+ word.tr!("-", "_")
76
+ word.downcase!
77
+ word
78
+ end
79
+
80
+ # Capitalizes the first word and turns underscores into spaces and strips a
81
+ # trailing "_id", if any. Like +titleize+, this is meant for creating pretty
82
+ # output.
83
+ #
84
+ # 'employee_salary'.humanize # => "Employee salary"
85
+ # 'author_id'.humanize # => "Author"
86
+ def humanize(lower_case_and_underscored_word)
87
+ result = lower_case_and_underscored_word.to_s.dup
88
+ inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
89
+ result.gsub!(/_id$/, "")
90
+ result.tr!('_', ' ')
91
+ result.gsub(/([a-z\d]*)/i) { |match|
92
+ "#{inflections.acronyms[match] || match.downcase}"
93
+ }.gsub(/^\w/) { $&.upcase }
94
+ end
95
+
96
+ # Capitalizes all the words and replaces some characters in the string to
97
+ # create a nicer looking title. +titleize+ is meant for creating pretty
98
+ # output. It is not used in the Rails internals.
99
+ #
100
+ # +titleize+ is also aliased as +titlecase+.
101
+ #
102
+ # 'man from the boondocks'.titleize # => "Man From The Boondocks"
103
+ # 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
104
+ # 'TheManWithoutAPast'.titleize # => "The Man Without A Past"
105
+ # 'raiders_of_the_lost_ark'.titleize # => "Raiders Of The Lost Ark"
106
+ def titleize(word)
107
+ humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { $&.capitalize }
108
+ end
109
+
110
+ # Create the name of a table like Rails does for models to table names. This
111
+ # method uses the +pluralize+ method on the last word in the string.
112
+ #
113
+ # 'RawScaledScorer'.tableize # => "raw_scaled_scorers"
114
+ # 'egg_and_ham'.tableize # => "egg_and_hams"
115
+ # 'fancyCategory'.tableize # => "fancy_categories"
116
+ def tableize(class_name)
117
+ pluralize(underscore(class_name))
118
+ end
119
+
120
+ # Create a class name from a plural table name like Rails does for table
121
+ # names to models. Note that this returns a string and not a Class (To
122
+ # convert to an actual class follow +classify+ with +constantize+).
123
+ #
124
+ # 'egg_and_hams'.classify # => "EggAndHam"
125
+ # 'posts'.classify # => "Post"
126
+ #
127
+ # Singular names are not handled correctly:
128
+ #
129
+ # 'business'.classify # => "Busines"
130
+ def classify(table_name)
131
+ # strip out any leading schema name
132
+ camelize(singularize(table_name.to_s.sub(/.*\./, '')))
133
+ end
134
+
135
+ # Replaces underscores with dashes in the string.
136
+ #
137
+ # 'puni_puni'.dasherize # => "puni-puni"
138
+ def dasherize(underscored_word)
139
+ underscored_word.tr('_', '-')
140
+ end
141
+
142
+ # Removes the module part from the expression in the string.
143
+ #
144
+ # 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
145
+ # 'Inflections'.demodulize # => "Inflections"
146
+ #
147
+ # See also +deconstantize+.
148
+ def demodulize(path)
149
+ path = path.to_s
150
+ if i = path.rindex('::')
151
+ path[(i+2)..-1]
152
+ else
153
+ path
154
+ end
155
+ end
156
+
157
+ # Removes the rightmost segment from the constant expression in the string.
158
+ #
159
+ # 'Net::HTTP'.deconstantize # => "Net"
160
+ # '::Net::HTTP'.deconstantize # => "::Net"
161
+ # 'String'.deconstantize # => ""
162
+ # '::String'.deconstantize # => ""
163
+ # ''.deconstantize # => ""
164
+ #
165
+ # See also +demodulize+.
166
+ def deconstantize(path)
167
+ path.to_s[0...(path.rindex('::') || 0)] # implementation based on the one in facets' Module#spacename
168
+ end
169
+
170
+ # Creates a foreign key name from a class name.
171
+ # +separate_class_name_and_id_with_underscore+ sets whether
172
+ # the method should put '_' between the name and 'id'.
173
+ #
174
+ # 'Message'.foreign_key # => "message_id"
175
+ # 'Message'.foreign_key(false) # => "messageid"
176
+ # 'Admin::Post'.foreign_key # => "post_id"
177
+ def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
178
+ underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
179
+ end
180
+
181
+ # Tries to find a constant with the name specified in the argument string.
182
+ #
183
+ # 'Module'.constantize # => Module
184
+ # 'Test::Unit'.constantize # => Test::Unit
185
+ #
186
+ # The name is assumed to be the one of a top-level constant, no matter
187
+ # whether it starts with "::" or not. No lexical context is taken into
188
+ # 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
231
+ # whether it starts with "::" or not. No lexical context is taken into
232
+ # account:
233
+ #
234
+ # C = 'outside'
235
+ # module M
236
+ # C = 'inside'
237
+ # C # => 'inside'
238
+ # 'C'.safe_constantize # => 'outside', same as ::C
239
+ # end
240
+ #
241
+ # +nil+ is returned when the name is not in CamelCase or the constant (or
242
+ # part of it) is unknown.
243
+ #
244
+ # 'blargle'.safe_constantize # => nil
245
+ # 'UnknownModule'.safe_constantize # => nil
246
+ # 'UnknownModule::Foo::Bar'.safe_constantize # => nil
247
+ def safe_constantize(camel_cased_word)
248
+ constantize(camel_cased_word)
249
+ rescue NameError => e
250
+ raise unless e.message =~ /(uninitialized constant|wrong constant name) #{const_regexp(camel_cased_word)}$/ ||
251
+ e.name.to_s == camel_cased_word.to_s
252
+ rescue ArgumentError => e
253
+ raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
254
+ end
255
+
256
+ # Returns the suffix that should be added to a number to denote the position
257
+ # in an ordered sequence such as 1st, 2nd, 3rd, 4th.
258
+ #
259
+ # ordinal(1) # => "st"
260
+ # ordinal(2) # => "nd"
261
+ # ordinal(1002) # => "nd"
262
+ # ordinal(1003) # => "rd"
263
+ # ordinal(-11) # => "th"
264
+ # ordinal(-1021) # => "st"
265
+ def ordinal(number)
266
+ abs_number = number.to_i.abs
267
+
268
+ if (11..13).include?(abs_number % 100)
269
+ "th"
270
+ else
271
+ case abs_number % 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
data/motion/logger.rb ADDED
@@ -0,0 +1,47 @@
1
+ module Kernel
2
+ def log(*args)
3
+ MotionSupport.logger.log(*args)
4
+ end
5
+
6
+ def l(*args)
7
+ MotionSupport.logger.log(args.map { |a| a.inspect })
8
+ end
9
+ end
10
+
11
+ module MotionSupport
12
+ class NullLogger
13
+ def log(*args)
14
+ end
15
+ end
16
+
17
+ class StdoutLogger
18
+ def log(*args)
19
+ puts args
20
+ end
21
+ end
22
+
23
+ class NetworkLogger
24
+ def initialize(host = "localhost", port = 2000)
25
+ readStream = Pointer.new(:object)
26
+ writeStream = Pointer.new(:object)
27
+ CFStreamCreatePairWithSocketToHost(nil, host, port, readStream, writeStream)
28
+ @output_stream = writeStream[0]
29
+ @output_stream.setDelegate(self)
30
+ @output_stream.scheduleInRunLoop(NSRunLoop.currentRunLoop, forMode:NSDefaultRunLoopMode)
31
+ @output_stream.open
32
+ end
33
+
34
+ def log(*args)
35
+ args.each do |string|
36
+ data = NSData.alloc.initWithData("#{string}\n".dataUsingEncoding(NSASCIIStringEncoding))
37
+ @output_stream.write(data.bytes, maxLength:data.length)
38
+ end
39
+ end
40
+ end
41
+
42
+ mattr_writer :logger
43
+
44
+ def self.logger
45
+ @logger ||= StdoutLogger.new
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ module MotionSupport
2
+ module NumberHelper
3
+ extend self
4
+
5
+ # Formats a +number+ into a US phone number (e.g., (555)
6
+ # 123-9876). You can customize the format in the +options+ hash.
7
+ #
8
+ # ==== Options
9
+ #
10
+ # * <tt>:area_code</tt> - Adds parentheses around the area code.
11
+ # * <tt>:delimiter</tt> - Specifies the delimiter to use
12
+ # (defaults to "-").
13
+ # * <tt>:extension</tt> - Specifies an extension to add to the
14
+ # end of the generated number.
15
+ # * <tt>:country_code</tt> - Sets the country code for the phone
16
+ # number.
17
+ # ==== Examples
18
+ #
19
+ # number_to_phone(5551234) # => 555-1234
20
+ # number_to_phone('5551234') # => 555-1234
21
+ # number_to_phone(1235551234) # => 123-555-1234
22
+ # number_to_phone(1235551234, area_code: true) # => (123) 555-1234
23
+ # number_to_phone(1235551234, delimiter: ' ') # => 123 555 1234
24
+ # number_to_phone(1235551234, area_code: true, extension: 555) # => (123) 555-1234 x 555
25
+ # number_to_phone(1235551234, country_code: 1) # => +1-123-555-1234
26
+ # number_to_phone('123a456') # => 123a456
27
+ #
28
+ # number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.')
29
+ # # => +1.123.555.1234 x 1343
30
+ def number_to_phone(number, options = {})
31
+ return unless number
32
+ options = options.symbolize_keys
33
+
34
+ number = number.to_s.strip
35
+ area_code = options[:area_code]
36
+ delimiter = options[:delimiter] || "-"
37
+ extension = options[:extension]
38
+ country_code = options[:country_code]
39
+
40
+ if area_code
41
+ number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3")
42
+ else
43
+ number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
44
+ number.slice!(0, 1) if number.start_with?(delimiter) && !delimiter.blank?
45
+ end
46
+
47
+ str = ''
48
+ str << "+#{country_code}#{delimiter}" unless country_code.blank?
49
+ str << number
50
+ str << " x #{extension}" unless extension.blank?
51
+ str
52
+ end
53
+ end
54
+ end
data/motion/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module MotionSupport
2
+ VERSION = '0.2.7'
3
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../motion/version', __FILE__)
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "motion_blender-support"
6
+ spec.version = MotionSupport::VERSION
7
+ spec.authors = ['kayhide', "Thomas Kadauke"]
8
+ spec.email = ['kayhide@gmail.com', "thomaspec.kadauke@googlemail.com"]
9
+ spec.homepage = "https://github.com/kayhide/motion_blender-support"
10
+ spec.summary = "Commonly useful extensions to the standard library for RubyMotion"
11
+ spec.description = "Commonly useful extensions to the standard library for RubyMotion. Ported from ActiveSupport."
12
+
13
+ spec.files = `git ls-files`.split($\)
14
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.require_paths = ["lib"]
16
+
17
+ spec.add_runtime_dependency "motion_blender"
18
+ spec.add_development_dependency 'rake'
19
+ spec.add_development_dependency 'pry'
20
+ spec.add_development_dependency 'pry-doc'
21
+ end
@@ -0,0 +1,75 @@
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(&block)
27
+ yield("Ace::Base::Case").should == Ace::Base::Case
28
+ yield("::Ace::Base::Case").should == Ace::Base::Case
29
+ yield("Ace::Base::Case::Dice").should == Ace::Base::Case::Dice
30
+ yield("Ace::Base::Fase::Dice").should == Ace::Base::Fase::Dice
31
+ yield("Ace::Gas::Case").should == Ace::Gas::Case
32
+ yield("Ace::Gas::Case::Dice").should == Ace::Gas::Case::Dice
33
+ yield("Case::Dice").should == Case::Dice
34
+ yield("Object::Case::Dice").should == Case::Dice
35
+ yield("ConstantizeTestCases").should == ConstantizeTestCases
36
+ yield("::ConstantizeTestCases").should == ConstantizeTestCases
37
+ yield("").should == Object
38
+ yield("::").should == Object
39
+ lambda { block.call("UnknownClass") }.should.raise NameError
40
+ lambda { block.call("UnknownClass::Ace") }.should.raise NameError
41
+ lambda { block.call("UnknownClass::Ace::Base") }.should.raise NameError
42
+ lambda { block.call("An invalid string") }.should.raise NameError
43
+ lambda { block.call("InvalidClass\n") }.should.raise NameError
44
+ lambda { block.call("Ace::ConstantizeTestCases") }.should.raise NameError
45
+ lambda { block.call("Ace::Base::ConstantizeTestCases") }.should.raise NameError
46
+ lambda { block.call("Ace::Gas::Base") }.should.raise NameError
47
+ lambda { block.call("Ace::Gas::ConstantizeTestCases") }.should.raise NameError
48
+ end
49
+
50
+ def run_safe_constantize_tests_on
51
+ yield("Ace::Base::Case").should == Ace::Base::Case
52
+ yield("::Ace::Base::Case").should == Ace::Base::Case
53
+ yield("Ace::Base::Case::Dice").should == Ace::Base::Case::Dice
54
+ yield("Ace::Base::Fase::Dice").should == Ace::Base::Fase::Dice
55
+ yield("Ace::Gas::Case").should == Ace::Gas::Case
56
+ yield("Ace::Gas::Case::Dice").should == Ace::Gas::Case::Dice
57
+ yield("Case::Dice").should == Case::Dice
58
+ yield("Object::Case::Dice").should == Case::Dice
59
+ yield("ConstantizeTestCases").should == ConstantizeTestCases
60
+ yield("::ConstantizeTestCases").should == ConstantizeTestCases
61
+ yield("").should == Object
62
+ yield("::").should == Object
63
+ yield("UnknownClass").should.be.nil
64
+ yield("UnknownClass::Ace").should.be.nil
65
+ yield("UnknownClass::Ace::Base").should.be.nil
66
+ yield("An invalid string").should.be.nil
67
+ yield("InvalidClass\n").should.be.nil
68
+ yield("blargle").should.be.nil
69
+ yield("Ace::ConstantizeTestCases").should.be.nil
70
+ yield("Ace::Base::ConstantizeTestCases").should.be.nil
71
+ yield("Ace::Gas::Base").should.be.nil
72
+ yield("Ace::Gas::ConstantizeTestCases").should.be.nil
73
+ yield("#<Class:0x7b8b718b>::Nested_1").should.be.nil
74
+ end
75
+ end