lib/quby/compiler/services/definition_validator.rb in quby-compiler-0.5.7 vs lib/quby/compiler/services/definition_validator.rb in quby-compiler-0.5.8
- old
+ new
@@ -19,10 +19,11 @@
validate_fields(questionnaire)
validate_questions(questionnaire)
validate_scores(questionnaire)
validate_table_edgecases(questionnaire)
validate_flags(questionnaire)
+ validate_key_uniqueness(questionnaire)
validate_respondent_types(questionnaire)
validate_outcome_tables(questionnaire)
validate_markdown_fields(questionnaire) if questionnaire.validate_html
validate_raw_content_items(questionnaire) if questionnaire.validate_html
# Some compilation errors are Exceptions (pure syntax errors) and some StandardErrors (NameErrors)
@@ -125,16 +126,23 @@
end
end
def validate_flags(questionnaire)
questionnaire.flags.each_value do |flag|
+ ensure_valid_descriptions(questionnaire, flag)
validate_flag_shows(questionnaire, flag)
validate_flag_hides(questionnaire, flag)
validate_flag_depends_on(questionnaire, flag)
end
end
+ def ensure_valid_descriptions(questionnaire, flag)
+ unless (flag.description_false.present? && flag.description_true.present?) || flag.description.present?
+ fail ArgumentError, "Flag '#{flag.key}' Requires at least either both description_true and description_false or a description"
+ end
+ end
+
def validate_flag_shows(questionnaire, flag)
unknown_questions = flag.shows_questions.select { |key| !questionnaire.key_in_use?(key) }
return if unknown_questions.blank?
fail ArgumentError, "Flag '#{flag.key}' has unknown shows_questions keys #{unknown_questions}"
@@ -151,10 +159,22 @@
return if (missing = flag.depends_on - questionnaire.flags.keys).blank?
fail ArgumentError, "Flag #{flag.key} depends_on nonexistent flag '#{missing.to_sentence}'"
end
+ def validate_key_uniqueness(questionnaire)
+ keys = questionnaire.fields.answer_keys.to_a \
+ + questionnaire.score_schemas.keys.map(&:to_sym) \
+ + questionnaire.flags.keys.map { delete_prefix(_1, questionnaire).to_sym } \
+ + questionnaire.textvars.keys.map { delete_prefix(_1, questionnaire).to_sym }
+
+ return if keys.size == keys.uniq.size
+
+ duplicates = keys.tally.filter_map { |k,v| k if v > 1 }
+ fail ArgumentError, "Duplicate keys: #{duplicates.to_sentence}"
+ end
+
def validate_respondent_types(questionnaire)
valid_respondent_types = Entities::Questionnaire::RESPONDENT_TYPES
invalid_types = questionnaire.respondent_types - valid_respondent_types
@@ -336,9 +356,13 @@
def validate_html(html, key = nil)
fragment = Nokogiri::HTML5.fragment(html, max_errors: 3)
return unless fragment.errors.present?
fail "#{key || html} contains invalid html: #{fragment.errors.map(&:to_s).join(', ')}."
+ end
+
+ def delete_prefix(key, questionnaire)
+ key.delete_prefix("#{questionnaire.key}_")
end
end
end
end
end