motion_blender-support 0.2.7

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.
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