mongoid-cached-json 1.5.1 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +80 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +85 -0
- data/CONTRIBUTING.md +118 -0
- data/Gemfile +21 -0
- data/README.md +49 -52
- data/Rakefile +34 -0
- data/lib/mongoid-cached-json.rb +0 -1
- data/lib/mongoid-cached-json/array.rb +1 -3
- data/lib/mongoid-cached-json/cached_json.rb +52 -50
- data/lib/mongoid-cached-json/config.rb +20 -21
- data/lib/mongoid-cached-json/hash.rb +1 -3
- data/lib/mongoid-cached-json/key_references.rb +0 -3
- data/lib/mongoid-cached-json/mongoid_criteria.rb +1 -3
- data/lib/mongoid-cached-json/version.rb +1 -2
- data/mongoid-cached-json.gemspec +17 -0
- data/spec/array_spec.rb +48 -0
- data/spec/benchmark_spec.rb +115 -0
- data/spec/cached_json_spec.rb +501 -0
- data/spec/config_spec.rb +21 -0
- data/spec/dalli_spec.rb +37 -0
- data/spec/hash_spec.rb +66 -0
- data/spec/mongoid_criteria_spec.rb +78 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/awesome_artwork.rb +11 -0
- data/spec/support/awesome_image.rb +14 -0
- data/spec/support/fast_json_artwork.rb +15 -0
- data/spec/support/fast_json_image.rb +12 -0
- data/spec/support/fast_json_url.rb +12 -0
- data/spec/support/json_embedded_foobar.rb +5 -0
- data/spec/support/json_employee.rb +12 -0
- data/spec/support/json_foobar.rb +19 -0
- data/spec/support/json_manager.rb +14 -0
- data/spec/support/json_math.rb +9 -0
- data/spec/support/json_parent_foobar.rb +11 -0
- data/spec/support/json_polymorphic_embedded_foobar.rb +9 -0
- data/spec/support/json_polymorphic_referenced_foobar.rb +9 -0
- data/spec/support/json_referenced_foobar.rb +5 -0
- data/spec/support/json_supervisor.rb +13 -0
- data/spec/support/json_transform.rb +13 -0
- data/spec/support/matchers/invalidate.rb +22 -0
- data/spec/support/person.rb +20 -0
- data/spec/support/poly_company.rb +10 -0
- data/spec/support/poly_person.rb +10 -0
- data/spec/support/poly_post.rb +9 -0
- data/spec/support/prison_cell.rb +11 -0
- data/spec/support/prison_inmate.rb +12 -0
- data/spec/support/secret_parent.rb +11 -0
- data/spec/support/sometimes_secret.rb +11 -0
- data/spec/support/tool.rb +11 -0
- data/spec/support/tool_box.rb +10 -0
- metadata +62 -137
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongoid::CachedJson::Config do
|
4
|
+
before :each do
|
5
|
+
@cache = Mongoid::CachedJson::Config.cache
|
6
|
+
end
|
7
|
+
after :each do
|
8
|
+
Mongoid::CachedJson::Config.cache = @cache
|
9
|
+
end
|
10
|
+
it 'configures a cache store' do
|
11
|
+
cache = Class.new
|
12
|
+
Mongoid::CachedJson.configure do |config|
|
13
|
+
config.cache = cache
|
14
|
+
end
|
15
|
+
expect(cache).to receive(:fetch).once
|
16
|
+
JsonFoobar.new.as_json
|
17
|
+
end
|
18
|
+
it 'sets disable_caching to false' do
|
19
|
+
expect(Mongoid::CachedJson.config.disable_caching).to be_falsey
|
20
|
+
end
|
21
|
+
end
|
data/spec/dalli_spec.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_support/cache/dalli_store'
|
3
|
+
|
4
|
+
describe ActiveSupport::Cache::DalliStore do
|
5
|
+
before :each do
|
6
|
+
@cache = Mongoid::CachedJson::Config.cache
|
7
|
+
Mongoid::CachedJson.configure do |config|
|
8
|
+
config.cache = ActiveSupport::Cache.lookup_store(:dalli_store)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
after :each do
|
12
|
+
Mongoid::CachedJson::Config.cache = @cache
|
13
|
+
end
|
14
|
+
it 'uses dalli_store' do
|
15
|
+
expect(Mongoid::CachedJson.config.cache).to be_a ActiveSupport::Cache::DalliStore
|
16
|
+
end
|
17
|
+
context 'read_multi' do
|
18
|
+
context 'array' do
|
19
|
+
it 'uses a local cache to fetch repeated objects' do
|
20
|
+
options = { properties: :all, is_top_level_json: true, version: :unspecified }
|
21
|
+
tool1 = Tool.create!(name: 'hammer')
|
22
|
+
tool1_key = Tool.cached_json_key(options, Tool, tool1.id)
|
23
|
+
tool2 = Tool.create!(name: 'screwdriver')
|
24
|
+
tool2_key = Tool.cached_json_key(options, Tool, tool2.id)
|
25
|
+
expect(Mongoid::CachedJson.config.cache).not_to receive(:fetch)
|
26
|
+
expect(Mongoid::CachedJson.config.cache).to receive(:read_multi).with(tool1_key, tool2_key).once.and_return(
|
27
|
+
tool1_key => { _id: tool1.id.to_s },
|
28
|
+
tool2_key => { _id: tool2.id.to_s }
|
29
|
+
)
|
30
|
+
expect([tool1, tool2].as_json(properties: :all)).to eq([
|
31
|
+
{ tool_box: nil, _id: tool1.id.to_s },
|
32
|
+
{ tool_box: nil, _id: tool2.id.to_s }
|
33
|
+
])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/spec/hash_spec.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hash do
|
4
|
+
it 'hash' do
|
5
|
+
expect({ x: 'x', y: 'y' }.as_json).to eq(x: 'x', y: 'y')
|
6
|
+
end
|
7
|
+
it 'materializes multiple objects that may or may not respond to as_json_partial' do
|
8
|
+
foobar1 = JsonFoobar.create(foo: 'FOO1', baz: 'BAZ', bar: 'BAR')
|
9
|
+
foobar2 = JsonFoobar.create(foo: 'FOO2', baz: 'BAZ', bar: 'BAR')
|
10
|
+
expect({
|
11
|
+
:x => :y,
|
12
|
+
:foobar1 => foobar1,
|
13
|
+
:foobar2 => foobar2,
|
14
|
+
:z => {
|
15
|
+
foobar1: foobar1
|
16
|
+
},
|
17
|
+
:t => [foobar1, :y],
|
18
|
+
'empty' => []
|
19
|
+
}.as_json).to eq(
|
20
|
+
:x => 'y',
|
21
|
+
:foobar1 => { :foo => 'FOO1', 'Baz' => 'BAZ', :default_foo => 'DEFAULT_FOO' },
|
22
|
+
:foobar2 => { :foo => 'FOO2', 'Baz' => 'BAZ', :default_foo => 'DEFAULT_FOO' },
|
23
|
+
:z => { foobar1: { :foo => 'FOO1', 'Baz' => 'BAZ', :default_foo => 'DEFAULT_FOO' } },
|
24
|
+
:t => [{ :foo => 'FOO1', 'Baz' => 'BAZ', :default_foo => 'DEFAULT_FOO' }, 'y'],
|
25
|
+
'empty' => []
|
26
|
+
)
|
27
|
+
end
|
28
|
+
context 'without read_multi' do
|
29
|
+
before :each do
|
30
|
+
Mongoid::CachedJson.config.cache.instance_eval { undef :read_multi }
|
31
|
+
end
|
32
|
+
it 'uses a local cache to fetch repeated objects' do
|
33
|
+
tool = Tool.create!(name: 'hammer')
|
34
|
+
expect(Mongoid::CachedJson.config.cache).to receive(:fetch).once.and_return(
|
35
|
+
x: :y
|
36
|
+
)
|
37
|
+
expect({
|
38
|
+
t1: tool,
|
39
|
+
t2: tool,
|
40
|
+
t3: tool
|
41
|
+
}.as_json(properties: :all)).to eq(
|
42
|
+
t1: { tool_box: nil, x: :y },
|
43
|
+
t2: { tool_box: nil, x: :y },
|
44
|
+
t3: { tool_box: nil, x: :y }
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
context 'with read_multi' do
|
49
|
+
it 'uses a local cache to fetch repeated objects' do
|
50
|
+
tool = Tool.create!(name: 'hammer')
|
51
|
+
tool_key = "as_json/unspecified/Tool/#{tool.id}/all/true"
|
52
|
+
expect(Mongoid::CachedJson.config.cache).to receive(:read_multi).once.with(tool_key).and_return(
|
53
|
+
tool_key => { x: :y }
|
54
|
+
)
|
55
|
+
expect({
|
56
|
+
t1: tool,
|
57
|
+
t2: tool,
|
58
|
+
t3: tool
|
59
|
+
}.as_json(properties: :all)).to eq(
|
60
|
+
t1: { tool_box: nil, x: :y },
|
61
|
+
t2: { tool_box: nil, x: :y },
|
62
|
+
t3: { tool_box: nil, x: :y }
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongoid::Criteria do
|
4
|
+
it 'mongoid_criteria' do
|
5
|
+
tool_box = ToolBox.create!(color: 'red')
|
6
|
+
Tool.create!(name: 'hammer', tool_box: tool_box)
|
7
|
+
Tool.create!(name: 'screwdriver', tool_box: tool_box)
|
8
|
+
expect(Tool.where(tool_box_id: tool_box.id).as_json(properties: :all)).to eq([
|
9
|
+
{ tool_box: { color: 'red' }, name: 'hammer' },
|
10
|
+
{ tool_box: { color: 'red' }, name: 'screwdriver' }
|
11
|
+
])
|
12
|
+
end
|
13
|
+
context 'without read_multi' do
|
14
|
+
before :each do
|
15
|
+
Mongoid::CachedJson.config.cache.instance_eval { undef :read_multi }
|
16
|
+
end
|
17
|
+
it 'materializes multiple objects using a single partial' do
|
18
|
+
tool_box = ToolBox.create!(color: 'red')
|
19
|
+
Tool.create!(name: 'hammer', tool_box: tool_box)
|
20
|
+
Tool.create!(name: 'screwdriver', tool_box: tool_box)
|
21
|
+
# once per tool and once for the tool box
|
22
|
+
expect(Mongoid::CachedJson.config.cache).to receive(:fetch).exactly(3).times.and_return(
|
23
|
+
x: :y
|
24
|
+
)
|
25
|
+
expect(tool_box.tools.as_json(properties: :all)).to eq([
|
26
|
+
{ tool_box: { x: :y }, x: :y },
|
27
|
+
{ tool_box: { x: :y }, x: :y }
|
28
|
+
])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
context 'with read_multi' do
|
32
|
+
it 'responds to read_multi' do
|
33
|
+
expect(Mongoid::CachedJson.config.cache).to respond_to :read_multi
|
34
|
+
end
|
35
|
+
it 'materializes multiple objects using a single partial' do
|
36
|
+
tool_box = ToolBox.create!(color: 'red')
|
37
|
+
tool1 = Tool.create!(name: 'hammer', tool_box: tool_box)
|
38
|
+
tool2 = Tool.create!(name: 'screwdriver', tool_box: tool_box)
|
39
|
+
# once per tool and once for the tool box
|
40
|
+
keys = [
|
41
|
+
"as_json/unspecified/Tool/#{tool1.id}/all/true",
|
42
|
+
"as_json/unspecified/ToolBox/#{tool_box.id}/all/false",
|
43
|
+
"as_json/unspecified/Tool/#{tool2.id}/all/true"
|
44
|
+
]
|
45
|
+
expect(Mongoid::CachedJson.config.cache).to receive(:read_multi).once.with(*keys).and_return(
|
46
|
+
keys[0] => { x: :y },
|
47
|
+
keys[1] => { x: :y },
|
48
|
+
keys[2] => { x: :y }
|
49
|
+
)
|
50
|
+
expect(tool_box.tools.as_json(properties: :all)).to eq([
|
51
|
+
{ tool_box: { x: :y }, x: :y },
|
52
|
+
{ tool_box: { x: :y }, x: :y }
|
53
|
+
])
|
54
|
+
end
|
55
|
+
it 'does not call fetch for missing objects, only write' do
|
56
|
+
tool_box = ToolBox.create!(color: 'red')
|
57
|
+
tool1 = Tool.create!(name: 'hammer', tool_box: tool_box)
|
58
|
+
tool2 = Tool.create!(name: 'screwdriver', tool_box: tool_box)
|
59
|
+
# once per tool and once for the tool box
|
60
|
+
keys = [
|
61
|
+
"as_json/unspecified/Tool/#{tool1.id}/all/true",
|
62
|
+
"as_json/unspecified/ToolBox/#{tool_box.id}/all/false",
|
63
|
+
"as_json/unspecified/Tool/#{tool2.id}/all/true"
|
64
|
+
]
|
65
|
+
expect(Mongoid::CachedJson.config.cache).to receive(:read_multi).once.with(*keys).and_return(
|
66
|
+
keys[0] => { x: :y },
|
67
|
+
keys[1] => { x: :y }
|
68
|
+
)
|
69
|
+
# read_multi returned only 2 of 3 things, don't call fetch, just store the third value
|
70
|
+
expect(Mongoid::CachedJson.config.cache).not_to receive(:fetch)
|
71
|
+
expect(Mongoid::CachedJson.config.cache).to receive(:write).with("as_json/unspecified/Tool/#{tool2.id}/all/true", name: 'screwdriver')
|
72
|
+
expect(tool_box.tools.as_json(properties: :all)).to eq([
|
73
|
+
{ tool_box: { x: :y }, x: :y },
|
74
|
+
{ tool_box: { x: :y }, name: 'screwdriver' }
|
75
|
+
])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
require 'mongoid-cached-json'
|
6
|
+
|
7
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each do |f|
|
8
|
+
require f
|
9
|
+
end
|
10
|
+
|
11
|
+
Mongoid.configure do |config|
|
12
|
+
config.connect_to('cached_json_test')
|
13
|
+
end
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.raise_errors_for_deprecations!
|
17
|
+
config.after :each do
|
18
|
+
Mongoid::CachedJson.config.reset!
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class AwesomeImage
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::CachedJson
|
4
|
+
|
5
|
+
field :name
|
6
|
+
field :nickname, default: 'Mona'
|
7
|
+
field :url, default: 'http://example.com/404.html'
|
8
|
+
belongs_to :awesome_artwork
|
9
|
+
|
10
|
+
json_fields \
|
11
|
+
name: {},
|
12
|
+
nickname: {},
|
13
|
+
url: { properties: :public }
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class FastJsonArtwork
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::CachedJson
|
4
|
+
|
5
|
+
field :name, default: 'Artwork'
|
6
|
+
field :display_name, default: 'Awesome Artwork'
|
7
|
+
field :price, default: 1000
|
8
|
+
has_one :fast_json_image
|
9
|
+
|
10
|
+
json_fields \
|
11
|
+
name: {},
|
12
|
+
display_name: { properties: :public },
|
13
|
+
price: { properties: :all },
|
14
|
+
image: { type: :reference, definition: :fast_json_image }
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class FastJsonImage
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::CachedJson
|
4
|
+
|
5
|
+
field :name, default: 'Image'
|
6
|
+
belongs_to :fast_json_artwork
|
7
|
+
has_and_belongs_to_many :fast_json_urls
|
8
|
+
|
9
|
+
json_fields \
|
10
|
+
name: {},
|
11
|
+
urls: { type: :reference, definition: :fast_json_urls }
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class FastJsonUrl
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::CachedJson
|
4
|
+
|
5
|
+
field :url, default: 'http://art.sy/omg.jpeg'
|
6
|
+
field :is_public, default: false
|
7
|
+
has_and_belongs_to_many :fast_json_image
|
8
|
+
|
9
|
+
json_fields \
|
10
|
+
url: {},
|
11
|
+
is_public: { properties: :all }
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class JsonFoobar
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::CachedJson
|
4
|
+
|
5
|
+
field :foo
|
6
|
+
field :bar
|
7
|
+
field :baz
|
8
|
+
field :default_foo, default: 'DEFAULT_FOO'
|
9
|
+
|
10
|
+
json_fields \
|
11
|
+
:foo => { properties: :short },
|
12
|
+
:bar => { properties: :public },
|
13
|
+
'Baz' => { definition: :baz, version: :unspecified },
|
14
|
+
'Taz' => { definition: :baz, version: :v2 },
|
15
|
+
'Naz' => { definition: :baz, versions: [:v2, :v3] },
|
16
|
+
:renamed_baz => { properties: :all, definition: :baz },
|
17
|
+
:default_foo => {}, # default value for properties is :short
|
18
|
+
:computed_field => { properties: :all, definition: lambda { |x| "#{x.foo}#{x.bar}" } }
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class JsonManager
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::CachedJson
|
4
|
+
|
5
|
+
field :name
|
6
|
+
field :ssn, default: '123-45-6789'
|
7
|
+
has_many :json_employees
|
8
|
+
belongs_to :supervisor, class_name: 'JsonSupervisor'
|
9
|
+
|
10
|
+
json_fields \
|
11
|
+
name: {},
|
12
|
+
ssn: { properties: :all },
|
13
|
+
employees: { type: :reference, definition: :json_employees }
|
14
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class JsonParentFoobar
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::CachedJson
|
4
|
+
|
5
|
+
belongs_to :json_polymorphic_referenced_foobar
|
6
|
+
embeds_one :json_polymorphic_embedded_foobar
|
7
|
+
|
8
|
+
json_fields \
|
9
|
+
json_polymorphic_referenced_foobar: { type: :reference },
|
10
|
+
json_polymorphic_embedded_foobar: { type: :reference }
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class JsonSupervisor
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::CachedJson
|
4
|
+
|
5
|
+
field :name
|
6
|
+
field :ssn, default: '123-45-6789'
|
7
|
+
has_many :json_managers
|
8
|
+
|
9
|
+
json_fields \
|
10
|
+
name: {},
|
11
|
+
ssn: { properties: :all },
|
12
|
+
managers: { type: :reference, definition: :json_managers, properties: :all, reference_properties: :short }
|
13
|
+
end
|