gorillib 0.1.11 → 0.4.0pre

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 (143) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +1 -2
  3. data/.yardopts +9 -0
  4. data/{CHANGELOG.textile → CHANGELOG.md} +35 -9
  5. data/Gemfile +21 -14
  6. data/Guardfile +19 -0
  7. data/{LICENSE.textile → LICENSE.md} +43 -29
  8. data/README.md +47 -52
  9. data/Rakefile +31 -30
  10. data/TODO.md +32 -0
  11. data/VERSION +1 -1
  12. data/examples/builder/ironfan.rb +133 -0
  13. data/examples/model/simple.rb +17 -0
  14. data/gorillib.gemspec +106 -86
  15. data/lib/alt/kernel/call_stack.rb +56 -0
  16. data/lib/gorillib/array/wrap.rb +53 -0
  17. data/lib/gorillib/base.rb +3 -3
  18. data/lib/gorillib/builder/field.rb +5 -0
  19. data/lib/gorillib/builder.rb +260 -0
  20. data/lib/gorillib/collection/has_collection.rb +31 -0
  21. data/lib/gorillib/collection.rb +129 -0
  22. data/lib/gorillib/configurable.rb +28 -0
  23. data/lib/gorillib/datetime/{flat.rb → to_flat.rb} +0 -0
  24. data/lib/gorillib/exception/confidence.rb +17 -0
  25. data/lib/gorillib/exception/raisers.rb +78 -0
  26. data/lib/gorillib/hash/mash.rb +202 -0
  27. data/lib/gorillib/hashlike/slice.rb +53 -19
  28. data/lib/gorillib/hashlike.rb +5 -3
  29. data/lib/gorillib/io/system_helpers.rb +30 -0
  30. data/lib/gorillib/logger/log.rb +18 -0
  31. data/lib/gorillib/metaprogramming/concern.rb +124 -0
  32. data/lib/gorillib/model/active_model_conversion.rb +68 -0
  33. data/lib/gorillib/model/active_model_naming.rb +87 -0
  34. data/lib/gorillib/model/active_model_shim.rb +33 -0
  35. data/lib/gorillib/model/base.rb +341 -0
  36. data/lib/gorillib/model/defaults.rb +71 -0
  37. data/lib/gorillib/model/errors.rb +14 -0
  38. data/lib/gorillib/model/factories.rb +372 -0
  39. data/lib/gorillib/model/field.rb +146 -0
  40. data/lib/gorillib/model/named_schema.rb +53 -0
  41. data/lib/gorillib/{struct/hashlike_iteration.rb → model/overlay.rb} +0 -0
  42. data/lib/gorillib/model/record_schema.rb +9 -0
  43. data/lib/gorillib/model/serialization.rb +23 -0
  44. data/lib/gorillib/model/validate.rb +22 -0
  45. data/lib/gorillib/model.rb +23 -0
  46. data/lib/gorillib/pathname.rb +78 -0
  47. data/lib/gorillib/{serialization.rb → serialization/to_wire.rb} +0 -0
  48. data/lib/gorillib/some.rb +11 -9
  49. data/lib/gorillib/string/constantize.rb +21 -14
  50. data/lib/gorillib/string/inflections.rb +6 -76
  51. data/lib/gorillib/string/inflector.rb +192 -0
  52. data/lib/gorillib/string/simple_inflector.rb +267 -0
  53. data/lib/gorillib/type/extended.rb +52 -0
  54. data/lib/gorillib/utils/capture_output.rb +28 -0
  55. data/lib/gorillib/utils/console.rb +131 -0
  56. data/lib/gorillib/utils/nuke_constants.rb +9 -0
  57. data/lib/gorillib/utils/stub_module.rb +33 -0
  58. data/spec/examples/builder/ironfan_spec.rb +37 -0
  59. data/spec/extlib/hash_spec.rb +64 -0
  60. data/spec/extlib/mash_spec.rb +312 -0
  61. data/spec/{array → gorillib/array}/compact_blank_spec.rb +2 -2
  62. data/spec/{array → gorillib/array}/extract_options_spec.rb +2 -2
  63. data/spec/gorillib/builder_spec.rb +187 -0
  64. data/spec/gorillib/collection_spec.rb +20 -0
  65. data/spec/gorillib/configurable_spec.rb +62 -0
  66. data/spec/{datetime → gorillib/datetime}/parse_spec.rb +3 -3
  67. data/spec/{datetime/flat_spec.rb → gorillib/datetime/to_flat_spec.rb} +4 -4
  68. data/spec/{enumerable → gorillib/enumerable}/sum_spec.rb +5 -5
  69. data/spec/gorillib/exception/raisers_spec.rb +60 -0
  70. data/spec/{hash → gorillib/hash}/compact_spec.rb +2 -2
  71. data/spec/{hash → gorillib/hash}/deep_compact_spec.rb +3 -3
  72. data/spec/{hash → gorillib/hash}/deep_merge_spec.rb +2 -2
  73. data/spec/{hash → gorillib/hash}/keys_spec.rb +2 -2
  74. data/spec/{hash → gorillib/hash}/reverse_merge_spec.rb +2 -2
  75. data/spec/{hash → gorillib/hash}/slice_spec.rb +2 -2
  76. data/spec/{hash → gorillib/hash}/zip_spec.rb +2 -2
  77. data/spec/{hashlike → gorillib/hashlike}/behave_same_as_hash_spec.rb +6 -3
  78. data/spec/{hashlike → gorillib/hashlike}/deep_hash_spec.rb +2 -2
  79. data/spec/{hashlike → gorillib/hashlike}/hashlike_behavior_spec.rb +32 -30
  80. data/spec/{hashlike → gorillib/hashlike}/hashlike_via_accessors_spec.rb +3 -3
  81. data/spec/{hashlike_spec.rb → gorillib/hashlike_spec.rb} +3 -3
  82. data/spec/{logger → gorillib/logger}/log_spec.rb +2 -2
  83. data/spec/{metaprogramming → gorillib/metaprogramming}/aliasing_spec.rb +3 -3
  84. data/spec/{metaprogramming → gorillib/metaprogramming}/class_attribute_spec.rb +3 -3
  85. data/spec/{metaprogramming → gorillib/metaprogramming}/delegation_spec.rb +3 -3
  86. data/spec/{metaprogramming → gorillib/metaprogramming}/singleton_class_spec.rb +3 -3
  87. data/spec/gorillib/model/record/defaults_spec.rb +108 -0
  88. data/spec/gorillib/model/record/factories_spec.rb +321 -0
  89. data/spec/gorillib/model/record/overlay_spec.rb +46 -0
  90. data/spec/gorillib/model/serialization_spec.rb +48 -0
  91. data/spec/gorillib/model_spec.rb +281 -0
  92. data/spec/{numeric → gorillib/numeric}/clamp_spec.rb +2 -2
  93. data/spec/{object → gorillib/object}/blank_spec.rb +2 -2
  94. data/spec/{object → gorillib/object}/try_dup_spec.rb +2 -2
  95. data/spec/{object → gorillib/object}/try_spec.rb +3 -2
  96. data/spec/gorillib/pathname_spec.rb +114 -0
  97. data/spec/{string → gorillib/string}/constantize_spec.rb +2 -2
  98. data/spec/{string → gorillib/string}/human_spec.rb +2 -2
  99. data/spec/{string → gorillib/string}/inflections_spec.rb +4 -3
  100. data/spec/{string → gorillib/string}/inflector_test_cases.rb +0 -0
  101. data/spec/{string → gorillib/string}/truncate_spec.rb +4 -10
  102. data/spec/gorillib/type/extended_spec.rb +120 -0
  103. data/spec/gorillib/utils/capture_output_spec.rb +71 -0
  104. data/spec/spec_helper.rb +8 -11
  105. data/spec/support/gorillib_test_helpers.rb +66 -0
  106. data/spec/support/hashlike_fuzzing_helper.rb +31 -33
  107. data/spec/support/hashlike_helper.rb +3 -3
  108. data/spec/support/model_test_helpers.rb +81 -0
  109. data/spec/support/shared_examples/included_module.rb +20 -0
  110. metadata +177 -158
  111. data/lib/gorillib/array/average.rb +0 -13
  112. data/lib/gorillib/array/sorted_median.rb +0 -11
  113. data/lib/gorillib/array/sorted_percentile.rb +0 -11
  114. data/lib/gorillib/array/sorted_sample.rb +0 -12
  115. data/lib/gorillib/dsl_object.rb +0 -64
  116. data/lib/gorillib/hash/indifferent_access.rb +0 -207
  117. data/lib/gorillib/hash/tree_merge.rb +0 -4
  118. data/lib/gorillib/hashlike/tree_merge.rb +0 -49
  119. data/lib/gorillib/metaprogramming/cattr_accessor.rb +0 -79
  120. data/lib/gorillib/metaprogramming/mattr_accessor.rb +0 -61
  121. data/lib/gorillib/receiver/active_model_shim.rb +0 -32
  122. data/lib/gorillib/receiver/acts_as_hash.rb +0 -195
  123. data/lib/gorillib/receiver/acts_as_loadable.rb +0 -42
  124. data/lib/gorillib/receiver/locale/en.yml +0 -27
  125. data/lib/gorillib/receiver/tree_diff.rb +0 -74
  126. data/lib/gorillib/receiver/validations.rb +0 -30
  127. data/lib/gorillib/receiver.rb +0 -402
  128. data/lib/gorillib/receiver_model.rb +0 -21
  129. data/lib/gorillib/struct/acts_as_hash.rb +0 -108
  130. data/notes/fancy_hashes_and_receivers.textile +0 -120
  131. data/notes/hash_rdocs.textile +0 -97
  132. data/spec/array/average_spec.rb +0 -24
  133. data/spec/array/sorted_median_spec.rb +0 -18
  134. data/spec/array/sorted_percentile_spec.rb +0 -24
  135. data/spec/array/sorted_sample_spec.rb +0 -28
  136. data/spec/dsl_object_spec.rb +0 -99
  137. data/spec/hash/indifferent_access_spec.rb +0 -391
  138. data/spec/metaprogramming/cattr_accessor_spec.rb +0 -43
  139. data/spec/metaprogramming/mattr_accessor_spec.rb +0 -45
  140. data/spec/receiver/acts_as_hash_spec.rb +0 -295
  141. data/spec/receiver_spec.rb +0 -551
  142. data/spec/struct/acts_as_hash_fuzz_spec.rb +0 -71
  143. data/spec/struct/acts_as_hash_spec.rb +0 -422
@@ -0,0 +1,267 @@
1
+ module Gorillib ; end
2
+
3
+ # String inflections define new methods on the String class to transform names for different purposes.
4
+ #
5
+ # "ScaleScore".underscore # => "scale_score"
6
+ #
7
+ # This doesn't define the full set of inflections -- only
8
+ #
9
+ # * camelize
10
+ # * snakeize
11
+ # * underscore
12
+ # * demodulize
13
+ #
14
+ module Gorillib::Inflector
15
+ extend self
16
+
17
+ def self.pluralizations
18
+ @pluralizations ||= {}
19
+ end
20
+
21
+ def pluralize(str)
22
+ Gorillib::Inflector.pluralizations.fetch(str){ "#{str}s" }
23
+ end
24
+
25
+ # The reverse of +pluralize+, returns the singular form of a word in a string.
26
+ #
27
+ # Examples:
28
+ # "posts".singularize # => "post"
29
+ # # it's not very smart
30
+ # "octopi".singularize # => "octopi"
31
+ # "bonus".singularize # => "bonu"
32
+ # "boxes".singularize # => "boxe"
33
+ # "CamelOctopi".singularize # => "CamelOctopi"
34
+ def singularize(str)
35
+ Gorillib::Inflector.pluralizations.invert.fetch(str){ str.gsub(/s$/, '') }
36
+ end
37
+
38
+ # Capitalizes the first word and turns underscores into spaces and strips a
39
+ # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
40
+ #
41
+ # Examples:
42
+ # "employee_salary" # => "Employee salary"
43
+ # "author_id" # => "Author"
44
+ def humanize(lower_case_and_underscored_word)
45
+ result = lower_case_and_underscored_word.to_s.dup
46
+ result.gsub!(/_id$/, "")
47
+ result.gsub(/(_)?([a-z\d]*)/i){ "#{ $1 && ' ' }#{ $2.downcase}" }.gsub(/^\w/){ $&.upcase }
48
+ end
49
+
50
+ # Capitalizes all the words and replaces some characters in the string to create
51
+ # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
52
+ # used in the Rails internals.
53
+ #
54
+ # +titleize+ is also aliased as as +titlecase+.
55
+ #
56
+ # Examples:
57
+ # "man from the boondocks".titleize # => "Man From The Boondocks"
58
+ # "x-men: the last stand".titleize # => "X Men: The Last Stand"
59
+ # "TheManWithoutAPast".titleize # => "The Man Without A Past"
60
+ # "raiders_of_the_lost_ark".titleize # => "Raiders Of The Lost Ark"
61
+ def titleize(word)
62
+ humanize(underscore(word)).gsub(/\b('?[a-z])/){ $1.capitalize }
63
+ end
64
+
65
+ # Create the name of a table like Rails does for models to table names. This method
66
+ # uses the +pluralize+ method on the last word in the string.
67
+ #
68
+ # Examples
69
+ # "RawScaledScorer".tableize # => "raw_scaled_scorers"
70
+ # "egg_and_ham".tableize # => "egg_and_hams"
71
+ # "fancyCategory".tableize # => "fancy_categories"
72
+ def tableize(class_name)
73
+ pluralize(underscore(class_name))
74
+ end
75
+
76
+ # Create a class name from a plural table name like Rails does for table names to models.
77
+ # Note that this returns a string and not a Class. (To convert to an actual class
78
+ # follow +classify+ with +constantize+.)
79
+ #
80
+ # Examples:
81
+ # "egg_and_hams".classify # => "EggAndHam"
82
+ # "posts".classify # => "Post"
83
+ #
84
+ # Singular names are not handled correctly:
85
+ # "business".classify # => "Busines"
86
+ def classify(table_name)
87
+ # strip out any leading schema name
88
+ camelize(singularize(table_name.to_s.sub(/.*\./, '')))
89
+ end
90
+
91
+ private
92
+
93
+ # def uncountable_words #:doc
94
+ # %w( equipment information rice money species series fish )
95
+ # end
96
+ #
97
+ # def plural_rules #:doc:
98
+ # [
99
+ # [/(x|ch|ss|sh)$/i, '\1es'], # search, switch, fix, box, process, address
100
+ # [/([^aeiouy]|qu)y$/i, '\1ies'], # query, ability, agency
101
+ # [/(p)erson$/i, '\1eople'], # person, salesperson
102
+ # [/(m)an$/i, '\1en'], # man, woman, spokesman
103
+ # [/(c)hild$/i, '\1hildren'], # child
104
+ # [/s$/i, 's'], # no change (compatibility)
105
+ # [/$/, 's']
106
+ # ]
107
+ # end
108
+ #
109
+ # def singular_rules
110
+ # [
111
+ # [/(x|ch|ss|sh)es$/i, '\1'],
112
+ # [/([^aeiouy]|qu)ies$/i, '\1y'],
113
+ # [/(p)eople$/i, '\1\2erson'],
114
+ # [/(m)en$/i, '\1an'],
115
+ # [/(c)hildren$/i, '\1\2hild'],
116
+ # [/s$/i, '']
117
+ # ]
118
+ # end
119
+
120
+ # %w[
121
+ # equipment equipment
122
+ # information information
123
+ # rice rice
124
+ # money money
125
+ # species species
126
+ # series series
127
+ # fish fish
128
+ # ]
129
+
130
+ # def uncountable_words #:doc
131
+ # %w( equipment information rice money species series fish )
132
+ # end
133
+ #
134
+ # def plural_rules #:doc:
135
+ # [
136
+ # [/^(ox)$/i, '\1\2en'], # ox
137
+ # [/([m|l])ouse$/i, '\1ice'], # mouse, louse
138
+ # [/(matr|vert|ind)ix|ex$/i, '\1ices'], # matrix, vertex, index
139
+ # [/(x|ch|ss|sh)$/i, '\1es'], # search, switch, fix, box, process, address
140
+ # [/([^aeiouy]|qu)ies$/i, '\1y'],
141
+ # [/([^aeiouy]|qu)y$/i, '\1ies'], # query, ability, agency
142
+ # [/(hive)$/i, '\1s'], # archive, hive
143
+ # [/(?:([^f])fe|([lr])f)$/i, '\1\2ves'], # half, safe, wife
144
+ # [/sis$/i, 'ses'], # basis, diagnosis
145
+ # [/([ti])um$/i, '\1a'], # datum, medium
146
+ # [/(p)erson$/i, '\1eople'], # person, salesperson
147
+ # [/(m)an$/i, '\1en'], # man, woman, spokesman
148
+ # [/(c)hild$/i, '\1hildren'], # child
149
+ # [/(buffal|tomat)o$/i, '\1\2oes'], # buffalo, tomato
150
+ # [/(bu)s$/i, '\1\2ses'], # bus
151
+ # [/(alias)/i, '\1es'], # alias
152
+ # [/(octop|vir)us$/i, '\1i'], # octopus, virus - virus has no defined plural (according to Latin/dictionary.com), but viri is better than viruses/viruss
153
+ # [/(ax|cri|test)is$/i, '\1es'], # axis, crisis
154
+ # [/s$/i, 's'], # no change (compatibility)
155
+ # [/$/, 's']
156
+ # ]
157
+ # end
158
+ #
159
+ # def singular_rules
160
+ # [
161
+ # [/(matr)ices$/i, '\1ix'],
162
+ # [/(vert|ind)ices$/i, '\1ex'],
163
+ # [/^(ox)en/i, '\1'],
164
+ # [/(alias)es$/i, '\1'],
165
+ # [/([octop|vir])i$/i, '\1us'],
166
+ # [/(cris|ax|test)es$/i, '\1is'],
167
+ # [/(shoe)s$/i, '\1'],
168
+ # [/(o)es$/i, '\1'],
169
+ # [/(bus)es$/i, '\1'],
170
+ # [/([m|l])ice$/i, '\1ouse'],
171
+ # [/(x|ch|ss|sh)es$/i, '\1'],
172
+ # [/(m)ovies$/i, '\1\2ovie'],
173
+ # [/(s)eries$/i, '\1\2eries'],
174
+ # [/([^aeiouy]|qu)ies$/i, '\1y'],
175
+ # [/([lr])ves$/i, '\1f'],
176
+ # [/(tive)s$/i, '\1'],
177
+ # [/(hive)s$/i, '\1'],
178
+ # [/([^f])ves$/i, '\1fe'],
179
+ # [/([ti])a$/i, '\1um'],
180
+ # [/(p)eople$/i, '\1\2erson'],
181
+ # [/(m)en$/i, '\1an'],
182
+ # [/(s)tatus$/i, '\1\2tatus'],
183
+ # [/(c)hildren$/i, '\1\2hild'],
184
+ # [/(n)ews$/i, '\1\2ews'],
185
+ # [/s$/i, '']
186
+ # ]
187
+ # end
188
+
189
+ # inflect.plural(/$/, 's')
190
+ # inflect.plural(/s$/i, 's')
191
+ # inflect.plural(/^(ax|test)is$/i, '\1es')
192
+ # inflect.plural(/(octop|vir)us$/i, '\1i')
193
+ # inflect.plural(/(octop|vir)i$/i, '\1i')
194
+ # inflect.plural(/(alias|status)$/i, '\1es')
195
+ # inflect.plural(/(bu)s$/i, '\1ses')
196
+ # inflect.plural(/(buffal|tomat)o$/i, '\1oes')
197
+ # inflect.plural(/([ti])um$/i, '\1a')
198
+ # inflect.plural(/([ti])a$/i, '\1a')
199
+ # inflect.plural(/sis$/i, 'ses')
200
+ # inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
201
+ # inflect.plural(/(hive)$/i, '\1s')
202
+ # inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
203
+ # inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
204
+ # inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices')
205
+ # inflect.plural(/(m|l)ouse$/i, '\1ice')
206
+ # inflect.plural(/(m|l)ice$/i, '\1ice')
207
+ # inflect.plural(/^(ox)$/i, '\1en')
208
+ # inflect.plural(/^(oxen)$/i, '\1')
209
+ # inflect.plural(/(quiz)$/i, '\1zes')
210
+
211
+ # inflect.singular(/s$/i, '')
212
+ # inflect.singular(/(ss)$/i, '\1')
213
+ # inflect.singular(/(n)ews$/i, '\1ews')
214
+ # inflect.singular(/([ti])a$/i, '\1um')
215
+ # inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1\2sis')
216
+ # inflect.singular(/(^analy)(sis|ses)$/i, '\1sis')
217
+ # inflect.singular(/([^f])ves$/i, '\1fe')
218
+ # inflect.singular(/(hive)s$/i, '\1')
219
+ # inflect.singular(/(tive)s$/i, '\1')
220
+ # inflect.singular(/([lr])ves$/i, '\1f')
221
+ # inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
222
+ # inflect.singular(/(s)eries$/i, '\1eries')
223
+ # inflect.singular(/(m)ovies$/i, '\1ovie')
224
+ # inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
225
+ # inflect.singular(/(m|l)ice$/i, '\1ouse')
226
+ # inflect.singular(/(bus)(es)?$/i, '\1')
227
+ # inflect.singular(/(o)es$/i, '\1')
228
+ # inflect.singular(/(shoe)s$/i, '\1')
229
+ # inflect.singular(/(cris|test)(is|es)$/i, '\1is')
230
+ # inflect.singular(/^(a)x[ie]s$/i, '\1xis')
231
+ # inflect.singular(/(octop|vir)(us|i)$/i, '\1us')
232
+ # inflect.singular(/(alias|status)(es)?$/i, '\1')
233
+ # inflect.singular(/^(ox)en/i, '\1')
234
+ # inflect.singular(/(vert|ind)ices$/i, '\1ex')
235
+ # inflect.singular(/(matr)ices$/i, '\1ix')
236
+ # inflect.singular(/(quiz)zes$/i, '\1')
237
+ # inflect.singular(/(database)s$/i, '\1')
238
+ #
239
+ # inflect.irregular('person', 'people')
240
+ # inflect.irregular('man', 'men')
241
+ # inflect.irregular('child', 'children')
242
+ # inflect.irregular('sex', 'sexes')
243
+ # inflect.irregular('move', 'moves')
244
+ # inflect.irregular('cow', 'kine')
245
+ # inflect.irregular('zombie', 'zombies')
246
+ #
247
+ # inflect.uncountable(%w(equipment information rice money species series fish sheep jeans))
248
+
249
+ public
250
+
251
+ # def pluralize(word)
252
+ # result = word.dup
253
+ # plural_rules.each do |(rule, replacement)|
254
+ # break if result.gsub!(rule, replacement)
255
+ # end
256
+ # return result
257
+ # end
258
+ #
259
+ # def singularize(word)
260
+ # result = word.dup
261
+ # singular_rules.each do |(rule, replacement)|
262
+ # break if result.gsub!(rule, replacement)
263
+ # end
264
+ # return result
265
+ # end
266
+
267
+ end
@@ -0,0 +1,52 @@
1
+ require 'pathname'
2
+ require 'time'
3
+
4
+ class ::Long < ::Integer ; end
5
+ class ::Double < ::Float ; end
6
+ class ::Binary < ::String ; end
7
+
8
+ class ::Guid < ::String ; end
9
+ class ::IpAddress < ::String ; end
10
+ class ::Hostname < ::String ; end
11
+
12
+ class ::Url < ::String ; end
13
+
14
+ # require 'gorillib/metaprogramming/delegation'
15
+ #
16
+ # class ::Boolean < ::Object
17
+ # attr_accessor :val
18
+ # def initialize(val=nil)
19
+ # self.val = val
20
+ # end
21
+ #
22
+ # delegate :!, :to_s, :blank?, :frozen?, :nil?, :present?, :to => :val
23
+ # delegate :!=, :&, :<=>, :=~, :^, :|, :to => :val
24
+ #
25
+ # def inspect()
26
+ # "<Boolean #{val.inspect}>"
27
+ # end
28
+ # def try_dup()
29
+ # ::Boolean.new(val)
30
+ # end
31
+ #
32
+ # def self.true ; self.new(true) ; end
33
+ # def self.false ; self.new(false) ; end
34
+ #
35
+ # def is_a?(klass) val.is_a?(klass) || super ; end
36
+ # def kind_of?(klass) val.kind_of?(klass) || super ; end
37
+ # def instance_of?(klass) val.instance_of?(klass) || super ; end
38
+ #
39
+ # def !=(other_val) other_val = other_val.val if other_val.is_a?(::Boolean) ; (val != other_val) ; end
40
+ # def ==(other_val) other_val = other_val.val if other_val.is_a?(::Boolean) ; (val == other_val) ; end
41
+ # def ===(other_val) other_val = other_val.val if other_val.is_a?(::Boolean) ; (val === other_val) ; end
42
+ # def <=>(other_val) other_val = other_val.val if other_val.is_a?(::Boolean) ; (val <=> other_val) ; end
43
+ # def eql?(other_val) other_val = other_val.val if other_val.is_a?(::Boolean) ; (val.eql? other_val) ; end
44
+ # def equal?(other_val) other_val = other_val.val if other_val.is_a?(::Boolean) ; (val.equal? other_val) ; end
45
+ #
46
+ # end
47
+
48
+ # Datamapper also defines:
49
+ #
50
+ # Apikey BCryptHash Decimal URI UUID Slug CommaSeparatedList Csv IpAddress Json Yaml Enum Flag Discriminator
51
+ #
52
+ # maybe someday we will too...
@@ -0,0 +1,28 @@
1
+ module Gorillib
2
+ module TestHelpers
3
+ module_function
4
+
5
+ def dummy_stdio(stdin_text=nil)
6
+ stdin = stdin_text.nil? ? $stdin : StringIO.new(stdin_text)
7
+ new_fhs = [stdin, StringIO.new('', 'w'), StringIO.new('', 'w')]
8
+ old_fhs = [$stdin, $stdout, $stderr]
9
+ begin
10
+ $stdin, $stdout, $stderr = new_fhs
11
+ yield
12
+ ensure
13
+ $stdin, $stdout, $stderr = old_fhs
14
+ end
15
+ new_fhs[1..2]
16
+ end
17
+
18
+ #
19
+ # Temporarily sets the global variables $stderr and $stdout to a capturable StringIO;
20
+ # restores them at the end, even if there is an error
21
+ #
22
+ def capture_output
23
+ dummy_stdio{ yield }
24
+ end
25
+
26
+ alias_method :quiet_output, :capture_output
27
+ end
28
+ end
@@ -0,0 +1,131 @@
1
+ #
2
+ # An inspecting delegator.
3
+ #
4
+ # Create a trap passing in any object of your choice.
5
+ #
6
+ # Any time a method is called on the trap, it prints the method name, all its
7
+ # args, and the direct caller.
8
+ #
9
+ # @example Did you know how basic operators work? Now you do!
10
+ #
11
+ # trapped_int = ItsATrap.new(3)
12
+ #
13
+ # trapped_int - 55
14
+ # [:-, [55], nil, "..."]
15
+ # => -52
16
+ #
17
+ # 55 - trapped_int
18
+ # [:coerce, [55], nil, "..."]
19
+ # => 52
20
+ #
21
+ # - trapped_int
22
+ # [:-@, [], nil, "..."]
23
+ # => -3
24
+ #
25
+ class ItsATrap < BasicObject
26
+ def initialize(obj=::Object.new, show_ret=false)
27
+ @obj = obj
28
+ @call_count = 0
29
+ @show_ret = show_ret
30
+ end
31
+
32
+ # We implement to_s and inspect, because otherwise it's annoyingly noisy. :pretty_inspect makes pry happy.
33
+
34
+ def inspect() "~#{@obj.inspect}~" ; end
35
+ def to_s() @obj.to_s ; end
36
+ alias_method :pretty_inspect, :inspect
37
+ def methods() @obj.methods ; end
38
+
39
+ # These are defined on BasicObject, delegate them along with the rest
40
+ # BasicObject.instance_methods
41
+ # => [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]
42
+
43
+ def ==( *args, &block) ; __describe_and_send__(:==, *args, &block) ; end
44
+ def equal?(*args, &block) ; __describe_and_send__(:equal?, *args, &block) ; end
45
+ def !@( *args, &block) ; __describe_and_send__(:!, *args, &block) ; end
46
+ def !=( *args, &block) ; __describe_and_send__(:!=, *args, &block) ; end
47
+ def instance_eval(*args, &block) ; __describe_and_send__(:instance_eval, *args, &block) ; end
48
+ def instance_exec(*args, &block) ; __describe_and_send__(:instance_exec, *args, &block) ; end
49
+
50
+ private
51
+
52
+ #
53
+ # Any time a method is called on the trap, it prints the method name, all its
54
+ # args, and the direct caller.
55
+ #
56
+ def method_missing(meth, *args, &block)
57
+ __describe_and_send__(meth, *args, &block)
58
+ end
59
+
60
+ def __describe_and_send__(meth, *args, &block)
61
+ pref = "%-3d %-14s %-15s" % [@call_count, __id__, self.to_s[0..14]]
62
+ @call_count += 1
63
+ $stderr.puts "%s %-15s <- %-30s %s -- %s" % [pref, meth.to_s[0..14], args.map(&:inspect).join(','), block, ::Kernel.caller.first]
64
+ ret = @obj.__send__(meth, *args, &block)
65
+ $stderr.puts "%s %-15s -> %s" % [pref, meth.to_s[0..14], ret.inspect] if @show_ret
66
+ ret
67
+ end
68
+ end
69
+
70
+ module Test
71
+ module_function
72
+
73
+ def create_class(name, *args, &block)
74
+ Object.class_eval do
75
+ remove_const(name) if self.const_defined?(name)
76
+ const_set(name, Class.new(*args, &block))
77
+ end
78
+ end
79
+
80
+ def example_singleton(name, *args)
81
+ require 'singleton'
82
+ create_class(name, *args){ include ::Singleton }
83
+ end
84
+
85
+ end
86
+
87
+ class Module
88
+
89
+ #
90
+ # Lists the differences in methods between two modules/classes
91
+ #
92
+ # Breaks them down by providing module, and shows class and instance methods.
93
+ # @param other [Module] other class or module to compare with
94
+ # @param show_common [true,false] true to show methods they have in common; false by default
95
+ #
96
+ # @example Range has several extra instance methods; the Foo class and its instances have methods via the Happy module
97
+ # module Happy ; def hello() 3 ; end ; end
98
+ # class Foo ; include Enumerable ; include Happy ; extend Happy ; end
99
+ # { "Foo#" => { Happy => [:hello] },
100
+ # "Foo." => { Happy => [:hello] },
101
+ # "Range#" => { Range => [:each, :step, :begin, :end, :last, :exclude_end?, :cover?]} }
102
+ #
103
+ def compare_methods(other=Object, show_common=false)
104
+ result = Hash.new{|h,k| h[k] = Hash.new{|hh,hk| hh[hk] = [] } }
105
+
106
+ inst_ancestors_both = ancestors & other.ancestors
107
+ klass_ancestors_both = singleton_class.ancestors & other.singleton_class.ancestors
108
+
109
+ inst_meths = (self.instance_methods | other.instance_methods)
110
+ klass_meths = (self.methods | other.methods)
111
+
112
+ [ [:both, inst_ancestors_both, klass_ancestors_both],
113
+ [self, (self.ancestors - inst_ancestors_both), (self.singleton_class.ancestors - klass_ancestors_both)],
114
+ [other, (other.ancestors - inst_ancestors_both), (other.singleton_class.ancestors - klass_ancestors_both)],
115
+ ].each do |mod, inst_anc, klass_anc|
116
+ inst_anc.reverse.each do |ancestor|
117
+ result["#{mod}#"][ancestor] = inst_meths & ancestor.instance_methods
118
+ inst_meths -= ancestor.instance_methods
119
+ end
120
+ klass_anc.reverse.each do |ancestor|
121
+ result["#{mod}."][ancestor] = klass_meths & ancestor.instance_methods
122
+ klass_meths -= ancestor.instance_methods
123
+ end
124
+ end
125
+ unless show_common then result.delete("both#") ; result.delete("both.") ; end
126
+ result.each{|type,hsh| hsh.reject!{|k,v| v.empty? } }
127
+ result.reject!{|type,hsh| hsh.empty? }
128
+ result
129
+ end
130
+
131
+ end
@@ -0,0 +1,9 @@
1
+ class Module
2
+ #
3
+ # Removes all constants in the module's namespace -- this is useful when
4
+ # writing specs for metaprogramming methods
5
+ #
6
+ def nuke_constants
7
+ constants.each{|const| remove_const(const) }
8
+ end
9
+ end
@@ -0,0 +1,33 @@
1
+ # spec/spec_helper_lite.rb
2
+
3
+ # Conditionally creates empty or "stub" modules only if
4
+ # a) they are not already defined; and
5
+ # b) they are not auto-loadable.
6
+ #
7
+ # From http://objectsonrails.com/#sec-7-1
8
+ #
9
+ # @example Faking out ActiveModel
10
+ # # ...
11
+ # require_relative '../spec_helper_lite'
12
+ # stub_module 'ActiveModel::Conversion'
13
+ # stub_module 'ActiveModel::Naming'
14
+ # require_relative '../../app/models/post'
15
+ # # ...
16
+ #
17
+ def stub_module(full_name)
18
+ # Uses #const_get to attempt to reference the given module. If the module is
19
+ # defined, or if calling #const_get causes it to be auto-loaded, the method
20
+ # does nothing more. But if #const_get fails to turn up the module, it defines
21
+ # an anonymous empty module to act as a placeholder.
22
+ full_name.to_s.split(/::/).inject(Object) do |context, name|
23
+ begin
24
+ context.const_get(name)
25
+ rescue NameError
26
+ context.const_set(name, Module.new)
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ # refute
33
+ # does_not_allow
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ # related libs
3
+ require 'gorillib/model'
4
+ require 'gorillib/model/field'
5
+ require 'gorillib/model/defaults'
6
+ # libs under test
7
+ require 'gorillib/builder'
8
+ require 'gorillib/builder/field'
9
+ require 'gorillib/string/simple_inflector'
10
+ # testing helpers
11
+
12
+ load GORILLIB_ROOT_DIR('examples/builder/ironfan.rb')
13
+
14
+ module Gorillib::Test ; end
15
+ module Meta::Gorillib::Test ; end
16
+
17
+ describe Gorillib::Builder, :model_spec => true do
18
+ after(:each){ Gorillib::Test.nuke_constants ; Meta::Gorillib::Test.nuke_constants }
19
+ def example_cluster
20
+ Gorillib::Test.cluster
21
+ end
22
+
23
+ let(:ec_webnode ){ fac = example_cluster.facet(:webnode); fac.cluster(example_cluster) ; fac }
24
+ let(:ec_webnode_a){ svr = ec_webnode.server(:a); svr.facet(ec_webnode) ; svr }
25
+
26
+ # it 'is awesome'
27
+
28
+ context "collections get a {foo}_name accessor:" do
29
+ it("facet.cluster_name"){ ec_webnode.cluster_name.should == :yellowhat }
30
+ it("server.facet_name" ){ ec_webnode_a.facet_name.should == :webnode }
31
+ end
32
+
33
+ context "collections get a `has_{foo}` tester:" do
34
+ it("server.facet?" ){ ec_webnode_a.facet?.should be_true }
35
+ it("facet.has_server?"){ ec_webnode.should have_server(:a) }
36
+ end
37
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'gorillib/hash/slice'
3
+
4
+ describe Hash, "only" do
5
+ before do
6
+ @hash = { :one => 'ONE', 'two' => 'TWO', 3 => 'THREE', 4 => nil }
7
+ end
8
+
9
+ it "should return a hash with only the given key(s)" do
10
+ @hash.only(:not_in_there).should == {}
11
+ @hash.only(4).should == {4 => nil}
12
+ @hash.only(:one).should == { :one => 'ONE' }
13
+ @hash.only(:one, 3).should == { :one => 'ONE', 3 => 'THREE' }
14
+ end
15
+ end
16
+
17
+
18
+ describe Hash, "except" do
19
+ before do
20
+ @hash = { :one => 'ONE', 'two' => 'TWO', 3 => 'THREE' }
21
+ end
22
+
23
+ it "should return a hash without only the given key(s)" do
24
+ @hash.except(:one).should == { 'two' => 'TWO', 3 => 'THREE' }
25
+ @hash.except(:one, 3).should == { 'two' => 'TWO' }
26
+ end
27
+ end
28
+
29
+ # describe Hash, 'to_params' do
30
+ # {
31
+ # { "foo" => "bar", "baz" => "bat" } => "foo=bar&baz=bat",
32
+ # { "foo" => [ "bar", "baz" ] } => "foo%5B%5D=bar&foo%5B%5D=baz",
33
+ # { "foo" => [ {"bar" => "1"}, {"bar" => 2} ] } => "foo%5B%5D%5Bbar%5D=1&foo%5B%5D%5Bbar%5D=2",
34
+ # { "foo" => { "bar" => [ {"baz" => 1}, {"baz" => "2"} ] } } => "foo%5Bbar%5D%5B%5D%5Bbaz%5D=1&foo%5Bbar%5D%5B%5D%5Bbaz%5D=2",
35
+ # { "foo" => {"1" => "bar", "2" => "baz"} } => "foo%5B1%5D=bar&foo%5B2%5D=baz"
36
+ # }.each do |hash, params|
37
+ # it "should covert hash: #{hash.inspect} to params: #{params.inspect}" do
38
+ # hash.to_params.split('&').sort.should == params.split('&').sort
39
+ # end
40
+ # end
41
+ #
42
+ # it 'should not leave a trailing &' do
43
+ # { :name => 'Bob', :address => { :street => '111 Ruby Ave.', :city => 'Ruby Central', :phones => ['111-111-1111', '222-222-2222'] } }.to_params.should_not match(/&$/)
44
+ # end
45
+ #
46
+ # it 'should encode query keys' do
47
+ # { 'First & Last' => 'Alice Smith' }.to_params.should == "First%20%26%20Last=Alice%20Smith"
48
+ # end
49
+ #
50
+ # it 'should encode query values' do
51
+ # { :name => 'Alice & Bob' }.to_params.should == "name=Alice%20%26%20Bob"
52
+ # end
53
+ # end
54
+ #
55
+ # describe Hash, 'to_mash' do
56
+ # before :each do
57
+ # @hash = Hash.new(10)
58
+ # end
59
+ #
60
+ # it "copies default Hash value to Mash" do
61
+ # @mash = @hash.to_mash
62
+ # @mash[:merb].should == 10
63
+ # end
64
+ # end