diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb index 8f88ccf5bf4..0baefa70f61 100644 --- a/lib/gitlab/ci/config.rb +++ b/lib/gitlab/ci/config.rb @@ -4,13 +4,13 @@ module Gitlab class ParserError < StandardError; end def initialize(config) - @config = YAML.safe_load(config, [Symbol], [], true) + parser = Parser.new(config) - unless @config.is_a?(Hash) - raise ParserError, 'YAML should be a hash' + unless parser.valid? + raise ParserError, 'Invalid configuration format!' end - @config = @config.deep_symbolize_keys + @config = parser.parse end def to_hash diff --git a/lib/gitlab/ci/config/parser.rb b/lib/gitlab/ci/config/parser.rb new file mode 100644 index 00000000000..6e1b7ec8267 --- /dev/null +++ b/lib/gitlab/ci/config/parser.rb @@ -0,0 +1,25 @@ +module Gitlab + module Ci + class Config + class Parser + class FormatError < StandardError; end + + def initialize(config) + @config = YAML.safe_load(config, [Symbol], [], true) + end + + def valid? + @config.is_a?(Hash) + end + + def parse + unless valid? + raise FormatError, 'Invalid configuration format' + end + + @config.deep_symbolize_keys + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/parser_spec.rb b/spec/lib/gitlab/ci/config/parser_spec.rb new file mode 100644 index 00000000000..b35e66cde51 --- /dev/null +++ b/spec/lib/gitlab/ci/config/parser_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Parser do + let(:parser) { described_class.new(yml) } + + context 'when yaml syntax is correct' do + let(:yml) { 'image: ruby:2.2' } + + describe '#valid?' do + it 'returns true' do + expect(parser.valid?).to be true + end + end + + describe '#parse' do + it 'returns a hash' do + expect(parser.parse).to be_a Hash + end + + it 'returns a valid hash' do + expect(parser.parse).to eq(image: 'ruby:2.2') + end + end + end + + context 'when yaml syntax is incorrect' do + let(:yml) { '// incorrect' } + + describe '#valid?' do + it 'returns false' do + expect(parser.valid?).to be false + end + end + + describe '#parse' do + it 'raises error' do + expect { parser.parse }.to raise_error( + Gitlab::Ci::Config::Parser::FormatError, + 'Invalid configuration format' + ) + end + end + end + + context 'when yaml config is empty' do + let(:yml) { '' } + + describe '#valid?' do + it 'returns false' do + expect(parser.valid?).to be false + end + end + end +end diff --git a/spec/lib/gitlab/ci/config_spec.rb b/spec/lib/gitlab/ci/config_spec.rb index 6e251706714..691c1ee8ba7 100644 --- a/spec/lib/gitlab/ci/config_spec.rb +++ b/spec/lib/gitlab/ci/config_spec.rb @@ -5,7 +5,7 @@ describe Gitlab::Ci::Config do described_class.new(yml) end - context 'when yml config is valid' do + context 'when config is valid' do let(:yml) do <<-EOS image: ruby:2.2 @@ -30,5 +30,17 @@ describe Gitlab::Ci::Config do expect(config.to_hash).to eq hash end end + + context 'when config is invalid' do + let(:yml) { '// invalid' } + + describe '.new' do + it 'raises error' do + expect { config }.to raise_error( + Gitlab::Ci::Config::ParserError, /Invalid configuration format/ + ) + end + end + end end end