# frozen_string_literal: true require "forwardable" require_relative "loaded_mocks/features" module ActiveMocker class LoadedMocks class << self extend Forwardable def_delegators :mocks, :find, :delete_all # Returns an Enumerable of all currently loaded mocks. # # ActiveMocker::LoadedMocks.mocks # => PersonMock}> # @return ActiveMocker::LoadedMocks::Collection def mocks Collection.new(mocks_store.values.each_with_object({}) do |mock_constant, hash| hash[mock_constant.send(:mocked_class)] = mock_constant end) end # @deprecated Use {#mocks} instead of this method. alias class_name_to_mock mocks # @deprecated Use {#mocks} instead of this method. alias all mocks # @deprecated Use {#delete_all} instead of this method. alias clear_all delete_all def features @features ||= Features.instance end class Collection include Enumerable # @option opts [Hash] hash def initialize(hash = {}) @hash = Hash[hash] end extend Forwardable def_delegators :hash, :[]=, :[], :each, :to_hash, :to_h # Calls {#delete_all} for all mocks globally, which removes all records that were saved or created. # @return [NilClass] def delete_all mocks.each(&__method__) end # @param [Array] args an array of ActiveRecord Model Names as Strings or Symbols # or of mock object. # @return [ActiveMocker::LoadedMocks::Collection] returns ActiveMock equivalent class. def slice(*args) self.class.new(select { |k, v| get_item(args, k, v) }) end # Input ActiveRecord Model Name as String or Symbol and it returns everything but that ActiveMock equivalent class. # except('User') => [AccountMock, OtherMock] # @param [Array] args # @return ActiveMocker::LoadedMocks::Collection def except(*args) self.class.new(reject { |k, v| get_item(args, k, v) }) end # Input ActiveRecord Model Name as String or Symbol returns ActiveMock equivalent class. # find('User') => UserMock # @param [Symbol, String, ActiveMocker::Mock] item # @return ActiveMocker::Mock def find(item) slice(item).mocks.first end # @return [Array] def mocks hash.values end alias values mocks private attr_reader :hash def get_item(args, k, v) args.map do |e| if [:to_str, :to_sym].any? { |i| e.respond_to? i } e.to_s == k else e == v end end.any? { |a| a } end end private def mocks_store @mocks ||= {} end def add(mocks_to_add) mocks_store.merge!(mocks_to_add.name => mocks_to_add) end end end end