require 'spec_helper' require 'r10k/module/svn' describe R10K::Module::SVN do include_context 'fail on execution' describe "statically determined version support" do it 'is unsupported by svn backed modules' do static_version = described_class.statically_defined_version('branan/eight_hundred', { svn: 'my/remote', revision: '123adf' }) expect(static_version).to eq(nil) end end describe "determining it implements a Puppetfile mod" do it "implements mods with the :svn hash key" do implements = described_class.implement?('r10k-fixture-repo', :svn => 'https://github.com/adrienthebo/r10k-fixture-repo') expect(implements).to eq true end end describe "path variables" do it "uses the module name as the name" do svn = described_class.new('foo', '/moduledir', :rev => 'r10') expect(svn.name).to eq 'foo' expect(svn.owner).to be_nil expect(svn.dirname).to eq '/moduledir' expect(svn.path).to eq Pathname.new('/moduledir/foo') end it "does not include the owner in the path" do svn = described_class.new('bar/foo', '/moduledir', :rev => 'r10') expect(svn.name).to eq 'foo' expect(svn.owner).to eq 'bar' expect(svn.dirname).to eq '/moduledir' expect(svn.path).to eq Pathname.new('/moduledir/foo') end end describe "instantiating based on Puppetfile configuration" do it "can specify a revision with the :rev key" do svn = described_class.new('foo', '/moduledir', :rev => 'r10') expect(svn.expected_revision).to eq 'r10' end it "can specify a revision with the :revision key" do svn = described_class.new('foo', '/moduledir', :revision => 'r10') expect(svn.expected_revision).to eq 'r10' end end describe "properties" do subject { described_class.new('foo', '/moduledir', :svn => 'https://github.com/adrienthebo/r10k-fixture-repo', :rev => 123) } it "sets the module type to :svn" do expect(subject.properties).to include(:type => :svn) end it "sets the expected version" do expect(subject.properties).to include(:expected => 123) end it "sets the actual version to the revision when the revision is available" do expect(subject.working_dir).to receive(:revision).and_return(12) expect(subject.properties).to include(:actual => 12) end it "sets the actual version (unresolvable) when the revision is unavailable" do expect(subject.working_dir).to receive(:revision).and_raise(ArgumentError) expect(subject.properties).to include(:actual => "(unresolvable)") end end describe "determining the status" do subject { described_class.new('foo', '/moduledir', :svn => 'https://github.com/adrienthebo/r10k-fixture-repo', :rev => 123) } let(:working_dir) { double 'working_dir' } before do allow(R10K::SVN::WorkingDir).to receive(:new).and_return working_dir end it "is :absent if the module directory is absent" do allow(subject).to receive(:exist?).and_return false expect(subject.status).to eq :absent end it "is :mismatched if the directory is present but not an SVN repo" do allow(subject).to receive(:exist?).and_return true allow(working_dir).to receive(:is_svn?).and_return false expect(subject.status).to eq :mismatched end it "is mismatched when the wrong SVN URL is checked out" do allow(subject).to receive(:exist?).and_return true allow(working_dir).to receive(:is_svn?).and_return true allow(working_dir).to receive(:url).and_return 'svn://nope/trunk' expect(subject.status).to eq :mismatched end it "is :outdated when the expected rev doesn't match the actual rev" do allow(subject).to receive(:exist?).and_return true allow(working_dir).to receive(:is_svn?).and_return true allow(working_dir).to receive(:url).and_return 'https://github.com/adrienthebo/r10k-fixture-repo' allow(working_dir).to receive(:revision).and_return 99 expect(subject.status).to eq :outdated end it "is :insync if all other conditions are satisfied" do allow(subject).to receive(:exist?).and_return true allow(working_dir).to receive(:is_svn?).and_return true allow(working_dir).to receive(:url).and_return 'https://github.com/adrienthebo/r10k-fixture-repo' allow(working_dir).to receive(:revision).and_return 123 expect(subject.status).to eq :insync end end describe 'the default spec dir' do let(:module_org) { "coolorg" } let(:module_name) { "coolmod" } let(:title) { "#{module_org}-#{module_name}" } let(:dirname) { Pathname.new(Dir.mktmpdir) } let(:spec_path) { dirname + module_name + 'spec' } subject { described_class.new(title, dirname, {}) } it 'is kept by default' do FileUtils.mkdir_p(spec_path) expect(subject).to receive(:status).and_return(:absent) expect(subject).to receive(:install).and_return(nil) subject.sync expect(Dir.exist?(spec_path)).to eq true end end describe "synchronizing" do subject { described_class.new('foo', '/moduledir', :svn => 'https://github.com/adrienthebo/r10k-fixture-repo', :rev => 123) } before do allow(File).to receive(:directory?).with('/moduledir').and_return true end describe "and the state is :absent" do before { allow(subject).to receive(:status).and_return :absent } it "installs the SVN module" do expect(subject).to receive(:install) expect(subject.sync).to be true end end describe "and the state is :mismatched" do before { allow(subject).to receive(:status).and_return :mismatched } it "reinstalls the module" do expect(subject).to receive(:reinstall) expect(subject.sync).to be true end it "removes the existing directory" do expect(subject.path).to receive(:rmtree) allow(subject).to receive(:install) expect(subject.sync).to be true end end describe "and the state is :outdated" do before { allow(subject).to receive(:status).and_return :outdated } it "upgrades the repository" do expect(subject).to receive(:update) expect(subject.sync).to be true end end describe "and the state is :insync" do before { allow(subject).to receive(:status).and_return :insync } it "doesn't change anything" do expect(subject).to receive(:install).never expect(subject).to receive(:reinstall).never expect(subject).to receive(:update).never expect(subject.sync).to be false end end it 'and `should_sync?` is false' do # modules do not sync if they are not requested mod = described_class.new('my_mod', '/path/to/mod', { overrides: { modules: { requested_modules: ['other_mod'] } } }) expect(mod.sync).to be false end end end