# frozen_string_literal: true RSpec.describe Yardcheck::Runner do subject(:runner) do described_class.new(observer.associate_with(docs), io) end let(:observer) { Yardcheck::SpecObserver.new(observed_events) } let(:docs) { Yardcheck::Documentation.new(yardocs) } let(:io) { StringIO.new } let(:yardocs) do YardcheckSpec::YARDOCS.each do |yardoc| allow(yardoc).to receive(:file).and_wrap_original do |method| File.join('./test_app', method.call).to_s end end end let(:observed_events) do [ Yardcheck::MethodCall::Return.process( scope: :instance, selector: :add, namespace: TestApp::Namespace, params: { left: 'foo', right: 3 }, return_value: 5, example_metadata: { location: 'test_app_spec.rb:1', id: 'test_app_spec.rb[1:1]' } ), Yardcheck::MethodCall::Return.process( scope: :class, selector: :add, namespace: TestApp::Namespace.singleton_class, params: { left: 2, right: 3 }, return_value: 5, example_metadata: { location: 'test_app_spec.rb:2', id: 'test_app_spec.rb[1:2]' } ) ] end let(:output) do <<~MSG Expected ##add to return String but observed Integer source: ./test_app/lib/test_app.rb:15 tests: - test_app_spec.rb:2 rerun with: rspec 'test_app_spec.rb[1:2]' # Singleton method with correct param definition and incorrect return # # @param left [Integer] # @param right [Integer] # # @return [String] def self.add(left, right) left + right end Expected TestApp::Namespace#add to receive Integer for left but observed String source: ./test_app/lib/test_app.rb:25 tests: - test_app_spec.rb:1 rerun with: rspec 'test_app_spec.rb[1:1]' # Instance method with correct param definition and incorrect return # # @param left [Integer] # @param right [Integer] # # @return [String] def add(left, right) left + right end Expected TestApp::Namespace#add to return String but observed Integer source: ./test_app/lib/test_app.rb:25 tests: - test_app_spec.rb:1 rerun with: rspec 'test_app_spec.rb[1:1]' # Instance method with correct param definition and incorrect return # # @param left [Integer] # @param right [Integer] # # @return [String] def add(left, right) left + right end MSG end def remove_color(string) string.gsub(/\e\[(?:1\;)?\d+m/, '') end before do allow(Kernel).to receive(:exit).with(1) end shared_examples 'violation output' do it 'compares the spec observations against the documentation' do runner.check expect(remove_color(io.string)).to eql(output) end end include_examples 'violation output' context 'when multiple tests find the same violation' do let(:observed_events) do [ Yardcheck::MethodCall::Return.process( scope: :instance, selector: :add, namespace: TestApp::Namespace, params: { left: 'foo', right: 3 }, return_value: 'valid return type', example_metadata: { location: 'test_app_spec.rb:1', id: 'test_app_spec.rb[1:1]' } ), Yardcheck::MethodCall::Return.process( scope: :instance, selector: :add, namespace: TestApp::Namespace, params: { left: 'foo', right: 3 }, return_value: 'valid return type', example_metadata: { location: 'test_app_spec.rb:2', id: 'test_app_spec.rb[1:2]' } ), Yardcheck::MethodCall::Return.process( scope: :instance, selector: :add, namespace: TestApp::Namespace, params: { left: 1, right: 'now this one is wrong' }, return_value: 'valid return type', example_metadata: { location: 'test_app_spec.rb:3', id: 'test_app_spec.rb[1:3]' } ) ] end let(:output) do <<~MSG Expected TestApp::Namespace#add to receive Integer for left but observed String source: ./test_app/lib/test_app.rb:25 tests: - test_app_spec.rb:1 - test_app_spec.rb:2 rerun with: rspec 'test_app_spec.rb[1:1]' 'test_app_spec.rb[1:2]' # Instance method with correct param definition and incorrect return # # @param left [Integer] # @param right [Integer] # # @return [String] def add(left, right) left + right end Expected TestApp::Namespace#add to receive Integer for right but observed String source: ./test_app/lib/test_app.rb:25 tests: - test_app_spec.rb:3 rerun with: rspec 'test_app_spec.rb[1:3]' # Instance method with correct param definition and incorrect return # # @param left [Integer] # @param right [Integer] # # @return [String] def add(left, right) left + right end MSG end include_examples 'violation output' end end