mongomodel 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +34 -0
  3. data/Rakefile +47 -0
  4. data/bin/console +45 -0
  5. data/lib/mongomodel.rb +92 -0
  6. data/lib/mongomodel/attributes/mongo.rb +40 -0
  7. data/lib/mongomodel/attributes/store.rb +30 -0
  8. data/lib/mongomodel/attributes/typecasting.rb +51 -0
  9. data/lib/mongomodel/concerns/abstract_class.rb +17 -0
  10. data/lib/mongomodel/concerns/activemodel.rb +11 -0
  11. data/lib/mongomodel/concerns/associations.rb +103 -0
  12. data/lib/mongomodel/concerns/associations/base/association.rb +33 -0
  13. data/lib/mongomodel/concerns/associations/base/definition.rb +56 -0
  14. data/lib/mongomodel/concerns/associations/base/proxy.rb +58 -0
  15. data/lib/mongomodel/concerns/associations/belongs_to.rb +68 -0
  16. data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +159 -0
  17. data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +175 -0
  18. data/lib/mongomodel/concerns/attribute_methods.rb +55 -0
  19. data/lib/mongomodel/concerns/attribute_methods/before_type_cast.rb +29 -0
  20. data/lib/mongomodel/concerns/attribute_methods/dirty.rb +35 -0
  21. data/lib/mongomodel/concerns/attribute_methods/protected.rb +127 -0
  22. data/lib/mongomodel/concerns/attribute_methods/query.rb +22 -0
  23. data/lib/mongomodel/concerns/attribute_methods/read.rb +29 -0
  24. data/lib/mongomodel/concerns/attribute_methods/write.rb +29 -0
  25. data/lib/mongomodel/concerns/attributes.rb +85 -0
  26. data/lib/mongomodel/concerns/callbacks.rb +294 -0
  27. data/lib/mongomodel/concerns/logging.rb +15 -0
  28. data/lib/mongomodel/concerns/pretty_inspect.rb +29 -0
  29. data/lib/mongomodel/concerns/properties.rb +69 -0
  30. data/lib/mongomodel/concerns/record_status.rb +42 -0
  31. data/lib/mongomodel/concerns/timestamps.rb +32 -0
  32. data/lib/mongomodel/concerns/validations.rb +38 -0
  33. data/lib/mongomodel/concerns/validations/associated.rb +46 -0
  34. data/lib/mongomodel/document.rb +20 -0
  35. data/lib/mongomodel/document/callbacks.rb +46 -0
  36. data/lib/mongomodel/document/dynamic_finders.rb +88 -0
  37. data/lib/mongomodel/document/finders.rb +82 -0
  38. data/lib/mongomodel/document/indexes.rb +91 -0
  39. data/lib/mongomodel/document/optimistic_locking.rb +48 -0
  40. data/lib/mongomodel/document/persistence.rb +143 -0
  41. data/lib/mongomodel/document/scopes.rb +161 -0
  42. data/lib/mongomodel/document/validations.rb +68 -0
  43. data/lib/mongomodel/document/validations/uniqueness.rb +78 -0
  44. data/lib/mongomodel/embedded_document.rb +42 -0
  45. data/lib/mongomodel/locale/en.yml +55 -0
  46. data/lib/mongomodel/support/collection.rb +109 -0
  47. data/lib/mongomodel/support/configuration.rb +35 -0
  48. data/lib/mongomodel/support/core_extensions.rb +10 -0
  49. data/lib/mongomodel/support/exceptions.rb +25 -0
  50. data/lib/mongomodel/support/mongo_options.rb +177 -0
  51. data/lib/mongomodel/support/types.rb +35 -0
  52. data/lib/mongomodel/support/types/array.rb +11 -0
  53. data/lib/mongomodel/support/types/boolean.rb +25 -0
  54. data/lib/mongomodel/support/types/custom.rb +38 -0
  55. data/lib/mongomodel/support/types/date.rb +20 -0
  56. data/lib/mongomodel/support/types/float.rb +13 -0
  57. data/lib/mongomodel/support/types/hash.rb +18 -0
  58. data/lib/mongomodel/support/types/integer.rb +13 -0
  59. data/lib/mongomodel/support/types/object.rb +21 -0
  60. data/lib/mongomodel/support/types/string.rb +9 -0
  61. data/lib/mongomodel/support/types/symbol.rb +9 -0
  62. data/lib/mongomodel/support/types/time.rb +12 -0
  63. data/lib/mongomodel/version.rb +3 -0
  64. data/spec/mongomodel/attributes/store_spec.rb +273 -0
  65. data/spec/mongomodel/concerns/activemodel_spec.rb +61 -0
  66. data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +153 -0
  67. data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +165 -0
  68. data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +192 -0
  69. data/spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb +46 -0
  70. data/spec/mongomodel/concerns/attribute_methods/dirty_spec.rb +131 -0
  71. data/spec/mongomodel/concerns/attribute_methods/protected_spec.rb +86 -0
  72. data/spec/mongomodel/concerns/attribute_methods/query_spec.rb +27 -0
  73. data/spec/mongomodel/concerns/attribute_methods/read_spec.rb +52 -0
  74. data/spec/mongomodel/concerns/attribute_methods/write_spec.rb +43 -0
  75. data/spec/mongomodel/concerns/attributes_spec.rb +152 -0
  76. data/spec/mongomodel/concerns/callbacks_spec.rb +90 -0
  77. data/spec/mongomodel/concerns/logging_spec.rb +20 -0
  78. data/spec/mongomodel/concerns/pretty_inspect_spec.rb +68 -0
  79. data/spec/mongomodel/concerns/properties_spec.rb +29 -0
  80. data/spec/mongomodel/concerns/timestamps_spec.rb +170 -0
  81. data/spec/mongomodel/concerns/validations_spec.rb +159 -0
  82. data/spec/mongomodel/document/callbacks_spec.rb +80 -0
  83. data/spec/mongomodel/document/dynamic_finders_spec.rb +183 -0
  84. data/spec/mongomodel/document/finders_spec.rb +231 -0
  85. data/spec/mongomodel/document/indexes_spec.rb +121 -0
  86. data/spec/mongomodel/document/optimistic_locking_spec.rb +57 -0
  87. data/spec/mongomodel/document/persistence_spec.rb +319 -0
  88. data/spec/mongomodel/document/scopes_spec.rb +204 -0
  89. data/spec/mongomodel/document/validations/uniqueness_spec.rb +217 -0
  90. data/spec/mongomodel/document/validations_spec.rb +132 -0
  91. data/spec/mongomodel/document_spec.rb +74 -0
  92. data/spec/mongomodel/embedded_document_spec.rb +66 -0
  93. data/spec/mongomodel/mongomodel_spec.rb +33 -0
  94. data/spec/mongomodel/support/collection_spec.rb +248 -0
  95. data/spec/mongomodel/support/mongo_options_spec.rb +295 -0
  96. data/spec/mongomodel/support/property_spec.rb +83 -0
  97. data/spec/spec.opts +6 -0
  98. data/spec/spec_helper.rb +21 -0
  99. data/spec/specdoc.opts +6 -0
  100. data/spec/support/callbacks.rb +44 -0
  101. data/spec/support/helpers/define_class.rb +24 -0
  102. data/spec/support/helpers/specs_for.rb +11 -0
  103. data/spec/support/matchers/be_a_subclass_of.rb +5 -0
  104. data/spec/support/matchers/respond_to_boolean.rb +17 -0
  105. data/spec/support/matchers/run_callbacks.rb +20 -0
  106. data/spec/support/models.rb +23 -0
  107. data/spec/support/time.rb +6 -0
  108. metadata +232 -0
@@ -0,0 +1,35 @@
1
+ require 'mongomodel/support/types/object'
2
+ require 'mongomodel/support/types/string'
3
+ require 'mongomodel/support/types/integer'
4
+ require 'mongomodel/support/types/float'
5
+ require 'mongomodel/support/types/boolean'
6
+ require 'mongomodel/support/types/symbol'
7
+ require 'mongomodel/support/types/date'
8
+ require 'mongomodel/support/types/time'
9
+ require 'mongomodel/support/types/custom'
10
+ require 'mongomodel/support/types/array'
11
+ require 'mongomodel/support/types/hash'
12
+
13
+ module MongoModel
14
+ module Types
15
+ CONVERTERS = {
16
+ ::String => Types::String.new,
17
+ ::Integer => Types::Integer.new,
18
+ ::Float => Types::Float.new,
19
+ ::Boolean => Types::Boolean.new,
20
+ ::Symbol => Types::Symbol.new,
21
+ ::Date => Types::Date.new,
22
+ ::Time => Types::Time.new,
23
+ ::Array => Types::Array.new,
24
+ ::Hash => Types::Hash.new
25
+ }
26
+
27
+ def self.converter_for(type)
28
+ if CONVERTERS[type]
29
+ CONVERTERS[type]
30
+ else
31
+ CONVERTERS[type] = Types::Custom.new(type)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ module MongoModel
2
+ module Types
3
+ class Array < Object
4
+ def to_mongo(array)
5
+ array.map { |i|
6
+ Types.converter_for(i.class).to_mongo(i)
7
+ }
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ module MongoModel
2
+ module Types
3
+ class Boolean < Object
4
+ TRUE_VALUES = [ true, 'true', 't', 'TRUE', 'T', 'YES', 'y', '1', 1 ]
5
+ FALSE_VALUES = [ false, 'false', 'f', 'FALSE', 'F', 'NO', 'n', '0', 0 ]
6
+
7
+ def cast(value)
8
+ if true?(value)
9
+ true
10
+ elsif false?(value)
11
+ false
12
+ end
13
+ end
14
+
15
+ private
16
+ def true?(value)
17
+ TRUE_VALUES.include?(value)
18
+ end
19
+
20
+ def false?(value)
21
+ FALSE_VALUES.include?(value)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,38 @@
1
+ require 'active_support/core_ext/hash/indifferent_access'
2
+
3
+ module MongoModel
4
+ module Types
5
+ class Custom < Object
6
+ def initialize(type)
7
+ @type = type
8
+ end
9
+
10
+ def cast(value)
11
+ if value.is_a?(@type)
12
+ value
13
+ elsif @type.respond_to?(:cast)
14
+ @type.cast(value)
15
+ else
16
+ @type.new(value)
17
+ end
18
+ end
19
+
20
+ def to_mongo(value)
21
+ if value.respond_to?(:to_mongo)
22
+ value.to_mongo
23
+ else
24
+ value
25
+ end
26
+ end
27
+
28
+ def from_mongo(value)
29
+ if @type.respond_to?(:from_mongo)
30
+ value = value.with_indifferent_access if value.respond_to?(:with_indifferent_access)
31
+ @type.from_mongo(value)
32
+ else
33
+ value
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,20 @@
1
+ require 'active_support/core_ext/date/conversions'
2
+ require 'active_support/core_ext/string/conversions'
3
+
4
+ module MongoModel
5
+ module Types
6
+ class Date < Object
7
+ def cast(value)
8
+ value.to_date rescue nil
9
+ end
10
+
11
+ def to_mongo(value)
12
+ value.strftime("%Y/%m/%d") if value
13
+ end
14
+
15
+ def from_mongo(value)
16
+ value.to_date if value
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module MongoModel
2
+ module Types
3
+ class Float < Object
4
+ def cast(value)
5
+ value.to_f if value.respond_to?(:to_f)
6
+ end
7
+
8
+ def boolean(value)
9
+ !value.zero?
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ require 'active_support/core_ext/hash/indifferent_access'
2
+
3
+ module MongoModel
4
+ module Types
5
+ class Hash < Object
6
+ def to_mongo(hash)
7
+ hash.inject({}) { |result, (k, v)|
8
+ result[k] = Types.converter_for(v.class).to_mongo(v)
9
+ result
10
+ }
11
+ end
12
+
13
+ def from_mongo(hash)
14
+ hash.with_indifferent_access if hash
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module MongoModel
2
+ module Types
3
+ class Integer < Object
4
+ def cast(value)
5
+ value.to_i if value.respond_to?(:to_i)
6
+ end
7
+
8
+ def boolean(value)
9
+ !value.zero?
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ module MongoModel
2
+ module Types
3
+ class Object
4
+ def cast(value)
5
+ value
6
+ end
7
+
8
+ def boolean(value)
9
+ !value.blank?
10
+ end
11
+
12
+ def to_mongo(value)
13
+ value
14
+ end
15
+
16
+ def from_mongo(value)
17
+ value
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ module MongoModel
2
+ module Types
3
+ class String < Object
4
+ def cast(value)
5
+ value.to_s if value.respond_to?(:to_s)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module MongoModel
2
+ module Types
3
+ class Symbol < Object
4
+ def cast(value)
5
+ value.to_sym if value.respond_to?(:to_sym)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ require 'active_support/core_ext/time/conversions'
2
+ require 'active_support/core_ext/string/conversions'
3
+
4
+ module MongoModel
5
+ module Types
6
+ class Time < Object
7
+ def cast(value)
8
+ value.to_time.utc rescue nil
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module MongoModel
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,273 @@
1
+ require 'spec_helper'
2
+ require 'active_support/core_ext/hash/indifferent_access'
3
+
4
+ module MongoModel
5
+ describe Attributes::Store do
6
+ let(:properties) do
7
+ properties = ActiveSupport::OrderedHash.new
8
+ properties[:string] = MongoModel::Properties::Property.new(:string, String)
9
+ properties[:integer] = MongoModel::Properties::Property.new(:integer, Integer)
10
+ properties[:float] = MongoModel::Properties::Property.new(:float, Float)
11
+ properties[:boolean] = MongoModel::Properties::Property.new(:boolean, Boolean)
12
+ properties[:symbol] = MongoModel::Properties::Property.new(:symbol, Symbol)
13
+ properties[:hash] = MongoModel::Properties::Property.new(:hash, Hash)
14
+ properties[:array] = MongoModel::Properties::Property.new(:array, Array)
15
+ properties[:date] = MongoModel::Properties::Property.new(:date, Date)
16
+ properties[:time] = MongoModel::Properties::Property.new(:time, Time)
17
+ properties[:custom] = MongoModel::Properties::Property.new(:custom, CustomClass)
18
+ properties[:default] = MongoModel::Properties::Property.new(:default, String, :default => 'Default')
19
+ properties[:as] = MongoModel::Properties::Property.new(:as, String, :as => '_custom_as')
20
+ properties
21
+ end
22
+ let(:instance) { mock('instance', :properties => properties) }
23
+
24
+ subject { Attributes::Store.new(instance) }
25
+
26
+ it "should set default property values" do
27
+ subject.keys.should == properties.keys
28
+ subject[:default].should == 'Default'
29
+ end
30
+
31
+ describe "setting to nil" do
32
+ specify "all property types should be nullable" do
33
+ properties.keys.each do |property|
34
+ subject[property] = nil
35
+ subject[property].should be_nil
36
+ end
37
+ end
38
+ end
39
+
40
+ it "should set attributes that aren't properties" do
41
+ subject[:non_property] = "Hello World"
42
+ subject[:non_property].should == "Hello World"
43
+ end
44
+
45
+ describe "type-casting" do
46
+ TypeCastExamples = {
47
+ :string =>
48
+ {
49
+ "abc" => "abc",
50
+ 123 => "123"
51
+ },
52
+ :integer =>
53
+ {
54
+ 123 => 123,
55
+ 55.123 => 55,
56
+ "999" => 999,
57
+ "12.123" => 12
58
+ },
59
+ :float =>
60
+ {
61
+ 55.123 => 55.123,
62
+ 123 => 123.0,
63
+ "12.123" => 12.123
64
+ },
65
+ :boolean =>
66
+ {
67
+ true => true,
68
+ false => false,
69
+ "true" => true,
70
+ "false" => false,
71
+ 1 => true,
72
+ 0 => false,
73
+ "1" => true,
74
+ "0" => false,
75
+ '' => nil
76
+ },
77
+ :symbol =>
78
+ {
79
+ :some_symbol => :some_symbol,
80
+ "some_string" => :some_string
81
+ },
82
+ :hash =>
83
+ {
84
+ { :foo => 'bar' } => { :foo => 'bar' }
85
+ },
86
+ :array =>
87
+ {
88
+ [123, 'abc', :foo, true] => [123, 'abc', :foo, true]
89
+ },
90
+ :date =>
91
+ {
92
+ Date.civil(2009, 11, 15) => Date.civil(2009, 11, 15),
93
+ Time.local(2008, 12, 3, 0, 0, 0, 0) => Date.civil(2008, 12, 3),
94
+ "2009/3/4" => Date.civil(2009, 3, 4),
95
+ "Sat Jan 01 20:15:01 UTC 2000" => Date.civil(2000, 1, 1)
96
+ },
97
+ :time =>
98
+ {
99
+ Time.local(2008, 5, 14, 1, 2, 3, 4) => Time.local(2008, 5, 14, 1, 2, 3, 4),
100
+ Date.civil(2009, 11, 15) => Time.local(2009, 11, 15, 0, 0, 0, 0),
101
+ "Sat Jan 01 20:15:01 UTC 2000" => Time.utc(2000, 1, 1, 20, 15, 1, 0),
102
+ "2009/3/4" => Time.utc(2009, 3, 4, 0, 0, 0, 0)
103
+ }
104
+ }
105
+
106
+ TypeCastExamples.each do |type, examples|
107
+ context "assigning to #{type} property" do
108
+ examples.each do |assigned, expected|
109
+ it "should cast #{assigned.inspect} to #{expected.inspect}" do
110
+ subject[type] = assigned
111
+ subject[type].should == expected
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ context "assigning to custom property" do
118
+ before(:each) do
119
+ @custom = CustomClass.new('instance name')
120
+ end
121
+
122
+ it "should not alter instances of CustomClass" do
123
+ subject[:custom] = @custom
124
+ subject[:custom].should == @custom
125
+ end
126
+
127
+ it "should cast strings to CustomClass" do
128
+ subject[:custom] = "foobar"
129
+ subject[:custom].should == CustomClass.new('foobar')
130
+ end
131
+ end
132
+ end
133
+
134
+ describe "#before_type_cast" do
135
+ BeforeTypeCastExamples = {
136
+ :string => [ "abc", 123 ],
137
+ :integer => [ 123, 55.123, "999", "12.123" ],
138
+ :float => [ 55.123, 123, "12.123" ],
139
+ :boolean => [ true, false, "true", "false", 1, 0, "1", "0", '' ],
140
+ :symbol => [ :some_symbol, "some_string" ],
141
+ :hash => [ { :foo => 'bar' } ],
142
+ :array => [ [123, 'abc', :foo, true] ],
143
+ :date => [ Date.civil(2009, 11, 15), Time.local(2008, 12, 3, 0, 0, 0, 0), "2009/3/4", "Sat Jan 01 20:15:01 UTC 2000" ],
144
+ :time => [ Time.local(2008, 5, 14, 1, 2, 3, 4), Date.civil(2009, 11, 15), "Sat Jan 01 20:15:01 UTC 2000", "2009/3/4" ]
145
+ }
146
+
147
+ BeforeTypeCastExamples.each do |type, examples|
148
+ context "assigning to #{type} property" do
149
+ examples.each do |example|
150
+ it "should access pre-typecasted value of #{example.inspect}" do
151
+ subject[type] = example
152
+ subject.before_type_cast(type).should == example
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ describe "#has?" do
160
+ TrueExamples = {
161
+ :string => [ 'abc', '1' ],
162
+ :integer => [ -1, 1, 100 ],
163
+ :float => [ 0.1, 44.123 ],
164
+ :boolean => [ true, 1, "true" ],
165
+ :symbol => [ :some_symbol ],
166
+ :hash => [ { :foo => 'bar' } ],
167
+ :array => [ [''], [123, 'abc', :foo, true] ],
168
+ :date => [ Date.civil(2009, 11, 15) ],
169
+ :time => [ Time.local(2008, 5, 14, 1, 2, 3, 4) ],
170
+ :custom => [ CustomClass.new('foobar'), 'baz' ]
171
+ }
172
+
173
+ FalseExamples = {
174
+ :string => [ nil, '' ],
175
+ :integer => [ nil, 0 ],
176
+ :float => [ nil, 0.0 ],
177
+ :boolean => [ nil, false, 0, "false" ],
178
+ :symbol => [ nil, 0 ],
179
+ :hash => [ nil, {} ],
180
+ :array => [ [] ],
181
+ :date => [ nil, '' ],
182
+ :time => [ nil, '' ],
183
+ :custom => [ nil ]
184
+ }
185
+
186
+ TrueExamples.each do |type, examples|
187
+ context "assigning to #{type} property" do
188
+ examples.each do |example|
189
+ it "should return true for #{example.inspect}" do
190
+ subject[type] = example
191
+ subject.has?(type).should == true
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ FalseExamples.each do |type, examples|
198
+ context "assigning to #{type} property" do
199
+ examples.each do |example|
200
+ it "should return false for #{example.inspect}" do
201
+ subject[type] = example
202
+ subject.has?(type).should == false
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+
209
+ describe "serialization" do
210
+ it "should convert to mongo representation" do
211
+ subject[:string] = 'string'
212
+ subject[:integer] = 42
213
+ subject[:float] = 123.45
214
+ subject[:boolean] = false
215
+ subject[:symbol] = :symbol
216
+ subject[:hash] = { :foo => 'bar', :custom => CustomClass.new('custom in hash') }
217
+ subject[:array] = [ 123, 'abc', 45.67, true, :bar, CustomClass.new('custom in array') ]
218
+ subject[:date] = Date.civil(2009, 11, 15)
219
+ subject[:time] = Time.local(2008, 5, 14, 1, 2, 3, 4)
220
+ subject[:custom] = CustomClass.new('custom')
221
+ subject[:as] = "As property"
222
+ subject[:non_property] = "Hello World"
223
+ subject[:custom_non_property] = CustomClass.new('custom non property')
224
+
225
+ subject.to_mongo.should include({
226
+ 'string' => 'string',
227
+ 'integer' => 42,
228
+ 'float' => 123.45,
229
+ 'boolean' => false,
230
+ 'symbol' => :symbol,
231
+ 'hash' => { :foo => 'bar', :custom => { :name => 'custom in hash' } },
232
+ 'array' => [ 123, 'abc', 45.67, true, :bar, { :name => 'custom in array' } ],
233
+ 'date' => "2009/11/15",
234
+ 'time' => Time.local(2008, 5, 14, 1, 2, 3, 4),
235
+ 'custom' => { :name => 'custom' },
236
+ '_custom_as' => "As property",
237
+ 'non_property' => "Hello World",
238
+ 'custom_non_property' => { :name => 'custom non property' },
239
+ })
240
+ end
241
+
242
+ it "should load from mongo representation" do
243
+ subject.from_mongo!({
244
+ 'string' => 'string',
245
+ 'integer' => 42,
246
+ 'float' => 123.45,
247
+ 'boolean' => false,
248
+ 'symbol' => :symbol,
249
+ 'hash' => { :foo => 'bar' },
250
+ 'array' => [ 123, 'abc', 45.67, true, :bar ],
251
+ 'date' => Time.utc(2009, 11, 15),
252
+ 'time' => Time.local(2008, 5, 14, 1, 2, 3, 4),
253
+ 'custom' => { :name => 'custom' },
254
+ '_custom_as' => "As property",
255
+ 'custom_non_property' => { :name => 'custom non property' }
256
+ })
257
+
258
+ subject[:string].should == 'string'
259
+ subject[:integer].should == 42
260
+ subject[:float].should == 123.45
261
+ subject[:boolean].should == false
262
+ subject[:symbol].should == :symbol
263
+ subject[:hash].should == { :foo => 'bar' }.with_indifferent_access
264
+ subject[:array].should == [ 123, 'abc', 45.67, true, :bar ]
265
+ subject[:date].should == Date.civil(2009, 11, 15)
266
+ subject[:time].should == Time.local(2008, 5, 14, 1, 2, 3, 4)
267
+ subject[:custom].should == CustomClass.new('custom')
268
+ subject[:as].should == "As property"
269
+ subject[:custom_non_property].should == { :name => 'custom non property' }
270
+ end
271
+ end
272
+ end
273
+ end