diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..33dbcfc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,61 @@ +# This workflow uses actions that are not certified by GitHub. They are +# provided by a third-party and are governed by separate terms of service, +# privacy policy, and support documentation. +# +# This workflow will install a prebuilt Ruby version, install dependencies, and +# run tests and linters. +name: "active_remote-cached" +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + ruby-version: [ '3.2', '3.1', '3.0', '2.7', 'jruby-9.4' ] + gemfile: [ 'rails60', 'rails61', 'rails70' ] + env: + RAILS_ENV: test + steps: + - name: Checkout code + uses: actions/checkout@v3 + # Add or replace dependency steps here + - name: Install Ruby and gems + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + ruby-version: ${{ matrix.ruby-version }} + env: + BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile + # Add or replace test runners here + - name: Run tests + run: bundle exec rake test + env: + BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile + old_tests: + runs-on: ubuntu-latest + strategy: + matrix: + ruby-version: [ '2.6', 'jruby-9.3' ] + gemfile: [ 'rails60', 'rails61' ] + env: + RAILS_ENV: test + steps: + - name: Checkout code + uses: actions/checkout@v3 + # Add or replace dependency steps here + - name: Install Ruby and gems + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + ruby-version: ${{ matrix.ruby-version }} + env: + BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile + # Add or replace test runners here + - name: Run tests + run: bundle exec rake test + env: + BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile diff --git a/README.md b/README.md index a99df54..132a9c7 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,8 @@ end _*This is already done for you in Rails_ -Then declare some cache finder methods. Cached finders can be defined for individual fields or defined as composites for mulitple fields +Then declare some cache finder methods. Cached finders can be defined for individual fields or defined as composites for +multiple fields ```ruby class Customer < ::ActiveRemote::Base @@ -42,7 +43,8 @@ class Customer < ::ActiveRemote::Base end ``` -Now that you have a model that has cached finders on it you can use the `cached_search`, `cached_find`, or dynamic cached finder methods on the model to use the cache before you issue the AR search/find method. +Now that you have a model that has cached finders on it you can use the `cached_search`, `cached_find`, or dynamic +cached finder methods on the model to use the cache before you issue the AR search/find method. ```ruby customer = ::Customer.cached_find_by_id(1) # => @@ -62,13 +64,14 @@ customer = ::Customer.cached_find_by_name("name") # => NoMethodError ### Configuring the cache provider -ActiveRemote::Cached relies on an ActiveSupport::Cache-compatible cache provider. The cache is initialized with a simple memory store (defaults to 32MB), but can be overridden via `ActiveRemote::Cached.cache`: +ActiveRemote::Cached relies on an ActiveSupport::Cache-compatible cache provider. The cache is initialized with a simple +memory store (defaults to 32MB), but can be overridden via `ActiveRemote::Cached.cache`: ```ruby ActiveRemote::Cached.cache(Your::ActiveSupport::Cache::Compatible::Provider.new) ``` -In Rails apps, the memory store is replaced the whatever Rails is using as it's cache store. +In Rails apps, the memory store is replaced with whatever Rails is using as it's cache store. #### Default options @@ -78,11 +81,19 @@ The default cache options used when interacting with the cache can be specified ActiveRemote::Cached.default_options(:expires_in => 1.hour) ``` -In Rails apps, the :race_condition_ttl option defaults to 5 seconds. +In Rails apps, the options are: + +| Configuration Option | Default | Description | +|-----------------------|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `:race_condition_ttl` | `5.seconds` | See [ActiveSupport::Cache::Store documentation](https://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html) | +| `:expires_in` | `5.minutes` | See [ActiveSupport::Cache::Store documentation](https://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html) | +| `:handle_cache_error` | `false` | When true, cache errors will be handled and optionally sent to handler and return value will be as if cache missed, when cache errors will raise to application | +| `:cache_error_proc` | `nil` | Can be a proc that accepts a single value, the cache error raised, to be used in any kind of error handling you might want | #### Local overrides -Each finder as takes an optional options hash that will override the options passed to the caching provider (override from the global defaults setup for ActiveRemote::Cached) +Each finder takes an optional options hash that will override the options passed to the caching provider (override from +the global defaults setup for ActiveRemote::Cached) ```ruby customer = ::Customer.cached_find_by_id(1, :expires_in => 15.minutes) diff --git a/gemfiles/rails60.gemfile b/gemfiles/rails60.gemfile new file mode 100644 index 0000000..fce542b --- /dev/null +++ b/gemfiles/rails60.gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "activesupport", "~> 6.0.0" +gemspec path: "../" diff --git a/gemfiles/rails60.gemfile.lock b/gemfiles/rails60.gemfile.lock new file mode 100644 index 0000000..b099da6 --- /dev/null +++ b/gemfiles/rails60.gemfile.lock @@ -0,0 +1,71 @@ +PATH + remote: .. + specs: + active_remote-cached (0.2.0) + active_remote + activesupport + +GEM + remote: https://rubygems.org/ + specs: + active_remote (6.0.2) + activemodel (~> 6.0.0) + activesupport (~> 6.0.0) + protobuf (>= 3.0) + activemodel (6.0.6.1) + activesupport (= 6.0.6.1) + activesupport (6.0.6.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + zeitwerk (~> 2.2, >= 2.2.2) + coderay (1.1.3) + concurrent-ruby (1.2.2) + ffi (1.15.5-java) + i18n (1.12.0) + concurrent-ruby (~> 1.0) + method_source (1.0.0) + middleware (0.1.0) + minitest (5.18.0) + mocha (2.0.2) + ruby2_keywords (>= 0.0.5) + protobuf (3.10.7) + activesupport (>= 3.2) + middleware + thor + thread_safe + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) + pry (0.14.2-java) + coderay (~> 1.1) + method_source (~> 1.0) + spoon (~> 0.0) + rake (13.0.6) + ruby2_keywords (0.0.5) + spoon (0.0.6) + ffi + thor (1.2.1) + thread_safe (0.3.6) + thread_safe (0.3.6-java) + tzinfo (1.2.11) + thread_safe (~> 0.1) + zeitwerk (2.6.7) + +PLATFORMS + universal-java-1.8 + universal-java-11 + x86_64-darwin-22 + x86_64-linux + +DEPENDENCIES + active_remote-cached! + activesupport (~> 6.0.0) + bundler + mocha + pry + rake + +BUNDLED WITH + 2.4.12 diff --git a/gemfiles/rails61.gemfile b/gemfiles/rails61.gemfile new file mode 100644 index 0000000..4fa71e7 --- /dev/null +++ b/gemfiles/rails61.gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "activesupport", "~> 6.1.0" +gemspec path: "../" diff --git a/gemfiles/rails61.gemfile.lock b/gemfiles/rails61.gemfile.lock new file mode 100644 index 0000000..7b45887 --- /dev/null +++ b/gemfiles/rails61.gemfile.lock @@ -0,0 +1,71 @@ +PATH + remote: .. + specs: + active_remote-cached (0.2.0) + active_remote + activesupport + +GEM + remote: https://rubygems.org/ + specs: + active_remote (6.1.1) + activemodel (~> 6.1.0) + activesupport (~> 6.1.0) + protobuf (>= 3.0) + activemodel (6.1.7.3) + activesupport (= 6.1.7.3) + activesupport (6.1.7.3) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) + coderay (1.1.3) + concurrent-ruby (1.2.2) + ffi (1.15.5-java) + i18n (1.12.0) + concurrent-ruby (~> 1.0) + method_source (1.0.0) + middleware (0.1.0) + minitest (5.18.0) + mocha (2.0.2) + ruby2_keywords (>= 0.0.5) + protobuf (3.10.7) + activesupport (>= 3.2) + middleware + thor + thread_safe + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) + pry (0.14.2-java) + coderay (~> 1.1) + method_source (~> 1.0) + spoon (~> 0.0) + rake (13.0.6) + ruby2_keywords (0.0.5) + spoon (0.0.6) + ffi + thor (1.2.1) + thread_safe (0.3.6) + thread_safe (0.3.6-java) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + zeitwerk (2.6.7) + +PLATFORMS + universal-java-1.8 + universal-java-11 + x86_64-darwin-22 + x86_64-linux + +DEPENDENCIES + active_remote-cached! + activesupport (~> 6.1.0) + bundler + mocha + pry + rake + +BUNDLED WITH + 2.4.12 diff --git a/gemfiles/rails70.gemfile b/gemfiles/rails70.gemfile new file mode 100644 index 0000000..9818eb6 --- /dev/null +++ b/gemfiles/rails70.gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "activesupport", "~> 7.0.0" +gemspec path: "../" diff --git a/gemfiles/rails70.gemfile.lock b/gemfiles/rails70.gemfile.lock new file mode 100644 index 0000000..bc8c06f --- /dev/null +++ b/gemfiles/rails70.gemfile.lock @@ -0,0 +1,69 @@ +PATH + remote: .. + specs: + active_remote-cached (0.2.0) + active_remote + activesupport + +GEM + remote: https://rubygems.org/ + specs: + active_remote (3.1.2) + activemodel (>= 4.0) + activesupport (>= 4.0) + protobuf (>= 3.0) + activemodel (7.0.4.3) + activesupport (= 7.0.4.3) + activesupport (7.0.4.3) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + coderay (1.1.3) + concurrent-ruby (1.2.2) + ffi (1.15.5-java) + i18n (1.12.0) + concurrent-ruby (~> 1.0) + method_source (1.0.0) + middleware (0.1.0) + minitest (5.18.0) + mocha (2.0.2) + ruby2_keywords (>= 0.0.5) + protobuf (3.10.7) + activesupport (>= 3.2) + middleware + thor + thread_safe + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) + pry (0.14.2-java) + coderay (~> 1.1) + method_source (~> 1.0) + spoon (~> 0.0) + rake (13.0.6) + ruby2_keywords (0.0.5) + spoon (0.0.6) + ffi + thor (1.2.1) + thread_safe (0.3.6) + thread_safe (0.3.6-java) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + +PLATFORMS + universal-java-1.8 + universal-java-11 + x86_64-darwin-22 + x86_64-linux + +DEPENDENCIES + active_remote-cached! + activesupport (~> 7.0.0) + bundler + mocha + pry + rake + +BUNDLED WITH + 2.4.12 diff --git a/lib/active_remote/cached.rb b/lib/active_remote/cached.rb index 4940e46..cdba0d0 100644 --- a/lib/active_remote/cached.rb +++ b/lib/active_remote/cached.rb @@ -3,10 +3,11 @@ require "active_support/concern" require "active_support/core_ext/array/extract_options" +require "active_remote" +require "active_remote/errors" require "active_remote/cached/argument_keys" require "active_remote/cached/cache" require "active_remote/cached/version" -require "active_remote/errors" module ActiveRemote module Cached @@ -24,6 +25,17 @@ def self.cache(cache_provider = nil) @cache_provider end + def self.cache_options + ::ActiveRemote::Cached.default_options.slice( + :expires_in, + "expires_in", + :namespace, + "namespace", + :race_condition_ttl, + "race_condition_ttl" + ) + end + def self.default_options(options = nil) if options @default_options = options @@ -145,7 +157,7 @@ def _define_cached_delete_method(method_name, *method_arguments, cached_finder_o # ::ActiveRemote::Cached.cache.delete([name, user_guid]) # end def self.#{method_name}(#{expanded_method_args}, __active_remote_cached_options = {}) - __active_remote_cached_options = ::ActiveRemote::Cached.default_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) + __active_remote_cached_options = ::ActiveRemote::Cached.cache_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) namespace = __active_remote_cached_options.delete(:namespace) find_cache_key = [ RUBY_AND_ACTIVE_SUPPORT_VERSION, @@ -179,7 +191,7 @@ def _define_cached_exist_find_method(method_name, *method_arguments, cached_find # ::ActiveRemote::Cached.cache.exist?([name, user_guid]) # end def self.#{method_name}(#{expanded_method_args}, __active_remote_cached_options = {}) - __active_remote_cached_options = ::ActiveRemote::Cached.default_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) + __active_remote_cached_options = ::ActiveRemote::Cached.cache_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) namespace = __active_remote_cached_options.delete(:namespace) cache_key = [ RUBY_AND_ACTIVE_SUPPORT_VERSION, @@ -206,7 +218,7 @@ def _define_cached_exist_search_method(method_name, *method_arguments, cached_fi # ::ActiveRemote::Cached.cache.exist?([namespace, name, "#search", user_guid]) # end def self.#{method_name}(#{expanded_method_args}, __active_remote_cached_options = {}) - __active_remote_cached_options = ::ActiveRemote::Cached.default_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) + __active_remote_cached_options = ::ActiveRemote::Cached.cache_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) namespace = __active_remote_cached_options.delete(:namespace) cache_key = [ RUBY_AND_ACTIVE_SUPPORT_VERSION, @@ -235,7 +247,7 @@ def _define_cached_find_method(method_name, *method_arguments, cached_finder_opt self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 # def self.cached_find_by_user_guid(user_guid, options = {}) - # options = ::ActiveRemote::Cached.default_options.merge({}).merge(options) + # options = ::ActiveRemote::Cached.cache_options.merge({}).merge(options) # # ::ActiveRemote::Cached.cache.fetch([namespace, name, "#find", user_guid], options) do # self.find(:user_guid => user_guid) @@ -246,7 +258,7 @@ def _define_cached_find_method(method_name, *method_arguments, cached_finder_opt # of the result object is maintained for requests/responses # def self.#{method_name}(#{expanded_method_args}, __active_remote_cached_options = {}) - __active_remote_cached_options = ::ActiveRemote::Cached.default_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) + __active_remote_cached_options = ::ActiveRemote::Cached.cache_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) namespace = __active_remote_cached_options.delete(:namespace) cache_key = [ RUBY_AND_ACTIVE_SUPPORT_VERSION, @@ -279,7 +291,7 @@ def _define_cached_search_method(method_name, *method_arguments, cached_finder_o self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 # def self.cached_search_by_user_guid(user_guid, options = {}) - # options = ::ActiveRemote::Cached.default_options.merge({}).merge(options) + # options = ::ActiveRemote::Cached.cache_options.merge({}).merge(options) # # ::ActiveRemote::Cached.cache.fetch([namespace, name, "#search", user_guid], options) do # if block_given? @@ -294,7 +306,7 @@ def _define_cached_search_method(method_name, *method_arguments, cached_finder_o # of the result object is maintained for requests/responses # def self.#{method_name}(#{expanded_method_args}, __active_remote_cached_options = {}) - __active_remote_cached_options = ::ActiveRemote::Cached.default_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) + __active_remote_cached_options = ::ActiveRemote::Cached.cache_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) namespace = __active_remote_cached_options.delete(:namespace) cache_key = [ RUBY_AND_ACTIVE_SUPPORT_VERSION, @@ -327,7 +339,7 @@ def _define_cached_search_bang_method(method_name, *method_arguments, cached_fin self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 # def self.cached_search_by_user_guid!(user_guid, options = {}) - # options = ::ActiveRemote::Cached.default_options.merge({}).merge(options) + # options = ::ActiveRemote::Cached.cache_options.merge({}).merge(options) # # ::ActiveRemote::Cached.cache.fetch([namespace, name, "#search", user_guid], options) do # results = [] @@ -347,7 +359,7 @@ def _define_cached_search_bang_method(method_name, *method_arguments, cached_fin # of the result object is maintained for requests/responses # def self.#{method_name}(#{expanded_method_args}, __active_remote_cached_options = {}) - __active_remote_cached_options = ::ActiveRemote::Cached.default_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) + __active_remote_cached_options = ::ActiveRemote::Cached.cache_options.merge(#{cached_finder_options}).merge(__active_remote_cached_options) namespace = __active_remote_cached_options.delete(:namespace) cache_key = [ RUBY_AND_ACTIVE_SUPPORT_VERSION, diff --git a/lib/active_remote/cached/cache.rb b/lib/active_remote/cached/cache.rb index ff5dae2..c826e03 100644 --- a/lib/active_remote/cached/cache.rb +++ b/lib/active_remote/cached/cache.rb @@ -20,6 +20,9 @@ def initialize(new_cache_provider) def delete(*args) nested_cache_provider.delete(*args) super + rescue => e + handle_or_reraise_cache_error(e) + nil end def enable_nested_caching! @@ -28,10 +31,17 @@ def enable_nested_caching! def exist?(*args) nested_cache_provider.exist?(*args) || super + rescue => e + handle_or_reraise_cache_error(e) + false end def fetch(name, options = {}) - fetch_value = nested_cache_provider.fetch(name, options) { super } + fetch_value = read(name, options) + if fetch_value.nil? + fetch_value = super if block_given? + write(name, fetch_value, options) if valid_fetched_value?(fetch_value, options) + end unless valid_fetched_value?(fetch_value, options) delete(name) @@ -42,15 +52,27 @@ def fetch(name, options = {}) def read(*args) nested_cache_provider.read(*args) || super + rescue => e + handle_or_reraise_cache_error(e) + nil end def write(*args) nested_cache_provider.write(*args) super + rescue => e + handle_or_reraise_cache_error(e) + nil end private + def handle_or_reraise_cache_error(e) + raise e unless ::ActiveRemote::Cached.default_options[:handle_cache_error] + error_proc = ::ActiveRemote::Cached.default_options[:cache_error_proc] + error_proc.call(e) if error_proc.respond_to?(:call) + end + def nested_cache_provider @nested_cache_provider end diff --git a/lib/active_remote/cached/railtie.rb b/lib/active_remote/cached/railtie.rb index 8a8069c..337a999 100644 --- a/lib/active_remote/cached/railtie.rb +++ b/lib/active_remote/cached/railtie.rb @@ -6,17 +6,21 @@ class Railtie < ::Rails::Railtie config.active_remote_cached = ::ActiveSupport::OrderedOptions.new initializer "active_remote-cached.initialize_cache" do |app| + config.active_remote_cached.cache_error_proc ||= nil config.active_remote_cached.expires_in ||= 5.minutes + config.active_remote_cached.handle_cache_error ||= false config.active_remote_cached.race_condition_ttl ||= 5.seconds - ::ActiveRemote::Cached.cache(Rails.cache) + ::ActiveRemote::Cached.cache(::Rails.cache) if config.active_remote_cached.enable_nested_caching ::ActiveRemote::Cached.cache.enable_nested_caching! end ::ActiveRemote::Cached.default_options( + :cache_error_proc => config.active_remote_cached.cache_error_proc, :expires_in => config.active_remote_cached.expires_in, + :handle_cache_error => config.active_remote_cached.handle_cache_error, :race_condition_ttl => config.active_remote_cached.race_condition_ttl ) end diff --git a/lib/active_remote/cached/version.rb b/lib/active_remote/cached/version.rb index 7fb1c28..76c4931 100644 --- a/lib/active_remote/cached/version.rb +++ b/lib/active_remote/cached/version.rb @@ -1,5 +1,5 @@ module ActiveRemote module Cached - VERSION = "0.2.0" + VERSION = "0.3.0.rc1" end end diff --git a/spec/active_remote/cached/argument_keys_spec.rb b/spec/active_remote/cached/argument_keys_spec.rb index 161fca1..7ee856f 100644 --- a/spec/active_remote/cached/argument_keys_spec.rb +++ b/spec/active_remote/cached/argument_keys_spec.rb @@ -2,24 +2,24 @@ describe ::ActiveRemote::Cached::ArgumentKeys do it "does not mutate a string by default" do - ::ActiveRemote::Cached::ArgumentKeys.new("hello", {}).cache_key.must_equal("hello") + _(::ActiveRemote::Cached::ArgumentKeys.new("hello", {}).cache_key).must_equal("hello") end it "returns a string of a symbol by default" do - ::ActiveRemote::Cached::ArgumentKeys.new(:hello, {}).cache_key.must_equal("hello") + _(::ActiveRemote::Cached::ArgumentKeys.new(:hello, {}).cache_key).must_equal("hello") end it "does not mutate a string with special characters by default" do - ::ActiveRemote::Cached::ArgumentKeys.new("hello {}", {}).cache_key.must_equal("hello {}") + _(::ActiveRemote::Cached::ArgumentKeys.new("hello {}", {}).cache_key).must_equal("hello {}") end it "removes special characters from string with special characters when :active_remote_cached_remove_characters" do options = { :active_remote_cached_remove_characters => true } - ::ActiveRemote::Cached::ArgumentKeys.new("hello {}", options).cache_key.must_equal("hello") + _(::ActiveRemote::Cached::ArgumentKeys.new("hello {}", options).cache_key).must_equal("hello") end it "replaces special characters from string with special characters when :active_remote_cached_replace_characters" do options = { :active_remote_cached_replace_characters => true } - ::ActiveRemote::Cached::ArgumentKeys.new("hello {}", options).cache_key.must_equal("helloSPLBRB") + _(::ActiveRemote::Cached::ArgumentKeys.new("hello {}", options).cache_key).must_equal("helloSPLBRB") end end diff --git a/spec/active_remote/cached/cache_spec.rb b/spec/active_remote/cached/cache_spec.rb index f07a4ec..81b265f 100644 --- a/spec/active_remote/cached/cache_spec.rb +++ b/spec/active_remote/cached/cache_spec.rb @@ -4,32 +4,208 @@ describe "API" do it "validates #delete present" do cache = OpenStruct.new(:write => nil, :fetch => nil, :read => nil, :exist? => nil) - error = lambda { ::ActiveRemote::Cached.cache(cache) }.must_raise(RuntimeError) - error.message.must_match(/respond_to.*delete/i) + error = _(lambda { ::ActiveRemote::Cached.cache(cache) }).must_raise(RuntimeError) + _(error.message).must_match(/respond_to.*delete/i) end it "validates #exist? present" do cache = OpenStruct.new(:write => nil, :delete => nil, :read => nil, :fetch => nil) - error = lambda { ::ActiveRemote::Cached.cache(cache) }.must_raise(RuntimeError) - error.message.must_match(/respond_to.*exist/i) + error = _(lambda { ::ActiveRemote::Cached.cache(cache) }).must_raise(RuntimeError) + _(error.message).must_match(/respond_to.*exist/i) end it "validates #fetch present" do cache = OpenStruct.new(:write => nil, :delete => nil, :read => nil, :exist? => nil) - error = lambda { ::ActiveRemote::Cached.cache(cache) }.must_raise(RuntimeError) - error.message.must_match(/respond_to.*fetch/i) + error = _(lambda { ::ActiveRemote::Cached.cache(cache) }).must_raise(RuntimeError) + _(error.message).must_match(/respond_to.*fetch/i) end it "validates #read present" do cache = OpenStruct.new(:write => nil, :delete => nil, :fetch => nil, :exist? => nil) - error = lambda { ::ActiveRemote::Cached.cache(cache) }.must_raise(RuntimeError) - error.message.must_match(/respond_to.*read/i) + error = _(lambda { ::ActiveRemote::Cached.cache(cache) }).must_raise(RuntimeError) + _(error.message).must_match(/respond_to.*read/i) end it "validates #write present" do cache = OpenStruct.new(:read => nil, :delete => nil, :fetch => nil, :exist? => nil) - error = lambda { ::ActiveRemote::Cached.cache(cache)}.must_raise(RuntimeError) - error.message.must_match(/respond_to.*write/i) + error = _(lambda { ::ActiveRemote::Cached.cache(cache) }).must_raise(RuntimeError) + _(error.message).must_match(/respond_to.*write/i) + end + end + + describe "#delete" do + it "returns nil when cache delete attempt raises an error" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => true, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:delete).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _(ar_cache.delete("some_key")).must_be_nil + end + + it "calls error proc" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => true, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:delete).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + ::ActiveRemote::Cached.default_options[:cache_error_proc].expects(:call) + ar_cache.delete("some_key") + end + + describe "when handle_cache_error is false" do + it "raises error" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => false, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:delete).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _ { ar_cache.delete("some_key") }.must_raise(::RuntimeError, "kaBOOM") + end + + it "doesn't invoke error proc" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => false, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:delete).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + ::ActiveRemote::Cached.default_options[:cache_error_proc].expects(:log).never + _ { ar_cache.delete("some_key") }.must_raise(::RuntimeError, "kaBOOM") + end + end + end + + describe "#exist?" do + it "returns false when cache exist? attempt check raises an error" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => true, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:exist?).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _(ar_cache.exist?("some_key")).must_equal(false) + end + + it "calls error proc" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => true, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:exist?).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + ::ActiveRemote::Cached.default_options[:cache_error_proc].expects(:call) + ar_cache.exist?("some_key") + end + + describe "when handle_cache_error is false" do + it "raises error" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => false, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:exist?).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _ { ar_cache.exist?("some_key") }.must_raise(::RuntimeError, "kaBOOM") + end + + it "doesn't invoke error proc" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => false, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:exist?).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + ::ActiveRemote::Cached.default_options[:cache_error_proc].expects(:log).never + _ { ar_cache.exist?("some_key") }.must_raise(::RuntimeError, "kaBOOM") + end + end + end + + describe "#fetch" do + it "returns cached value when read finds something" do + cache = HashCache.new + cache.write("some_key", "tada!") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _(ar_cache.fetch("some_key")).must_equal("tada!") + end + + it "invokes block when read returns nothing" do + cache = HashCache.new + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _(ar_cache.fetch("some_key") { "tada!" }).must_equal("tada!") + end + + it "removes cache key when returned value is invalid" do + cache = HashCache.new + cache.write("some_key", []) + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _(cache.exist?("some_key")).must_equal(true) + ar_cache.fetch("some_key") + _(cache.exist?("some_key")).must_equal(false) + end + end + + describe "#read" do + it "returns nil when cache read attempt raises an error" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => true, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:read).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _(ar_cache.read("some_key")).must_be_nil + end + + it "calls error proc" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => true, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:read).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + ::ActiveRemote::Cached.default_options[:cache_error_proc].expects(:call) + ar_cache.read("some_key") + end + + describe "when handle_cache_error is false" do + it "raises error" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => false, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:read).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _ { ar_cache.read("some_key") }.must_raise(::RuntimeError, "kaBOOM") + end + + it "doesn't invoke error proc" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => false, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:read).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + ::ActiveRemote::Cached.default_options[:cache_error_proc].expects(:log).never + _ { ar_cache.read("some_key") }.must_raise(::RuntimeError, "kaBOOM") + end + end + end + + describe "#write" do + it "returns nil when cache write attempt raises an error" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => true, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:write).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _(ar_cache.write("some_key", "some_value")).must_be_nil + end + + it "calls error proc" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => true, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:write).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + ::ActiveRemote::Cached.default_options[:cache_error_proc].expects(:call) + ar_cache.write("some_key", "some_value") + end + + describe "when handle_cache_error is false" do + it "raises error" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => false, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:write).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + _ { ar_cache.write("some_key", "some_value") }.must_raise(::RuntimeError, "kaBOOM") + end + + it "doesn't invoke error proc" do + ::ActiveRemote::Cached.default_options(:handle_cache_error => false, :cache_error_proc => lambda { |_| } ) + cache = HashCache.new + cache.expects(:write).raises(::RuntimeError, "kaBOOM") + ar_cache = ::ActiveRemote::Cached::Cache.new(cache) + ::ActiveRemote::Cached.default_options[:cache_error_proc].expects(:log).never + _ { ar_cache.write("some_key", "some_value") }.must_raise(::RuntimeError, "kaBOOM") + end end end end diff --git a/spec/active_remote/cached_delete_methods_spec.rb b/spec/active_remote/cached_delete_methods_spec.rb index 8635d83..d5dffc5 100644 --- a/spec/active_remote/cached_delete_methods_spec.rb +++ b/spec/active_remote/cached_delete_methods_spec.rb @@ -15,31 +15,31 @@ def self.search; nil; end describe DeleteMethodClass do describe "API" do it "creates 'cached_delete_by_guid'" do - DeleteMethodClass.must_respond_to("cached_delete_by_guid") + _(DeleteMethodClass).must_respond_to("cached_delete_by_guid") end it "creates 'cached_delete_by_user_guid'" do - DeleteMethodClass.must_respond_to("cached_delete_by_user_guid") + _(DeleteMethodClass).must_respond_to("cached_delete_by_user_guid") end it "creates 'cached_delete_by_user_guid_and_client_guid'" do - DeleteMethodClass.must_respond_to("cached_delete_by_user_guid_and_client_guid") + _(DeleteMethodClass).must_respond_to("cached_delete_by_user_guid_and_client_guid") end it "creates 'cached_delete_by_client_guid_and_user_guid'" do - DeleteMethodClass.must_respond_to("cached_delete_by_client_guid_and_user_guid") + _(DeleteMethodClass).must_respond_to("cached_delete_by_client_guid_and_user_guid") end it "creates 'cached_delete_by_derp_and_user_guid_and_client_guid'" do - DeleteMethodClass.must_respond_to("cached_delete_by_derp_and_user_guid_and_client_guid") + _(DeleteMethodClass).must_respond_to("cached_delete_by_derp_and_user_guid_and_client_guid") end it "creates 'cached_delete_by_client_guid_and_derp_and_user_guid'" do - DeleteMethodClass.must_respond_to("cached_delete_by_client_guid_and_derp_and_user_guid") + _(DeleteMethodClass).must_respond_to("cached_delete_by_client_guid_and_derp_and_user_guid") end it "creates 'cached_delete_by_client_guid_and_user_guid_and_derp'" do - DeleteMethodClass.must_respond_to("cached_delete_by_client_guid_and_user_guid_and_derp") + _(DeleteMethodClass).must_respond_to("cached_delete_by_client_guid_and_user_guid_and_derp") end end end diff --git a/spec/active_remote/cached_exist_methods_spec.rb b/spec/active_remote/cached_exist_methods_spec.rb index dc9e61e..f58e6ca 100644 --- a/spec/active_remote/cached_exist_methods_spec.rb +++ b/spec/active_remote/cached_exist_methods_spec.rb @@ -15,116 +15,116 @@ def self.search; nil; end describe ExistMethodClass do describe "API" do it "creates 'cached_exist_find_by_guid'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_guid") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_guid") end it "creates 'cached_exist_search_by_guid'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_guid") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_guid") end it "creates 'cached_exist_find_by_user_guid'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_user_guid") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_user_guid") end it "creates 'cached_exist_search_by_user_guid'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_user_guid") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_user_guid") end it "creates 'cached_exist_find_by_user_guid_and_client_guid'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_user_guid_and_client_guid") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_user_guid_and_client_guid") end it "creates 'cached_exist_search_by_user_guid_and_client_guid'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_user_guid_and_client_guid") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_user_guid_and_client_guid") end it "creates 'cached_exist_find_by_client_guid_and_user_guid'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_client_guid_and_user_guid") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_client_guid_and_user_guid") end it "creates 'cached_exist_search_by_client_guid_and_user_guid'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_client_guid_and_user_guid") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_client_guid_and_user_guid") end it "creates 'cached_exist_find_by_derp_and_user_guid_and_client_guid'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_derp_and_user_guid_and_client_guid") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_derp_and_user_guid_and_client_guid") end it "creates 'cached_exist_search_by_derp_and_user_guid_and_client_guid'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_derp_and_user_guid_and_client_guid") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_derp_and_user_guid_and_client_guid") end it "creates 'cached_exist_find_by_client_guid_and_derp_and_user_guid'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_client_guid_and_derp_and_user_guid") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_client_guid_and_derp_and_user_guid") end it "creates 'cached_exist_search_by_client_guid_and_derp_and_user_guid'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_client_guid_and_derp_and_user_guid") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_client_guid_and_derp_and_user_guid") end it "creates 'cached_exist_find_by_client_guid_and_user_guid_and_derp'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_client_guid_and_user_guid_and_derp") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_client_guid_and_user_guid_and_derp") end it "creates 'cached_exist_search_by_client_guid_and_user_guid_and_derp'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_client_guid_and_user_guid_and_derp") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_client_guid_and_user_guid_and_derp") end # ? based methods it "creates 'cached_exist_find_by_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_guid?") end it "creates 'cached_exist_search_by_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_guid?") end it "creates 'cached_exist_find_by_user_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_user_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_user_guid?") end it "creates 'cached_exist_search_by_user_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_user_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_user_guid?") end it "creates 'cached_exist_find_by_user_guid_and_client_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_user_guid_and_client_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_user_guid_and_client_guid?") end it "creates 'cached_exist_search_by_user_guid_and_client_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_user_guid_and_client_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_user_guid_and_client_guid?") end it "creates 'cached_exist_find_by_client_guid_and_user_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_client_guid_and_user_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_client_guid_and_user_guid?") end it "creates 'cached_exist_search_by_client_guid_and_user_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_client_guid_and_user_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_client_guid_and_user_guid?") end it "creates 'cached_exist_find_by_derp_and_user_guid_and_client_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_derp_and_user_guid_and_client_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_derp_and_user_guid_and_client_guid?") end it "creates 'cached_exist_search_by_derp_and_user_guid_and_client_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_derp_and_user_guid_and_client_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_derp_and_user_guid_and_client_guid?") end it "creates 'cached_exist_find_by_client_guid_and_derp_and_user_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_client_guid_and_derp_and_user_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_client_guid_and_derp_and_user_guid?") end it "creates 'cached_exist_search_by_client_guid_and_derp_and_user_guid?'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_client_guid_and_derp_and_user_guid?") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_client_guid_and_derp_and_user_guid?") end it "creates 'cached_exist_find_by_client_guid_and_user_guid_and_derp?'" do - ExistMethodClass.must_respond_to("cached_exist_find_by_client_guid_and_user_guid_and_derp?") + _(ExistMethodClass).must_respond_to("cached_exist_find_by_client_guid_and_user_guid_and_derp?") end it "creates 'cached_exist_search_by_client_guid_and_user_guid_and_derp?'" do - ExistMethodClass.must_respond_to("cached_exist_search_by_client_guid_and_user_guid_and_derp?") + _(ExistMethodClass).must_respond_to("cached_exist_search_by_client_guid_and_user_guid_and_derp?") end end end diff --git a/spec/active_remote/cached_find_methods_spec.rb b/spec/active_remote/cached_find_methods_spec.rb index 0c520d0..24919ca 100644 --- a/spec/active_remote/cached_find_methods_spec.rb +++ b/spec/active_remote/cached_find_methods_spec.rb @@ -16,35 +16,35 @@ def self.search; nil; end describe FindMethodClass do describe "API" do it "creates 'cached_find_by_foo'" do - FindMethodClass.must_respond_to("cached_find_by_foo") + _(FindMethodClass).must_respond_to("cached_find_by_foo") end it "creates 'cached_find_by_guid'" do - FindMethodClass.must_respond_to("cached_find_by_guid") + _(FindMethodClass).must_respond_to("cached_find_by_guid") end it "creates 'cached_find_by_user_guid'" do - FindMethodClass.must_respond_to("cached_find_by_user_guid") + _(FindMethodClass).must_respond_to("cached_find_by_user_guid") end it "creates 'cached_find_by_user_guid_and_client_guid'" do - FindMethodClass.must_respond_to("cached_find_by_user_guid_and_client_guid") + _(FindMethodClass).must_respond_to("cached_find_by_user_guid_and_client_guid") end it "creates 'cached_find_by_client_guid_and_user_guid'" do - FindMethodClass.must_respond_to("cached_find_by_client_guid_and_user_guid") + _(FindMethodClass).must_respond_to("cached_find_by_client_guid_and_user_guid") end it "creates 'cached_find_by_derp_and_user_guid_and_client_guid'" do - FindMethodClass.must_respond_to("cached_find_by_derp_and_user_guid_and_client_guid") + _(FindMethodClass).must_respond_to("cached_find_by_derp_and_user_guid_and_client_guid") end it "creates 'cached_find_by_client_guid_and_derp_and_user_guid'" do - FindMethodClass.must_respond_to("cached_find_by_client_guid_and_derp_and_user_guid") + _(FindMethodClass).must_respond_to("cached_find_by_client_guid_and_derp_and_user_guid") end it "creates 'cached_find_by_client_guid_and_user_guid_and_derp'" do - FindMethodClass.must_respond_to("cached_find_by_client_guid_and_user_guid_and_derp") + _(FindMethodClass).must_respond_to("cached_find_by_client_guid_and_user_guid_and_derp") end end @@ -60,29 +60,29 @@ def self.search; nil; end it "executes find_by_guid when cached_find with guid called" do FindMethodClass.stub(:find, :hello) do - FindMethodClass.cached_find(:guid => :guid).must_equal(:hello) + _(FindMethodClass.cached_find(:guid => :guid)).must_equal(:hello) end end it "executes the fetch block if not present in cache" do FindMethodClass.stub(:find, :hello) do - FindMethodClass.cached_find_by_guid(:guid).must_equal(:hello) + _(FindMethodClass.cached_find_by_guid(:guid)).must_equal(:hello) end end it "merges the default options in for the fetch call" do - ::ActiveRemote::Cached.cache.expects(:fetch).with([FindMethodClass.name, "#find", "guid"], :expires_in => 100).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, FindMethodClass.name, "#find", "guid"], { :expires_in => 100 }).returns(:hello) FindMethodClass.stub(:find, :hello) do - FindMethodClass.cached_find_by_guid(:guid).must_equal(:hello) + _(FindMethodClass.cached_find_by_guid(:guid)).must_equal(:hello) end end it "overrides the default options with local options for the fetch call" do - ::ActiveRemote::Cached.cache.expects(:fetch).with([FindMethodClass.name, "#find", "guid"], :expires_in => 200).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, FindMethodClass.name, "#find", "guid"], { :expires_in => 200 }).returns(:hello) FindMethodClass.stub(:find, :hello) do - FindMethodClass.cached_find_by_guid(:guid, :expires_in => 200).must_equal(:hello) + _(FindMethodClass.cached_find_by_guid(:guid, :expires_in => 200)).must_equal(:hello) end end @@ -92,7 +92,7 @@ def self.search; nil; end end it "uses the namespace as a prefix to the cache key" do - ::ActiveRemote::Cached.cache.expects(:fetch).with(["MyApp", FindMethodClass.name, "#find", "guid"], :expires_in => 100).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, "MyApp", FindMethodClass.name, "#find", "guid"], { :expires_in => 100 }).returns(:hello) FindMethodClass.stub(:find, :hello) do FindMethodClass.cached_find_by_guid(:guid) @@ -112,18 +112,18 @@ def self.search; nil; end end it "overrides the default options with cached_finder options for the fetch call" do - ::ActiveRemote::Cached.cache.expects(:fetch).with([FindMethodClass.name, "#find", "foo"], :expires_in => 500).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, FindMethodClass.name, "#find", "foo"], { :expires_in => 500 }).returns(:hello) FindMethodClass.stub(:find, :hello) do - FindMethodClass.cached_find_by_foo(:foo).must_equal(:hello) + _(FindMethodClass.cached_find_by_foo(:foo)).must_equal(:hello) end end it "overrides the cached_finder options with local options for the fetch call" do - ::ActiveRemote::Cached.cache.expects(:fetch).with([FindMethodClass.name, "#find", "foo"], :expires_in => 200).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, FindMethodClass.name, "#find", "foo"], { :expires_in => 200 }).returns(:hello) FindMethodClass.stub(:find, :hello) do - FindMethodClass.cached_find_by_foo(:foo, :expires_in => 200).must_equal(:hello) + _(FindMethodClass.cached_find_by_foo(:foo, :expires_in => 200)).must_equal(:hello) end end end diff --git a/spec/active_remote/cached_search_methods_spec.rb b/spec/active_remote/cached_search_methods_spec.rb index d95096a..e5bc741 100644 --- a/spec/active_remote/cached_search_methods_spec.rb +++ b/spec/active_remote/cached_search_methods_spec.rb @@ -17,43 +17,43 @@ def self.search; nil; end describe SearchMethodClass do describe "API" do it "creates 'cached_search_by_foo'" do - SearchMethodClass.must_respond_to("cached_search_by_foo") + _(SearchMethodClass).must_respond_to("cached_search_by_foo") end it "creates 'cached_search_by_foo!'" do - SearchMethodClass.must_respond_to("cached_search_by_foo!") + _(SearchMethodClass).must_respond_to("cached_search_by_foo!") end it "creates 'cached_search_by_guid'" do - SearchMethodClass.must_respond_to("cached_search_by_guid") + _(SearchMethodClass).must_respond_to("cached_search_by_guid") end it "creates 'cached_search_by_user_guid'" do - SearchMethodClass.must_respond_to("cached_search_by_user_guid") + _(SearchMethodClass).must_respond_to("cached_search_by_user_guid") end it "creates 'cached_search_by_user_guid_and_client_guid'" do - SearchMethodClass.must_respond_to("cached_search_by_user_guid_and_client_guid") + _(SearchMethodClass).must_respond_to("cached_search_by_user_guid_and_client_guid") end it "creates 'cached_search_by_client_guid_and_user_guid'" do - SearchMethodClass.must_respond_to("cached_search_by_client_guid_and_user_guid") + _(SearchMethodClass).must_respond_to("cached_search_by_client_guid_and_user_guid") end it "creates 'cached_search_by_derp_and_user_guid_and_client_guid'" do - SearchMethodClass.must_respond_to("cached_search_by_derp_and_user_guid_and_client_guid") + _(SearchMethodClass).must_respond_to("cached_search_by_derp_and_user_guid_and_client_guid") end it "creates 'cached_search_by_client_guid_and_derp_and_user_guid'" do - SearchMethodClass.must_respond_to("cached_search_by_client_guid_and_derp_and_user_guid") + _(SearchMethodClass).must_respond_to("cached_search_by_client_guid_and_derp_and_user_guid") end it "creates 'cached_search_by_client_guid_and_user_guid_and_derp'" do - SearchMethodClass.must_respond_to("cached_search_by_client_guid_and_user_guid_and_derp") + _(SearchMethodClass).must_respond_to("cached_search_by_client_guid_and_user_guid_and_derp") end it "creates 'cached_search_by_client_guid_and_user_guid_and_derp!'" do - SearchMethodClass.must_respond_to("cached_search_by_client_guid_and_user_guid_and_derp!") + _(SearchMethodClass).must_respond_to("cached_search_by_client_guid_and_user_guid_and_derp!") end end @@ -69,9 +69,9 @@ def self.search; nil; end it "executes the search block when a block is passed" do SearchMethodClass.stub(:derp, :derp) do - SearchMethodClass.cached_search(:guid => :guid) do + _(SearchMethodClass.cached_search(:guid => :guid) do SearchMethodClass.derp - end.must_equal(:derp) + end).must_equal(:derp) end end @@ -81,7 +81,7 @@ def self.search; nil; end SearchMethodClass.derp end - SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(false) + _(SearchMethodClass.cached_exist_search_by_guid?(:guid)).must_equal(false) end end @@ -91,7 +91,7 @@ def self.search; nil; end SearchMethodClass.derp end - SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(true) + _(SearchMethodClass.cached_exist_search_by_guid?(:guid)).must_equal(true) end end @@ -101,7 +101,7 @@ def self.search; nil; end SearchMethodClass.derp end - SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(false) + _(SearchMethodClass.cached_exist_search_by_guid?(:guid)).must_equal(false) end end @@ -111,7 +111,7 @@ def self.search; nil; end SearchMethodClass.derp end - SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(true) + _(SearchMethodClass.cached_exist_search_by_guid?(:guid)).must_equal(true) end end @@ -121,35 +121,35 @@ def self.search; nil; end SearchMethodClass.derp end - SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(true) + _(SearchMethodClass.cached_exist_search_by_guid?(:guid)).must_equal(true) end end it "executes search_by_guid when cached_search with guid called" do FindMethodClass.stub(:search, :hello) do - FindMethodClass.cached_search(:guid => :guid).must_equal(:hello) + _(FindMethodClass.cached_search(:guid => :guid)).must_equal(:hello) end end it "executes the fetch block if not present in cache" do SearchMethodClass.stub(:search, :hello) do - SearchMethodClass.cached_search_by_guid(:guid).must_equal(:hello) + _(SearchMethodClass.cached_search_by_guid(:guid)).must_equal(:hello) end end it "merges the default options in for the fetch call" do - ::ActiveRemote::Cached.cache.expects(:fetch).with([SearchMethodClass.name, "#search", "guid"], :expires_in => 100).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, SearchMethodClass.name, "#search", "guid"], { :expires_in => 100 }).returns(:hello) SearchMethodClass.stub(:search, :hello) do - SearchMethodClass.cached_search_by_guid(:guid).must_equal(:hello) + _(SearchMethodClass.cached_search_by_guid(:guid)).must_equal(:hello) end end it "overrides the default options with local options for the fetch call" do - ::ActiveRemote::Cached.cache.expects(:fetch).with([SearchMethodClass.name, "#search", "guid"], :expires_in => 200).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, SearchMethodClass.name, "#search", "guid"], { :expires_in => 200 }).returns(:hello) SearchMethodClass.stub(:search, :hello) do - SearchMethodClass.cached_search_by_guid(:guid, :expires_in => 200).must_equal(:hello) + _(SearchMethodClass.cached_search_by_guid(:guid, :expires_in => 200)).must_equal(:hello) end end @@ -159,7 +159,7 @@ def self.search; nil; end end it "uses the namespace as a prefix to the cache key" do - ::ActiveRemote::Cached.cache.expects(:fetch).with(["MyApp", SearchMethodClass.name, "#search", "guid"], :expires_in => 100).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, "MyApp", SearchMethodClass.name, "#search", "guid"], { :expires_in => 100 }).returns(:hello) SearchMethodClass.stub(:search, :hello) do SearchMethodClass.cached_search_by_guid(:guid) @@ -179,18 +179,18 @@ def self.search; nil; end end it "overrides the default options with cached_finder options for the fetch call" do - ::ActiveRemote::Cached.cache.expects(:fetch).with([SearchMethodClass.name, "#search", "foo"], :expires_in => 500).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, SearchMethodClass.name, "#search", "foo"], { :expires_in => 500 }).returns(:hello) SearchMethodClass.stub(:find, :hello) do - SearchMethodClass.cached_search_by_foo(:foo).must_equal(:hello) + _(SearchMethodClass.cached_search_by_foo(:foo)).must_equal(:hello) end end it "overrides the cached_finder options with local options for the fetch call" do - ::ActiveRemote::Cached.cache.expects(:fetch).with([SearchMethodClass.name, "#search", "foo"], :expires_in => 200).returns(:hello) + ::ActiveRemote::Cached.cache.expects(:fetch).with([::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION, SearchMethodClass.name, "#search", "foo"], { :expires_in => 200 }).returns(:hello) SearchMethodClass.stub(:find, :hello) do - SearchMethodClass.cached_search_by_foo(:foo, :expires_in => 200).must_equal(:hello) + _(SearchMethodClass.cached_search_by_foo(:foo, :expires_in => 200)).must_equal(:hello) end end end @@ -207,13 +207,13 @@ def self.search; nil; end it "returns results when present" do SearchMethodClass.stub(:search, [:hello]) do - SearchMethodClass.cached_search_by_foo!(:foo, :expires_in => 200).must_equal([:hello]) + _(SearchMethodClass.cached_search_by_foo!(:foo, :expires_in => 200)).must_equal([:hello]) end end it "raises ActiveRemote::RemoteRecordNotFound when not found" do SearchMethodClass.stub(:search, []) do - -> { SearchMethodClass.cached_search_by_foo!(:foo, :expires_in => 200) }.must_raise ::ActiveRemote::RemoteRecordNotFound + _(-> { SearchMethodClass.cached_search_by_foo!(:foo, :expires_in => 200) }).must_raise ::ActiveRemote::RemoteRecordNotFound end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 613b93c..3ea1206 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,13 +2,12 @@ require 'bundler' Bundler.require(:default, :development, :test) -require 'minitest/mock' -require 'minitest/spec' require 'minitest/autorun' require 'minitest/pride' +require 'mocha/minitest' class HashCache < Hash - def exist?(key) + def exist?(key, _options = nil) self.has_key?(key) end @@ -20,13 +19,11 @@ def fetch(key, options = {}, &blk) self[key] = yield end - def read(key) + def read(key, _options = {}) self[key] end - def write(key, value) + def write(key, value, _options = nil) self[key] = value end end - -require 'mocha/api'