diff --git a/lib/producer/core/env.rb b/lib/producer/core/env.rb index ff29627..b2e3e68 100644 --- a/lib/producer/core/env.rb +++ b/lib/producer/core/env.rb @@ -4,10 +4,11 @@ module Producer attr_reader :input, :output, :registry attr_accessor :target - def initialize(input: $stdin, output: $stdout, registry: {}) + def initialize(input: $stdin, output: $stdout, remote: nil, registry: {}) @input = input @output = output @registry = registry + @remote = remote @target = nil end diff --git a/lib/producer/core/testing.rb b/lib/producer/core/testing.rb new file mode 100644 index 0000000..83dd0ba --- /dev/null +++ b/lib/producer/core/testing.rb @@ -0,0 +1 @@ +require 'producer/core/testing/mock_remote' diff --git a/lib/producer/core/testing/mock_remote.rb b/lib/producer/core/testing/mock_remote.rb new file mode 100644 index 0000000..9a472ea --- /dev/null +++ b/lib/producer/core/testing/mock_remote.rb @@ -0,0 +1,25 @@ +module Producer + module Core + module Testing + class MockRemote < Remote + def session + raise 'no session for mock remote!' + end + + def execute(command) + tokens = command.split + program = tokens.shift + + case program + when 'echo' + tokens.join ' ' + when 'true' + '' + when 'false' + raise RemoteCommandExecutionError + end + end + end + end + end +end diff --git a/spec/producer/core/actions/echo_spec.rb b/spec/producer/core/actions/echo_spec.rb index f48fded..48ddfff 100644 --- a/spec/producer/core/actions/echo_spec.rb +++ b/spec/producer/core/actions/echo_spec.rb @@ -2,8 +2,7 @@ require 'spec_helper' module Producer::Core module Actions - describe Echo do - let(:env) { Env.new(output: StringIO.new) } + describe Echo, :env do let(:text) { 'hello' } subject(:echo) { Echo.new(env, text) } @@ -12,7 +11,7 @@ module Producer::Core describe '#apply' do it 'writes the given string to env output with a record separator' do echo.apply - expect(env.output.string).to eq "hello\n" + expect(output).to eq "hello\n" end end end diff --git a/spec/producer/core/actions/file_writer_spec.rb b/spec/producer/core/actions/file_writer_spec.rb index 79b7e19..d785d38 100644 --- a/spec/producer/core/actions/file_writer_spec.rb +++ b/spec/producer/core/actions/file_writer_spec.rb @@ -2,8 +2,7 @@ require 'spec_helper' module Producer::Core module Actions - describe FileWriter do - let(:env) { Env.new } + describe FileWriter, :env do let(:path) { 'some_path' } let(:content) { 'some_content' } subject(:writer) { FileWriter.new(env, path, content) } @@ -12,7 +11,7 @@ module Producer::Core describe '#apply' do it 'writes content to file on remote filesystem' do - expect(writer.fs).to receive(:file_write).with(path, content) + expect(remote_fs).to receive(:file_write).with(path, content) writer.apply end end diff --git a/spec/producer/core/actions/mkdir_spec.rb b/spec/producer/core/actions/mkdir_spec.rb index 811cc92..cc1781b 100644 --- a/spec/producer/core/actions/mkdir_spec.rb +++ b/spec/producer/core/actions/mkdir_spec.rb @@ -2,8 +2,7 @@ require 'spec_helper' module Producer::Core module Actions - describe Mkdir do - let(:env) { Env.new } + describe Mkdir, :env do let(:path) { 'some_path' } subject(:mkdir) { Mkdir.new(env, path) } @@ -11,7 +10,7 @@ module Producer::Core describe '#apply' do it 'creates directory on remote filesystem' do - expect(mkdir.fs).to receive(:mkdir).with(path) + expect(remote_fs).to receive(:mkdir).with(path) mkdir.apply end end diff --git a/spec/producer/core/actions/shell_command_spec.rb b/spec/producer/core/actions/shell_command_spec.rb index 79efe61..6b2b851 100644 --- a/spec/producer/core/actions/shell_command_spec.rb +++ b/spec/producer/core/actions/shell_command_spec.rb @@ -2,8 +2,7 @@ require 'spec_helper' module Producer::Core module Actions - describe ShellCommand do - let(:env) { Env.new(output: StringIO.new) } + describe ShellCommand, :env do let(:command_args) { 'hello from remote host' } let(:command) { "echo #{command_args}" } subject(:sh) { ShellCommand.new(env, command) } @@ -12,14 +11,13 @@ module Producer::Core describe '#apply' do it 'executes the remote command' do - expect(sh.remote).to receive(:execute).with(command) + expect_execution(command) sh.apply end it 'writes the returned output with a record separator' do - allow(sh.remote).to receive(:execute) { command_args } sh.apply - expect(sh.output.string).to eq "#{command_args}\n" + expect(output).to eq "#{command_args}\n" end end end diff --git a/spec/producer/core/env_spec.rb b/spec/producer/core/env_spec.rb index 74c1422..275f388 100644 --- a/spec/producer/core/env_spec.rb +++ b/spec/producer/core/env_spec.rb @@ -38,6 +38,15 @@ module Producer::Core expect(env.output).to be output end end + + context 'when remote is given as argument' do + let(:remote) { double 'remote' } + subject(:env) { described_class.new(remote: remote) } + + it 'assigns the given remote' do + expect(env.remote).to be remote + end + end end describe '#target' do diff --git a/spec/producer/core/testing/mock_remote_spec.rb b/spec/producer/core/testing/mock_remote_spec.rb new file mode 100644 index 0000000..aef8238 --- /dev/null +++ b/spec/producer/core/testing/mock_remote_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' +require 'producer/core/testing' + +module Producer::Core + module Testing + describe MockRemote do + subject(:remote) { MockRemote.new('some_host.example') } + + it 'is a remote' do + expect(remote).to be_a Remote + end + + describe '#session' do + it 'raises an error to prevent real session usage' do + expect { remote.session }.to raise_error + end + end + + describe '#execute' do + context 'dummy echo command' do + let(:command) { 'echo some arguments' } + + it 'returns command arguments' do + expect(remote.execute(command)).to eq 'some arguments' + end + end + + context 'dummy true command' do + let(:command) { 'true' } + + it 'returns an empty string' do + expect(remote.execute(command)).to eq '' + end + end + + context 'dummy false command' do + let(:command) { 'false' } + + it 'raises a RemoteCommandExecutionError' do + expect { remote.execute(command) }.to raise_error(RemoteCommandExecutionError) + end + end + end + end + end +end diff --git a/spec/producer/core/tests/file_contains_spec.rb b/spec/producer/core/tests/file_contains_spec.rb index b19b911..5364a47 100644 --- a/spec/producer/core/tests/file_contains_spec.rb +++ b/spec/producer/core/tests/file_contains_spec.rb @@ -2,8 +2,7 @@ require 'spec_helper' module Producer::Core module Tests - describe FileContains do - let(:env) { Env.new } + describe FileContains, :env do let(:filepath) { 'some_file' } let(:content) { 'some_content' } subject(:test) { FileContains.new(env, filepath, content) } @@ -11,13 +10,9 @@ module Producer::Core it_behaves_like 'test' describe '#verify' do - let(:fs) { double 'fs' } - - before { allow(test).to receive(:fs) { fs } } - context 'when file contains the content' do before do - allow(fs) + allow(remote_fs) .to receive(:file_read).with(filepath) { "foo#{content}bar" } end @@ -28,7 +23,7 @@ module Producer::Core context 'when file does not contain the content' do before do - allow(fs).to receive(:file_read).with(filepath) { 'foo bar' } + allow(remote_fs).to receive(:file_read).with(filepath) { 'foo bar' } end it 'returns false' do @@ -37,7 +32,9 @@ module Producer::Core end context 'when file does not exist' do - before { allow(fs).to receive(:file_read).with(filepath) { nil } } + before do + allow(remote_fs).to receive(:file_read).with(filepath) { nil } + end it 'returns false' do expect(test.verify).to be false diff --git a/spec/producer/core/tests/has_dir_spec.rb b/spec/producer/core/tests/has_dir_spec.rb index 8840dce..39ebfc1 100644 --- a/spec/producer/core/tests/has_dir_spec.rb +++ b/spec/producer/core/tests/has_dir_spec.rb @@ -2,24 +2,21 @@ require 'spec_helper' module Producer::Core module Tests - describe HasDir do - let(:env) { Env.new } + describe HasDir, :env do let(:path) { 'some_directory' } subject(:has_dir) { HasDir.new(env, path) } it_behaves_like 'test' - describe '#verify', :ssh do - before { sftp_story } - + describe '#verify' do it 'delegates the call on remote FS' do - expect(env.remote.fs).to receive(:dir?).with(path) + expect(remote_fs).to receive(:dir?).with(path) has_dir.verify end it 'returns the dir existence' do existence = double 'existence' - allow(env.remote.fs).to receive(:dir?) { existence } + allow(remote_fs).to receive(:dir?) { existence } expect(has_dir.verify).to be existence end end diff --git a/spec/producer/core/tests/has_file_spec.rb b/spec/producer/core/tests/has_file_spec.rb index bc8be8e..b7a584e 100644 --- a/spec/producer/core/tests/has_file_spec.rb +++ b/spec/producer/core/tests/has_file_spec.rb @@ -2,24 +2,21 @@ require 'spec_helper' module Producer::Core module Tests - describe HasFile do - let(:env) { Env.new } + describe HasFile, :env do let(:filepath) { 'some_file' } subject(:has_file) { HasFile.new(env, filepath) } it_behaves_like 'test' - describe '#verify', :ssh do - before { sftp_story } - + describe '#verify' do it 'delegates the call on remote FS' do - expect(env.remote.fs).to receive(:file?).with(filepath) + expect(remote_fs).to receive(:file?).with(filepath) has_file.verify end it 'returns the file existence' do existence = double 'existence' - allow(env.remote.fs).to receive(:file?) { existence } + allow(remote_fs).to receive(:file?) { existence } expect(has_file.verify).to be existence end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 782c81e..9302f15 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,6 +6,8 @@ Dir['spec/support/**/*.rb'].map { |e| require e.gsub 'spec/', '' } RSpec.configure do |c| c.treat_symbols_as_metadata_keys_with_true_values = true + c.include TestEnvHelpers, :env + c.include NetSSHStoryHelpers, :ssh c.before(:each, :ssh) do allow(Net::SSH).to receive(:start) { connection } diff --git a/spec/support/shared_action.rb b/spec/support/shared_action.rb index 132169a..c8c6224 100644 --- a/spec/support/shared_action.rb +++ b/spec/support/shared_action.rb @@ -1,8 +1,7 @@ module Producer::Core shared_examples 'action' do - let(:input) { StringIO.new } - let(:output) { StringIO.new } - let(:env) { Env.new(input: input, output: output) } + include TestEnvHelpers + let(:arguments) { [:some, :arguments] } subject(:action) { described_class.new(env, *arguments) } @@ -20,25 +19,25 @@ module Producer::Core describe '#input' do it 'returns env input' do - expect(action.input).to be input + expect(action.input).to be env.input end end describe '#output' do it 'returns env output' do - expect(action.output).to be output + expect(action.output).to be env.output end end describe '#remote' do it 'returns env remote' do - expect(action.remote).to be action.env.remote + expect(action.remote).to be env.remote end end describe '#fs' do it 'returns env remote fs' do - expect(action.fs).to be action.env.remote.fs + expect(action.fs).to be env.remote.fs end end end diff --git a/spec/support/shared_test.rb b/spec/support/shared_test.rb index d46eee6..e2ca0f6 100644 --- a/spec/support/shared_test.rb +++ b/spec/support/shared_test.rb @@ -1,6 +1,7 @@ module Producer::Core shared_examples 'test' do - let(:env) { Env.new } + include TestEnvHelpers + let(:arguments) { [:some, :arguments] } subject(:test) { described_class.new(env, *arguments) } diff --git a/spec/support/test_env_helpers.rb b/spec/support/test_env_helpers.rb new file mode 100644 index 0000000..5797a6c --- /dev/null +++ b/spec/support/test_env_helpers.rb @@ -0,0 +1,31 @@ +module TestEnvHelpers + require 'producer/core/testing' + + def env + @_env ||= build_env + end + + def output + env.output.string + end + + def remote_fs + env.remote.fs + end + + def expect_execution(command) + opts = { expected_from: caller.first } + RSpec::Mocks.expect_message(env.remote, :execute, opts).with(command) + end + + + private + + def build_env + Producer::Core::Env.new(output: StringIO.new, remote: build_remote) + end + + def build_remote + Producer::Core::Testing::MockRemote.new('some_host.test') + end +end