Sha256: 0021f7e9b903eaf6ab041fb458374c71fd8585b90c14b57720dc7a7f2eb56541

Contents?: true

Size: 1.74 KB

Versions: 1

Compression:

Stored size: 1.74 KB

Contents

require "suggest/version"
require "set"

module Suggest
  SUGGEST_MODS = Set.new([Array, Enumerable, String, Hash, Regexp, Integer])
  UNSAFE = Set.new([Array.instance_method(:cycle)])

  module Mixin
    def what_returns?(expected, args: [], allow_mutation: false)
      block = Proc.new if block_given?

      applicable_methods = self.methods.map(&method(:method)).select { |m| SUGGEST_MODS.include?(m.owner) }

      applicable_methods.select do |m|
        arity = m.arity
        next unless arity == -1 || arity == args.count

        post = clone
        if block
          next if UNSAFE.include?(m.unbind)
          result = post.public_send(m.name, *args, &block) rescue next
        else
          result = post.public_send(m.name, *args) rescue next
        end

        next unless allow_mutation || self == post

        Suggest.eq?(result, expected)
      end.map(&:name)
    end

    def what_mutates?(expected, opts = {})
      args = opts[:args] || []
      block = Proc.new if block_given?

      applicable_methods = self.methods.map(&method(:method)).select { |m| SUGGEST_MODS.include?(m.owner) }

      applicable_methods.select do |m|
        arity = m.arity
        next unless arity == -1 || arity == args.count

        post = clone
        if block
          next if UNSAFE.include?(m.unbind)
          result = post.public_send(m.name, *args, &block) rescue next
        else
          result = post.public_send(m.name, *args) rescue next
        end

        if opts.key?(:returns)
          next unless Suggest.eq?(result, opts[:returns])
        end

        Suggest.eq?(post, expected)
      end.map(&:name)
    end
  end

  def self.eq?(result, expected)
    result.is_a?(expected.class) && result == expected
  end
end

Object.include(Suggest::Mixin)

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
suggest_rb-0.1.0 lib/suggest.rb