Implement GitLab QA release inflection strategy

This commit is contained in:
Grzegorz Bizon 2017-03-09 12:18:55 +01:00
parent 2ae578c6b1
commit 5becdf0194
3 changed files with 110 additions and 0 deletions

View file

@ -5,6 +5,7 @@ module QA
# GitLab QA runtime classes, mostly singletons.
#
module Runtime
autoload :Release, 'qa/runtime/release'
autoload :User, 'qa/runtime/user'
autoload :Namespace, 'qa/runtime/namespace'
end
@ -81,3 +82,5 @@ module QA
autoload :Runner, 'qa/specs/runner'
end
end
QA::Runtime::Release.autoloads

45
qa/qa/runtime/release.rb Normal file
View file

@ -0,0 +1,45 @@
module QA
module Runtime
##
# Class that is responsible for plugging CE/EE extensions in, depending on
# environment variable GITLAB_RELEASE that should be present in the runtime
# environment.
#
# We need that to reduce the probability of conflicts when merging
# CE to EE.
#
class Release
UnspecifiedReleaseError = Class.new(StandardError)
def initialize(version = ENV['GITLAB_RELEASE'])
@version = version.to_s.upcase
unless %w[CE EE].include?(@version)
raise UnspecifiedReleaseError, 'GITLAB_RELEASE env not defined!'
end
begin
require "#{version.downcase}/strategy"
rescue LoadError
# noop
end
end
def has_strategy?
QA.const_defined?("#{@version}::Strategy")
end
def strategy
QA.const_get("#{@version}::Strategy")
end
def self.method_missing(name, *args)
@release ||= self.new
if @release.has_strategy?
@release.strategy.public_send(name, *args)
end
end
end
end
end

View file

@ -0,0 +1,62 @@
describe QA::Runtime::Release do
context 'when release version has extension strategy' do
subject { described_class.new('CE') }
let(:strategy) { spy('CE::Strategy') }
before do
stub_const('QA::CE::Strategy', strategy)
end
describe '#has_strategy?' do
it 'return true' do
expect(subject.has_strategy?).to be true
end
end
describe '#strategy' do
it 'return the strategy constant' do
expect(subject.strategy).to eq QA::CE::Strategy
end
end
describe 'delegated class methods' do
it 'delegates all calls to strategy class' do
described_class.some_method(1, 2)
expect(strategy).to have_received(:some_method)
.with(1, 2)
end
end
end
context 'when release version does not have extension strategy' do
subject { described_class.new('CE') }
describe '#has_strategy?' do
it 'returns false' do
expect(subject.has_strategy?).to be false
end
end
describe '#strategy' do
it 'raises error' do
expect { subject.strategy }.to raise_error(NameError)
end
end
describe 'delegated class methods' do
it 'behaves like a null object and does nothing' do
expect { described_class.some_method(2, 3) }.not_to raise_error
end
end
end
context 'when release version is invalid or unspecified' do
describe '#new' do
it 'raises an exception' do
expect { described_class.new(nil) }
.to raise_error(described_class::UnspecifiedReleaseError)
end
end
end
end