Skip to content

Commit 729438a

Browse files
committed
fix set_specific_max_scores and each_form_with_document
1 parent a01ef53 commit 729438a

File tree

5 files changed

+142
-87
lines changed

5 files changed

+142
-87
lines changed

Gemfile.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ GIT
88
PATH
99
remote: .
1010
specs:
11-
json_schema_form (0.10.0)
11+
json_schema_form (0.10.1)
1212
activesupport (~> 6)
1313
dry-schema (~> 1.10)
1414
json_schemer (= 0.2.17)

lib/jsf/forms/field/concerns/base.rb

-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ def valid_for_locale?(locale = DEFAULT_LOCALE)
9898
#
9999
# @return [Boolean]
100100
def scored?
101-
# raise NoMethodError.new('this field does not implement scored?')
102101
false
103102
end
104103

lib/jsf/forms/form.rb

+42-22
Original file line numberDiff line numberDiff line change
@@ -473,15 +473,24 @@ def properties
473473
self[:properties]
474474
end
475475

476+
# TODO: deprecate, use reduce_each_form
477+
#
476478
# get own and dynamic properties
477479
#
478480
# @return [Hash{String => JSF::Forms::Field::*}]
479481
def merged_properties(**args)
480-
properties = {}
482+
reduce_each_form({}, **args) do |acum, form|
483+
acum.merge!(form&.properties || {})
484+
end
485+
end
486+
487+
# similar to Array.reduce
488+
#
489+
def reduce_each_form(init_value, **args)
481490
each_form(**args) do |form|
482-
properties.merge!(form&.properties || {})
491+
init_value = yield(init_value, form)
483492
end
484-
properties
493+
init_value
485494
end
486495

487496
# gets the property definition inside the properties key
@@ -819,8 +828,6 @@ def each_form(
819828
# for each value in the document's array. If you want forms to only be yielded once,
820829
# use each_form
821830
#
822-
# @param skip_property_proc [Proc] skips a property if it returns true when called
823-
#
824831
# @yieldparam [JSF::Forms::Form] form
825832
# @yieldparam [JSF::Forms::Condition] condition
826833
# @yieldparam [Proc] skip_branch_proc
@@ -829,7 +836,7 @@ def each_form(
829836
# @yieldparam [Array<String,Integer>] document_path
830837
#
831838
# @return [void]
832-
def each_form_with_document(document, section_or_shared: nil, document_path: [], skip_property_proc: nil, skip_on_condition: false, condition_proc: nil, **kwargs, &block)
839+
def each_form_with_document(document, section_or_shared: nil, document_path: [], skip_on_condition: false, condition_proc: nil, **kwargs, &block)
833840
empty_document = {}
834841

835842
# since JSF::Forms::Field::Shared and JSF::Forms::Section are already
@@ -852,38 +859,37 @@ def each_form_with_document(document, section_or_shared: nil, document_path: [],
852859
section_or_shared
853860
)
854861

855-
# handle all properties that have a value that is a hash or an array because the document_path is modified
862+
# handle all properties that have a value in which the document_path is modified (sections, shared)
856863
form[:properties].each do |key, property|
857864
next if kwargs[:skip_tree_when_hidden] && !property.visible(is_create: kwargs[:is_create])
858-
next if skip_property_proc&.call(key, property)
859-
865+
860866
# go recursive
861-
case property
862-
when JSF::Forms::Section
863-
value = document[key]
867+
if !kwargs[:ignore_sections] && property.is_a?(JSF::Forms::Section)
868+
if !property.repeatable?
869+
document[key] ||= []
870+
document[key].push({}) if document[key].empty?
871+
end
864872
empty_document[key] ||= []
865-
value&.map&.with_index do |doc, i|
873+
document[key]&.map&.with_index do |doc, i|
866874
empty_document[key][i] = property
867875
.form
868876
.each_form_with_document(
869877
doc,
870878
document_path: document_path + [key, i],
871-
skip_property_proc: skip_property_proc,
872879
skip_on_condition: skip_on_condition,
873880
section_or_shared: property,
874881
condition_proc: condition_proc,
875882
**kwargs,
876883
&block
877884
)
878885
end
879-
when JSF::Forms::Field::Shared
886+
elsif !kwargs[:ignore_definitions] && property.is_a?(JSF::Forms::Field::Shared)
880887
value = document[key] || {}
881888
empty_document[key] = property
882889
.shared_definition
883890
.each_form_with_document(
884891
value,
885892
document_path: (document_path + [key]),
886-
skip_property_proc: skip_property_proc,
887893
skip_on_condition: skip_on_condition,
888894
section_or_shared: property,
889895
condition_proc: condition_proc,
@@ -1015,7 +1021,7 @@ def set_specific_max_scores!(document, is_create: false, condition_proc: nil, **
10151021
# iterate properties
10161022
form[:properties].each do |k, prop|
10171023
next unless prop.visible(is_create: is_create)
1018-
next unless JSF::Forms::Form::SCORABLE_FIELDS.include?(prop.class)
1024+
next unless (JSF::Forms::Form::SCORABLE_FIELDS.include?(prop.class) && prop.scored?)
10191025

10201026
value = current_doc.dig(k)
10211027

@@ -1024,15 +1030,16 @@ def set_specific_max_scores!(document, is_create: false, condition_proc: nil, **
10241030
else
10251031

10261032
# check for any visible child field
1027-
visible_children = prop.dependent_conditions.any? do |cond|
1033+
visible_scorable_children = prop.dependent_conditions.any? do |cond|
10281034
next unless cond.evaluate(current_doc, &condition_proc)
10291035

1030-
cond.dig(:then, :properties)&.any? do |k,v|
1031-
v.visible(is_create: is_create)
1032-
end
1036+
cond[:then]&.scored_with_document?(
1037+
current_doc,
1038+
is_create: is_create
1039+
) # TODO: need to pass more arguments?
10331040
end
10341041

1035-
if visible_children
1042+
if visible_scorable_children
10361043
prop.score_for_value(value)
10371044
else
10381045
prop.max_score
@@ -1140,6 +1147,19 @@ def scored?(**args)
11401147
has_scoring
11411148
end
11421149

1150+
# @return [Boolean]
1151+
def scored_with_document?(document, is_create: false, **kwargs)
1152+
each_form_with_document(document) do |form, condition, skip_branch_proc, current_level, current_doc, current_empty_doc, document_path, section_or_shared|
1153+
form[:properties].each do |key, property|
1154+
next unless property.visible(is_create: is_create)
1155+
next if property.is_a?(JSF::Forms::Section)
1156+
1157+
return true if property.scored?
1158+
end
1159+
end
1160+
false
1161+
end
1162+
11431163
# Initial value when scoring a document
11441164
#
11451165
# @return [Float, NilClass]

lib/jsf/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module JSF
2-
VERSION = "0.10.0"
2+
VERSION = "0.10.1"
33
end

test/spec/forms/form_spec.rb

+98-62
Original file line numberDiff line numberDiff line change
@@ -998,84 +998,120 @@ def test_set_specific_max_scores!
998998
end
999999
end
10001000

1001+
form = JSF::Forms::FormBuilder.build do
1002+
add_response_set(:response_set_1, example('response_set')).tap do |response_set|
1003+
response_set.add_response(example('response', :is_inspection)).tap do |r|
1004+
r[:const] = 'score_0'
1005+
r[:score] = 0
1006+
r.set_translation('score 0', 'es')
1007+
end
1008+
response_set.add_response(example('response', :is_inspection)).tap do |r|
1009+
r[:const] = 'score_1'
1010+
r[:score] = 1
1011+
r.set_translation('score 1', 'es')
1012+
end
1013+
end
1014+
1015+
append_property(:select_1, example('select')) do |f, key|
1016+
f.response_set_id = :response_set_1
1017+
append_conditional_property(:markdown_1_1, example('markdown'), dependent_on: key, type: :enum, value: ['score_0'])
1018+
end
1019+
end
1020+
1021+
[
1022+
{
1023+
doc: {'select_1' => nil},
1024+
hash: {"select_1"=>1},
1025+
total: 1,
1026+
},
1027+
{
1028+
doc: {'select_1' => 'score_1'},
1029+
hash: {"select_1"=>1},
1030+
total: 1,
1031+
},
1032+
{
1033+
doc: {'select_1' => 'score_0'},
1034+
hash: {"select_1"=>1},
1035+
total: 1,
1036+
}
1037+
].each do |obj|
1038+
assert_equal obj[:total], form.set_specific_max_scores!(obj[:doc])
1039+
assert_equal obj[:doc]['meta']['specific_max_score_hash'], obj[:hash]
1040+
end
1041+
10011042
### SCORABLE FIELDS ###
10021043

1003-
scored_form_proc = Proc.new do
1004-
JSF::Forms::FormBuilder.build do
1044+
form = JSF::Forms::FormBuilder.build do
10051045

1006-
add_response_set(:response_set_1, example('response_set')).tap do |response_set|
1007-
response_set.add_response(example('response', :is_inspection)).tap do |r|
1008-
r[:const] = 'nil_score'
1009-
r[:score] = nil
1010-
end
1011-
response_set.add_response(example('response', :is_inspection)).tap do |r|
1012-
r[:const] = 'score_3'
1013-
r[:score] = 3
1014-
end
1015-
response_set.add_response(example('response', :is_inspection)).tap do |r|
1016-
r[:const] = 'score_6'
1017-
r[:score] = 6
1018-
end
1046+
add_response_set(:response_set_1, example('response_set')).tap do |response_set|
1047+
response_set.add_response(example('response', :is_inspection)).tap do |r|
1048+
r[:const] = 'nil_score'
1049+
r[:score] = nil
10191050
end
1020-
1021-
add_response_set(:response_set_2, example('response_set')).tap do |response_set|
1022-
response_set.add_response(example('response', :is_inspection)).tap do |r|
1023-
r[:const] = 'nil_score'
1024-
r[:score] = nil
1025-
end
1026-
response_set.add_response(example('response', :is_inspection)).tap do |r|
1027-
r[:const] = 'score_1'
1028-
r[:score] = 1
1029-
end
1030-
response_set.add_response(example('response', :is_inspection)).tap do |r|
1031-
r[:const] = 'score_2'
1032-
r[:score] = 2
1033-
end
1051+
response_set.add_response(example('response', :is_inspection)).tap do |r|
1052+
r[:const] = 'score_3'
1053+
r[:score] = 3
1054+
end
1055+
response_set.add_response(example('response', :is_inspection)).tap do |r|
1056+
r[:const] = 'score_6'
1057+
r[:score] = 6
10341058
end
1059+
end
1060+
1061+
add_response_set(:response_set_2, example('response_set')).tap do |response_set|
1062+
response_set.add_response(example('response', :is_inspection)).tap do |r|
1063+
r[:const] = 'nil_score'
1064+
r[:score] = nil
1065+
end
1066+
response_set.add_response(example('response', :is_inspection)).tap do |r|
1067+
r[:const] = 'score_1'
1068+
r[:score] = 1
1069+
end
1070+
response_set.add_response(example('response', :is_inspection)).tap do |r|
1071+
r[:const] = 'score_2'
1072+
r[:score] = 2
1073+
end
1074+
end
1075+
1076+
append_property(:markdown_1, example('markdown'))
1077+
append_property(:switch_1, example('switch'))
1078+
1079+
append_property(:select_1, example('select')) do |f, key|
1080+
f.response_set_id = :response_set_1
1081+
1082+
append_conditional_property(:select_1_1, example('select'), dependent_on: key, type: :enum, value: ['nil_score', 'score_3']) do |f, key, subform|
1083+
f.response_set_id = :response_set_2
10351084

1036-
append_property(:markdown_1, example('markdown'))
1037-
append_property(:switch_1, example('switch'))
1085+
subform.append_conditional_property(:select_1_1_1, example('select'), dependent_on: key, type: :const, value: 'nil_score') do |f, key, subform|
1086+
f.response_set_id = :response_set_1
1087+
end
10381088

1039-
append_property(:select_1, example('select')) do |f, key|
1040-
f.response_set_id = :response_set_1
1041-
1042-
append_conditional_property(:select_1_1, example('select'), dependent_on: key, type: :enum, value: ['nil_score', 'score_3']) do |f, key, subform|
1089+
subform.append_conditional_property(:checkbox_1_1_2, example('checkbox'), dependent_on: key, type: :enum, value: ['nil_score', 'score_1']) do |f, key, subform|
10431090
f.response_set_id = :response_set_2
1044-
1045-
subform.append_conditional_property(:select_1_1_1, example('select'), dependent_on: key, type: :const, value: 'nil_score') do |f, key, subform|
1046-
f.response_set_id = :response_set_1
1047-
end
1048-
1049-
subform.append_conditional_property(:checkbox_1_1_2, example('checkbox'), dependent_on: key, type: :enum, value: ['nil_score', 'score_1']) do |f, key, subform|
1050-
f.response_set_id = :response_set_2
1051-
end
10521091
end
1053-
10541092
end
10551093

1056-
append_property(:section_1, example('section')) do |f, _|
1057-
f.form.instance_eval do
1058-
append_property(:slider_sec_1, example('slider'))
1059-
append_property(:number_input_sec_2, example('number_input')) do |f, key|
1060-
append_conditional_property(:select_sec_1_1, example('select'), dependent_on: key, type: :const, value: 1) do |f, key, subform|
1061-
f.response_set_id = :response_set_2
1062-
1063-
subform.append_conditional_property(:switch_1_1_1, example('switch'), dependent_on: key, type: :const, value: 'score_2')
1064-
subform.append_conditional_property(:section_1_1_1, example('section'), dependent_on: key, type: :const, value: 'score_1') do |f, _|
1065-
f.form.instance_eval do
1066-
append_property(:switch_1_1_1_1, example('switch'))
1067-
end
1094+
end
1095+
1096+
append_property(:section_1, example('section')) do |f, _|
1097+
f.form.instance_eval do
1098+
append_property(:slider_sec_1, example('slider'))
1099+
append_property(:number_input_sec_2, example('number_input')) do |f, key|
1100+
append_conditional_property(:select_sec_1_1, example('select'), dependent_on: key, type: :const, value: 1) do |f, key, subform|
1101+
f.response_set_id = :response_set_2
1102+
1103+
subform.append_conditional_property(:switch_1_1_1, example('switch'), dependent_on: key, type: :const, value: 'score_2')
1104+
subform.append_conditional_property(:section_1_1_1, example('section'), dependent_on: key, type: :const, value: 'score_1') do |f, _|
1105+
f.form.instance_eval do
1106+
append_property(:switch_1_1_1_1, example('switch'))
10681107
end
10691108
end
10701109
end
10711110
end
10721111
end
1073-
10741112
end
1075-
end
10761113

1077-
# test multiple documents for a form with no hidden fields
1078-
form = scored_form_proc.call
1114+
end
10791115

10801116
values = [
10811117
{
@@ -1150,8 +1186,8 @@ def test_set_specific_max_scores!
11501186
},
11511187
{
11521188
doc: {'select_1' => 'nil_score', 'select_1_1' => 'nil_score', 'section_1' => [{'number_input_sec_2' => 1}, {'number_input_sec_2' => 1, 'select_sec_1_1' => 'score_1'}] },
1153-
hash: {"switch_1"=>1, "select_1"=>nil, "section_1"=>[{"slider_sec_1"=>10, "select_sec_1_1"=>2}, {"slider_sec_1"=>10, "select_sec_1_1"=>1, "section_1_1_1"=>[]}], "select_1_1"=>nil, "select_1_1_1"=>6, "checkbox_1_1_2"=>3},
1154-
total: 33.0,
1189+
hash: {"switch_1"=>1, "select_1"=>nil, "section_1"=>[{"slider_sec_1"=>10, "select_sec_1_1"=>2}, {"slider_sec_1"=>10, "select_sec_1_1"=>2, "section_1_1_1"=>[]}], "select_1_1"=>nil, "select_1_1_1"=>6, "checkbox_1_1_2"=>3},
1190+
total: 34.0,
11551191
},
11561192
{
11571193
doc: {'select_1' => 'nil_score', 'select_1_1' => 'nil_score', 'section_1' => [{'number_input_sec_2' => 1}, {'number_input_sec_2' => 1, 'select_sec_1_1' => 'score_2'}] },

0 commit comments

Comments
 (0)