cache_crispies 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bed703f9038261d6ff63e08465e7c0dccea1bcb6e2cb583de3ab154da562ef8f
4
- data.tar.gz: ed55298237e61b9c6995a0194c61cd6ec221ea3cd62be176afa8842cb9d28c50
3
+ metadata.gz: af451e5837f96664e141a147df118fbfffb7ee4fedc71cd5e6c34438b9069461
4
+ data.tar.gz: ffe23f3217c50b5c6bbbd183127a2274b6c4afb59ad93e50a271c880d20968f4
5
5
  SHA512:
6
- metadata.gz: e6897a7621e75851e7d9b2092674a44ed0ff42f328c61876b9de82dfc984c1eb2a7379dbe60f336659552be6445798063a1df83941fab55aeb0537a67fea5718
7
- data.tar.gz: 0a9ac99db021a8e5ac1d06547d55c84e346aa550f020598f716993a5b783c2f2f8bcf002fda92d113f1864da2083f03719a5a240ae3e8dbebf3e24df01e1a543
6
+ metadata.gz: e8208c9ef13c4f66e9d64c7b8a5394e7d2907b894ff4ca6617357ca785ede999048d3ef4ffc00d900a30e5ac284401a5b145fb2271764f878d16603017ac08d1
7
+ data.tar.gz: 167cf43b28151ec4d6c65c0badfcbe73a871f7a102bc916f04eb0e889069843e518db1a608da31c854096a60843bd50a69ab99a2b4b784a89ce1d5ecd5e549fe
@@ -1,12 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/dependencies'
2
4
  require 'oj'
3
5
 
6
+ # The top level namespace module for the gem
4
7
  module CacheCrispies
5
- CACHE_KEY_PREFIX = 'cache-crispies'.freeze
6
- CACHE_KEY_SEPARATOR = '+'.freeze
8
+ # A prefix used in building cache key. This should be extra insurance against
9
+ # key conflicts and also provides an easy way to search for keys in Redis.
10
+ CACHE_KEY_PREFIX = 'cache-crispies'
11
+
12
+ # The string to use to join parts of the cache keys together
13
+ CACHE_KEY_SEPARATOR = '+'
7
14
 
8
15
  require 'cache_crispies/version'
9
16
 
17
+ # Use autoload for better Rails development
10
18
  autoload :Attribute, 'cache_crispies/attribute'
11
19
  autoload :Base, 'cache_crispies/base'
12
20
  autoload :Collection, 'cache_crispies/collection'
@@ -15,4 +23,4 @@ module CacheCrispies
15
23
  autoload :Memoizer, 'cache_crispies/memoizer'
16
24
  autoload :Controller, 'cache_crispies/controller'
17
25
  autoload :Plan, 'cache_crispies/plan'
18
- end
26
+ end
@@ -1,8 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CacheCrispies
4
+ # Reperesents a single serialized attribute in a serializer. It's generated
5
+ # by a call to either {CacheCrispies::Base.serialize} or
6
+ # {CacheCrispies::Base.merge}.
2
7
  class Attribute
3
- class InvalidCoersionType < ArgumentError; end
8
+ # Represents an invalid option passed in the to: argument
9
+ class InvalidCoercionType < ArgumentError; end
4
10
 
5
- def initialize(key, from: nil, with: nil, to: nil, nesting: [], conditions: [])
11
+ # Initializes a new CacheCrispies::Attribute instance
12
+ #
13
+ # @param key [Symbol] the JSON key for this attribute
14
+ # @param from [Symbol] the method on the model to call to get the value
15
+ # @param with [CacheCrispies::Base] a serializer to use to serialize the
16
+ # @param to [Class, Symbol] the data type to coerce the value into
17
+ # @param nesting [Array<Symbol>] the JSON keys this attribute will be
18
+ # nested inside
19
+ # @param conditions [Array<CacheCrispies::Condition>] the show_if condition
20
+ # blocks this attribute is nested inside. These will be evaluated for
21
+ # thruthiness and must all be true for this attribute to reneder.
22
+ # argument's value
23
+ def initialize(
24
+ key,
25
+ from: nil, with: nil, to: nil, nesting: [], conditions: []
26
+ )
6
27
  @key = key
7
28
  @method_name = from || key || :itself
8
29
  @serializer = with
@@ -11,8 +32,22 @@ module CacheCrispies
11
32
  @conditions = Array(conditions)
12
33
  end
13
34
 
14
- attr_reader :method_name, :key, :serializer, :coerce_to, :nesting, :conditions
35
+ attr_reader(
36
+ :method_name,
37
+ :key,
38
+ :serializer,
39
+ :coerce_to,
40
+ :nesting,
41
+ :conditions
42
+ )
15
43
 
44
+ # Gets the value of the attribute for the given model and options
45
+ #
46
+ # @param model [Object] typically ActiveRecord::Base, but could be anything
47
+ # @param options [Hash] any optional values from the serializer instance
48
+ # @return the value for the attribute for the given model and options
49
+ # @raise [InvalidCoercionType] when an invalid argument is passed in the
50
+ # to: argument
16
51
  def value_for(model, options)
17
52
  value = model.public_send(method_name)
18
53
 
@@ -51,7 +86,7 @@ module CacheCrispies
51
86
  !!value
52
87
  else
53
88
  raise(
54
- InvalidCoersionType,
89
+ InvalidCoercionType,
55
90
  "#{coerce_to} has no registered coercion strategy"
56
91
  )
57
92
  end
@@ -63,4 +98,4 @@ module CacheCrispies
63
98
  ).public_send(method_name)
64
99
  end
65
100
  end
66
- end
101
+ end
@@ -1,50 +1,109 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'digest'
2
4
  require 'rails'
3
5
 
4
6
  module CacheCrispies
7
+ # The Base class that all serializer classes should inherit from
5
8
  class Base
6
9
  attr_reader :model, :options
7
10
 
11
+ # Define class-level instance variables and their default values when the
12
+ # class is inherited by another class. This is not meant to be called
13
+ # directly. It is called internally by Ruby.
14
+ #
15
+ # @param other [Class] the inheriting child class
16
+ # @return [void]
17
+ def self.inherited(other)
18
+ other.instance_variable_set(:@attributes, [])
19
+ other.instance_variable_set(:@nesting, [])
20
+ other.instance_variable_set(:@conditions, [])
21
+ end
22
+
23
+ class << self
24
+ attr_reader :attributes
25
+ end
26
+ delegate :attributes, to: :class
27
+
28
+ # Initializes a new instance of CacheCrispies::Base, or really, it should
29
+ # always be a subclass of CacheCrispies::Base.
30
+ #
31
+ # @param model [Object] typically ActiveRecord::Base, but could be anything
32
+ # @param options [Hash] any optional custom values you want to be
33
+ # accessible in your subclass.
8
34
  def initialize(model, options = {})
9
35
  @model = model
10
36
  @options = options
11
37
  end
12
38
 
39
+ # Renders the serializer instance to a JSON-ready Hash
40
+ #
41
+ # @return [Hash] a JSON-ready hash
13
42
  def as_json
14
43
  HashBuilder.new(self).call
15
44
  end
16
45
 
46
+ # Whether or not this serializer class should allow caching of results.
47
+ # It is set to false by default, but can be overridden in child classes.
48
+ #
49
+ # @return [Boolean]
17
50
  def self.do_caching?
18
51
  false
19
52
  end
20
53
 
54
+ # A JSON key to use as a root key on a non-collection serializable. by
55
+ # default it's the name of the class without the "Serializer" part. But it
56
+ # can be overridden in a subclass to be anything.
57
+ #
58
+ # @return [Symbol] a symbol to be used as a key for a JSON-ready Hash
21
59
  def self.key
22
60
  to_s.demodulize.chomp('Serializer').underscore.to_sym
23
61
  end
24
62
 
63
+ # A JSON key to use as a root key on a collection-type serializable. By
64
+ # deafult it's the plural version of .key, but it can be overridden in a
65
+ # subclass to be anything.
66
+ #
67
+ # @return [Symbol] a symbol to be used as a key for a JSON-ready Hash
25
68
  def self.collection_key
26
69
  return nil unless key
27
70
 
28
71
  key.to_s.pluralize.to_sym
29
72
  end
30
73
 
31
- # Can be overridden in subclasses
32
- # options: Hash of the same options that would be passed to the
33
- # individual serializer instances
74
+ # An array of strings that should be added to the cache key for an instance
75
+ # of this serializer. Typically you'd add in the #cache_key or string value
76
+ # for any extra models or data passed in through the options hash here. But
77
+ # it could also contain any custom logic about how to construct a cache
78
+ # key. This method is meant to be overridden in subclasses.
79
+ #
80
+ # @example cache based off models provided in options
81
+ # def self.cache_key_addons(options)
82
+ # [options[:current_user].cache_key]
83
+ # end
84
+ #
85
+ # @example time-based caching
86
+ # def self.cache_key_addons(_options)
87
+ # [Date.today.to_s]
88
+ # end
89
+ #
90
+ # @param options [Hash] the options hash passed to the serializer, will be
91
+ # passed in here as well so you can refernce it if needed.
92
+ # @return [Array<String>]
34
93
  def self.cache_key_addons(_options = {})
35
94
  []
36
95
  end
37
96
 
97
+ # Return a cache key string for the serializer class to be included in the
98
+ # cache key for the instances. The key includes the name of the class, and
99
+ # a digest of the contents of the main class file.
100
+ #
101
+ # @return [String] a cache key for the class
38
102
  def self.cache_key_base
39
103
  # TODO: we may need to get a cache key from nested serializers as well :(
40
104
  @cache_key_base ||= "#{self}-#{file_hash}"
41
105
  end
42
106
 
43
- def self.attributes
44
- @attributes || []
45
- end
46
- delegate :attributes, to: :class
47
-
48
107
  private
49
108
 
50
109
  def self.file_hash
@@ -63,7 +122,6 @@ module CacheCrispies
63
122
  private_class_method :path
64
123
 
65
124
  def self.nest_in(key, &block)
66
- @nesting ||= []
67
125
  @nesting << key
68
126
 
69
127
  block.call
@@ -73,7 +131,6 @@ module CacheCrispies
73
131
  private_class_method :nest_in
74
132
 
75
133
  def self.show_if(condition_proc, &block)
76
- @conditions ||= []
77
134
  @conditions << Condition.new(condition_proc)
78
135
 
79
136
  block.call
@@ -83,8 +140,6 @@ module CacheCrispies
83
140
  private_class_method :show_if
84
141
 
85
142
  def self.serialize(*attribute_names, from: nil, with: nil, to: nil)
86
- @attributes ||= []
87
-
88
143
  attribute_names.flatten.map { |att| att&.to_sym }.map do |attrib|
89
144
  current_nesting = Array(@nesting).dup
90
145
  current_conditions = Array(@conditions).dup
@@ -107,4 +162,4 @@ module CacheCrispies
107
162
  end
108
163
  private_class_method :merge
109
164
  end
110
- end
165
+ end
@@ -1,13 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails'
2
4
 
3
5
  module CacheCrispies
6
+ # Handles rendering and possibly caching a collection of models using a
7
+ # Serializer
4
8
  class Collection
9
+ # Initializes a new instance of CacheCrispies::Collection
10
+ #
11
+ # @param colleciton [Object] typically an enumerable containing instances of
12
+ # ActiveRecord::Base, but could be any enumerable
13
+ # @param serializer [CacheCrispies::Base] a class inheriting from
14
+ # CacheCrispies::Base
15
+ # @param options [Hash] any optional values from the serializer instance
5
16
  def initialize(collection, serializer, options = {})
6
17
  @collection = collection
7
18
  @serializer = serializer
8
19
  @options = options
9
20
  end
10
21
 
22
+ # Renders the collection to a JSON-ready Hash trying to cache the hash
23
+ # along the way
24
+ #
25
+ # @return [Hash] the JSON-ready Hash
11
26
  def as_json
12
27
  if serializer.do_caching? && collection.respond_to?(:cache_key)
13
28
  cached_json
@@ -40,4 +55,4 @@ module CacheCrispies
40
55
  end
41
56
  end
42
57
  end
43
- end
58
+ end
@@ -1,17 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CacheCrispies
2
- # Represents an instance of a conditional built by a show_if call
4
+ # Represents an instance of a conditional built by a
5
+ # {CacheCrispies::Base.show_if} call
3
6
  class Condition
7
+ # Returns a new instance of Condition
8
+ #
9
+ # @param block [Proc] a block containing the logic for the condition
4
10
  def initialize(block)
5
11
  @block = block
6
12
  end
7
13
 
8
- # Public: A system-wide unique ID used for memoizaiton
9
- # Returns an Integer
14
+ # A system-wide unique ID used for memoizaiton
15
+ #
16
+ # @eturn [Integer] the unique ID for this condition
10
17
  def uid
11
18
  # Just reusing the block's object_id seems to make sense
12
19
  block.object_id
13
20
  end
14
21
 
22
+ # Test the truthiness of the condition against a model and options
23
+ #
24
+ # @param model [Object] typically ActiveRecord::Base, but could be anything
25
+ # @param options [Hash] any optional values from the serializer instance
26
+ # @return [Boolean] the condition's truthiness
15
27
  def true_for?(model, options = {})
16
28
  !!case block.arity
17
29
  when 0
@@ -27,4 +39,4 @@ module CacheCrispies
27
39
 
28
40
  attr_reader :block
29
41
  end
30
- end
42
+ end
@@ -1,9 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CacheCrispies
4
+ # A Rails concern designed to be used in Rails controllers to provide access to
5
+ # the #cache_render method
2
6
  module Controller
3
7
  extend ActiveSupport::Concern
4
8
 
9
+ # The serialization mode that should be used with the oj gem
5
10
  OJ_MODE = :rails
6
11
 
12
+ # Renders the provided cacheable object to JSON using the provided
13
+ # serializer
14
+ #
15
+ # @param serializer [CacheCrispies::Base] a class inheriting from
16
+ # CacheCrispies::Base
17
+ # @param cacheable [Object] can be any object. But is typically a Rails
18
+ # model inheriting from ActiveRecord::Base
19
+ # @param options [Hash] any hash of custom options that should be passed
20
+ # to the serializer instance
21
+ # @return [void]
7
22
  def cache_render(serializer, cacheable, options = {})
8
23
  plan = CacheCrispies::Plan.new(serializer, cacheable, options)
9
24
 
@@ -23,4 +38,4 @@ module CacheCrispies
23
38
  render json: Oj.dump(plan.wrap(serializer_json), mode: OJ_MODE)
24
39
  end
25
40
  end
26
- end
41
+ end
@@ -1,10 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CacheCrispies
4
+ # Builds out a JSON-ready Hash using the attributes in a Serializer
2
5
  class HashBuilder
6
+ # Initializes a new instance of CacheCrispies::HashBuilder
7
+ #
8
+ # @param serializer [CacheCrispies::Base] an instance of a subclass of
9
+ # CacheCrispies::Base
3
10
  def initialize(serializer)
4
11
  @serializer = serializer
5
12
  @condition_results = Memoizer.new
6
13
  end
7
14
 
15
+ # Builds the Hash
16
+ #
17
+ # @return [Hash]
8
18
  def call
9
19
  hash = {}
10
20
 
@@ -58,4 +68,4 @@ module CacheCrispies
58
68
  attribute.value_for(target, serializer.options)
59
69
  end
60
70
  end
61
- end
71
+ end
@@ -1,9 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CacheCrispies
4
+ # Simple class to handle memoizing values by a key. This really just provides
5
+ # a bit of wrapper around doing this yourself with a hash.
2
6
  class Memoizer
3
7
  def initialize
4
8
  @cache = {}
5
9
  end
6
10
 
11
+ # Fetches a cached value for the given key, if it exists. Otherwise it calls
12
+ # the block and caches that value
13
+ #
14
+ # @param key [Object] the value to use as a cache key
15
+ # @yield the value to cache and return if there is a cache miss
16
+ # @return [Object] either the cached value or the block's value
7
17
  def fetch(key, &_block)
8
18
  # Avoid ||= because we need to memoize falsey values.
9
19
  return cache[key] if cache.key?(key)
@@ -15,4 +25,4 @@ module CacheCrispies
15
25
 
16
26
  attr_reader :cache
17
27
  end
18
- end
28
+ end
@@ -1,7 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CacheCrispies
4
+ # Represents a plan on how to cache a given cacheable with a given serializer
2
5
  class Plan
3
6
  attr_reader :serializer, :cacheable, :options
4
7
 
8
+ # Initializes a new instance of CacheCrispies::Plan
9
+ #
10
+ # @param serializer [CacheCrispies::Base] a class inheriting from
11
+ # CacheCrispies::Base
12
+ # @param cacheable [Object] typically ActiveRecord::Base or an enumerable
13
+ # containing instances of ActiveRecord::Base, but could be anything
14
+ # @param options [Hash] any optional values from the serializer instance
5
15
  def initialize(serializer, cacheable, options = {})
6
16
  @serializer = serializer
7
17
  @cacheable = cacheable
@@ -9,14 +19,30 @@ module CacheCrispies
9
19
  @options = options
10
20
  end
11
21
 
22
+ # Whether or not the cacheable should be treated like a collection
23
+ #
24
+ # @return [Boolean] true if cacheable is a collection
12
25
  def collection?
13
26
  cacheable.respond_to?(:each)
14
27
  end
15
28
 
29
+ # Returns the cache_key in a format suitable for an ETag header
30
+ #
31
+ # @return [String] an MD5 digest of cache_key
16
32
  def etag
17
33
  Digest::MD5.hexdigest(cache_key)
18
34
  end
19
35
 
36
+ # Returns a string of cache keys for all dependent objects. Changes to any
37
+ # of keys should bust the overall key for this plan. The key consists of:
38
+ # - a global key for this gem
39
+ # - the serializers class name
40
+ # - a digest of the contents of the of serializer class file
41
+ # - any addon keys the serializer may define
42
+ # - the #cache_key method on the cacheable (ActiveRecord provides this by
43
+ # default)
44
+ #
45
+ # @return [String] a suitable cache key
20
46
  def cache_key
21
47
  @cache_key ||=
22
48
  [
@@ -27,6 +53,11 @@ module CacheCrispies
27
53
  ].flatten.compact.join(CACHE_KEY_SEPARATOR)
28
54
  end
29
55
 
56
+ # Caches the contents of the block, if the plan is cacheable, otherwise
57
+ # calls yields to the block directly
58
+ #
59
+ # @yield calls the block that should return a value to be cached
60
+ # @return whatever the provided block returns
30
61
  def cache
31
62
  if cache?
32
63
  Rails.cache.fetch(cache_key) { yield }
@@ -35,6 +66,13 @@ module CacheCrispies
35
66
  end
36
67
  end
37
68
 
69
+ # Wraps a value in a JSON key/object. Returns json_hash directly if there
70
+ # is no key.
71
+ #
72
+ # @param json_hash [Hash, Array, Object] typically a JSON-ready Hash or
73
+ # Array, but could be anything really
74
+ # @return [Hash, Object] will return a hash with a single key of #key,
75
+ # unless there is no #key, then returns the json_hash directly.
38
76
  def wrap(json_hash)
39
77
  return json_hash unless key?
40
78
 
@@ -65,4 +103,4 @@ module CacheCrispies
65
103
  Digest::MD5.hexdigest(addons.join('|'))
66
104
  end
67
105
  end
68
- end
106
+ end
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CacheCrispies
2
- VERSION = '0.1.0'.freeze
3
- end
4
+ # The version of the gem
5
+ VERSION = '0.1.1'
6
+ end
@@ -151,9 +151,9 @@ describe CacheCrispies::Attribute do
151
151
  let(:to) { OpenStruct }
152
152
 
153
153
  it 'raises an exception' do
154
- expect { subject }.to raise_exception CacheCrispies::Attribute::InvalidCoersionType
154
+ expect { subject }.to raise_exception CacheCrispies::Attribute::InvalidCoercionType
155
155
  end
156
156
  end
157
157
  end
158
158
  end
159
- end
159
+ end
@@ -20,9 +20,7 @@ describe CacheCrispies::Collection do
20
20
  let(:uncacheable_models) { [model1, model2] }
21
21
  let(:cacheable_models) {
22
22
  [model1, model2].tap do |models|
23
- def models.cache_key
24
- 'cereals-key'
25
- end
23
+ def models.cache_key() end
26
24
  end
27
25
  }
28
26
  let(:collection) { cacheable_models }
@@ -3,8 +3,6 @@ require 'spec_helper'
3
3
  describe CacheCrispies::Memoizer do
4
4
  describe '#fetch' do
5
5
  it 'only calls the block once per key' do
6
- block = -> {}
7
-
8
6
  expect { |block| subject.fetch 1, &block }.to yield_with_no_args
9
7
  expect { |block| subject.fetch 1, &block }.to_not yield_with_no_args
10
8
  expect { |block| subject.fetch 2, &block }.to yield_with_no_args
data/spec/plan_spec.rb CHANGED
@@ -49,7 +49,10 @@ describe CacheCrispies::Plan do
49
49
  end
50
50
 
51
51
  describe '#etag' do
52
-
52
+ it 'generates an MD5 digest of the cache_key' do
53
+ expect(subject).to receive(:cache_key).and_return 'foo'
54
+ expect(subject.etag).to eq Digest::MD5::hexdigest('foo')
55
+ end
53
56
  end
54
57
 
55
58
  describe '#cache_key' do
@@ -104,6 +107,21 @@ describe CacheCrispies::Plan do
104
107
  end
105
108
 
106
109
  describe '#cache' do
110
+ context 'when the plan is not cacheable' do
111
+ it "doesn't cache the results" do
112
+ expect(Rails).to_not receive(:cache)
113
+ subject.cache {}
114
+ end
115
+ end
116
+
117
+ context 'when the plan is not cacheable' do
118
+ it "doesn't cache the results" do
119
+ expect(subject).to receive(:cache?).and_return true
120
+ expect(subject).to receive(:cache_key).and_return 'bar'
121
+ expect(Rails).to receive_message_chain(:cache, :fetch).with('bar')
122
+ subject.cache {}
123
+ end
124
+ end
107
125
  end
108
126
 
109
127
  describe '#wrap' do
data/spec/spec_helper.rb CHANGED
@@ -1,102 +1,21 @@
1
- require 'byebug'
1
+ require 'simplecov'
2
+ SimpleCov.start
2
3
 
4
+ require 'byebug'
3
5
  require_relative '../lib/cache_crispies'
4
6
 
5
- # This file was generated by the `rspec --init` command. Conventionally, all
6
- # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
- # The generated `.rspec` file contains `--require spec_helper` which will cause
8
- # this file to always be loaded, without a need to explicitly require it in any
9
- # files.
10
- #
11
- # Given that it is always loaded, you are encouraged to keep this file as
12
- # light-weight as possible. Requiring heavyweight dependencies from this file
13
- # will add to the boot time of your test suite on EVERY test run, even for an
14
- # individual file that may not need all of that loaded. Instead, consider making
15
- # a separate helper file that requires the additional dependencies and performs
16
- # the additional setup, and require it from the spec files that actually need
17
- # it.
18
- #
19
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
20
7
  RSpec.configure do |config|
21
- # rspec-expectations config goes here. You can use an alternate
22
- # assertion/expectation library such as wrong or the stdlib/minitest
23
- # assertions if you prefer.
24
8
  config.expect_with :rspec do |expectations|
25
- # This option will default to `true` in RSpec 4. It makes the `description`
26
- # and `failure_message` of custom matchers include text for helper methods
27
- # defined using `chain`, e.g.:
28
- # be_bigger_than(2).and_smaller_than(4).description
29
- # # => "be bigger than 2 and smaller than 4"
30
- # ...rather than:
31
- # # => "be bigger than 2"
32
9
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
33
10
  end
34
11
 
35
- # rspec-mocks config goes here. You can use an alternate test double
36
- # library (such as bogus or mocha) by changing the `mock_with` option here.
37
12
  config.mock_with :rspec do |mocks|
38
- # Prevents you from mocking or stubbing a method that does not exist on
39
- # a real object. This is generally recommended, and will default to
40
- # `true` in RSpec 4.
41
13
  mocks.verify_partial_doubles = true
42
14
  end
43
15
 
44
- # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
45
- # have no way to turn it off -- the option exists only for backwards
46
- # compatibility in RSpec 3). It causes shared context metadata to be
47
- # inherited by the metadata hash of host groups and examples, rather than
48
- # triggering implicit auto-inclusion in groups with matching metadata.
49
16
  config.shared_context_metadata_behavior = :apply_to_host_groups
50
17
 
51
- # The settings below are suggested to provide a good initial experience
52
- # with RSpec, but feel free to customize to your heart's content.
53
- # # This allows you to limit a spec run to individual examples or groups
54
- # # you care about by tagging them with `:focus` metadata. When nothing
55
- # # is tagged with `:focus`, all examples get run. RSpec also provides
56
- # # aliases for `it`, `describe`, and `context` that include `:focus`
57
- # # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
58
- # config.filter_run_when_matching :focus
59
- #
60
- # # Allows RSpec to persist some state between runs in order to support
61
- # # the `--only-failures` and `--next-failure` CLI options. We recommend
62
- # # you configure your source control system to ignore this file.
63
- # config.example_status_persistence_file_path = "spec/examples.txt"
64
- #
65
- # # Limits the available syntax to the non-monkey patched syntax that is
66
- # # recommended. For more details, see:
67
- # # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
68
- # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
69
- # # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
70
- # config.disable_monkey_patching!
71
- #
72
- # # This setting enables warnings. It's recommended, but in some cases may
73
- # # be too noisy due to issues in dependencies.
74
- # config.warnings = true
75
- #
76
- # # Many RSpec users commonly either run the entire suite or an individual
77
- # # file, and it's useful to allow more verbose output when running an
78
- # # individual spec file.
79
- # if config.files_to_run.one?
80
- # # Use the documentation formatter for detailed output,
81
- # # unless a formatter has already been configured
82
- # # (e.g. via a command-line flag).
83
- # config.default_formatter = "doc"
84
- # end
85
- #
86
- # # Print the 10 slowest examples and example groups at the
87
- # # end of the spec run, to help surface which specs are running
88
- # # particularly slow.
89
- # config.profile_examples = 10
90
- #
91
- # # Run specs in random order to surface order dependencies. If you find an
92
- # # order dependency and want to debug it, you can fix the order by providing
93
- # # the seed, which is printed after each run.
94
- # # --seed 1234
95
- # config.order = :random
96
- #
97
- # # Seed global randomization in this process using the `--seed` CLI option.
98
- # # Setting this allows you to use `--seed` to deterministically reproduce
99
- # # test failures related to randomization by passing the same `--seed` value
100
- # # as the one that triggered the failure.
101
- # Kernel.srand config.seed
18
+ config.warnings = true
19
+ config.order = :random
20
+ Kernel.srand config.seed
102
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache_crispies
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Crownoble
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 3.8.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.17'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.17'
83
97
  description:
84
98
  email: adam@codenoble.com
85
99
  executables: []