identity_cache 0.4.1 → 1.1.0

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 (94) hide show
  1. checksums.yaml +5 -5
  2. data/.github/probots.yml +2 -0
  3. data/.github/workflows/ci.yml +92 -0
  4. data/.gitignore +2 -0
  5. data/.rubocop.yml +5 -0
  6. data/CAVEATS.md +25 -0
  7. data/CHANGELOG.md +73 -19
  8. data/Gemfile +5 -1
  9. data/LICENSE +1 -1
  10. data/README.md +49 -27
  11. data/Rakefile +14 -5
  12. data/dev.yml +12 -16
  13. data/gemfiles/Gemfile.latest-release +8 -0
  14. data/gemfiles/Gemfile.min-supported +7 -0
  15. data/gemfiles/Gemfile.rails-edge +7 -0
  16. data/identity_cache.gemspec +29 -10
  17. data/lib/identity_cache.rb +78 -51
  18. data/lib/identity_cache/belongs_to_caching.rb +12 -40
  19. data/lib/identity_cache/cache_fetcher.rb +6 -5
  20. data/lib/identity_cache/cache_hash.rb +2 -2
  21. data/lib/identity_cache/cache_invalidation.rb +4 -11
  22. data/lib/identity_cache/cache_key_generation.rb +17 -65
  23. data/lib/identity_cache/cache_key_loader.rb +128 -0
  24. data/lib/identity_cache/cached.rb +7 -0
  25. data/lib/identity_cache/cached/association.rb +87 -0
  26. data/lib/identity_cache/cached/attribute.rb +123 -0
  27. data/lib/identity_cache/cached/attribute_by_multi.rb +37 -0
  28. data/lib/identity_cache/cached/attribute_by_one.rb +88 -0
  29. data/lib/identity_cache/cached/belongs_to.rb +100 -0
  30. data/lib/identity_cache/cached/embedded_fetching.rb +41 -0
  31. data/lib/identity_cache/cached/prefetcher.rb +61 -0
  32. data/lib/identity_cache/cached/primary_index.rb +96 -0
  33. data/lib/identity_cache/cached/recursive/association.rb +109 -0
  34. data/lib/identity_cache/cached/recursive/has_many.rb +9 -0
  35. data/lib/identity_cache/cached/recursive/has_one.rb +9 -0
  36. data/lib/identity_cache/cached/reference/association.rb +16 -0
  37. data/lib/identity_cache/cached/reference/has_many.rb +105 -0
  38. data/lib/identity_cache/cached/reference/has_one.rb +100 -0
  39. data/lib/identity_cache/configuration_dsl.rb +53 -215
  40. data/lib/identity_cache/encoder.rb +95 -0
  41. data/lib/identity_cache/expiry_hook.rb +36 -0
  42. data/lib/identity_cache/fallback_fetcher.rb +2 -1
  43. data/lib/identity_cache/load_strategy/eager.rb +28 -0
  44. data/lib/identity_cache/load_strategy/lazy.rb +71 -0
  45. data/lib/identity_cache/load_strategy/load_request.rb +20 -0
  46. data/lib/identity_cache/load_strategy/multi_load_request.rb +27 -0
  47. data/lib/identity_cache/mem_cache_store_cas.rb +53 -0
  48. data/lib/identity_cache/memoized_cache_proxy.rb +137 -58
  49. data/lib/identity_cache/parent_model_expiration.rb +46 -11
  50. data/lib/identity_cache/query_api.rb +102 -408
  51. data/lib/identity_cache/railtie.rb +8 -0
  52. data/lib/identity_cache/record_not_found.rb +6 -0
  53. data/lib/identity_cache/should_use_cache.rb +1 -0
  54. data/lib/identity_cache/version.rb +3 -2
  55. data/lib/identity_cache/with_primary_index.rb +136 -0
  56. data/lib/identity_cache/without_primary_index.rb +24 -3
  57. data/performance/cache_runner.rb +25 -73
  58. data/performance/cpu.rb +4 -3
  59. data/performance/externals.rb +4 -3
  60. data/performance/profile.rb +6 -5
  61. data/railgun.yml +16 -0
  62. metadata +60 -73
  63. data/.travis.yml +0 -30
  64. data/Gemfile.rails42 +0 -6
  65. data/Gemfile.rails50 +0 -6
  66. data/test/attribute_cache_test.rb +0 -110
  67. data/test/cache_fetch_includes_test.rb +0 -46
  68. data/test/cache_hash_test.rb +0 -14
  69. data/test/cache_invalidation_test.rb +0 -139
  70. data/test/deeply_nested_associated_record_test.rb +0 -19
  71. data/test/denormalized_has_many_test.rb +0 -211
  72. data/test/denormalized_has_one_test.rb +0 -160
  73. data/test/fetch_multi_test.rb +0 -308
  74. data/test/fetch_test.rb +0 -258
  75. data/test/fixtures/serialized_record.mysql2 +0 -0
  76. data/test/fixtures/serialized_record.postgresql +0 -0
  77. data/test/helpers/active_record_objects.rb +0 -106
  78. data/test/helpers/database_connection.rb +0 -72
  79. data/test/helpers/serialization_format.rb +0 -42
  80. data/test/helpers/update_serialization_format.rb +0 -24
  81. data/test/identity_cache_test.rb +0 -29
  82. data/test/index_cache_test.rb +0 -161
  83. data/test/memoized_attributes_test.rb +0 -49
  84. data/test/memoized_cache_proxy_test.rb +0 -107
  85. data/test/normalized_belongs_to_test.rb +0 -107
  86. data/test/normalized_has_many_test.rb +0 -231
  87. data/test/normalized_has_one_test.rb +0 -9
  88. data/test/prefetch_associations_test.rb +0 -364
  89. data/test/readonly_test.rb +0 -109
  90. data/test/recursive_denormalized_has_many_test.rb +0 -131
  91. data/test/save_test.rb +0 -82
  92. data/test/schema_change_test.rb +0 -112
  93. data/test/serialization_format_change_test.rb +0 -16
  94. data/test/test_helper.rb +0 -140
@@ -1,107 +0,0 @@
1
- require "test_helper"
2
-
3
- class MemoizedCacheProxyTest < IdentityCache::TestCase
4
- def test_changing_default_cache
5
- IdentityCache.cache_backend = ActiveSupport::Cache::MemoryStore.new
6
- IdentityCache.cache.write('foo', 'bar')
7
- assert_equal 'bar', IdentityCache.cache.fetch('foo')
8
- end
9
-
10
- def test_fetch_multi_with_fallback_fetcher
11
- IdentityCache.cache_backend = backend = ActiveSupport::Cache::MemoryStore.new
12
- IdentityCache.cache.write('foo', 'bar')
13
- backend.expects(:write).with('bar', 'baz')
14
- yielded = nil
15
- assert_equal({'foo' => 'bar', 'bar' => 'baz'}, IdentityCache.cache.fetch_multi('foo', 'bar') {|_| yielded = ['baz'] })
16
- assert_equal ['baz'], yielded
17
- end
18
-
19
- def test_fetch_should_short_circuit_on_memoized_values
20
- fetcher.expects(:fetch).never
21
-
22
- IdentityCache.cache.with_memoization do
23
- IdentityCache.cache.write('foo', 'bar')
24
- assert_equal 'bar', IdentityCache.cache.fetch('foo')
25
- end
26
- end
27
-
28
- def test_fetch_should_short_circuit_on_falsy_memoized_values
29
- fetcher.expects(:fetch).never
30
-
31
- IdentityCache.cache.with_memoization do
32
- IdentityCache.cache.write('foo', nil)
33
- assert_nil IdentityCache.cache.fetch('foo')
34
- IdentityCache.cache.write('bar', false)
35
- assert_equal false, IdentityCache.cache.fetch('bar')
36
- end
37
- end
38
-
39
- def test_fetch_should_try_memcached_on_not_memoized_values
40
- fetcher.expects(:fetch).with('foo').returns('bar')
41
-
42
- IdentityCache.cache.with_memoization do
43
- assert_equal 'bar', IdentityCache.cache.fetch('foo')
44
- end
45
- end
46
-
47
- def test_write_should_memoize_values
48
- fetcher.expects(:fetch).never
49
- fetcher.expects(:write).with('foo', 'bar')
50
-
51
- IdentityCache.cache.with_memoization do
52
- IdentityCache.cache.write('foo', 'bar')
53
- assert_equal 'bar', IdentityCache.cache.fetch('foo')
54
- end
55
- end
56
-
57
- def test_fetch_should_memoize_values
58
- backend.write('foo', 'bar')
59
-
60
- IdentityCache.cache.with_memoization do
61
- assert_equal 'bar', IdentityCache.cache.fetch('foo')
62
- backend.delete('foo')
63
- assert_equal 'bar', IdentityCache.cache.fetch('foo')
64
- end
65
- end
66
-
67
- def test_fetch_multi_should_memoize_values
68
- expected_hash = {'foo' => 'bar', 'fooz' => IdentityCache::CACHED_NIL}
69
-
70
- backend.write('foo', 'bar')
71
-
72
- IdentityCache.cache.with_memoization do
73
- assert_equal(expected_hash, IdentityCache.cache.fetch_multi('foo', 'fooz') {|_| [IdentityCache::CACHED_NIL] })
74
- assert_equal(expected_hash, IdentityCache.cache.memoized_key_values)
75
- backend.delete('foo')
76
- backend.write('fooz', 'baz')
77
- assert_equal(expected_hash, IdentityCache.cache.fetch_multi('foo', 'fooz'))
78
- end
79
- end
80
-
81
- def test_fetch_multi_with_partially_memoized_should_read_missing_keys_from_memcache
82
- IdentityCache.cache.write('foo', 'bar')
83
- @backend.write('fooz', 'baz')
84
-
85
- IdentityCache.cache.with_memoization do
86
- assert_equal({'foo' => 'bar', 'fooz' => 'baz'}, IdentityCache.cache.fetch_multi('foo', 'fooz'))
87
- end
88
- end
89
-
90
- def test_fetch_multi_with_blank_values_should_not_hit_the_cache_engine
91
- @backend.expects(:fetch_multi).never
92
-
93
- IdentityCache.cache.with_memoization do
94
- IdentityCache.cache.write('foo', [])
95
- IdentityCache.cache.write('bar', false)
96
- IdentityCache.cache.write('baz', {})
97
- assert_equal({'foo' => [], 'bar' => false, 'baz' => {}}, IdentityCache.cache.fetch_multi('foo', 'bar', 'baz'))
98
- end
99
- end
100
-
101
- def test_with_memoization_should_not_clear_rails_cache_when_the_block_ends
102
- IdentityCache.cache.with_memoization do
103
- IdentityCache.cache.write('foo', 'bar')
104
- end
105
- assert_equal 'bar', @backend.fetch('foo')
106
- end
107
- end
@@ -1,107 +0,0 @@
1
- require "test_helper"
2
-
3
- class NormalizedBelongsToTest < IdentityCache::TestCase
4
- def setup
5
- super
6
- AssociatedRecord.cache_belongs_to :item, :embed => false
7
-
8
- @parent_record = Item.new(:title => 'foo')
9
- @parent_record.associated_records << AssociatedRecord.new(:name => 'bar')
10
- @parent_record.save
11
- @parent_record.reload
12
- @record = @parent_record.associated_records.first
13
- # Reset association cache, so we remove the inverse of in memory reference
14
- @record.association(:item).reset
15
- end
16
-
17
- def test_fetching_the_association_should_delegate_to_the_normal_association_fetcher_if_any_transactions_are_open
18
- Item.expects(:fetch_by_id).never
19
- @record.transaction do
20
- assert_equal @parent_record, @record.fetch_item
21
- end
22
- end
23
-
24
- def test_fetching_the_association_should_delegate_to_the_normal_association_fetcher_if_the_normal_association_is_loaded
25
- # Warm the ActiveRecord association
26
- @record.item
27
-
28
- Item.expects(:fetch_by_id).never
29
- assert_equal @parent_record, @record.fetch_item
30
- end
31
-
32
- def test_fetching_the_association_should_fetch_the_record_from_identity_cache
33
- Item.expects(:fetch_by_id).with(@parent_record.id).returns(@parent_record)
34
- assert_equal @parent_record, @record.fetch_item
35
- end
36
-
37
- def test_fetching_the_association_should_assign_the_result_to_an_instance_variable_so_that_successive_accesses_are_cached
38
- Item.expects(:fetch_by_id).with(@parent_record.id).returns(@parent_record)
39
- assert_equal @parent_record, @record.fetch_item
40
- assert_equal false, @record.association(:item).loaded?
41
- assert_equal @parent_record, @record.fetch_item
42
- end
43
-
44
- def test_fetching_the_association_should_cache_nil_and_not_raise_if_the_record_cant_be_found
45
- Item.expects(:fetch_by_id).with(@parent_record.id).returns(nil)
46
- assert_nil @record.fetch_item # miss
47
- assert_nil @record.fetch_item # hit
48
- end
49
-
50
- def test_cache_belongs_to_on_derived_model_raises
51
- assert_raises(IdentityCache::DerivedModelError) do
52
- StiRecordTypeA.cache_belongs_to :item, :embed => false
53
- end
54
- end
55
-
56
- def test_fetching_polymorphic_belongs_to_association
57
- PolymorphicRecord.include IdentityCache
58
- PolymorphicRecord.cache_belongs_to :owner
59
- PolymorphicRecord.create!(owner: @parent_record)
60
-
61
- assert_equal @parent_record, PolymorphicRecord.first.fetch_owner
62
- end
63
-
64
- def test_returned_record_should_be_readonly_on_cache_hit
65
- IdentityCache.with_fetch_read_only_records do
66
- @record.fetch_item # warm cache
67
- assert @record.fetch_item.readonly?
68
- refute @record.item.readonly?
69
- end
70
- end
71
-
72
- def test_returned_record_should_be_readonly_on_cache_miss
73
- IdentityCache.with_fetch_read_only_records do
74
- assert @record.fetch_item.readonly?
75
- refute @record.item.readonly?
76
- end
77
- end
78
-
79
- def test_db_returned_record_should_never_be_readonly
80
- IdentityCache.with_fetch_read_only_records do
81
- uncached_record = @record.item
82
- refute uncached_record.readonly?
83
- @record.fetch_item
84
- refute uncached_record.readonly?
85
- end
86
- end
87
-
88
- def test_returned_record_with_open_transactions_should_not_be_readonly
89
- IdentityCache.with_fetch_read_only_records do
90
- Item.transaction do
91
- refute IdentityCache.should_use_cache?
92
- refute @record.fetch_item.readonly?
93
- end
94
- end
95
- end
96
-
97
- def test_respects_should_use_cache_on_parent
98
- @record.reload
99
- @parent_record.class.stubs(:should_use_cache?).returns(false)
100
-
101
- assert_queries(1) do
102
- assert_memcache_operations(0) do
103
- @record.fetch_item
104
- end
105
- end
106
- end
107
- end
@@ -1,231 +0,0 @@
1
- require "test_helper"
2
-
3
- class NormalizedHasManyTest < IdentityCache::TestCase
4
- def setup
5
- super
6
- Item.cache_has_many :associated_records, :embed => :ids
7
-
8
- @record = Item.new(:title => 'foo')
9
- @record.not_cached_records << NotCachedRecord.new(:name => 'NoCache')
10
- @record.associated_records << AssociatedRecord.new(:name => 'bar')
11
- @record.associated_records << AssociatedRecord.new(:name => 'baz')
12
- @record.save
13
- @record.reload
14
- @baz, @bar = @record.associated_records[0], @record.associated_records[1]
15
- @not_cached = @record.not_cached_records.first
16
- end
17
-
18
- def test_a_records_list_of_associated_ids_on_the_parent_record_retains_association_sort_order
19
- assert_equal [2, 1], @record.associated_record_ids
20
-
21
- AssociatedRecord.create(name: 'foo', item_id: @record.id)
22
- @record.reload
23
- assert_equal [3, 2, 1], @record.associated_record_ids
24
- end
25
-
26
- def test_defining_a_denormalized_has_many_cache_caches_the_list_of_associated_ids_on_the_parent_record_during_cache_miss
27
- fetched_record = Item.fetch(@record.id)
28
- assert_equal [2, 1], fetched_record.cached_associated_record_ids
29
- assert_equal false, fetched_record.associated_records.loaded?
30
- end
31
-
32
- def test_batch_fetching_of_association_for_multiple_parent_records
33
- record2 = Item.new(:title => 'two')
34
- record2.associated_records << AssociatedRecord.new(:name => 'a')
35
- record2.associated_records << AssociatedRecord.new(:name => 'b')
36
- record2.save!
37
-
38
- fetched_records = assert_queries(2) do
39
- Item.fetch_multi(@record.id, record2.id)
40
- end
41
- assert_equal [[2, 1], [4, 3]], fetched_records.map(&:cached_associated_record_ids)
42
- assert_equal false, fetched_records.any?{ |record| record.associated_records.loaded? }
43
- end
44
-
45
- def test_batch_fetching_of_deeply_associated_records
46
- Item.has_many :denormalized_associated_records, class_name: 'AssociatedRecord'
47
- Item.cache_has_many :denormalized_associated_records, embed: true
48
- AssociatedRecord.cache_has_many :deeply_associated_records, embed: :ids
49
- @record.associated_records[0].deeply_associated_records << DeeplyAssociatedRecord.new(:name => 'deep1')
50
- @record.associated_records[1].deeply_associated_records << DeeplyAssociatedRecord.new(:name => 'deep2')
51
- @record.associated_records.each(&:save!)
52
-
53
- fetched_records = assert_queries(4) do
54
- Item.fetch(@record.id)
55
- end
56
- assert_no_queries do
57
- assert_equal [[1], [2]], fetched_records.fetch_denormalized_associated_records.map(&:cached_deeply_associated_record_ids)
58
- assert_equal false, fetched_records.fetch_denormalized_associated_records.any?{ |record| record.deeply_associated_records.loaded? }
59
- end
60
- end
61
-
62
- def test_batch_fetching_stops_with_nil_parent
63
- Item.cache_has_one :associated, embed: true
64
- AssociatedRecord.cache_has_many :deeply_associated_records, embed: :ids
65
- AssociatedRecord.delete_all
66
-
67
- fetched_records = assert_queries(3) do
68
- Item.fetch(@record.id)
69
- end
70
- assert_no_queries do
71
- assert_equal @record, fetched_records
72
- assert_nil fetched_records.fetch_associated
73
- end
74
- end
75
-
76
- def test_fetching_associated_ids_will_populate_the_value_if_the_record_isnt_from_the_cache
77
- assert_equal [2, 1], @record.fetch_associated_record_ids
78
- end
79
-
80
- def test_fetching_associated_ids_will_use_the_cached_value_if_the_record_is_from_the_cache
81
- @record = Item.fetch(@record.id)
82
- assert_queries(0) do
83
- assert_equal [2, 1], @record.fetch_associated_record_ids
84
- end
85
- end
86
-
87
- def test_the_cached_the_list_of_associated_ids_on_the_parent_record_should_not_be_populated_by_default
88
- assert_nil @record.cached_associated_record_ids
89
- end
90
-
91
- def test_fetching_the_association_should_fetch_each_record_by_id
92
- assert_equal [@baz, @bar], @record.fetch_associated_records
93
- end
94
-
95
- def test_fetching_the_association_from_a_record_on_a_cache_hit_should_not_issue_any_queries
96
- # Populate the cache
97
- @record = Item.fetch(@record.id)
98
- @record.fetch_associated_records
99
- assert_queries(0) do
100
- @record = Item.fetch(@record.id)
101
- assert_equal [@baz, @bar], @record.fetch_associated_records
102
- end
103
- end
104
-
105
- def test_fetching_the_association_from_a_identity_cached_record_should_not_re_fetch_the_association_ids
106
- @record = Item.fetch(@record.id)
107
- @record.expects(:associated_record_ids).never
108
- assert_equal [@baz, @bar], @record.fetch_associated_records
109
- end
110
-
111
- def test_fetching_the_association_should_delegate_to_the_normal_association_fetcher_if_any_transaction_are_open
112
- @record = Item.fetch(@record.id)
113
-
114
- assert_memcache_operations(0) do
115
- @record.transaction do
116
- assert_equal [@baz, @bar], @record.fetch_associated_records
117
- end
118
- end
119
- end
120
-
121
- def test_fetching_the_association_should_delegate_to_the_normal_association_fetcher_if_the_normal_association_is_loaded
122
- # Warm the ActiveRecord association
123
- @record.associated_records.to_a
124
-
125
- assert_memcache_operations(0) do
126
- assert_equal [@baz, @bar], @record.fetch_associated_records
127
- end
128
- end
129
-
130
- def test_saving_a_child_record_shouldnt_expire_the_parents_blob_if_the_foreign_key_hasnt_changed
131
- IdentityCache.cache.expects(:delete).with(@record.primary_cache_index_key).never
132
- IdentityCache.cache.expects(:delete).with(@baz.primary_cache_index_key)
133
- @baz.name = 'foo'
134
- @baz.save!
135
- assert_equal [@baz.id, @bar.id], Item.fetch(@record.id).cached_associated_record_ids
136
- assert_equal [@baz, @bar], Item.fetch(@record.id).fetch_associated_records
137
- end
138
-
139
- def test_creating_a_child_record_should_expire_the_parents_cache_blob
140
- IdentityCache.cache.expects(:delete).with(@record.primary_cache_index_key).once
141
- IdentityCache.cache.expects(:delete).with(@bar.primary_cache_index_key[0...-1] + '3')
142
- @qux = @record.associated_records.create!(:name => 'qux')
143
- assert_equal [@qux, @baz, @bar], Item.fetch(@record.id).fetch_associated_records
144
- end
145
-
146
- def test_saving_a_child_record_should_expire_the_new_and_old_parents_cache_blob
147
- @new_record = Item.create
148
- @baz.item = @new_record
149
-
150
- IdentityCache.cache.expects(:delete).with(@record.primary_cache_index_key).once
151
- IdentityCache.cache.expects(:delete).with(@new_record.primary_cache_index_key).once
152
- IdentityCache.cache.expects(:delete).with(@baz.primary_cache_index_key).once
153
-
154
- @baz.save!
155
-
156
- assert_equal [@bar.id], Item.fetch(@record.id).cached_associated_record_ids
157
- assert_equal [@bar], Item.fetch(@record.id).fetch_associated_records
158
- end
159
-
160
- def test_saving_a_child_record_in_a_transaction_should_expire_the_new_and_old_parents_cache_blob
161
- @new_record = Item.create
162
- @baz.item_id = @new_record.id
163
-
164
- @baz.transaction do
165
- IdentityCache.cache.expects(:delete).with(@record.primary_cache_index_key).once
166
- IdentityCache.cache.expects(:delete).with(@new_record.primary_cache_index_key).once
167
- IdentityCache.cache.expects(:delete).with(@baz.primary_cache_index_key).once
168
-
169
- @baz.save!
170
- @baz.reload
171
- end
172
-
173
- assert_equal [@bar.id], Item.fetch(@record.id).cached_associated_record_ids
174
- assert_equal [@bar], Item.fetch(@record.id).fetch_associated_records
175
- end
176
-
177
- def test_destroying_a_child_record_should_expire_the_parents_cache_blob
178
- IdentityCache.cache.expects(:delete).with(@record.primary_cache_index_key).once
179
- IdentityCache.cache.expects(:delete).with(@baz.primary_cache_index_key).once
180
- @baz.destroy
181
- assert_equal [@bar], @record.reload.fetch_associated_records
182
- end
183
-
184
- def test_saving_a_child_record_should_expire_only_itself
185
- IdentityCache.cache.expects(:delete).with(@baz.primary_cache_index_key).once
186
- @baz.save!
187
- end
188
-
189
- def test_touching_child_with_touch_true_on_parent_expires_parent
190
- IdentityCache.cache.expects(:delete).with(@record.primary_cache_index_key).once
191
- @not_cached.touch
192
- end
193
-
194
- def test_saving_child_with_touch_true_on_parent_expires_parent
195
- IdentityCache.cache.expects(:delete).with(@record.primary_cache_index_key).once
196
- @not_cached.name = 'Changed'
197
- @not_cached.save!
198
- end
199
-
200
- def test_fetch_association_does_not_allow_chaining
201
- check = proc { assert_equal false, Item.fetch(@record.id).fetch_associated_records.respond_to?(:where) }
202
- 2.times { check.call } # for miss and hit
203
- Item.transaction { check.call }
204
- end
205
-
206
- def test_returned_records_should_be_readonly_on_cache_hit
207
- IdentityCache.with_fetch_read_only_records do
208
- Item.fetch(@record.id) # warm cache
209
- record_from_cache_hit = Item.fetch(@record.id)
210
- record_from_cache_hit.fetch_associated_records.all?(&:readonly?)
211
- end
212
- end
213
-
214
- def test_returned_records_should_be_readonly_on_cache_miss
215
- IdentityCache.with_fetch_read_only_records do
216
- record_from_cache_miss = Item.fetch(@record.id)
217
- assert record_from_cache_miss.fetch_associated_records.all?(&:readonly?)
218
- end
219
- end
220
-
221
- def test_respects_should_use_cache_on_association
222
- @record.reload
223
- AssociatedRecord.stubs(:should_use_cache?).returns(false)
224
-
225
- assert_queries(1) do
226
- assert_memcache_operations(0) do
227
- @record.fetch_associated_records
228
- end
229
- end
230
- end
231
- end
@@ -1,9 +0,0 @@
1
- require "test_helper"
2
-
3
- class NormalizedHasOneTest < IdentityCache::TestCase
4
- def test_not_implemented_error
5
- assert_raises(NotImplementedError) do
6
- Item.cache_has_one :associated, :embed => false
7
- end
8
- end
9
- end