lib/evil/client/rspec.rb in evil-client-1.0.0 vs lib/evil/client/rspec.rb in evil-client-1.1.0

- old
+ new

@@ -1,127 +1,25 @@ -# -# Checks that an operation has been performed with given options -# -# @example -# subject do -# MyClient.new(token: "foo").users(version: 3).fetch(token: "bar", id: 42) -# end -# -# # call only matcher -# expect { subject }.to perform_operation("MyClient.users.fetch") -# -# # exact matcher -# expect { subject } -# .to perform_operation("MyClient.users.fetch") -# .with_exactly(token: "bar", version: 3, id: 42) -# -# # partial matcher -# expect { subject } -# .to perform_operation("MyClient.users.fetch") -# .with(token: "bar", version: 3) -# -# # absence matcher -# expect { subject } -# .to perform_operation("MyClient.users.fetch") -# .without(:user, :password) -# -# # block syntax -# expect { subject } -# .to perform_operation("MyClient.users.fetch") -# .with { |token:, **| expect(token).to eq "bar" } -# -# @param [String] name The full name of the operation -# -RSpec::Matchers.define :perform_operation do |name| - supports_block_expectations +class Evil::Client + # + # Collection of RSpec-related definitions + # + module RSpec + require_relative "rspec/evil_client_schema_matching" + require_relative "rspec/base_stub" + require_relative "rspec/allow_stub" + require_relative "rspec/expect_stub" - description { "perform operation #{name} " } - - chain :with do |**options| - @some_options = options - end - - chain :with_exactly do |**options| - @exact_options = options - end - - chain :without do |*options| - @no_options = options.flatten.map(&:to_sym) - end - - def full_signature(name) - name.dup.tap do |text| - text << " with options #{@exact_options}" if @exact_options - text << " with options including #{@some_options}" if @some_options - text << " without options :#{@no_options.join(', :')}" if @no_options + def stub_client_operation(klass = Evil::Client, name = nil) + AllowStub.new(klass, name) end - end - # rubocop: disable Metrics/CyclomaticComplexity - # rubocop: disable Style/InverseMethods - def expected_options?(options, check) - return if @exact_options && options != @exact_options - return if @some_options && !(options >= @some_options) - return if (options.keys & @no_options.to_a).any? - check.nil? || check.call(options) - end - # rubocop: enable Metrics/CyclomaticComplexity - # rubocop: enable Style/InverseMethods - - def stub_resolver - resolver = Evil::Client::Resolver::Request - - allow(resolver).to receive(:call) do |schema, settings| - register(schema, settings) - resolver.new(schema, settings).send(:__call__) + def expect_client_operation(klass, name = nil) + ExpectStub.new(klass, name) end - end - def actual_operations - @actual_operations ||= [] - end - - def register(schema, settings) - actual_operations << [schema.to_s, settings.options] - end - - def performed(name, check) - @performed ||= actual_operations.find do |(key, options)| - (key == name) && expected_options?(options, check) + def unstub_all + allow(Evil::Client::Container::Operation) + .to receive(:new) + .and_call_original end - end - - match do |block| - stub_resolver - block.call - !performed(name, block_arg).nil? - end - - match_when_negated do |block| - stub_resolver - block.call - performed(name, block_arg).nil? - end - - def describe_expectations(name, perform) - "It was expected the operation #{full_signature(name)}" \ - " #{'NOT ' unless perform}to be performed.\n" \ - "The following operations has been actually performed:" - end - - failure_message do - text = describe_expectations(name, true) - actual_operations.each.with_index(1) do |(key, opts), index| - text << format("\n %02d) #{key} with #{opts}", index) - end - text - end - - failure_message_when_negated do - text = describe_expectations(name, false) - actual_operations.each.with_index(1) do |(key, opts), index| - marker = performed(name, block_arg) == [key, opts] ? "->" : " " - text << format("\n#{marker} % 2d) #{key} with #{opts}", index) - end - text end end