class RSpec::Memory::Matchers::LimitAllocations

Public Class Methods

new(allocations = {}, count: nil, size: nil) click to toggle source
# File lib/rspec/memory/matchers/limit_allocations.rb, line 32
def initialize(allocations = {}, count: nil, size: nil)
        @count = count
        @size = size
        
        @allocations = {}
        @errors = []
        
        allocations.each do |klass, count|
                self.of(klass, count: count)
        end
end

Public Instance Methods

failure_message() click to toggle source
# File lib/rspec/memory/matchers/limit_allocations.rb, line 103
def failure_message
        "exceeded allocation limit: #{@errors.join(', ')}"
end
matches?(given_proc) click to toggle source
# File lib/rspec/memory/matchers/limit_allocations.rb, line 67
def matches?(given_proc)
        return true unless trace = Trace.capture(@allocations.keys, &given_proc)
        
        if @count or @size
                # If the spec specifies a total limit, we have a limit which we can enforce which takes all allocations into account:
                total = trace.total
                
                check(total.count, @count) do |expected|
                        @errors << "allocated #{total.count} instances, #{total.size} bytes, #{expected} instances"
                end if @count
                
                check(total.size, @size) do |expected|
                        @errors << "allocated #{total.count} instances, #{total.size} bytes, #{expected} bytes"
                end if @size
        else
                # Otherwise unspecified allocations are considered an error:
                trace.ignored.each do |klass, allocation|
                        @errors << "allocated #{allocation.count} #{klass} instances, #{allocation.size} bytes, but it was not specified"
                end
        end
        
        trace.allocated.each do |klass, allocation|
                next unless acceptable = @allocations[klass]
                
                check(allocation.count, acceptable[:count]) do |expected|
                        @errors << "allocated #{allocation.count} #{klass} instances, #{allocation.size} bytes, #{expected} instances"
                end
                
                check(allocation.size, acceptable[:size]) do |expected|
                        @errors << "allocated #{allocation.count} #{klass} instances, #{allocation.size} bytes, #{expected} bytes"
                end
        end
        
        return @errors.empty?
end
of(klass, **limits) click to toggle source
# File lib/rspec/memory/matchers/limit_allocations.rb, line 48
def of(klass, **limits)
        @allocations[klass] = limits
        
        return self
end
supports_block_expectations?() click to toggle source
# File lib/rspec/memory/matchers/limit_allocations.rb, line 44
def supports_block_expectations?
        true
end

Private Instance Methods

check(value, limit) { |"expected within #{limit}"| ... } click to toggle source
# File lib/rspec/memory/matchers/limit_allocations.rb, line 54
        def check(value, limit)
        case limit
        when Range
                unless limit.include? value
                        yield "expected within #{limit}"
                end
        when Integer
                unless value == limit
                        yield "expected exactly #{limit}"
                end
        end
end