diff --git a/.gitignore b/.gitignore index e17f3ba..4bdf39a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ /pkg/ /spec/reports/ /tmp/ +/tags /.idea/ /graphql-result_cache-*.gem \ No newline at end of file diff --git a/lib/graphql/result_cache.rb b/lib/graphql/result_cache.rb index 187cff9..83d9725 100644 --- a/lib/graphql/result_cache.rb +++ b/lib/graphql/result_cache.rb @@ -43,4 +43,6 @@ def self.use(schema_def, options: {}) end end +GraphQL::Schema::Field.accepts_definition(:result_cache) + require 'graphql/result_cache/rails' if defined?(::Rails::Engine) diff --git a/spec/fixtures/query_type.rb b/spec/fixtures/query_type.rb new file mode 100644 index 0000000..4826998 --- /dev/null +++ b/spec/fixtures/query_type.rb @@ -0,0 +1,9 @@ +class QueryType < GraphQL::Schema::Object + field_class GraphQL::ResultCache::Field + + field :colors, [String], null: false, result_cache: true + + def colors + %w[red yellow blue] + end +end diff --git a/spec/fixtures/schema.rb b/spec/fixtures/schema.rb new file mode 100644 index 0000000..534261f --- /dev/null +++ b/spec/fixtures/schema.rb @@ -0,0 +1,4 @@ +class Schema < GraphQL::Schema + query QueryType + use GraphQL::ResultCache +end diff --git a/spec/graphql/result_cache/condition_spec.rb b/spec/graphql/result_cache/condition_spec.rb index 0bfb578..f7f2995 100644 --- a/spec/graphql/result_cache/condition_spec.rb +++ b/spec/graphql/result_cache/condition_spec.rb @@ -30,8 +30,8 @@ context 'with global except' do context 'as proc' do - before(:all) do - ::GraphQL::ResultCache.except = ->(ctx) { !ctx[:result_cacheable] } + before do + allow(::GraphQL::ResultCache).to receive(:except).and_return ->(ctx) { !ctx[:result_cacheable] } end context 'evaluated as true' do diff --git a/spec/graphql/result_cache/context_config_spec.rb b/spec/graphql/result_cache/context_config_spec.rb index 3426630..60f2805 100644 --- a/spec/graphql/result_cache/context_config_spec.rb +++ b/spec/graphql/result_cache/context_config_spec.rb @@ -6,17 +6,17 @@ let(:context) { instance_double('GraphQL::Context', query: query, path: path) } let(:result) { instance_double('GraphQL::Result', query: query) } let(:cache_key) { 'cache_key' } - let(:cache) { double('cache') } + let(:cache_store) { double('cache') } let(:callback) { instance_double('GraphQL::ResultCache::Callback') } before do - ::GraphQL::ResultCache.cache = cache + allow(::GraphQL::ResultCache).to receive(:cache).and_return cache_store end describe '#add' do context 'when not cached' do before do - expect(cache).to receive(:exist?).with(cache_key).and_return false + expect(cache_store).to receive(:exist?).with(cache_key).and_return false end after do @@ -34,8 +34,8 @@ context 'when cached' do before do - expect(cache).to receive(:exist?).with(cache_key).and_return true - allow(cache).to receive(:read).with(cache_key).and_return 'cached_result' + expect(cache_store).to receive(:exist?).with(cache_key).and_return true + allow(cache_store).to receive(:read).with(cache_key).and_return 'cached_result' end it 'should add with cached result' do @@ -55,7 +55,7 @@ context 'without cached result' do after do expect(subject).to receive(:dig).with(result, 'data', *path).and_return 'result_on_path' - expect(cache).to receive(:write).with(cache_key, 'result_on_path', expires_in: 3600) + expect(cache_store).to receive(:write).with(cache_key, 'result_on_path', expires_in: 3600) expect(subject.process(result)).to eq result end @@ -75,7 +75,7 @@ after do allow(result).to receive(:to_h).and_return result_value - expect(cache).to receive(:write).never + expect(cache_store).to receive(:write).never expect(subject.process(result)).to eq result expect(result_value).to eq expected_result end @@ -98,7 +98,7 @@ it 'should return result without process' do subject.value[other_query] = [{path: path, key: cache_key, result: nil}] expect(subject).to receive(:dig).never - expect(cache).to receive(:write).never + expect(cache_store).to receive(:write).never expect(subject.process(result)).to eq result end end diff --git a/spec/graphql/result_cache/key_spec.rb b/spec/graphql/result_cache/key_spec.rb index 9e675f7..73c0cd3 100644 --- a/spec/graphql/result_cache/key_spec.rb +++ b/spec/graphql/result_cache/key_spec.rb @@ -79,19 +79,19 @@ let(:client_hash_value) { Time.now.to_i } it 'should call the proc' do - ::GraphQL::ResultCache.client_hash = -> { client_hash_value } + allow(::GraphQL::ResultCache).to receive(:client_hash).and_return -> { client_hash_value } expect(clause).to eq(client_hash_value) end end context 'when client hash is a scala value' do it 'should be nil when client hash not set' do - ::GraphQL::ResultCache.client_hash = nil + allow(::GraphQL::ResultCache).to receive(:client_hash).and_return nil expect(clause).to be_nil end it 'should be the value when client hash is a string' do - ::GraphQL::ResultCache.client_hash = 'abcdef' + allow(::GraphQL::ResultCache).to receive(:client_hash).and_return 'abcdef' expect(clause).to eq('abcdef') end end diff --git a/spec/query_spec.rb b/spec/query_spec.rb new file mode 100644 index 0000000..bbbd97c --- /dev/null +++ b/spec/query_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' +require 'fixtures/query_type' +require 'fixtures/schema' + +RSpec.describe 'query with result cache' do + let(:cache_store) { double('cache_store') } + let(:query_string) { 'query { colors }' } + let(:result) { GraphQL::ResultCache::Result.new(Schema.execute(query_string)).value } + + before do + allow(GraphQL::ResultCache).to receive(:cache).and_return cache_store + end + + it 'query with cache missed' do + cache_key = 'GraphQL:Result:colors' + expect(cache_store).to receive(:exist?).with(cache_key).and_return false + expect(cache_store).not_to receive(:read) + expect(cache_store).to receive(:write).with(cache_key, %w[red yellow blue], expires_in: 3600) + expect(result).to eq 'data' => { 'colors' => %w[red yellow blue] } + end + + it 'queries with cache hits' do + cache_key = 'GraphQL:Result:colors' + expect(cache_store).to receive(:exist?).with(cache_key).and_return true + expect(cache_store).to receive(:read).with(cache_key).and_return %w[red yellow] + expect(cache_store).not_to receive(:write) + expect(result).to eq 'data' => { 'colors' => %w[red yellow] } + end +end