cache_crispies 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []