lookout-mongo_mapper 0.11.3

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 (176) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +33 -0
  3. data/UPGRADES +26 -0
  4. data/bin/mmconsole +59 -0
  5. data/examples/attr_accessible.rb +22 -0
  6. data/examples/attr_protected.rb +22 -0
  7. data/examples/cache_key.rb +24 -0
  8. data/examples/custom_types.rb +24 -0
  9. data/examples/identity_map.rb +33 -0
  10. data/examples/identity_map/automatic.rb +2 -0
  11. data/examples/keys.rb +40 -0
  12. data/examples/modifiers/set.rb +25 -0
  13. data/examples/plugins.rb +38 -0
  14. data/examples/querying.rb +35 -0
  15. data/examples/safe.rb +43 -0
  16. data/examples/scopes.rb +52 -0
  17. data/examples/validating/embedded_docs.rb +29 -0
  18. data/lib/mongo_mapper.rb +94 -0
  19. data/lib/mongo_mapper/connection.rb +96 -0
  20. data/lib/mongo_mapper/document.rb +42 -0
  21. data/lib/mongo_mapper/embedded_document.rb +32 -0
  22. data/lib/mongo_mapper/exceptions.rb +30 -0
  23. data/lib/mongo_mapper/extensions/array.rb +19 -0
  24. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  25. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  26. data/lib/mongo_mapper/extensions/date.rb +25 -0
  27. data/lib/mongo_mapper/extensions/float.rb +14 -0
  28. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  29. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  30. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  31. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  32. data/lib/mongo_mapper/extensions/object.rb +26 -0
  33. data/lib/mongo_mapper/extensions/object_id.rb +32 -0
  34. data/lib/mongo_mapper/extensions/set.rb +20 -0
  35. data/lib/mongo_mapper/extensions/string.rb +18 -0
  36. data/lib/mongo_mapper/extensions/time.rb +28 -0
  37. data/lib/mongo_mapper/locale/en.yml +5 -0
  38. data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
  39. data/lib/mongo_mapper/plugins.rb +22 -0
  40. data/lib/mongo_mapper/plugins/accessible.rb +52 -0
  41. data/lib/mongo_mapper/plugins/active_model.rb +18 -0
  42. data/lib/mongo_mapper/plugins/associations.rb +90 -0
  43. data/lib/mongo_mapper/plugins/associations/base.rb +92 -0
  44. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +54 -0
  45. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +34 -0
  46. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
  47. data/lib/mongo_mapper/plugins/associations/collection.rb +27 -0
  48. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +44 -0
  49. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +133 -0
  50. data/lib/mongo_mapper/plugins/associations/many_association.rb +63 -0
  51. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  52. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +118 -0
  53. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  54. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  55. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  56. data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +22 -0
  57. data/lib/mongo_mapper/plugins/associations/one_association.rb +48 -0
  58. data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
  59. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
  60. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +95 -0
  61. data/lib/mongo_mapper/plugins/associations/proxy.rb +134 -0
  62. data/lib/mongo_mapper/plugins/associations/single_association.rb +46 -0
  63. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  64. data/lib/mongo_mapper/plugins/callbacks.rb +29 -0
  65. data/lib/mongo_mapper/plugins/clone.rb +22 -0
  66. data/lib/mongo_mapper/plugins/dirty.rb +60 -0
  67. data/lib/mongo_mapper/plugins/document.rb +41 -0
  68. data/lib/mongo_mapper/plugins/dynamic_querying.rb +45 -0
  69. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  70. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +56 -0
  71. data/lib/mongo_mapper/plugins/embedded_document.rb +53 -0
  72. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  73. data/lib/mongo_mapper/plugins/identity_map.rb +128 -0
  74. data/lib/mongo_mapper/plugins/indexes.rb +13 -0
  75. data/lib/mongo_mapper/plugins/inspect.rb +16 -0
  76. data/lib/mongo_mapper/plugins/keys.rb +313 -0
  77. data/lib/mongo_mapper/plugins/keys/key.rb +61 -0
  78. data/lib/mongo_mapper/plugins/logger.rb +18 -0
  79. data/lib/mongo_mapper/plugins/modifiers.rb +134 -0
  80. data/lib/mongo_mapper/plugins/pagination.rb +16 -0
  81. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  82. data/lib/mongo_mapper/plugins/protected.rb +45 -0
  83. data/lib/mongo_mapper/plugins/querying.rb +165 -0
  84. data/lib/mongo_mapper/plugins/querying/decorator.rb +36 -0
  85. data/lib/mongo_mapper/plugins/rails.rb +58 -0
  86. data/lib/mongo_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
  87. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  88. data/lib/mongo_mapper/plugins/sci.rb +36 -0
  89. data/lib/mongo_mapper/plugins/scopes.rb +27 -0
  90. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  91. data/lib/mongo_mapper/plugins/timestamps.rb +22 -0
  92. data/lib/mongo_mapper/plugins/touch.rb +18 -0
  93. data/lib/mongo_mapper/plugins/userstamps.rb +18 -0
  94. data/lib/mongo_mapper/plugins/validations.rb +86 -0
  95. data/lib/mongo_mapper/railtie.rb +48 -0
  96. data/lib/mongo_mapper/railtie/database.rake +65 -0
  97. data/lib/mongo_mapper/translation.rb +10 -0
  98. data/lib/mongo_mapper/version.rb +4 -0
  99. data/lib/rails/generators/mongo_mapper/config/config_generator.rb +24 -0
  100. data/lib/rails/generators/mongo_mapper/config/templates/mongo.yml +18 -0
  101. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +23 -0
  102. data/lib/rails/generators/mongo_mapper/model/templates/model.rb +13 -0
  103. data/test/_NOTE_ON_TESTING +1 -0
  104. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +64 -0
  105. data/test/functional/associations/test_belongs_to_proxy.rb +238 -0
  106. data/test/functional/associations/test_in_array_proxy.rb +349 -0
  107. data/test/functional/associations/test_many_documents_as_proxy.rb +231 -0
  108. data/test/functional/associations/test_many_documents_proxy.rb +866 -0
  109. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +239 -0
  110. data/test/functional/associations/test_many_embedded_proxy.rb +289 -0
  111. data/test/functional/associations/test_many_polymorphic_proxy.rb +303 -0
  112. data/test/functional/associations/test_one_as_proxy.rb +491 -0
  113. data/test/functional/associations/test_one_embedded_polymorphic_proxy.rb +208 -0
  114. data/test/functional/associations/test_one_embedded_proxy.rb +100 -0
  115. data/test/functional/associations/test_one_proxy.rb +383 -0
  116. data/test/functional/test_accessible.rb +198 -0
  117. data/test/functional/test_associations.rb +46 -0
  118. data/test/functional/test_binary.rb +27 -0
  119. data/test/functional/test_caching.rb +77 -0
  120. data/test/functional/test_callbacks.rb +232 -0
  121. data/test/functional/test_dirty.rb +301 -0
  122. data/test/functional/test_document.rb +282 -0
  123. data/test/functional/test_dynamic_querying.rb +75 -0
  124. data/test/functional/test_embedded_document.rb +288 -0
  125. data/test/functional/test_equality.rb +20 -0
  126. data/test/functional/test_identity_map.rb +513 -0
  127. data/test/functional/test_indexes.rb +50 -0
  128. data/test/functional/test_logger.rb +20 -0
  129. data/test/functional/test_modifiers.rb +537 -0
  130. data/test/functional/test_pagination.rb +91 -0
  131. data/test/functional/test_protected.rb +201 -0
  132. data/test/functional/test_querying.rb +935 -0
  133. data/test/functional/test_safe.rb +76 -0
  134. data/test/functional/test_sci.rb +240 -0
  135. data/test/functional/test_scopes.rb +171 -0
  136. data/test/functional/test_timestamps.rb +62 -0
  137. data/test/functional/test_touch.rb +125 -0
  138. data/test/functional/test_userstamps.rb +44 -0
  139. data/test/functional/test_validations.rb +414 -0
  140. data/test/models.rb +261 -0
  141. data/test/support/railtie.rb +4 -0
  142. data/test/support/railtie/autoloaded.rb +2 -0
  143. data/test/support/railtie/not_autoloaded.rb +3 -0
  144. data/test/support/railtie/parent.rb +3 -0
  145. data/test/test_active_model_lint.rb +18 -0
  146. data/test/test_helper.rb +93 -0
  147. data/test/unit/associations/test_base.rb +146 -0
  148. data/test/unit/associations/test_belongs_to_association.rb +29 -0
  149. data/test/unit/associations/test_many_association.rb +63 -0
  150. data/test/unit/associations/test_one_association.rb +47 -0
  151. data/test/unit/associations/test_proxy.rb +100 -0
  152. data/test/unit/serializers/test_json_serializer.rb +216 -0
  153. data/test/unit/serializers/test_xml_serializer.rb +196 -0
  154. data/test/unit/test_clone.rb +69 -0
  155. data/test/unit/test_document.rb +249 -0
  156. data/test/unit/test_dynamic_finder.rb +125 -0
  157. data/test/unit/test_embedded_document.rb +682 -0
  158. data/test/unit/test_equality.rb +38 -0
  159. data/test/unit/test_exceptions.rb +12 -0
  160. data/test/unit/test_extensions.rb +380 -0
  161. data/test/unit/test_identity_map_middleware.rb +34 -0
  162. data/test/unit/test_inspect.rb +47 -0
  163. data/test/unit/test_key.rb +205 -0
  164. data/test/unit/test_keys.rb +65 -0
  165. data/test/unit/test_mongo_mapper.rb +143 -0
  166. data/test/unit/test_pagination.rb +11 -0
  167. data/test/unit/test_plugins.rb +89 -0
  168. data/test/unit/test_rails.rb +183 -0
  169. data/test/unit/test_rails_compatibility.rb +38 -0
  170. data/test/unit/test_rails_reflect_on_association.rb +118 -0
  171. data/test/unit/test_railtie.rb +66 -0
  172. data/test/unit/test_serialization.rb +166 -0
  173. data/test/unit/test_time_zones.rb +44 -0
  174. data/test/unit/test_translation.rb +27 -0
  175. data/test/unit/test_validations.rb +562 -0
  176. metadata +285 -0
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class BelongsToAssociationTest < Test::Unit::TestCase
5
+ include MongoMapper::Plugins::Associations
6
+
7
+ context "class_name" do
8
+ should "camelize the name" do
9
+ BelongsToAssociation.new(:user).class_name.should == 'User'
10
+ end
11
+
12
+ should "be changeable using class_name option" do
13
+ association = BelongsToAssociation.new(:user, :class_name => 'Person')
14
+ association.class_name.should == 'Person'
15
+ end
16
+ end
17
+
18
+ context "embeddable?" do
19
+ should "be false even if class is embeddable" do
20
+ base = BelongsToAssociation.new(:address)
21
+ base.embeddable?.should be_false
22
+ end
23
+
24
+ should "be false if class is not embeddable" do
25
+ base = BelongsToAssociation.new(:project)
26
+ base.embeddable?.should be_false
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyAssociationTest < Test::Unit::TestCase
5
+ include MongoMapper::Plugins::Associations
6
+
7
+ context "class_name" do
8
+ should "camelize the name" do
9
+ ManyAssociation.new(:smart_people).class_name.should == 'SmartPerson'
10
+ end
11
+
12
+ should "be changeable using class_name option" do
13
+ base = ManyAssociation.new(:smart_people, :class_name => 'IntelligentPerson')
14
+ base.class_name.should == 'IntelligentPerson'
15
+ end
16
+ end
17
+
18
+ context "type_key_name" do
19
+ should "be _type" do
20
+ ManyAssociation.new(:foos).type_key_name.should == '_type'
21
+ end
22
+ end
23
+
24
+ context "embeddable?" do
25
+ should "be true if class is embeddable" do
26
+ base = ManyAssociation.new(:medias)
27
+ base.embeddable?.should be_true
28
+ end
29
+
30
+ should "be false if class is not embeddable" do
31
+ base = ManyAssociation.new(:statuses)
32
+ base.embeddable?.should be_false
33
+ end
34
+ end
35
+
36
+ context "proxy_class" do
37
+ should "be ManyDocumentsProxy for many" do
38
+ base = ManyAssociation.new(:statuses)
39
+ base.proxy_class.should == ManyDocumentsProxy
40
+ end
41
+
42
+ should "be ManyPolymorphicProxy for polymorphic many" do
43
+ base = ManyAssociation.new(:messages, :polymorphic => true)
44
+ base.proxy_class.should == ManyPolymorphicProxy
45
+ end
46
+
47
+ should "be ManyEmbeddedProxy for many embedded" do
48
+ base = ManyAssociation.new(:medias)
49
+ base.proxy_class.should == ManyEmbeddedProxy
50
+ end
51
+
52
+ should "be ManyEmbeddedPolymorphicProxy for polymorphic many embedded" do
53
+ base = ManyAssociation.new(:medias, :polymorphic => true)
54
+ base.proxy_class.should == ManyEmbeddedPolymorphicProxy
55
+ end
56
+
57
+ should "be InArrayProxy for many with :in option" do
58
+ base = ManyAssociation.new(:messages, :in => :message_ids)
59
+ base.proxy_class.should == InArrayProxy
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class OneAssociationTest < Test::Unit::TestCase
5
+ include MongoMapper::Plugins::Associations
6
+
7
+ context "type_key_name" do
8
+ should "be _type" do
9
+ OneAssociation.new(:foo).type_key_name.should == '_type'
10
+ end
11
+ end
12
+
13
+ context "embeddable?" do
14
+ should "be true if class is embeddable" do
15
+ base = OneAssociation.new(:media)
16
+ base.embeddable?.should be_true
17
+ end
18
+
19
+ should "be false if class is not embeddable" do
20
+ base = OneAssociation.new(:project)
21
+ base.embeddable?.should be_false
22
+ end
23
+ end
24
+
25
+ context "proxy_class" do
26
+ should "be OneProxy for one" do
27
+ base = OneAssociation.new(:status)
28
+ base.proxy_class.should == OneProxy
29
+ end
30
+
31
+ should "be OneAsProxy for one with :as option" do
32
+ base = OneAssociation.new(:message, :as => :messagable)
33
+ base.proxy_class.should == OneAsProxy
34
+ end
35
+
36
+ should "be OneEmbeddedProxy for one embedded" do
37
+ base = OneAssociation.new(:media)
38
+ base.proxy_class.should == OneEmbeddedProxy
39
+ end
40
+
41
+ should "be OneEmbeddedPolymorphicProxy for polymorphic one embedded" do
42
+ base = OneAssociation.new(:media, :polymorphic => true)
43
+ base.proxy_class.should == OneEmbeddedPolymorphicProxy
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+
3
+ class FakeNilProxy < MongoMapper::Plugins::Associations::Proxy
4
+ def find_target; nil end
5
+ end
6
+
7
+ class FakeBlankProxy < MongoMapper::Plugins::Associations::Proxy
8
+ def find_target; '' end
9
+ end
10
+
11
+ class FakeNumberProxy < MongoMapper::Plugins::Associations::Proxy
12
+ def find_target; 17 end
13
+ end
14
+
15
+ class FakeProxy < MongoMapper::Plugins::Associations::Proxy
16
+ def find_target; [1, 2] end
17
+ end
18
+
19
+ class ProxyTest < Test::Unit::TestCase
20
+ def setup
21
+ @owner = mock('owner')
22
+ @owner.stubs(:new?).returns(false)
23
+ @association = mock('association')
24
+ @association.stubs(:options).returns({:extend => []})
25
+
26
+ @proxy = FakeProxy.new(@owner, @association)
27
+ @nil_proxy = FakeNilProxy.new(@owner, @association)
28
+ @blank_proxy = FakeBlankProxy.new(@owner, @association)
29
+ end
30
+
31
+ should "set target to nil when reset is called" do
32
+ @proxy.reset
33
+ @proxy.target.should be_nil
34
+ end
35
+
36
+ should "be able to inspect the proxy" do
37
+ @proxy.inspect.should == '[1, 2]'
38
+ end
39
+
40
+ context "nil?" do
41
+ should "be true if nil" do
42
+ @nil_proxy.nil?.should be_true
43
+ end
44
+
45
+ should "be false if not nil" do
46
+ @proxy.nil?.should be_false
47
+ end
48
+ end
49
+
50
+ context "blank?" do
51
+ should "be true if blank" do
52
+ @blank_proxy.blank?.should be_true
53
+ @nil_proxy.blank?.should be_true
54
+ end
55
+
56
+ should "be false if not blank" do
57
+ @proxy.blank?.should be_false
58
+ end
59
+ end
60
+
61
+ context "present?" do
62
+ should "be true if present" do
63
+ @proxy.present?.should be_true
64
+ end
65
+
66
+ should "be false if not present" do
67
+ @blank_proxy.present?.should be_false
68
+ @nil_proxy.present?.should be_false
69
+ end
70
+ end
71
+
72
+ should "delegate respond_to? to target" do
73
+ @proxy.respond_to?(:each).should be_true
74
+ @proxy.respond_to?(:size).should be_true
75
+ @proxy.respond_to?(:gsub).should be_false
76
+ end
77
+
78
+ should "alias proxy owner to owner" do
79
+ @proxy.proxy_owner.should == @owner
80
+ end
81
+
82
+ should "alias proxy target to target" do
83
+ @proxy.proxy_target.should == @target
84
+ end
85
+
86
+ context "send" do
87
+ should "work if proxy responds to method" do
88
+ @proxy.send(:reset)
89
+ @proxy.target.should be_nil
90
+ end
91
+
92
+ should "work if the target responds to the method" do
93
+ @proxy.send(:size).should == 2
94
+ end
95
+
96
+ should "not work if neither the proxy or target respond to method" do
97
+ lambda { @proxy.send(:gsub) }.should raise_error
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,216 @@
1
+ require 'test_helper'
2
+
3
+ class JsonSerializationTest < Test::Unit::TestCase
4
+
5
+ # Helper function in case things change in the future
6
+ # - replacing all those to_json calls was a nightmare
7
+ def convert_to_json(object, options={})
8
+ ActiveSupport::JSON.encode(object, options)
9
+ end
10
+
11
+ class Tag
12
+ include MongoMapper::EmbeddedDocument
13
+ key :name, String
14
+ end
15
+
16
+ class Contact
17
+ include MongoMapper::Document
18
+ key :name, String
19
+ key :age, Integer
20
+ key :created_at, Time
21
+ key :awesome, Boolean
22
+ key :preferences, Hash
23
+
24
+ many :tags, :class_name => 'JsonSerializationTest::Tag'
25
+ end
26
+
27
+ def setup
28
+ Kernel.const_set('TopLevelContact', Doc('TopLevelContact'))
29
+ TopLevelContact.key :name, String
30
+
31
+ Contact.include_root_in_json = false
32
+ @contact = Contact.new(
33
+ :name => 'Konata Izumi',
34
+ :age => 16,
35
+ :created_at => Time.utc(2006, 8, 1),
36
+ :awesome => true,
37
+ :preferences => { :shows => 'anime' }
38
+ )
39
+ @top_level_contact = TopLevelContact.new(
40
+ :name => 'Konata Izumi'
41
+ )
42
+ end
43
+
44
+ def teardown
45
+ Kernel.send(:remove_const, 'TopLevelContact') if Object.const_defined?('TopLevelContact')
46
+ end
47
+
48
+ should "include root for class with no module" do
49
+ TopLevelContact.include_root_in_json = true
50
+ assert_match %r{^\{"top_level_contact":\s?\{}, convert_to_json(@top_level_contact)
51
+ end
52
+
53
+ should "include demodulized root" do
54
+ Contact.include_root_in_json = true
55
+ assert_match %r{^\{"contact":\s?\{}, convert_to_json(@contact)
56
+ end
57
+
58
+ should "encode all encodable attributes" do
59
+ json = convert_to_json(@contact)
60
+
61
+ assert_no_match %r{"_id"}, json
62
+ assert_match %r{"name":"Konata Izumi"}, json
63
+ assert_match %r{"age":16}, json
64
+ assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
65
+ assert_match %r{"awesome":true}, json
66
+ assert_match %r{"preferences":\{"shows":"anime"\}}, json
67
+ end
68
+
69
+ should "allow attribute filtering with only" do
70
+ json = convert_to_json(@contact, :only => [:name, :age])
71
+
72
+ assert_no_match %r{"_id"}, json
73
+ assert_match %r{"name":"Konata Izumi"}, json
74
+ assert_match %r{"age":16}, json
75
+ assert_no_match %r{"awesome"}, json
76
+ assert_no_match %r{"created_at"}, json
77
+ assert_no_match %r{"preferences"}, json
78
+ end
79
+
80
+ should "allow attribute filtering with except" do
81
+ json = convert_to_json(@contact, :except => [:name, :age])
82
+
83
+ assert_no_match %r{"_id"}, json
84
+ assert_no_match %r{"name"}, json
85
+ assert_no_match %r{"age"}, json
86
+ assert_match %r{"awesome"}, json
87
+ assert_match %r{"created_at"}, json
88
+ assert_match %r{"preferences"}, json
89
+ end
90
+
91
+ context "_id key" do
92
+ should "not be included by default" do
93
+ json = convert_to_json(@contact)
94
+ assert_no_match %r{"_id":}, json
95
+ end
96
+
97
+ should "not be included even if :except is used" do
98
+ json = convert_to_json(@contact, :except => :name)
99
+ assert_no_match %r{"_id":}, json
100
+ end
101
+ end
102
+
103
+ context "id method" do
104
+ setup do
105
+ def @contact.label; "Has cheezburger"; end
106
+ def @contact.favorite_quote; "Constraints are liberating"; end
107
+ end
108
+
109
+ should "be included by default" do
110
+ json = convert_to_json(@contact)
111
+ assert_match %r{"id"}, json
112
+ end
113
+
114
+ should "be included when single method included" do
115
+ json = convert_to_json(@contact, :methods => :label)
116
+ assert_match %r{"id"}, json
117
+ assert_match %r{"label":"Has cheezburger"}, json
118
+ assert_match %r{"name":"Konata Izumi"}, json
119
+ assert_no_match %r{"favorite_quote":"Constraints are liberating"}, json
120
+ end
121
+
122
+ should "be included when multiple methods included" do
123
+ json = convert_to_json(@contact, :methods => [:label, :favorite_quote])
124
+ assert_match %r{"id"}, json
125
+ assert_match %r{"label":"Has cheezburger"}, json
126
+ assert_match %r{"favorite_quote":"Constraints are liberating"}, json
127
+ assert_match %r{"name":"Konata Izumi"}, json
128
+ end
129
+
130
+ should "not be included if :only is present" do
131
+ json = convert_to_json(@contact, :only => :name)
132
+ assert_no_match %r{"id":}, json
133
+ end
134
+
135
+ should "be represented by a string" do
136
+ json = convert_to_json(@contact)
137
+ assert_match %r{"id":"}, json
138
+ end
139
+ end
140
+
141
+ context "including methods" do
142
+ setup do
143
+ def @contact.label; "Has cheezburger"; end
144
+ def @contact.favorite_quote; "Constraints are liberating"; end
145
+ end
146
+
147
+ should "include single method" do
148
+ json = convert_to_json(@contact, :methods => :label)
149
+ assert_match %r{"label":"Has cheezburger"}, json
150
+ end
151
+
152
+ should "include multiple methods" do
153
+ json = convert_to_json(@contact, :only => :name, :methods => [:label, :favorite_quote])
154
+ assert_match %r{"label":"Has cheezburger"}, json
155
+ assert_match %r{"favorite_quote":"Constraints are liberating"}, json
156
+ assert_match %r{"name":"Konata Izumi"}, json
157
+ assert_no_match %r{"age":16}, json
158
+ assert_no_match %r{"awesome"}, json
159
+ assert_no_match %r{"created_at"}, json
160
+ assert_no_match %r{"preferences"}, json
161
+ end
162
+ end
163
+
164
+ context "array of records" do
165
+ setup do
166
+ @contacts = [
167
+ Contact.new(:name => 'David', :age => 39),
168
+ Contact.new(:name => 'Mary', :age => 14)
169
+ ]
170
+ end
171
+
172
+ should "allow attribute filtering with only" do
173
+ json =convert_to_json(@contacts, :only => :name)
174
+ assert_match %r{\{"name":"David"\}}, json
175
+ assert_match %r{\{"name":"Mary"\}}, json
176
+ end
177
+
178
+ should "allow attribute filtering with except" do
179
+ json = convert_to_json(@contacts, :except => [:name, :preferences, :awesome, :created_at, :updated_at])
180
+ assert_match %r{"age":39}, json
181
+ assert_match %r{"age":14}, json
182
+ assert_no_match %r{"name":}, json
183
+ assert_no_match %r{"preferences":}, json
184
+ assert_no_match %r{"awesome":}, json
185
+ assert_no_match %r{"created_at":}, json
186
+ assert_no_match %r{"updated_at":}, json
187
+ end
188
+ end
189
+
190
+ should "allow options for hash of records" do
191
+ contacts = {
192
+ 1 => Contact.new(:name => 'David', :age => 39),
193
+ 2 => Contact.new(:name => 'Mary', :age => 14)
194
+ }
195
+ json = convert_to_json(contacts, :only => [1, :name])
196
+ assert_match %r{"1":}, json
197
+ assert_match %r{\{"name":"David"\}}, json
198
+ assert_no_match %r{"2":}, json
199
+ end
200
+
201
+ should "include embedded attributes" do
202
+ contact = Contact.new(:name => 'John', :age => 27)
203
+ contact.tags = [Tag.new(:name => 'awesome'), Tag.new(:name => 'ruby')]
204
+ json = convert_to_json(contact)
205
+ assert_match %r{"tags":}, json
206
+ assert_match %r{"name":"awesome"}, json
207
+ assert_match %r{"name":"ruby"}, json
208
+ end
209
+
210
+ should "include dynamic attributes" do
211
+ contact = Contact.new(:name => 'John', :age => 27, :foo => 'bar')
212
+ contact['smell'] = 'stinky'
213
+ json = convert_to_json(contact)
214
+ assert_match %r{"smell":"stinky"}, json
215
+ end
216
+ end