bean_counter 0.0.3 → 0.0.4
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.
- data/README.md +1 -1
- data/lib/bean_counter/core.rb +67 -41
- data/lib/bean_counter/enqueued_expectation.rb +61 -20
- data/lib/bean_counter/spec_matchers.rb +21 -8
- data/lib/bean_counter/strategies/stalk_climber_strategy.rb +67 -46
- data/lib/bean_counter/strategy.rb +101 -77
- data/lib/bean_counter/test_assertions.rb +148 -98
- data/lib/bean_counter/tube_expectation.rb +50 -18
- data/lib/bean_counter/version.rb +1 -1
- data/test/unit/core_test.rb +2 -3
- metadata +2 -2
    
        data/README.md
    CHANGED
    
    | @@ -312,7 +312,7 @@ verify that the exports tube is paused: | |
| 312 312 | 
             
            For more detailed explanations and more examples make sure to check out the
         | 
| 313 313 | 
             
            docs, expectations, and respective tests:
         | 
| 314 314 |  | 
| 315 | 
            -
            - [docs](http://rubydoc.info/gems/bean_counter/0.0. | 
| 315 | 
            +
            - [docs](http://rubydoc.info/gems/bean_counter/0.0.4/frames)
         | 
| 316 316 | 
             
            - [enqueued_expectation](https://github.com/gemeraldbeanstalk/bean_counter/tree/master/lib/bean_counter/enqueued_expectation.rb)
         | 
| 317 317 | 
             
            - [tube_expectation](https://github.com/gemeraldbeanstalk/bean_counter/tree/master/lib/bean_counter/tube_expectation.rb)
         | 
| 318 318 | 
             
            - [test_assertions](https://github.com/gemeraldbeanstalk/bean_counter/tree/master/lib/bean_counter/test_assertions.rb)
         | 
    
        data/lib/bean_counter/core.rb
    CHANGED
    
    | @@ -3,38 +3,52 @@ module BeanCounter | |
| 3 3 | 
             
              # Use StalkClimberStrategy by default because it works with standard Beanstalkd
         | 
| 4 4 | 
             
              DEFAULT_STRATEGY = :'BeanCounter::Strategy::StalkClimberStrategy'
         | 
| 5 5 |  | 
| 6 | 
            -
               | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 6 | 
            +
              # Sets the Beanstalkd server URLs to be used by BeanCounter.
         | 
| 7 | 
            +
              #
         | 
| 8 | 
            +
              # @param value [String, Array<String>] The new value to to assign to beanstalkd_urls
         | 
| 9 | 
            +
              # @return [Object] Returns the value given
         | 
| 10 | 
            +
              def self.beanstalkd_url=(value)
         | 
| 11 | 
            +
                @beanstalkd_url = value
         | 
| 9 12 | 
             
              end
         | 
| 10 13 |  | 
| 11 | 
            -
              #  | 
| 12 | 
            -
              # | 
| 13 | 
            -
              #
         | 
| 14 | 
            -
              # Returns an array of parsed beanstalkd urls.
         | 
| 15 | 
            -
              # Server urls provided via the environment variable +BEANSTALKD_URL+ are given
         | 
| 14 | 
            +
              # Returns an Array of parsed Beanstalkd URLs.
         | 
| 15 | 
            +
              # Server URLs provided via the environment variable `BEANSTALKD_URL` are given
         | 
| 16 16 | 
             
              # precedence. When setting beanstalkd_url from the environment, urls are
         | 
| 17 | 
            -
              # expected in a comma separated list. If ENV['BEANSTALKD_URL'] is not set
         | 
| 18 | 
            -
              # BeanCounter | 
| 19 | 
            -
              # BeanCounter | 
| 20 | 
            -
              # checked and parsed. If no | 
| 21 | 
            -
              #  | 
| 22 | 
            -
              #  | 
| 23 | 
            -
              #  | 
| 24 | 
            -
              # * beanstalk://127.0.0.1:11300 (host and port prefixed by beanstalk scheme)
         | 
| 17 | 
            +
              # expected in a comma separated list. If `ENV['BEANSTALKD_URL']` is not set,
         | 
| 18 | 
            +
              # the BeanCounter.beanstalkd_url instance variable is checked and parsed next.
         | 
| 19 | 
            +
              # Finally, if the BeanCounter.beanstalkd_url instance variable has not been
         | 
| 20 | 
            +
              # set, the configuration for Beaneater is checked and parsed. If no
         | 
| 21 | 
            +
              # beanstalkd_url can be determined a RuntimeError is raised.
         | 
| 22 | 
            +
              # Beanstalkd URLs can be provided in any of three supported formats shown in
         | 
| 23 | 
            +
              # in the examples below.
         | 
| 25 24 | 
             
              #
         | 
| 26 25 | 
             
              # In short, a host is the only required component. If no port is provided, the default
         | 
| 27 | 
            -
              # beanstalkd port of 11300 is assumed. If a scheme other than beanstalk | 
| 28 | 
            -
              #  | 
| 26 | 
            +
              # beanstalkd port of 11300 is assumed. If a URI scheme other than beanstalk
         | 
| 27 | 
            +
              # is provided the strategy in use will likely raise an error.
         | 
| 28 | 
            +
              #
         | 
| 29 | 
            +
              # @return [Array<String>] An Array of Beanstalkd URLs.
         | 
| 30 | 
            +
              # @example Valid beanstalkd_url formats
         | 
| 31 | 
            +
              #   # host only:
         | 
| 32 | 
            +
              #   'localhost'
         | 
| 33 | 
            +
              #
         | 
| 34 | 
            +
              #   # host and port:
         | 
| 35 | 
            +
              #   '192.168.1.100:11300'
         | 
| 36 | 
            +
              #
         | 
| 37 | 
            +
              #   # host and port prefixed by beanstalk URI scheme:
         | 
| 38 | 
            +
              #   'beanstalk://127.0.0.1:11300'
         | 
| 39 | 
            +
              #
         | 
| 40 | 
            +
              # @example BeanCounter.beanstalkd_url provided via ENV['BEANSTALKD_URL']
         | 
| 41 | 
            +
              #   # $ BEANSTALKD_URL='127.0.0.1,beanstalk://localhost:11300,localhost:11301' rake test
         | 
| 29 42 | 
             
              #
         | 
| 30 | 
            -
              #   $ BEANSTALKD_URL='127.0.0.1,beanstalk://localhost:11300,localhost:11301' rake test
         | 
| 31 43 | 
             
              #   BeanCounter.beanstalkd_url
         | 
| 32 44 | 
             
              #     #=> ['127.0.0.1', 'beanstalk://localhost:11300', 'localhost:11301']
         | 
| 33 45 | 
             
              #
         | 
| 46 | 
            +
              # @example BeanCounter.beanstalkd_url set explicitly
         | 
| 34 47 | 
             
              #   BeanCounter.beanstalkd_url = 'beanstalk://localhost'
         | 
| 35 48 | 
             
              #   BeanCounter.beanstalkd_url
         | 
| 36 49 | 
             
              #     #=> 'beanstalk://localhost'
         | 
| 37 50 | 
             
              #
         | 
| 51 | 
            +
              # @example BeanCounter.beanstalkd_url provided by Beaneater
         | 
| 38 52 | 
             
              #   Beaneater.configure do |config|
         | 
| 39 53 | 
             
              #     config.beanstalkd_url = ['localhost', 'localhost:11301']
         | 
| 40 54 | 
             
              #   end
         | 
| @@ -46,33 +60,35 @@ module BeanCounter | |
| 46 60 | 
             
                @hosts_from_env = @hosts_from_env.split(',').map!(&:strip) unless @hosts_from_env.nil?
         | 
| 47 61 | 
             
                beanstalkd_url = @hosts_from_env || @beanstalkd_url || Beaneater.configuration.beanstalkd_url
         | 
| 48 62 | 
             
                raise 'Could not determine beanstalkd url' if beanstalkd_url.to_s == ''
         | 
| 49 | 
            -
                return beanstalkd_url
         | 
| 63 | 
            +
                return beanstalkd_url.is_a?(Array) ? beanstalkd_url : [beanstalkd_url]
         | 
| 50 64 | 
             
              end
         | 
| 51 65 |  | 
| 52 66 |  | 
| 53 | 
            -
              #  | 
| 54 | 
            -
              # | 
| 67 | 
            +
              # Returns a previously materialized strategy or materializes a new default
         | 
| 68 | 
            +
              # strategy for use.
         | 
| 69 | 
            +
              #
         | 
| 70 | 
            +
              # See {BeanCounter::Strategy.materialize_strategy} for more information on the
         | 
| 71 | 
            +
              # materialization process.
         | 
| 55 72 | 
             
              #
         | 
| 56 | 
            -
              #  | 
| 57 | 
            -
              #  | 
| 58 | 
            -
              # information on the materialization process.
         | 
| 73 | 
            +
              # @see BeanCounter::Strategy.materialize_strategy
         | 
| 74 | 
            +
              # @return [BeanCounter::Strategy] An existing or newly materialized default strategy
         | 
| 59 75 | 
             
              def self.default_strategy
         | 
| 60 76 | 
             
                return @default_strategy ||= BeanCounter::Strategy.materialize_strategy(DEFAULT_STRATEGY)
         | 
| 61 77 | 
             
              end
         | 
| 62 78 |  | 
| 63 79 |  | 
| 64 | 
            -
              #  | 
| 65 | 
            -
              #    | 
| 66 | 
            -
              # Uses the strategy to delete all jobs from the +tube_name+ tube. If +tube_name+
         | 
| 67 | 
            -
              # is not provided, all jobs on the beanstalkd server are deleted.
         | 
| 80 | 
            +
              # Uses strategy to delete all jobs from the beanstalkd pool or from the tube
         | 
| 81 | 
            +
              #   specified by `tube_name`.
         | 
| 68 82 | 
             
              #
         | 
| 69 83 | 
             
              # It should be noted that jobs that are reserved can only be deleted by the
         | 
| 70 84 | 
             
              # reserving connection and thus cannot be deleted via this method. As such,
         | 
| 71 85 | 
             
              # care may need to be taken to ensure that jobs are not left in a reserved
         | 
| 72 86 | 
             
              # state.
         | 
| 73 87 | 
             
              #
         | 
| 74 | 
            -
              #  | 
| 75 | 
            -
              #  | 
| 88 | 
            +
              # @param tube_name [String] a particular tube to clear all jobs from. If not
         | 
| 89 | 
            +
              #   given, all jobs in the Beanstalkd pool will be} deleted.
         | 
| 90 | 
            +
              # @return [Boolean] Returns true if all encountered jobs were deleted successfully. Returns
         | 
| 91 | 
            +
              #   false if any of the jobs enumerated could not be deleted.
         | 
| 76 92 | 
             
              def self.reset!(tube_name = nil)
         | 
| 77 93 | 
             
                partial_failure = false
         | 
| 78 94 | 
             
                strategy.jobs.each do |job|
         | 
| @@ -83,19 +99,26 @@ module BeanCounter | |
| 83 99 | 
             
              end
         | 
| 84 100 |  | 
| 85 101 |  | 
| 86 | 
            -
              # Returns a list of known subclasses of BeanCounter::Strategy.
         | 
| 87 | 
            -
              #  | 
| 88 | 
            -
              # | 
| 102 | 
            +
              # Returns a list of known subclasses of BeanCounter::Strategy. Typically this
         | 
| 103 | 
            +
              # list represents the strategies available for interacting with Beanstalkd.
         | 
| 104 | 
            +
              #
         | 
| 105 | 
            +
              # @return [Array<BeanCounter::Strategy>] Returns a list of known subclasses of
         | 
| 106 | 
            +
              #   BeanCounter::Strategy
         | 
| 89 107 | 
             
              def self.strategies
         | 
| 90 108 | 
             
                return BeanCounter::Strategy.strategies
         | 
| 91 109 | 
             
              end
         | 
| 92 110 |  | 
| 93 111 |  | 
| 94 | 
            -
              # Sets the strategy that BeanCounter should use when interacting with
         | 
| 95 | 
            -
              #  | 
| 112 | 
            +
              # Sets the strategy that BeanCounter should use when interacting with Beanstalkd.
         | 
| 113 | 
            +
              # The value provided for `strategy_identifier` will be used to
         | 
| 96 114 | 
             
              # materialize an instance of the matching strategy class. If the provided
         | 
| 97 | 
            -
              #  | 
| 98 | 
            -
              # the next call to BeanCounter | 
| 115 | 
            +
              # `strategy_identifier` is nil, any existing strategy will be cleared and
         | 
| 116 | 
            +
              # the next call to BeanCounter.strategy will use the default strategy.
         | 
| 117 | 
            +
              #
         | 
| 118 | 
            +
              # @param strategy_identifier [Object] A class or an Object that responds to
         | 
| 119 | 
            +
              #   :to_sym identifying the subclass of BeanCounter::Strategy to use
         | 
| 120 | 
            +
              #   when communicating with the beanstalkd pool
         | 
| 121 | 
            +
              # @return [Object] Returns the value given
         | 
| 99 122 | 
             
              def self.strategy=(strategy_identifier)
         | 
| 100 123 | 
             
                if strategy_identifier.nil?
         | 
| 101 124 | 
             
                  @strategy = nil
         | 
| @@ -105,9 +128,12 @@ module BeanCounter | |
| 105 128 | 
             
              end
         | 
| 106 129 |  | 
| 107 130 |  | 
| 108 | 
            -
              # Returns a previously materialized strategy  | 
| 109 | 
            -
              # strategy exists, a new instance of | 
| 110 | 
            -
              # and returned.
         | 
| 131 | 
            +
              # Returns a previously materialized strategy or instantiates a new instance
         | 
| 132 | 
            +
              # of the default strategy. If no previous strategy exists, a new instance of
         | 
| 133 | 
            +
              # the default strategy is instantiated and returned.
         | 
| 134 | 
            +
              #
         | 
| 135 | 
            +
              # @return [BeanCounter::Strategy] Returns the existing strategy or a new
         | 
| 136 | 
            +
              #   instance of the default strategy
         | 
| 111 137 | 
             
              def self.strategy
         | 
| 112 138 | 
             
                return @strategy ||= default_strategy.new
         | 
| 113 139 | 
             
              end
         | 
| @@ -4,18 +4,27 @@ class BeanCounter::EnqueuedExpectation | |
| 4 4 |  | 
| 5 5 | 
             
              def_delegators BeanCounter, :strategy
         | 
| 6 6 |  | 
| 7 | 
            -
              # The  | 
| 7 | 
            +
              # The Hash of options given at instantiation that the expectation expects when
         | 
| 8 | 
            +
              # matching.
         | 
| 9 | 
            +
              # @return [Hash]
         | 
| 8 10 | 
             
              attr_reader :expected
         | 
| 9 11 |  | 
| 10 12 | 
             
              # The number of matching jobs the expectation expects
         | 
| 13 | 
            +
              # @return [Numeric, Range]
         | 
| 11 14 | 
             
              attr_reader :expected_count
         | 
| 12 15 |  | 
| 13 16 | 
             
              # The jobs found by the expecation during matching
         | 
| 17 | 
            +
              # @return [Array<Strategy::Job>]
         | 
| 14 18 | 
             
              attr_reader :found
         | 
| 15 19 |  | 
| 16 20 |  | 
| 17 21 | 
             
              # Iterates over the provided collection searching for jobs matching the
         | 
| 18 | 
            -
              # Hash of expected options provided  | 
| 22 | 
            +
              # Hash of expected options provided during instantiation.
         | 
| 23 | 
            +
              #
         | 
| 24 | 
            +
              # @param collection [Array<Strategy::Job>] A collection of jobs as
         | 
| 25 | 
            +
              #   implemented by the strategy to evaluate for a match.
         | 
| 26 | 
            +
              # @return [Boolean] true if the collection matches the expected options and
         | 
| 27 | 
            +
              #   count
         | 
| 19 28 | 
             
              def collection_matcher(collection)
         | 
| 20 29 | 
             
                @found = collection.send(expected_count? ? :select : :detect) do |job|
         | 
| 21 30 | 
             
                  strategy.job_matches?(job, expected)
         | 
| @@ -28,13 +37,19 @@ class BeanCounter::EnqueuedExpectation | |
| 28 37 |  | 
| 29 38 |  | 
| 30 39 | 
             
              # Returns a Boolean indicating whether a specific number of jobs are expected.
         | 
| 40 | 
            +
              #
         | 
| 41 | 
            +
              # @return [Boolean] true if a specifc number of jobs are expected, otherwise
         | 
| 42 | 
            +
              #   false
         | 
| 31 43 | 
             
              def expected_count?
         | 
| 32 44 | 
             
                return !!expected_count
         | 
| 33 45 | 
             
              end
         | 
| 34 46 |  | 
| 35 47 |  | 
| 36 48 | 
             
              # Builds the failure message used in the event of a positive expectation
         | 
| 37 | 
            -
              # failure
         | 
| 49 | 
            +
              # failure.
         | 
| 50 | 
            +
              #
         | 
| 51 | 
            +
              # @return [String] The failure message for use in the event of a positive
         | 
| 52 | 
            +
              #   expectation failure.
         | 
| 38 53 | 
             
              def failure_message
         | 
| 39 54 | 
             
                if found.nil?
         | 
| 40 55 | 
             
                  found_count = 'none'
         | 
| @@ -52,18 +67,28 @@ class BeanCounter::EnqueuedExpectation | |
| 52 67 | 
             
              end
         | 
| 53 68 |  | 
| 54 69 |  | 
| 55 | 
            -
              # Create a new enqueued expectation. Uses the given  | 
| 70 | 
            +
              # Create a new enqueued expectation. Uses the given `expected` Hash to determine
         | 
| 56 71 | 
             
              # if any jobs are enqueued that match the expected options.
         | 
| 57 72 | 
             
              #
         | 
| 58 | 
            -
              # Each  | 
| 59 | 
            -
              # of a job that the corresponding  | 
| 60 | 
            -
              # comparisons are performed using the triple | 
| 61 | 
            -
              # the given  | 
| 73 | 
            +
              # Each `key` in `expected` is a String or a Symbol that identifies an attribute
         | 
| 74 | 
            +
              # of a job that the corresponding `value` should be compared against. All attribute
         | 
| 75 | 
            +
              # comparisons are performed using the triple-equal (===) operator/method of
         | 
| 76 | 
            +
              # the given `value`.
         | 
| 62 77 | 
             
              #
         | 
| 63 | 
            -
              #  | 
| 78 | 
            +
              # `expected` may additionally include a `count` key of 'count' or :count that
         | 
| 64 79 | 
             
              # can be used to specify that a particular number of matching jobs are found.
         | 
| 65 80 | 
             
              #
         | 
| 66 | 
            -
              # See BeanCounter:: | 
| 81 | 
            +
              # See {BeanCounter::Strategy::MATCHABLE_JOB_ATTRIBUTES} for a list of
         | 
| 82 | 
            +
              #   attributes that can be used when matching.
         | 
| 83 | 
            +
              #
         | 
| 84 | 
            +
              # @see BeanCounter::Strategy::MATCHABLE_JOB_ATTRIBUTES
         | 
| 85 | 
            +
              # @see BeanCounter::TestAssertions
         | 
| 86 | 
            +
              # @see BeanCounter::SpecMatchers
         | 
| 87 | 
            +
              # @param expected
         | 
| 88 | 
            +
              #   [Hash{String, Symbol => Numeric, Proc, Range, Regexp, String, Symbol}]
         | 
| 89 | 
            +
              #   Options expected when evaluating match
         | 
| 90 | 
            +
              # @option expected [Numeric, Range] :count (nil) A particular number of matching
         | 
| 91 | 
            +
              #   jobs expected
         | 
| 67 92 | 
             
              def initialize(expected)
         | 
| 68 93 | 
             
                @expected = expected
         | 
| 69 94 | 
             
                @expected_count = [expected.delete(:count), expected.delete('count')].compact.first
         | 
| @@ -73,12 +98,12 @@ class BeanCounter::EnqueuedExpectation | |
| 73 98 | 
             
              # Checks the beanstalkd pool for jobs matching the Hash of expected options
         | 
| 74 99 | 
             
              # provided at instantiation.
         | 
| 75 100 | 
             
              #
         | 
| 76 | 
            -
              # If no  | 
| 101 | 
            +
              # If no `count` option is provided, the expectation succeeds if any job is found
         | 
| 77 102 | 
             
              # that matches all of the expected options. If no jobs are found that match the
         | 
| 78 103 | 
             
              # expected options, the expecation fails.
         | 
| 79 104 | 
             
              #
         | 
| 80 | 
            -
              # If a  | 
| 81 | 
            -
              # (===) operator/method of the value of  | 
| 105 | 
            +
              # If a `count` option is provided the expectation only succeeds if the triple-equal
         | 
| 106 | 
            +
              # (===) operator/method of the value of `count` evaluates to true when given the
         | 
| 82 107 | 
             
              # total number of matching jobs. Otherwise the expecation fails. The use of ===
         | 
| 83 108 | 
             
              # allows for more advanced comparisons using Procs, Ranges, Regexps, etc.
         | 
| 84 109 | 
             
              #
         | 
| @@ -86,8 +111,17 @@ class BeanCounter::EnqueuedExpectation | |
| 86 111 | 
             
              # in use for more detailed information on how it is determined whether or not
         | 
| 87 112 | 
             
              # a job matches the options expected.
         | 
| 88 113 | 
             
              #
         | 
| 89 | 
            -
              # See  | 
| 90 | 
            -
              #  | 
| 114 | 
            +
              # See {BeanCounter::Strategy::MATCHABLE_JOB_ATTRIBUTES} for a list of
         | 
| 115 | 
            +
              #   attributes that can be used when matching.
         | 
| 116 | 
            +
              #
         | 
| 117 | 
            +
              # @see BeanCounter::Strategy::MATCHABLE_JOB_ATTRIBUTES
         | 
| 118 | 
            +
              # @see BeanCounter::TestAssertions
         | 
| 119 | 
            +
              # @see BeanCounter::SpecMatchers
         | 
| 120 | 
            +
              # @param given [Proc] If a Proc is provided, only jobs enqueued during the
         | 
| 121 | 
            +
              #   execution of the Proc are considered when looking for a match. Otherwise
         | 
| 122 | 
            +
              #   all jobs available to the strategy will be evaluated for a match.
         | 
| 123 | 
            +
              # @return [Boolean] If a match is found, returns true. Otherwise, returns
         | 
| 124 | 
            +
              #   false.
         | 
| 91 125 | 
             
              def matches?(given = nil)
         | 
| 92 126 | 
             
                if given.kind_of?(Proc)
         | 
| 93 127 | 
             
                  return proc_matcher(given)
         | 
| @@ -99,6 +133,9 @@ class BeanCounter::EnqueuedExpectation | |
| 99 133 |  | 
| 100 134 | 
             
              # Builds the failure message used in the event of a negative expectation
         | 
| 101 135 | 
             
              # failure
         | 
| 136 | 
            +
              #
         | 
| 137 | 
            +
              # @return [String] The failure message for use in the event of a negative
         | 
| 138 | 
            +
              #   expectation failure.
         | 
| 102 139 | 
             
              def negative_failure_message
         | 
| 103 140 | 
             
                return '' if found.nil? || found == []
         | 
| 104 141 |  | 
| @@ -119,13 +156,17 @@ class BeanCounter::EnqueuedExpectation | |
| 119 156 | 
             
              end
         | 
| 120 157 |  | 
| 121 158 |  | 
| 122 | 
            -
              #  | 
| 123 | 
            -
              #  | 
| 124 | 
            -
              #  | 
| 125 | 
            -
              # | 
| 159 | 
            +
              # Evaluates jobs enqueued during the execution of the provided block to
         | 
| 160 | 
            +
              # determine if any jobs were enqueued that match the expected options provided
         | 
| 161 | 
            +
              # at instantiation
         | 
| 162 | 
            +
              #
         | 
| 163 | 
            +
              # @param block [Proc] A Proc that when executed should demonstrate that
         | 
| 164 | 
            +
              #   expected behavior.
         | 
| 165 | 
            +
              # @return [Boolean] If the jobs enqueued during the execution of the `block`
         | 
| 166 | 
            +
              #   include a match, returns true. Otherwise, returns false.
         | 
| 126 167 | 
             
              def proc_matcher(block)
         | 
| 127 168 | 
             
                new_jobs = strategy.collect_new_jobs(&block)
         | 
| 128 | 
            -
                collection_matcher(new_jobs)
         | 
| 169 | 
            +
                return collection_matcher(new_jobs)
         | 
| 129 170 | 
             
              end
         | 
| 130 171 |  | 
| 131 172 | 
             
            end
         | 
| @@ -1,23 +1,36 @@ | |
| 1 1 | 
             
            module BeanCounter::SpecMatchers
         | 
| 2 2 |  | 
| 3 | 
            -
              # Creates a new BeanCounter::EnqueuedExpectation with  | 
| 4 | 
            -
              # later use when matching. Most of the time the value provided for  | 
| 5 | 
            -
              # will be ignored, the only exception is when  | 
| 6 | 
            -
              # When a block is provided for  | 
| 3 | 
            +
              # Creates a new {BeanCounter::EnqueuedExpectation} with `expected` stored for
         | 
| 4 | 
            +
              # later use when matching. Most of the time the value provided for `expected`
         | 
| 5 | 
            +
              # will be ignored, the only exception is when `expected` is given a block.
         | 
| 6 | 
            +
              # When a block is provided for `expected`, only jobs enqueued during the
         | 
| 7 7 | 
             
              # execution of the block will be considered when matching.
         | 
| 8 8 | 
             
              #
         | 
| 9 | 
            -
              # See BeanCounter::EnqueuedExpectation for additional information and usage
         | 
| 9 | 
            +
              # See {BeanCounter::EnqueuedExpectation} for additional information and usage
         | 
| 10 10 | 
             
              # patterns.
         | 
| 11 | 
            +
              #
         | 
| 12 | 
            +
              # @see BeanCounter::EnqueuedExpectation
         | 
| 13 | 
            +
              # @param expected
         | 
| 14 | 
            +
              #   [Hash{String, Symbol => Numeric, Proc, Range, Regexp, String, Symbol}]
         | 
| 15 | 
            +
              #   options used for evaluating match.
         | 
| 16 | 
            +
              # @return [BeanCounter::EnqueuedExpectation] an expectation to be used for
         | 
| 17 | 
            +
              #   matching.
         | 
| 11 18 | 
             
              def have_enqueued(expected)
         | 
| 12 19 | 
             
                BeanCounter::EnqueuedExpectation.new(expected)
         | 
| 13 20 | 
             
              end
         | 
| 14 21 |  | 
| 15 | 
            -
              # Creates a new BeanCounter::TubeExpectation with  | 
| 16 | 
            -
              # later use when matching. However,  | 
| 22 | 
            +
              # Creates a new {BeanCounter::TubeExpectation} with `expected` stored for
         | 
| 23 | 
            +
              # later use when matching. However, `expected` is never used when matching.
         | 
| 17 24 | 
             
              # Instead, all tubes are matched against until a match is found.
         | 
| 18 25 | 
             
              #
         | 
| 19 | 
            -
              # See BeanCounter::TubeExpectation for additional information and usage
         | 
| 26 | 
            +
              # See {BeanCounter::TubeExpectation} for additional information and usage
         | 
| 20 27 | 
             
              # patterns.
         | 
| 28 | 
            +
              #
         | 
| 29 | 
            +
              # @param expected
         | 
| 30 | 
            +
              #   [Hash{String, Symbol => Numeric, Proc, Range, Regexp, String, Symbol}]
         | 
| 31 | 
            +
              #   options used for evaluating match.
         | 
| 32 | 
            +
              # @see BeanCounter::TubeExpectation
         | 
| 33 | 
            +
              # @return [BeanCounter::TubeExpectation] an expectation to be used for matching.
         | 
| 21 34 | 
             
              def have_tube(expected)
         | 
| 22 35 | 
             
                BeanCounter::TubeExpectation.new(expected)
         | 
| 23 36 | 
             
              end
         | 
| @@ -16,24 +16,26 @@ class BeanCounter::Strategy::StalkClimberStrategy < BeanCounter::Strategy | |
| 16 16 | 
             
                attr_methods
         | 
| 17 17 | 
             
              end
         | 
| 18 18 |  | 
| 19 | 
            -
              # Default tube used by StalkClimber when probing the  | 
| 19 | 
            +
              # Default tube used by StalkClimber when probing the Beanstalkd pool
         | 
| 20 20 | 
             
              TEST_TUBE = 'bean_counter_stalk_climber_test'
         | 
| 21 21 |  | 
| 22 | 
            -
              # The tube that will be used by StalkClimber when probing the  | 
| 23 | 
            -
              # Uses TEST_TUBE if no value provided.
         | 
| 22 | 
            +
              # The tube that will be used by StalkClimber when probing the Beanstalkd pool.
         | 
| 23 | 
            +
              # Uses {TEST_TUBE} if no value provided.
         | 
| 24 24 | 
             
              attr_writer :test_tube
         | 
| 25 25 |  | 
| 26 26 | 
             
              def_delegators :climber, :jobs, :tubes
         | 
| 27 27 |  | 
| 28 28 |  | 
| 29 | 
            -
              #  | 
| 30 | 
            -
              #   collect_new_jobs { block } => Array[StalkClimber::Job]
         | 
| 31 | 
            -
              #
         | 
| 32 | 
            -
              # Collects all jobs enqueued during the execution of the provided +block+.
         | 
| 29 | 
            +
              # Collects all jobs enqueued during the execution of the provided `block`.
         | 
| 33 30 | 
             
              # Returns an Array of StalkClimber::Job.
         | 
| 34 31 | 
             
              #
         | 
| 35 | 
            -
              # Fulfills Strategy#collect_new_jobs contract. | 
| 36 | 
            -
              # | 
| 32 | 
            +
              # Fulfills {BeanCounter::Strategy#collect_new_jobs} contract.
         | 
| 33 | 
            +
              #
         | 
| 34 | 
            +
              # @see BeanCounter::Strategy#collect_new_jobs
         | 
| 35 | 
            +
              # @yield Nothing is yielded to the provided `block`
         | 
| 36 | 
            +
              # @raise [ArgumentError] if a block is not provided.
         | 
| 37 | 
            +
              # @return [Array<StalkClimber::Job>] all jobs enqueued during the execution
         | 
| 38 | 
            +
              #   of the provided `block`
         | 
| 37 39 | 
             
              def collect_new_jobs
         | 
| 38 40 | 
             
                raise ArgumentError, 'Block required' unless block_given?
         | 
| 39 41 |  | 
| @@ -49,15 +51,16 @@ class BeanCounter::Strategy::StalkClimberStrategy < BeanCounter::Strategy | |
| 49 51 | 
             
              end
         | 
| 50 52 |  | 
| 51 53 |  | 
| 52 | 
            -
              #  | 
| 53 | 
            -
              # | 
| 54 | 
            -
              #
         | 
| 55 | 
            -
              # Attempts to delete the given StalkClimber::Job +job+. Returns true if
         | 
| 56 | 
            -
              # deletion succeeds or if +job+ does not exist. Returns false if +job+ could
         | 
| 54 | 
            +
              # Attempts to delete the given StalkClimber::Job `job`. Returns true if
         | 
| 55 | 
            +
              # deletion succeeds or if `job` does not exist. Returns false if `job` could
         | 
| 57 56 | 
             
              # not be deleted (typically due to it being reserved by another connection).
         | 
| 58 57 | 
             
              #
         | 
| 59 | 
            -
              # Fulfills Strategy#delete_job contract. | 
| 60 | 
            -
              # | 
| 58 | 
            +
              # Fulfills {BeanCounter::Strategy#delete_job} contract.
         | 
| 59 | 
            +
              #
         | 
| 60 | 
            +
              # @see BeanCounter::Strategy#delete_job
         | 
| 61 | 
            +
              # @param job [StalkClimber::Job] the job to be deleted
         | 
| 62 | 
            +
              # @return [Boolean] If the given job was successfully deleted or does not
         | 
| 63 | 
            +
              #   exist, returns true. Otherwise returns false.
         | 
| 61 64 | 
             
              def delete_job(job)
         | 
| 62 65 | 
             
                job.delete
         | 
| 63 66 | 
             
                return true
         | 
| @@ -66,67 +69,84 @@ class BeanCounter::Strategy::StalkClimberStrategy < BeanCounter::Strategy | |
| 66 69 | 
             
              end
         | 
| 67 70 |  | 
| 68 71 |  | 
| 69 | 
            -
              #  | 
| 70 | 
            -
              # | 
| 72 | 
            +
              # Returns a Boolean indicating whether or not the provided Sta`kClimber::Job
         | 
| 73 | 
            +
              # `job` matches the given Hash of `options`.
         | 
| 71 74 | 
             
              #
         | 
| 72 | 
            -
              #  | 
| 73 | 
            -
              #  | 
| 75 | 
            +
              # See {MATCHABLE_JOB_ATTRIBUTES} for a list of
         | 
| 76 | 
            +
              # attributes that can be used when matching.
         | 
| 74 77 | 
             
              #
         | 
| 75 | 
            -
              # Fulfills Strategy#job_matches? contract. | 
| 76 | 
            -
              # | 
| 77 | 
            -
               | 
| 78 | 
            -
             | 
| 78 | 
            +
              # Fulfills {BeanCounter::Strategy#job_matches?} contract.
         | 
| 79 | 
            +
              #
         | 
| 80 | 
            +
              # @see MATCHABLE_JOB_ATTRIBUTES
         | 
| 81 | 
            +
              # @see BeanCounter::Strategy#job_matches?
         | 
| 82 | 
            +
              # @param job [StalkClimber::Job] the job to evaluate if matches.
         | 
| 83 | 
            +
              # @param options
         | 
| 84 | 
            +
              #   [Hash{String, Symbol => Numeric, Proc, Range, Regexp, String, Symbol}]
         | 
| 85 | 
            +
              #   Options to be used to evaluate a match.
         | 
| 86 | 
            +
              # @return [Boolean] If job matches the provided options, returns true.
         | 
| 87 | 
            +
              #   Otherwise, returns false.
         | 
| 88 | 
            +
              def job_matches?(job, options = {})
         | 
| 89 | 
            +
                return matcher(MATCHABLE_JOB_ATTRIBUTES, job, options)
         | 
| 79 90 | 
             
              end
         | 
| 80 91 |  | 
| 81 92 |  | 
| 82 | 
            -
              #  | 
| 83 | 
            -
              #   pretty_print_job(job) => String
         | 
| 84 | 
            -
              #
         | 
| 85 | 
            -
              # Returns a String representation of the StalkClimber::Job +job+ in a pretty,
         | 
| 93 | 
            +
              # Returns a String representation of the StalkClimber::Job `job` in a pretty,
         | 
| 86 94 | 
             
              # human readable format.
         | 
| 87 95 | 
             
              #
         | 
| 88 | 
            -
              # Fulfills Strategy#pretty_print_job contract. | 
| 89 | 
            -
              # | 
| 96 | 
            +
              # Fulfills {BeanCounter::Strategy#pretty_print_job} contract.
         | 
| 97 | 
            +
              #
         | 
| 98 | 
            +
              # @see BeanCounter::Strategy#pretty_print_job
         | 
| 99 | 
            +
              # @param job [StalkClimber::Job] the job to print in a more readable format.
         | 
| 100 | 
            +
              # @return [String] A more human-readable representation of `job`.
         | 
| 90 101 | 
             
              def pretty_print_job(job)
         | 
| 91 102 | 
             
                return job.to_h.to_s
         | 
| 92 103 | 
             
              end
         | 
| 93 104 |  | 
| 94 105 |  | 
| 95 | 
            -
              #  | 
| 96 | 
            -
              #   pretty_print_tube(tube) => String
         | 
| 106 | 
            +
              # Returns a String representation of `tube` in a pretty, human readable format.
         | 
| 97 107 | 
             
              #
         | 
| 98 | 
            -
              #  | 
| 108 | 
            +
              # Fulfills {BeanCounter::Strategy#pretty_print_tube} contract.
         | 
| 99 109 | 
             
              #
         | 
| 100 | 
            -
              #  | 
| 101 | 
            -
              #  | 
| 110 | 
            +
              # @see BeanCounter::Strategy#pretty_print_tube
         | 
| 111 | 
            +
              # @param tube [StalkClimber::Tube] the tube to print in a more readable format.
         | 
| 112 | 
            +
              # @return [String] A more human-readable representation of `tube`.
         | 
| 102 113 | 
             
              def pretty_print_tube(tube)
         | 
| 103 114 | 
             
                return tube.to_h.to_s
         | 
| 104 115 | 
             
              end
         | 
| 105 116 |  | 
| 106 117 |  | 
| 107 | 
            -
              #  | 
| 108 | 
            -
              # | 
| 118 | 
            +
              # Returns a boolean indicating whether or not the provided StalkClimber `tube`
         | 
| 119 | 
            +
              # matches the given Hash of `options`.
         | 
| 120 | 
            +
              #
         | 
| 121 | 
            +
              # See {MATCHABLE_TUBE_ATTRIBUTES} for a list of attributes that can be used
         | 
| 122 | 
            +
              # when evaluating a match.
         | 
| 109 123 | 
             
              #
         | 
| 110 | 
            -
              #  | 
| 111 | 
            -
              # matches the given Hash of +options.
         | 
| 124 | 
            +
              # Fulfills {BeanCounter::Strategy#tube_matches?} contract.
         | 
| 112 125 | 
             
              #
         | 
| 113 | 
            -
              #  | 
| 114 | 
            -
              #  | 
| 115 | 
            -
               | 
| 116 | 
            -
             | 
| 126 | 
            +
              # @see BeanCounter::Strategy#tube_matches?
         | 
| 127 | 
            +
              # @param tube [StalkClimber::Tube] the tube to evaluate a match against.
         | 
| 128 | 
            +
              # @param options
         | 
| 129 | 
            +
              #   [Hash{String, Symbol => Numeric, Proc, Range, Regexp, String, Symbol}]
         | 
| 130 | 
            +
              #   a Hash of options to use when evaluating a match.
         | 
| 131 | 
            +
              # @return [Boolean] If `tube` matches against the provided options, returns
         | 
| 132 | 
            +
              #   true. Otherwise returns false.
         | 
| 133 | 
            +
              def tube_matches?(tube, options = {})
         | 
| 134 | 
            +
                return matcher(MATCHABLE_TUBE_ATTRIBUTES, tube, options)
         | 
| 117 135 | 
             
              end
         | 
| 118 136 |  | 
| 119 137 | 
             
              private
         | 
| 120 138 |  | 
| 121 139 | 
             
              # StalkClimber instance used to climb/crawl beanstalkd pool
         | 
| 140 | 
            +
              # @return [StalkClimber::Climber]
         | 
| 122 141 | 
             
              def climber
         | 
| 123 142 | 
             
                return @climber ||= StalkClimber::Climber.new(BeanCounter.beanstalkd_url, test_tube)
         | 
| 124 143 | 
             
              end
         | 
| 125 144 |  | 
| 126 145 |  | 
| 127 | 
            -
              # Given the set of valid attributes,  | 
| 128 | 
            -
              #  | 
| 129 | 
            -
              #  | 
| 146 | 
            +
              # Given the set of valid attributes, `valid_attributes`, determines if every
         | 
| 147 | 
            +
              # `value` of `opts` evaluates to true when compared to the attribute of
         | 
| 148 | 
            +
              # `matchable` identified by the corresponding `opts` `key`.
         | 
| 149 | 
            +
              # @return [Boolean]
         | 
| 130 150 | 
             
              def matcher(valid_attributes, matchable, opts = {})
         | 
| 131 151 | 
             
                # Refresh state/stats before checking match
         | 
| 132 152 | 
             
                return false unless matchable.exists?
         | 
| @@ -137,6 +157,7 @@ class BeanCounter::Strategy::StalkClimberStrategy < BeanCounter::Strategy | |
| 137 157 |  | 
| 138 158 |  | 
| 139 159 | 
             
              # Simplify lookup of what method to call to retrieve requested stat
         | 
| 160 | 
            +
              # @return [Symbol]
         | 
| 140 161 | 
             
              def stats_method_name(stats_attr)
         | 
| 141 162 | 
             
                return STATS_METHOD_NAMES[stats_attr.to_sym]
         | 
| 142 163 | 
             
              end
         |