feat(conditional): add include operator
This commit is contained in:
parent
84c52099fb
commit
fcb9b55bc4
7 changed files with 77 additions and 5 deletions
|
@ -119,6 +119,10 @@ class TypesDeChampEditor::ConditionsComponent < ApplicationComponent
|
|||
[t('is', scope: 'logic'), Eq.name],
|
||||
[t('is_not', scope: 'logic'), NotEq.name]
|
||||
]
|
||||
when ChampValue::CHAMP_VALUE_TYPE.fetch(:enums)
|
||||
[
|
||||
[t(IncludeOperator.name, scope: 'logic.operators'), IncludeOperator.name]
|
||||
]
|
||||
when ChampValue::CHAMP_VALUE_TYPE.fetch(:number)
|
||||
[Eq, LessThan, GreaterThan, LessThanEq, GreaterThanEq]
|
||||
.map(&:name)
|
||||
|
@ -151,7 +155,7 @@ class TypesDeChampEditor::ConditionsComponent < ApplicationComponent
|
|||
options_for_select(empty_target_for_select),
|
||||
id: input_id_for('value', row_index)
|
||||
)
|
||||
when :enum
|
||||
when :enum, :enums
|
||||
enums_for_select = left.options
|
||||
|
||||
if right_invalid
|
||||
|
|
|
@ -8,7 +8,7 @@ module Logic
|
|||
end
|
||||
|
||||
def self.class_from_name(name)
|
||||
[ChampValue, Constant, Empty, LessThan, LessThanEq, Eq, NotEq, GreaterThanEq, GreaterThan, EmptyOperator, And, Or]
|
||||
[ChampValue, Constant, Empty, LessThan, LessThanEq, Eq, NotEq, GreaterThanEq, GreaterThan, EmptyOperator, IncludeOperator, And, Or]
|
||||
.find { |c| c.name == name }
|
||||
end
|
||||
|
||||
|
@ -24,6 +24,8 @@ module Logic
|
|||
operator_class = EmptyOperator
|
||||
in [:enum, _]
|
||||
operator_class = Eq
|
||||
in [:enums, _]
|
||||
operator_class = IncludeOperator
|
||||
in [:number, EmptyOperator]
|
||||
operator_class = Eq
|
||||
in [:number, _]
|
||||
|
@ -35,7 +37,7 @@ module Logic
|
|||
Constant.new(true)
|
||||
when :empty
|
||||
Empty.new
|
||||
when :enum
|
||||
when :enum, :enums
|
||||
Constant.new(left.options.first.second)
|
||||
when :number
|
||||
Constant.new(0)
|
||||
|
@ -49,7 +51,7 @@ module Logic
|
|||
case [left.type, right.type]
|
||||
in [a, ^a] # syntax for same type
|
||||
true
|
||||
in [:enum, :string]
|
||||
in [:enum, :string] | [:enums, :string]
|
||||
left.options.map(&:second).include?(right.value)
|
||||
else
|
||||
false
|
||||
|
@ -84,6 +86,8 @@ module Logic
|
|||
|
||||
def less_than_eq(left, right) = Logic::LessThanEq.new(left, right)
|
||||
|
||||
def ds_include(left, right) = Logic::IncludeOperator.new(left, right)
|
||||
|
||||
def constant(value) = Logic::Constant.new(value)
|
||||
|
||||
def champ_value(stable_id) = Logic::ChampValue.new(stable_id)
|
||||
|
|
|
@ -4,13 +4,15 @@ class Logic::ChampValue < Logic::Term
|
|||
:checkbox,
|
||||
:integer_number,
|
||||
:decimal_number,
|
||||
:drop_down_list
|
||||
:drop_down_list,
|
||||
:multiple_drop_down_list
|
||||
)
|
||||
|
||||
CHAMP_VALUE_TYPE = {
|
||||
boolean: :boolean,
|
||||
number: :number,
|
||||
enum: :enum,
|
||||
enums: :enums,
|
||||
empty: :empty,
|
||||
unmanaged: :unmanaged
|
||||
}
|
||||
|
@ -35,6 +37,8 @@ class Logic::ChampValue < Logic::Term
|
|||
targeted_champ.for_api
|
||||
when MANAGED_TYPE_DE_CHAMP.fetch(:drop_down_list)
|
||||
targeted_champ.selected
|
||||
when MANAGED_TYPE_DE_CHAMP.fetch(:multiple_drop_down_list)
|
||||
targeted_champ.selected_options
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -49,6 +53,8 @@ class Logic::ChampValue < Logic::Term
|
|||
CHAMP_VALUE_TYPE.fetch(:number)
|
||||
when MANAGED_TYPE_DE_CHAMP.fetch(:drop_down_list)
|
||||
CHAMP_VALUE_TYPE.fetch(:enum)
|
||||
when MANAGED_TYPE_DE_CHAMP.fetch(:multiple_drop_down_list)
|
||||
CHAMP_VALUE_TYPE.fetch(:enums)
|
||||
else
|
||||
CHAMP_VALUE_TYPE.fetch(:unmanaged)
|
||||
end
|
||||
|
|
29
app/models/logic/include_operator.rb
Normal file
29
app/models/logic/include_operator.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
class Logic::IncludeOperator < Logic::BinaryOperator
|
||||
def operation = :include?
|
||||
|
||||
def errors(stable_ids = [])
|
||||
result = []
|
||||
|
||||
if left_not_a_list?
|
||||
result << { type: :required_list }
|
||||
elsif right_value_not_in_list?
|
||||
result << {
|
||||
type: :not_included,
|
||||
stable_id: @left.stable_id,
|
||||
right: @right
|
||||
}
|
||||
end
|
||||
|
||||
result + @left.errors(stable_ids) + @right.errors(stable_ids)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def left_not_a_list?
|
||||
@left.type != :enums
|
||||
end
|
||||
|
||||
def right_value_not_in_list?
|
||||
!@left.options.map(&:second).include?(@right.value)
|
||||
end
|
||||
end
|
|
@ -12,3 +12,4 @@ fr:
|
|||
'Logic::And': Et
|
||||
'Logic::Or': Ou
|
||||
'Logic::NotEq': N'est pas
|
||||
'Logic::IncludeOperator': Contient
|
||||
|
|
20
spec/models/logic/include_operator_spec.rb
Normal file
20
spec/models/logic/include_operator_spec.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
describe Logic::IncludeOperator do
|
||||
include Logic
|
||||
|
||||
let(:champ) { create(:champ_multiple_drop_down_list, value: '["val1", "val2"]') }
|
||||
|
||||
describe '#compute' do
|
||||
it { expect(ds_include(champ_value(champ.stable_id), constant('val1')).compute([champ])).to be(true) }
|
||||
it { expect(ds_include(champ_value(champ.stable_id), constant('something else')).compute([champ])).to be(false) }
|
||||
end
|
||||
|
||||
describe '#errors' do
|
||||
it { expect(ds_include(champ_value(champ.stable_id), constant('val1')).errors).to be_empty }
|
||||
it { expect(ds_include(champ_value(champ.stable_id), constant('something else')).errors).to eq(["« something else » ne fait pas partie de « #{champ.libelle} »"]) }
|
||||
it { expect(ds_include(constant(1), constant('val1')).errors).to eq(["Lʼopérateur inclusion ne sʼapplique que sur une liste"]) }
|
||||
end
|
||||
|
||||
describe '#==' do
|
||||
it { expect(ds_include(champ_value(champ.stable_id), constant('val1'))).to eq(ds_include(champ_value(champ.stable_id), constant('val1'))) }
|
||||
end
|
||||
end
|
|
@ -49,6 +49,14 @@ describe Logic do
|
|||
|
||||
it { is_expected.to eq(ds_eq(champ_value(drop_down), constant(first_option))) }
|
||||
end
|
||||
|
||||
context 'when multiple dropdown empty operator true' do
|
||||
let(:multiple_drop_down) { create(:type_de_champ_multiple_drop_down_list) }
|
||||
let(:first_option) { multiple_drop_down.drop_down_list_enabled_non_empty_options.first }
|
||||
let(:condition) { empty_operator(champ_value(multiple_drop_down), constant(true)) }
|
||||
|
||||
it { is_expected.to eq(ds_include(champ_value(multiple_drop_down), constant(first_option))) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '.compatible_type?' do
|
||||
|
|
Loading…
Add table
Reference in a new issue