RSpec.describe Metasploit::Model::Search::Operator::Association, type: :model do subject(:operator) do described_class.new( :association => association, :source_operator => source_operator ) end let(:association) do FactoryBot.generate :metasploit_model_search_operator_association_association end let(:source_operator) do double('Metasploit::Model::Search::Operator::Base') end it { is_expected.to be_a Metasploit::Model::Search::Operator::Base } context 'validations' do it { is_expected.to validate_presence_of(:association) } it { is_expected.to validate_presence_of(:source_operator) } end context '#help' do subject(:help) do operator.help end it 'should delegate to #source_operator' do expect(source_operator).to receive(:help) help end end context '#name' do subject(:name) do operator.name end let(:source_operator) { double( 'Metasploit::Model::Search::Operator::Base', name: source_operator_name ) } let(:source_operator_name) { 'source_operator_name' } it { is_expected.to be_a Symbol } it 'should be .' do expect(name).to eq :"#{association}.#{source_operator_name}" end end context '#operate_on' do subject(:operate_on) { operator.operate_on(formatted_value) } # # lets # let(:expected_source_operation) { double('source operation') } let(:formatted_value) { 'formatted-value' } let(:source_operator) { super().tap { |source_operator| expect(source_operator).to receive(:operate_on).with(formatted_value).and_return(expected_source_operation) } } it { is_expected.to be_a Metasploit::Model::Search::Operation::Association } context 'Metasploit::Model::Search::Operation::Association' do context '#operator' do subject(:operation_operator) { operate_on.operator } it 'is this association operator' do expect(operation_operator).to eq(operator) end end context '#source_operation' do subject(:source_operation) { operate_on.source_operation } it 'is operation from Metasploit::Model::Search::Operator::Association#source_operator' do expect(source_operation).to eq(expected_source_operation) end end end end end