Refactorize ChronicDurationAttribute concern
This commit is contained in:
parent
973e4030b1
commit
c2bc153314
|
@ -2,49 +2,38 @@ module ChronicDurationAttribute
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
def chronic_duration_attr(virtual_attribute, source_attribute)
|
|
||||||
chronic_duration_attr_reader(virtual_attribute, source_attribute)
|
|
||||||
chronic_duration_attr_writer(virtual_attribute, source_attribute)
|
|
||||||
end
|
|
||||||
|
|
||||||
def chronic_duration_attr_reader(virtual_attribute, source_attribute)
|
def chronic_duration_attr_reader(virtual_attribute, source_attribute)
|
||||||
define_method(virtual_attribute) do
|
define_method(virtual_attribute) do
|
||||||
value = self.send(source_attribute) # rubocop:disable GitlabSecurity/PublicSend
|
chronic_duration_attributes[virtual_attribute] || output_chronic_duration_attribute(source_attribute)
|
||||||
|
|
||||||
return '' if value.nil?
|
|
||||||
|
|
||||||
ChronicDuration.output(value, format: :short)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def chronic_duration_attr_writer(virtual_attribute, source_attribute)
|
def chronic_duration_attr_writer(virtual_attribute, source_attribute)
|
||||||
virtual_attribute_validator = "#{virtual_attribute}_validator".to_sym
|
chronic_duration_attr_reader(virtual_attribute, source_attribute)
|
||||||
validation_error = "#{virtual_attribute}_error".to_sym
|
|
||||||
|
|
||||||
validate virtual_attribute_validator
|
|
||||||
attr_accessor validation_error
|
|
||||||
|
|
||||||
define_method("#{virtual_attribute}=") do |value|
|
define_method("#{virtual_attribute}=") do |value|
|
||||||
|
chronic_duration_attributes[virtual_attribute] = value.presence || ''
|
||||||
|
|
||||||
begin
|
begin
|
||||||
self.send("#{validation_error}=", '') # rubocop:disable GitlabSecurity/PublicSend
|
new_value = ChronicDuration.parse(value).to_i if value.present?
|
||||||
|
assign_attributes(source_attribute => new_value)
|
||||||
new_value =
|
rescue ChronicDuration::DurationParseError
|
||||||
if value.blank?
|
# ignore error as it will be caught by validation
|
||||||
nil
|
|
||||||
else
|
|
||||||
ChronicDuration.parse(value).to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
self.send("#{source_attribute}=", new_value) # rubocop:disable GitlabSecurity/PublicSend
|
|
||||||
rescue ChronicDuration::DurationParseError => ex
|
|
||||||
self.send("#{validation_error}=", ex.message) # rubocop:disable GitlabSecurity/PublicSend
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method(virtual_attribute_validator) do
|
validates virtual_attribute, allow_nil: true, duration: true
|
||||||
error = self.send(validation_error) # rubocop:disable GitlabSecurity/PublicSend
|
|
||||||
self.send('errors').add(source_attribute, error) unless error.blank? # rubocop:disable GitlabSecurity/PublicSend
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
alias_method :chronic_duration_attr, :chronic_duration_attr_writer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def chronic_duration_attributes
|
||||||
|
@chronic_duration_attributes ||= {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def output_chronic_duration_attribute(source_attribute)
|
||||||
|
value = attributes[source_attribute.to_s]
|
||||||
|
ChronicDuration.output(value, format: :short) if value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,10 +12,10 @@ shared_examples 'ChronicDurationAttribute reader' do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when value is set to nil' do
|
context 'when value is set to nil' do
|
||||||
it 'outputs empty string' do
|
it 'outputs nil' do
|
||||||
subject.send("#{source_field}=", nil)
|
subject.send("#{source_field}=", nil)
|
||||||
|
|
||||||
expect(subject.send(virtual_field)).to be_empty
|
expect(subject.send(virtual_field)).to be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -25,15 +25,15 @@ shared_examples 'ChronicDurationAttribute writer' do
|
||||||
expect(subject.class).to be_public_method_defined("#{virtual_field}=")
|
expect(subject.class).to be_public_method_defined("#{virtual_field}=")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'parses chronic duration input' do
|
before do
|
||||||
subject.send("#{virtual_field}=", '10m')
|
subject.send("#{virtual_field}=", '10m')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'parses chronic duration input' do
|
||||||
expect(subject.send(source_field)).to eq(600)
|
expect(subject.send(source_field)).to eq(600)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'passes validation' do
|
it 'passes validation' do
|
||||||
subject.send("#{virtual_field}=", '10m')
|
|
||||||
|
|
||||||
expect(subject.valid?).to be_truthy
|
expect(subject.valid?).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,33 +54,34 @@ shared_examples 'ChronicDurationAttribute writer' do
|
||||||
subject.send("#{virtual_field}=", '-10m')
|
subject.send("#{virtual_field}=", '-10m')
|
||||||
|
|
||||||
expect(subject.valid?).to be_falsey
|
expect(subject.valid?).to be_falsey
|
||||||
|
expect(subject.errors&.messages).to include(virtual_field => ['is not a correct duration'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when empty input is used' do
|
context 'when empty input is used' do
|
||||||
it 'writes nil' do
|
before do
|
||||||
subject.send("#{virtual_field}=", '')
|
subject.send("#{virtual_field}=", '')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'writes nil' do
|
||||||
expect(subject.send(source_field)).to be_nil
|
expect(subject.send(source_field)).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'passes validation' do
|
it 'passes validation' do
|
||||||
subject.send("#{virtual_field}=", '')
|
|
||||||
|
|
||||||
expect(subject.valid?).to be_truthy
|
expect(subject.valid?).to be_truthy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when nil input is used' do
|
context 'when nil input is used' do
|
||||||
it 'writes nil' do
|
before do
|
||||||
subject.send("#{virtual_field}=", nil)
|
subject.send("#{virtual_field}=", nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'writes nil' do
|
||||||
expect(subject.send(source_field)).to be_nil
|
expect(subject.send(source_field)).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'passes validation' do
|
it 'passes validation' do
|
||||||
subject.send("#{virtual_field}=", nil)
|
|
||||||
|
|
||||||
expect(subject.valid?).to be_truthy
|
expect(subject.valid?).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -103,6 +104,7 @@ end
|
||||||
describe 'ChronicDurationAttribute - reader' do
|
describe 'ChronicDurationAttribute - reader' do
|
||||||
let(:source_field) {:timeout}
|
let(:source_field) {:timeout}
|
||||||
let(:virtual_field) {:timeout_human_readable}
|
let(:virtual_field) {:timeout_human_readable}
|
||||||
|
|
||||||
subject {Ci::BuildMetadata.new}
|
subject {Ci::BuildMetadata.new}
|
||||||
|
|
||||||
it "doesn't contain dynamically created writer method" do
|
it "doesn't contain dynamically created writer method" do
|
||||||
|
|
Loading…
Reference in New Issue