class RSpec::Benchmark::AllocationMatcher::Matcher

Implements the `perform_allocation` matcher

@api private

Public Class Methods

new(objects, **options) click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 12
def initialize(objects, **options)
  @objects = objects
  @retained_objects = nil
  @warmup = options.fetch(:warmup) { 1 }
  @bench  = ::Benchmark::Malloc
  @count_type = :objects
end

Public Instance Methods

actual() click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 127
def actual
  if @count_type == :memory
    "#{objects_to_s(@actual)} bytes"
  else
    desc = ["#{objects_to_s(@actual)} #{pluralize_objects(@actual)}"]
    if @retained_objects
      desc << " and retained #{objects_to_s(@actual_retained)}"
    end
    desc.join
  end
end
and_retain(objects) click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 66
def and_retain(objects)
  @retained_objects = objects
  self
end
bytes()
Alias for: memory
count_objects(objects) click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 110
def count_objects(objects)
  if @count_type == :memory
    "#{objects_to_s(objects)} #{objects == 1 ? "byte" : "bytes"}"
  else
    "#{objects_to_s(objects)} #{pluralize_objects(objects)}"
  end
end
description() click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 102
def description
  desc = ["perform allocation of #{count_objects(@objects)}"]
  if @retained_objects
    desc << " and retain #{count_objects(@retained_objects)}"
  end
  desc.join
end
failure_message() click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 94
def failure_message
  "expected block to #{description}, but #{positive_failure_reason}"
end
failure_message_when_negated() click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 98
def failure_message_when_negated
  "expected block not to #{description}, but #{negative_failure_reason}"
end
matches?(block) click to toggle source

@return [Boolean]

@api private

# File lib/rspec/benchmark/allocation_matcher.rb, line 32
def matches?(block)
  @block = block
  alloc_stats = @bench.trace(&block)
  @actual = nil
  @actual_retained = nil

  case @objects
  when Hash
    case @count_type
    when :memory
      @actual = alloc_stats.allocated.count_memory
    else
      @actual = alloc_stats.allocated.count_objects
    end
    @objects.all? do |name, count|
      @actual[name] <= count
    end
  when Numeric
    case @count_type
    when :memory
      @actual = alloc_stats.allocated.total_memory
      @actual_retained = alloc_stats.retained.total_memory
    else
      @actual = alloc_stats.allocated.total_objects
      @actual_retained = alloc_stats.retained.total_objects
    end
    result = @actual <= @objects
    result &= @actual_retained <= @retained_objects if @retained_objects
    result
  else
    raise ArgumentError, "'#{@objects}' is not a recognized argument"
  end
end
memory() click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 88
def memory
  @count_type = :memory
  self
end
Also aliased as: bytes
negative_failure_reason() click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 123
def negative_failure_reason
  "allocated #{actual}"
end
object()
Alias for: objects
objects() click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 82
def objects
  @count_type = :objects
  self
end
Also aliased as: object
objects_to_s(value) click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 151
def objects_to_s(value)
  if value.respond_to?(:to_hash)
    value
      .sort_by { |k, v| k.to_s }
      .map { |key, val| "#{val} #{key}" if @objects.keys.include?(key) }
      .compact.join(" and ")
  else
    value
  end
end
pluralize_objects(value) click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 139
def pluralize_objects(value)
  if value.respond_to?(:to_hash)
    if value.keys.size == 1 && value.values.reduce(&:+) == 1
      "object"
    else
      "objects"
    end
  else
    value == 1 ? "object" : "objects"
  end
end
positive_failure_reason() click to toggle source
# File lib/rspec/benchmark/allocation_matcher.rb, line 118
def positive_failure_reason
  return "was not a block" unless @block.is_a?(Proc)
  "allocated #{actual}"
end
supports_block_expectations?() click to toggle source

Indicates this matcher matches against a block

@return [True]

@api private

# File lib/rspec/benchmark/allocation_matcher.rb, line 25
def supports_block_expectations?
  true
end
warmup(value) click to toggle source

The time before measurements are taken

@param [Numeric] value

the time before measurements are taken

@api public

# File lib/rspec/benchmark/allocation_matcher.rb, line 77
def warmup(value)
  @warmup = value
  self
end