Commit 002e6ed1 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Improve CI config entries validations prototype

parent 95520dfc
......@@ -15,6 +15,7 @@ module Gitlab
#
module Configurable
extend ActiveSupport::Concern
include Validatable
included do
validations do
......@@ -28,10 +29,6 @@ module Gitlab
end
end
def allowed_nodes
self.class.allowed_nodes || {}
end
private
def create_node(key, factory)
......@@ -41,7 +38,7 @@ module Gitlab
end
class_methods do
def allowed_nodes
def nodes
Hash[@allowed_nodes.map { |key, factory| [key, factory.dup] }]
end
......
......@@ -7,7 +7,6 @@ module Gitlab
#
class Entry
class InvalidError < StandardError; end
include Validatable
attr_reader :config
attr_accessor :key, :description
......@@ -16,6 +15,7 @@ module Gitlab
@config = config
@nodes = {}
@validator = self.class.validator.new(self)
@validator.validate
end
def process!
......@@ -31,7 +31,7 @@ module Gitlab
end
def leaf?
allowed_nodes.none?
self.class.nodes.none?
end
def key
......@@ -47,18 +47,22 @@ module Gitlab
nodes.map(&:errors).flatten
end
def allowed_nodes
def value
raise NotImplementedError
end
def self.nodes
{}
end
def value
raise NotImplementedError
def self.validator
Validator
end
private
def compose!
allowed_nodes.each do |key, essence|
self.class.nodes.each do |key, essence|
@nodes[key] = create_node(key, essence)
end
end
......
......@@ -11,6 +11,8 @@ module Gitlab
# implementation in Runner.
#
class Script < Entry
include Validatable
validations do
include ValidationHelpers
......
......@@ -8,7 +8,6 @@ module Gitlab
class_methods do
def validator
validator = Class.new(Node::Validator)
validator.include(ActiveModel::Validations)
if defined?(@validations)
@validations.each { |rules| validator.class_eval(&rules) }
......
......@@ -3,10 +3,11 @@ module Gitlab
class Config
module Node
class Validator < SimpleDelegator
include ActiveModel::Validations
def initialize(node)
@node = node
super(node)
validate
@node = node
end
def full_errors
......
......@@ -4,30 +4,29 @@ describe Gitlab::Ci::Config::Node::Configurable do
let(:node) { Class.new }
before do
node.include(Gitlab::Ci::Config::Node::Validatable)
node.include(described_class)
end
describe 'allowed nodes' do
describe 'configured nodes' do
before do
node.class_eval do
allow_node :object, Object, description: 'test object'
end
end
describe '#allowed_nodes' do
it 'has valid allowed nodes' do
expect(node.allowed_nodes).to include :object
describe '.nodes' do
it 'has valid nodes' do
expect(node.nodes).to include :object
end
it 'creates a node factory' do
expect(node.allowed_nodes[:object])
expect(node.nodes[:object])
.to be_an_instance_of Gitlab::Ci::Config::Node::Factory
end
it 'returns a duplicated factory object' do
first_factory = node.allowed_nodes[:object]
second_factory = node.allowed_nodes[:object]
first_factory = node.nodes[:object]
second_factory = node.nodes[:object]
expect(first_factory).not_to be_equal(second_factory)
end
......
......@@ -3,13 +3,13 @@ require 'spec_helper'
describe Gitlab::Ci::Config::Node::Global do
let(:global) { described_class.new(hash) }
describe '#allowed_nodes' do
describe '.nodes' do
it 'can contain global config keys' do
expect(global.allowed_nodes).to include :before_script
expect(described_class.nodes).to include :before_script
end
it 'returns a hash' do
expect(global.allowed_nodes).to be_a Hash
expect(described_class.nodes).to be_a Hash
end
end
......
require 'spec_helper'
describe Gitlab::Ci::Config::Node::Validatable do
let(:node) { Class.new }
before do
node.include(described_class)
end
describe '.validator' do
before do
node.class_eval do
attr_accessor :test_attribute
validations do
validates :test_attribute, presence: true
end
end
end
it 'returns validator' do
expect(node.validator.superclass)
.to be Gitlab::Ci::Config::Node::Validator
end
context 'when validating node instance' do
let(:node_instance) { node.new }
context 'when attribute is valid' do
before do
node_instance.test_attribute = 'valid'
end
it 'instance of validator is valid' do
expect(node.validator.new(node_instance)).to be_valid
end
end
context 'when attribute is not valid' do
before do
node_instance.test_attribute = nil
end
it 'instance of validator is invalid' do
expect(node.validator.new(node_instance)).to be_invalid
end
end
end
end
end
require 'spec_helper'
describe Gitlab::Ci::Config::Node::Validator do
let(:validator) { Class.new(described_class) }
let(:validator_instance) { validator.new(node) }
let(:node) { spy('node') }
shared_examples 'delegated validator' do
context 'when node is valid' do
before do
allow(node).to receive(:test_attribute).and_return('valid value')
end
it 'validates attribute in node' do
expect(node).to receive(:test_attribute)
expect(validator_instance).to be_valid
end
it 'returns no errors' do
validator_instance.validate
expect(validator_instance.full_errors).to be_empty
end
end
context 'when node is invalid' do
before do
allow(node).to receive(:test_attribute).and_return(nil)
end
it 'validates attribute in node' do
expect(node).to receive(:test_attribute)
expect(validator_instance).to be_invalid
end
it 'returns errors' do
validator_instance.validate
expect(validator_instance.full_errors).not_to be_empty
end
end
end
describe 'attributes validations' do
before do
validator.class_eval do
validates :test_attribute, presence: true
end
end
it_behaves_like 'delegated validator'
end
describe 'interface validations' do
before do
validator.class_eval do
validate do
unless @node.test_attribute == 'valid value'
errors.add(:test_attribute, 'invalid value')
end
end
end
end
it_behaves_like 'delegated validator'
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment