1
0
зеркало из https://github.com/glebtv/telegram-bot.git synced 2026-09-07 19:35:52 +03:00
Этот коммит содержится в:
Max Melentiev
2016-11-07 20:07:55 +03:00
родитель ececfa660e
Коммит 194fc78202
9 изменённых файлов: 275 добавлений и 3 удалений

Просмотреть файл

@@ -43,7 +43,7 @@ module Telegram
@requests = Hash.new { |h, k| h[k] = [] }
end
def request(action, body)
def request(action, body = {})
requests[action.to_sym] << body
end
end

7
lib/telegram/bot/rspec.rb Обычный файл
Просмотреть файл

@@ -0,0 +1,7 @@
module Telegram
module Bot
module RSpec
autoload :ClientMatchers, 'telegram/bot/rspec/client_matchers'
end
end
end

151
lib/telegram/bot/rspec/client_matchers.rb Обычный файл
Просмотреть файл

@@ -0,0 +1,151 @@
module Telegram
module Bot
module RSpec
# Proxy that uses RSpec::Mocks::ArgListMatcher when it's available.
# Otherwise just performs `#==` match.
#
# Also allows to check argumets with custom block.
class ArgListMatcher
attr_reader :expected, :expected_proc
def initialize(*args, &block)
@expected_proc = block if block_given?
@expected =
if mocks_matcher?
::RSpec::Mocks::ArgumentListMatcher.new(*args)
else
args
end
end
def args_match?(*actual)
if expected_proc
expected_proc[*actual]
true
elsif mocks_matcher?
expected.args_match?(*actual)
else
expected == actual
end
end
def args
mocks_matcher? ? expected.args : expected
end
def mocks_matcher?
defined?(::RSpec::Mocks::ArgumentListMatcher)
end
def to_s
if mocks_matcher?
expected.expected_args.inspect
elsif expected_proc
'(proc matcher)'
else
expected.inspect
end
end
end
# Matchers to test requests to Telegram API.
#
# Complex matchers requires `rspec-mocks` to be installed.
module ClientMatchers
class MakeTelegramRequest < ::RSpec::Matchers::BuiltIn::BaseMatcher
EXPECTATION_TYPES = {
exactly: :==,
at_most: :>=,
at_least: :<=,
}.freeze
attr_reader :performed_requests, :description
def initialize(bot, action, description: nil)
@bot = bot
@action = action
@description = description || "make #{action} telegram request"
exactly(1)
end
def matches?(proc) # rubocop:disable AbcSize
raise ArgumentError, 'matcher only supports block expectations' unless proc.is_a?(Proc)
original_requests_count = bot.requests[action].count
proc.call
@performed_requests = bot.requests[action].drop(original_requests_count)
@matching_requests_count = performed_requests.count do |request|
!arg_list_matcher || arg_list_matcher.args_match?(request)
end
expectation_method = EXPECTATION_TYPES[expectation_type]
expected_number.public_send(expectation_method, matching_requests_count)
end
def with(*args, &block)
@arg_list_matcher = ArgListMatcher.new(*args, &block)
self
end
EXPECTATION_TYPES.each_key do |type|
define_method type do |count|
@expectation_type = type
@expected_number = Integer(count)
self
end
end
def times
self
end
def failure_message
"expected to #{base_message}"
end
def failure_message_when_negated
"expected not to #{base_message}"
end
def supports_block_expectations?
true
end
private
attr_reader :bot, :action, :expectation_type, :expected_number,
:arg_list_matcher, :matching_requests_count
def base_message
"make #{expectation_type.to_s.tr('_', ' ')} #{expected_number} " \
"#{bot.inspect}.#{action} requests,".tap do |msg|
msg << " with #{arg_list_matcher}," if arg_list_matcher
msg << " but made #{matching_requests_count}"
if performed_requests
actual_args = performed_requests.map(&:inspect).join(', ')
msg << ", and #{performed_requests.count} with #{actual_args}"
end
end
end
end
# Check that bot performed request to telegram API:
#
# expect { dispatch_message('Hi!') }.
# to make_telegram_request(bot, :sendMessage).
# with(text: 'Hello!', chat_id: chat_id)
def make_telegram_request(bot, action)
MakeTelegramRequest.new(bot, action)
end
# Helper for asserting message is sent. Note that options are checked
# with `hash_including`. For strict checks use #make_telegram_request.
def send_telegram_message(bot, text = nil, options = {})
text = a_string_matching(text) if text.is_a?(Regexp)
options = options.merge(text: text) if text
description = "send telegram message #{text.inspect}"
MakeTelegramRequest.new(bot, :sendMessage, description: description).
with(hash_including(options))
end
end
end
end
end

Просмотреть файл

@@ -50,7 +50,7 @@ module Telegram
# ControllerClass.new(bot, from: telegram_user, chat: telegram_chat).
# process(:help, *args)
#
class UpdatesController < AbstractController::Base # rubocop:disable ClassLength
class UpdatesController < AbstractController::Base
abstract!
require 'telegram/bot/updates_controller/session'

Просмотреть файл

@@ -14,11 +14,14 @@ RSpec.shared_context 'telegram/bot/updates_controller' do
let(:bot_name) { 'bot' }
let(:session) { controller.send(:session) }
include Telegram::Bot::RSpec::ClientMatchers
def dispatch(bot = self.bot, update = self.update)
controller.dispatch_again(bot, update)
end
def dispatch_message(text, options = {})
def dispatch_message(text, options = nil)
options ||= respond_to?(:default_message_options) ? default_message_options : {}
update = build_update :message, options.merge(text: text)
dispatch bot, update
end
@@ -34,4 +37,9 @@ RSpec.shared_context 'telegram/bot/updates_controller' do
else input
end
end
# Matcher to check response. Make sure to define `let(:chat_id)`.
def respond_with_message(expected)
send_telegram_message(bot, expected, chat_id: chat_id)
end
end