Skip to content

Commit 4b0cad9

Browse files
committed
Add basic tests to help in gem maintenance
1 parent 0433be8 commit 4b0cad9

File tree

10 files changed

+176
-22
lines changed

10 files changed

+176
-22
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
/pkg/
88
/spec/reports/
99
/tmp/
10+
.rspec_status

.ruby-version

Lines changed: 0 additions & 1 deletion
This file was deleted.

Rakefile

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
require 'bundler/gem_tasks'
2-
require 'rake/testtask'
2+
require 'rspec/core/rake_task'
33

4-
Rake::TestTask.new(:test) do |t|
5-
t.libs << 'test'
6-
t.libs << 'lib'
7-
t.test_files = FileList['test/**/*_test.rb']
8-
end
4+
RSpec::Core::RakeTask.new
95

10-
task default: :test
6+
task default: :spec

graphql-preload.gemspec

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ Gem::Specification.new do |spec|
2727
spec.add_runtime_dependency 'promise.rb', '~> 0.7'
2828

2929
spec.add_development_dependency 'bundler', '~> 1.16'
30-
spec.add_development_dependency 'minitest', '~> 5.0'
3130
spec.add_development_dependency 'pry', '~> 0.10'
3231
spec.add_development_dependency 'rake', '~> 10.0'
32+
spec.add_development_dependency 'rspec', '~> 3.8'
33+
spec.add_development_dependency 'rspec-sqlimit'
34+
spec.add_development_dependency 'sqlite3'
3335
spec.add_development_dependency 'yard', '~> 0.9'
3436
end

spec/graphql/preload_spec.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
require "spec_helper"
3+
4+
RSpec.describe GraphQL::Preload do
5+
subject do
6+
@result ||=
7+
PreloadSchema.execute(query: query_string, context: {}, variables: {})
8+
end
9+
10+
context "without associations" do
11+
let(:query_string) { "query { products { title } }" }
12+
13+
it "doesn't load associations at all" do
14+
expect { subject }.not_to exceed_query_limit 1
15+
end
16+
end
17+
18+
context "with associations" do
19+
let(:query_string) do
20+
<<~QRAPHQL
21+
query { posts { title comments { text } } }
22+
QRAPHQL
23+
end
24+
25+
it "preloads associations by single query" do
26+
expect { subject }.to exceed_query_limit 1 # to ensure that GraphQL query at least works
27+
expect { subject }.not_to exceed_query_limit 2
28+
posts = subject.dig("data", "posts")
29+
expect(posts.size).to eq(4)
30+
expect(posts.flat_map { |p| p["comments"] }.size).to eq(8)
31+
end
32+
end
33+
34+
context "with associations with custom scopes" do
35+
let(:query_string) do
36+
<<~QRAPHQL
37+
query { users { name posts { title } } }
38+
QRAPHQL
39+
end
40+
41+
it "preloads associations by single query and given order" do
42+
expect { subject }.not_to exceed_query_limit 2
43+
posts = subject.dig("data", "users").flat_map { |p| p["posts"] }
44+
# Posts for every user should be from greater rating to lower
45+
expect(posts.map { |p| p["title"] }).to eq(%w[Bar Foo Baz Huh])
46+
end
47+
end
48+
end

spec/spec_helper.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
require "bundler/setup"
4+
require "graphql/preload"
5+
require "rspec-sqlimit"
6+
require "pry"
7+
8+
require_relative "support/database"
9+
require_relative "support/graphql_schema"
10+
11+
RSpec.configure do |config|
12+
# Enable flags like --only-failures and --next-failure
13+
config.example_status_persistence_file_path = ".rspec_status"
14+
15+
# Disable RSpec exposing methods globally on `Module` and `main`
16+
config.disable_monkey_patching!
17+
18+
config.expect_with :rspec do |c|
19+
c.syntax = :expect
20+
end
21+
22+
config.mock_with :rspec
23+
24+
Kernel.srand config.seed
25+
config.order = :random
26+
end

spec/support/database.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# frozen_string_literal: true
2+
require "active_record"
3+
require "sqlite3"
4+
5+
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
6+
7+
ActiveRecord::Schema.define(version: 0) do
8+
create_table :users do |t|
9+
t.string :name
10+
end
11+
12+
create_table :posts do |t|
13+
t.string :title
14+
t.text :text
15+
t.float :rating
16+
t.references :author, foreign_key: { to_table: :users, column: :author_id, on_delete: :cascade }
17+
end
18+
19+
create_table :comments do |t|
20+
t.text :text
21+
t.references :post, foreign_key: { on_delete: :cascade }
22+
t.references :author, foreign_key: { to_table: :users, column: :author_id, on_delete: :cascade }
23+
end
24+
end
25+
26+
class User < ActiveRecord::Base
27+
has_many :posts, inverse_of: :author, foreign_key: :author_id
28+
has_many :comments, inverse_of: :author, foreign_key: :author_id
29+
end
30+
31+
class Post < ActiveRecord::Base
32+
belongs_to :author, class_name: "User"
33+
has_many :comments
34+
end
35+
36+
class Comment < ActiveRecord::Base
37+
belongs_to :author, class_name: "User"
38+
belongs_to :post
39+
end
40+
41+
alice, bob = User.create!([{ name: 'Alice' }, { name: 'Bob' }])
42+
43+
alice.posts.create!([{ title: "Foo", rating: 4 }, { title: "Bar", rating: 8 }])
44+
bob.posts.create!([{ title: "Baz", rating: 7 }, { title: "Huh", rating: 4.2 }])
45+
46+
Post.all.each do |post|
47+
alice.comments.create(post: post, text: "Great post!")
48+
bob.comments.create(post: post, text: "Great post!")
49+
end

spec/support/graphql_schema.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# frozen_string_literal: true
2+
3+
class CommentType < GraphQL::Schema::Object
4+
field :id, ID, null: false
5+
field :text, String, null: false
6+
field :author_id, ID, null: false
7+
field :post_id, ID, null: false
8+
end
9+
10+
class PostType < GraphQL::Schema::Object
11+
field :id, ID, null: false
12+
field :title, String, null: false
13+
field :text, String, null: false
14+
field :rating, Float, null: false
15+
field :comments, [CommentType], null: false, preload: :comments
16+
field :author_id, ID, null: false
17+
end
18+
19+
class UserType < GraphQL::Schema::Object
20+
field :id, ID, null: false
21+
field :name, String, null: false
22+
field :comments, [CommentType], null: false, preload: :comments
23+
field :posts, [PostType], null: false,
24+
preload: :posts,
25+
preload_scope: ->(*) { Post.order(rating: :desc) }
26+
end
27+
28+
class QueryType < GraphQL::Schema::Object
29+
field :users, [UserType], null: false
30+
field :posts, [PostType], null: false
31+
32+
def users
33+
User.all
34+
end
35+
36+
def posts
37+
Post.all
38+
end
39+
end
40+
41+
class PreloadSchema < GraphQL::Schema
42+
use GraphQL::Batch
43+
enable_preloading
44+
45+
query QueryType
46+
end

test/graphql/preload_test.rb

Lines changed: 0 additions & 9 deletions
This file was deleted.

test/test_helper.rb

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)