forked from luckyframework/avram
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Preloading specs refactor (luckyframework#548)
- Loading branch information
1 parent
4ee9f04
commit 8d84271
Showing
6 changed files
with
416 additions
and
344 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
require "../spec_helper" | ||
|
||
include LazyLoadHelpers | ||
|
||
class Post::BaseQuery | ||
include QuerySpy | ||
end | ||
|
||
describe "Preloading belongs_to associations" do | ||
it "works" do | ||
with_lazy_load(enabled: false) do | ||
Post::BaseQuery.times_called = 0 | ||
post = PostBox.create | ||
CommentBox.create &.post_id(post.id) | ||
|
||
comments = Comment::BaseQuery.new.preload_post | ||
|
||
comments.first.post.should eq(post) | ||
Post::BaseQuery.times_called.should eq 1 | ||
end | ||
end | ||
|
||
it "works with optional association" do | ||
with_lazy_load(enabled: false) do | ||
employee = EmployeeBox.create | ||
manager = ManagerBox.create | ||
|
||
employees = Employee::BaseQuery.new.preload_manager | ||
employees.first.manager.should be_nil | ||
|
||
Employee::SaveOperation.new(employee).tap do |operation| | ||
operation.manager_id.value = manager.id | ||
operation.update! | ||
end | ||
employees = Employee::BaseQuery.new.preload_manager | ||
employees.first.manager.should eq(manager) | ||
end | ||
end | ||
|
||
it "raises error if accessing association without preloading first" do | ||
with_lazy_load(enabled: false) do | ||
post = PostBox.create | ||
comment = CommentBox.create &.post_id(post.id) | ||
|
||
comment = Comment::BaseQuery.find(comment.id) | ||
|
||
expect_raises Avram::LazyLoadError do | ||
comment.post | ||
end | ||
end | ||
end | ||
|
||
it "works with nested preloads" do | ||
with_lazy_load(enabled: false) do | ||
post = PostBox.create | ||
comment = CommentBox.create &.post_id(post.id) | ||
comment2 = CommentBox.create &.post_id(post.id) | ||
|
||
comment = Comment::BaseQuery.new.preload_post(Post::BaseQuery.new.preload_comments).find(comment.id) | ||
|
||
comment.post.comments.should eq([comment, comment2]) | ||
end | ||
end | ||
|
||
it "does not fail when getting results multiple times" do | ||
post = PostBox.create | ||
CommentBox.create &.post_id(post.id) | ||
|
||
query = Comment::BaseQuery.new.preload_post | ||
|
||
2.times { query.results } | ||
end | ||
|
||
it "works with uuid foreign keys" do | ||
item = LineItemBox.create | ||
PriceBox.new.line_item_id(item.id).create | ||
|
||
PriceQuery.new.preload_line_item.first.line_item.should eq item | ||
end | ||
|
||
it "lazy loads if nothing is preloaded" do | ||
post = PostBox.create | ||
comment = CommentBox.create &.post_id(post.id) | ||
|
||
comment = Comment::BaseQuery.find(comment.id) | ||
|
||
comment.post.should eq(post) | ||
end | ||
|
||
it "skips running the preload when there's no results in the parent query" do | ||
Post::BaseQuery.times_called = 0 | ||
comments = Comment::BaseQuery.new.preload_post | ||
comments.results | ||
|
||
Post::BaseQuery.times_called.should eq 0 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
require "../spec_helper" | ||
|
||
include LazyLoadHelpers | ||
|
||
class Comment::BaseQuery | ||
include QuerySpy | ||
end | ||
|
||
describe "Preloading has_many associations" do | ||
it "works" do | ||
with_lazy_load(enabled: false) do | ||
Comment::BaseQuery.times_called = 0 | ||
post = PostBox.create | ||
comment = CommentBox.create &.post_id(post.id) | ||
|
||
posts = Post::BaseQuery.new.preload_comments | ||
|
||
posts.results.first.comments.should eq([comment]) | ||
Comment::BaseQuery.times_called.should eq 1 | ||
end | ||
end | ||
|
||
it "preserves additional criteria when used after adding a preload" do | ||
with_lazy_load(enabled: false) do | ||
post = PostBox.create | ||
another_post = PostBox.create | ||
comment = CommentBox.create &.post_id(post.id) | ||
|
||
CommentBox.create &.post_id(another_post.id) # should not be preloaded | ||
|
||
posts = Post::BaseQuery.new.preload_comments.limit(1) | ||
|
||
results = posts.results | ||
results.size.should eq(1) | ||
results.first.comments.should eq([comment]) | ||
end | ||
end | ||
|
||
it "works with custom query" do | ||
with_lazy_load(enabled: false) do | ||
post = PostBox.create | ||
comment = CommentBox.create &.post_id(post.id) | ||
|
||
posts = Post::BaseQuery.new.preload_comments( | ||
Comment::BaseQuery.new.id.not.eq(comment.id) | ||
) | ||
|
||
posts.results.first.comments.should eq([] of Comment) | ||
end | ||
end | ||
|
||
it "works with UUID foreign keys" do | ||
with_lazy_load(enabled: false) do | ||
item = LineItemBox.create | ||
scan = ScanBox.create &.line_item_id(item.id) | ||
|
||
items = LineItem::BaseQuery.new.preload_scans | ||
|
||
items.results.first.scans.should eq([scan]) | ||
end | ||
end | ||
|
||
it "works with nested preloads" do | ||
with_lazy_load(enabled: false) do | ||
post = PostBox.create | ||
CommentBox.create &.post_id(post.id) | ||
|
||
posts = Post::BaseQuery.new.preload_comments( | ||
Comment::BaseQuery.new.preload_post | ||
) | ||
|
||
posts.first.comments.first.post.should eq(post) | ||
end | ||
end | ||
|
||
it "raises error if accessing association without preloading first" do | ||
with_lazy_load(enabled: false) do | ||
post = PostBox.create | ||
|
||
expect_raises Avram::LazyLoadError do | ||
post.comments | ||
end | ||
end | ||
end | ||
|
||
it "uses an empty array if there are no associated records" do | ||
with_lazy_load(enabled: false) do | ||
PostBox.create | ||
|
||
posts = Post::BaseQuery.new.preload_comments | ||
|
||
posts.results.first.comments.should eq([] of Comment) | ||
end | ||
end | ||
|
||
it "does not fail when getting results multiple times" do | ||
PostBox.create | ||
|
||
posts = Post::BaseQuery.new.preload_comments | ||
|
||
2.times { posts.results } | ||
end | ||
|
||
it "does not fail when getting results multiple times with custom query" do | ||
post = PostBox.create | ||
_another_post = PostBox.create | ||
comment = CommentBox.create &.post_id(post.id) | ||
|
||
posts = Post::BaseQuery.new.preload_comments( | ||
Comment::BaseQuery.new.id.not.eq(comment.id) | ||
) | ||
|
||
2.times { posts.results } | ||
end | ||
|
||
it "uses preloaded records if available, even if lazy load is enabled" do | ||
with_lazy_load(enabled: true) do | ||
post = PostBox.create | ||
comment = CommentBox.create &.post_id(post.id) | ||
|
||
posts = Post::BaseQuery.new.preload_comments( | ||
Comment::BaseQuery.new.id.not.eq(comment.id) | ||
) | ||
|
||
posts.results.first.comments.should eq([] of Comment) | ||
end | ||
end | ||
|
||
it "lazy loads if nothing is preloaded" do | ||
post = PostBox.create | ||
comment = CommentBox.create &.post_id(post.id) | ||
|
||
posts = Post::BaseQuery.new | ||
|
||
posts.results.first.comments.should eq([comment]) | ||
end | ||
|
||
it "skips running the preload query when there's no results in the parent query" do | ||
Comment::BaseQuery.times_called = 0 | ||
posts = Post::BaseQuery.new.preload_comments | ||
posts.results | ||
|
||
Comment::BaseQuery.times_called.should eq 0 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
require "../spec_helper" | ||
|
||
include LazyLoadHelpers | ||
|
||
class Comment::BaseQuery | ||
include QuerySpy | ||
end | ||
|
||
describe "Preloading has_many through associations" do | ||
context "through is a has_many association that has a belongs_to relationship to target" do | ||
it "works" do | ||
with_lazy_load(enabled: false) do | ||
tag = TagBox.create | ||
TagBox.create # unused tag | ||
post = PostBox.create | ||
other_post = PostBox.create | ||
TaggingBox.create &.tag_id(tag.id).post_id(post.id) | ||
TaggingBox.create &.tag_id(tag.id).post_id(other_post.id) | ||
|
||
post_tags = Post::BaseQuery.new.preload_tags.results.first.tags | ||
|
||
post_tags.size.should eq(1) | ||
post_tags.should eq([tag]) | ||
end | ||
end | ||
|
||
it "works with uuid foreign keys" do | ||
with_lazy_load(enabled: false) do | ||
item = LineItemBox.create | ||
other_item = LineItemBox.create | ||
product = ProductBox.create | ||
ProductBox.create # unused product | ||
LineItemProductBox.create &.line_item_id(item.id).product_id(product.id) | ||
LineItemProductBox.create &.line_item_id(other_item.id).product_id(product.id) | ||
|
||
item_products = LineItemQuery.new.preload_associated_products.results.first.associated_products | ||
|
||
item_products.size.should eq(1) | ||
item_products.should eq([product]) | ||
end | ||
end | ||
|
||
it "does not fail when getting results multiple times" do | ||
PostBox.create | ||
|
||
posts = Post::BaseQuery.new.preload_tags | ||
|
||
2.times { posts.results } | ||
end | ||
end | ||
|
||
context "through is a has_many association that has a has_many relationship to target" do | ||
it "works" do | ||
with_lazy_load(enabled: false) do | ||
manager = ManagerBox.create | ||
employee = EmployeeBox.new.manager_id(manager.id).create | ||
customer = CustomerBox.new.employee_id(employee.id).create | ||
|
||
customers = Manager::BaseQuery.new.preload_customers.find(manager.id).customers | ||
|
||
customers.size.should eq(1) | ||
customers.should eq([customer]) | ||
end | ||
end | ||
end | ||
|
||
context "through is a belongs_to association that has a belongs_to relationship to target" do | ||
it "works" do | ||
with_lazy_load(enabled: false) do | ||
manager = ManagerBox.create | ||
employee = EmployeeBox.new.manager_id(manager.id).create | ||
customer = CustomerBox.new.employee_id(employee.id).create | ||
|
||
managers = Customer::BaseQuery.new.preload_managers.find(customer.id).managers | ||
|
||
managers.size.should eq(1) | ||
managers.should eq([manager]) | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.