Refactors allowed_types into boolean has_freetext and number min_responses and max_responses

This commit is contained in:
AliasAlreadyTaken 2024-10-08 16:15:21 +02:00
parent f2ec7825ce
commit dcc41a2487
3 changed files with 59 additions and 68 deletions

View File

@ -104,7 +104,7 @@ yl_survey.evaluate(s_id)
??? How do we evaluate that stuff ???
```
yl_survey.create_question(s_id, question, category, sort, {allowed_types}, {answers}, enabled)
yl_survey.create_question(s_id, question, category, sort, {options}, {answers}, enabled)
```
Returns `true, q_id` if successful, `false, "errormessage"` if not.
@ -115,12 +115,12 @@ Adds a question to the survey identified by `s_id`.
* question: string, required. This is the question text the survey asks its respondents.
* category: string, optional, default empty. Use it for additonal explanation, category, help. Is displayed near the question. May be nil or empty.
* sort: integer, optional, defaults to the next free number. Use this to order your questions.
* {allowed_types}: table of enum("singlechoice","multiplechoice","freetext"), required. `singlechoice` and `multiplechoice` are mutually exclusive, while freetxt can be combined with either.
* {options}: table of options with defaults `{"has_freetext" : true, "min_responses" : 0, "max_responses" : 0}`, optional. `max_responses : 0` means there is no limit on the maximum number of answers. Example: "singlechoice question without freetext": `{"has_freetext" : false, "min_responses" : 0, "max_responses" : 1}`
* {answers}: table of strings, optional. Holds the answers to a singlechoice or multiplechoice question.
* enabled: boolean, optional, defaults to true. If true, the question is delivered to a participant. If false, the question is hidden.
```
yl_survey.edit_question(s_id, q_id, question, sort, category, {allowed_types}, {answers}, enabled, delete_responses)
yl_survey.edit_question(s_id, q_id, question, sort, category, {options}, {answers}, enabled, delete_responses)
```
Returns `true, q_id` if successful, `false, "errormessage"` if not.

101
api.lua
View File

@ -44,37 +44,30 @@ local function validate(value, expect_type, allow_nil)
return false
end
local function validate_questiontype(allowed_types)
local valid_types = {
singlechoice = true,
multiplechoice = true,
freetext = true
}
local function validate_options(options)
local sm_count = 0
local ft_count = 0
if (validate(options, "table", false) == false) then return false end
if (validate(options.has_freetext, "boolean", true) == false) then return false end
if (validate(options.min_responses, "number", true) == false) then return false end
if (validate(options.max_responses, "number", true) == false) then return false end
for _, t in ipairs(allowed_types) do
if (options and options.min_responses and (options.min_responses < 0)) then return false end
if (options and options.max_responses and (options.max_responses < 0)) then return false end
-- Invalid question type
if (valid_types[t] == nil) then return false end
if (options and options.min_responses and options.max_responses and
(options.min_responses > options.max_responses)) then return false end
-- Either singlechoice OR multiplechoice
if ((t == "singlechoice") or (t == "multiplechoice")) then
sm_count = sm_count + 1
end
return true
end
if sm_count > 1 then return false end
-- Only one freetext allowed
if (t == "freetext") then ft_count = ft_count + 1 end
if ft_count > 1 then return false end
local function validate_answers(answers, options)
if (((answers == nil) or (next(answers) == nil)) and
((options and options.min_responses and (options.min_responses > 0)) or
(options and options.min_responses and (options.max_responses > 0)))) then
return false
end
if ((ft_count + sm_count) == 0) then return false end
return true
end
@ -322,7 +315,7 @@ function yl_survey.remove_record(id) return remove_record(id) end
-- create_question
--
local function create_question(id, question, category, sort, allowed_types,
local function create_question(id, question, category, sort, options,
answers, enabled)
-- Defense
if (validate(id, "string", false) == false) then
@ -338,8 +331,9 @@ local function create_question(id, question, category, sort, allowed_types,
if (validate_nil_or_positive(sort) == false) then
return false, yl_survey.t("sort must be positive number")
end
if (validate(allowed_types, "table", false) == false) then
return false, yl_survey.t("allowed_types must be table")
if (options == nil) then options = {} end
if (validate(options, "table", false) == false) then
return false, yl_survey.t("options must be table")
end
if (validate(answers, "table", true) == false) then
return false, yl_survey.t("answers must be table")
@ -349,19 +343,22 @@ local function create_question(id, question, category, sort, allowed_types,
return false, yl_survey.t("enabled must be boolean")
end
-- Specialcase : allowed_types must be a combination of
-- "singlechoice" or "multiplechoice" or "freetext"
if (validate_questiontype(allowed_types) == false) then
return false, yl_survey.t("wrong allowed_types")
if (validate_options(options) == false) then
return false, yl_survey.t("wrong options")
end
-- Specialcase : answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice
if (validate_answers(answers, options) == false) then
return false, yl_survey.t("wrong answers")
end
--[[
if (((answers == nil) or (next(answers) == nil)) and
((yl_survey.table_contains(allowed_types, "multiplechoice") == true) or
(yl_survey.table_contains(allowed_types, "singlechoice") == true))) then
((yl_survey.table_contains(options, "multiplechoice") == true) or
(yl_survey.table_contains(options, "singlechoice") == true))) then
return false, yl_survey.t(
"answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice")
end
]]--
local record = yl_survey.get_record(id)
@ -392,7 +389,9 @@ local function create_question(id, question, category, sort, allowed_types,
sort = next_sort,
question = question,
enabled = enabled,
allowed_types = allowed_types,
has_freetext = options.has_freetext or true,
min_responses = options.min_responses or 0,
max_responses = options.max_responses or 0,
answers = answers,
responses = {}
}
@ -409,16 +408,16 @@ local function create_question(id, question, category, sort, allowed_types,
end
end
function yl_survey.create_question(id, question, category, sort, allowed_types,
function yl_survey.create_question(id, question, category, sort, options,
answers, enabled)
return create_question(id, question, category, sort, allowed_types, answers,
return create_question(id, question, category, sort, options, answers,
enabled)
end
-- edit_question
--
local function edit_question(id, q_id, question, sort, category, allowed_types,
local function edit_question(id, q_id, question, sort, category, options,
answers, enabled, delete_responses)
-- Defense
if (validate(id, "string", false) == false) then
@ -438,8 +437,9 @@ local function edit_question(id, q_id, question, sort, category, allowed_types,
if (validate_nil_or_positive(sort) == false) then
return false, yl_survey.t("sort must be positive number")
end
if (validate(allowed_types, "table", true) == false) then
return false, yl_survey.t("allowed_types must be table")
if (options == nil) then options = {} end
if (validate(options, "table", false) == false) then
return false, yl_survey.t("options must be table")
end
if (validate(answers, "table", true) == false) then
return false, yl_survey.t("answers must be table")
@ -451,19 +451,12 @@ local function edit_question(id, q_id, question, sort, category, allowed_types,
return false, yl_survey.t("delete_responses must be boolean")
end
-- Specialcase : allowed_types must be a combination of
-- "singlechoice" or "multiplechoice" or "freetext"
if ((allowed_types ~= nil) and
(validate_questiontype(allowed_types) == false)) then
return false, yl_survey.t("wrong allowed_types")
if (validate_options(options) == false) then
return false, yl_survey.t("wrong options")
end
-- Specialcase : answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice
if ((answers ~= nil) and (next(answers) ~= nil) and
((yl_survey.table_contains(allowed_types, "multiplechoice") == true) or
(yl_survey.table_contains(allowed_types, "singlechoice") == true))) then
return false, yl_survey.t(
"answers cannot be nil or empty if allowedtypes has either multiplechoice or singlechoice")
if (validate_answers(answers, options) == false) then
return false, yl_survey.t("wrong answers")
end
local record = yl_survey.get_record(id)
@ -504,7 +497,9 @@ local function edit_question(id, q_id, question, sort, category, allowed_types,
sort = sort or t_question["sort"],
question = question or t_question["question"],
enabled = enabled or t_question["enabled"],
allowed_types = allowed_types or t_question["allowed_types"],
has_freetext = options.has_freetext or t_question["has_freetext"] or true,
min_responses = options.min_responses or t_question["min_responses"] or 0,
max_responses = options.max_responses or t_question["max_responses"] or 0,
answers = answers or t_question["answers"],
responses = n_responses
}
@ -523,9 +518,9 @@ local function edit_question(id, q_id, question, sort, category, allowed_types,
end
function yl_survey.edit_question(s_id, q_id, question, sort, category,
allowed_types, answers, enabled,
options, answers, enabled,
delete_responses)
return edit_question(s_id, q_id, question, sort, category, allowed_types,
return edit_question(s_id, q_id, question, sort, category, options,
answers, enabled, delete_responses)
end

View File

@ -20,8 +20,8 @@ remove_survey(s_id)
list_surveys()
evaluate(s_id)
create_question(s_id, question, category, sort, {allowed_types}, {answers}) return q_id
edit_question(s_id, q_id, question, sort, category, {allowed_types}, {answers}, delete_responses)
create_question(s_id, question, category, sort, {options}, {answers}) return q_id
edit_question(s_id, q_id, question, sort, category, {options}, {answers}, delete_responses)
remove_question(q_id)
list_questions()
@ -51,11 +51,9 @@ This is the planned data structure:
"sort": 99,
"question": "How did you find out about Minetest in general?",
"enabled" : true,
"allowed_types": [
"singlechoice",
"multiplechoice",
"freetext"
],
"has_freetext" : true,
"min_responses" : 1,
"max_responses" : 5,
"answers": {
"1": "Friend dragged me over",
"2": "I came here of my own free will"
@ -81,11 +79,9 @@ This is the planned data structure:
"sort": 2,
"question": "What do you think about the current state of the server?",
"enabled" : true,
"allowed_types": [
"singlechoice",
"multiplechoice",
"freetext"
],
"has_freetext" : true,
"min_responses" : 1,
"max_responses" : 0
"answers": {
"0": "Write your answer here",
"1": "Terrible",