Validating Our Templates
Let’s learn how to validate our templates.
We'll cover the following...
We'll cover the following...
The template fields represent a sterner test. The checker
and generators
fields will require us to validate lists and functions. Still, our simple framework that’s based on composition will make quick work of them.
Declaring the main module and core functions
Let’s start with the basic errors
function that composes validations over each field. As before, we’ll enumerate required
and optional
fields, in lib/mastery/boundary/template_validator.ex
, like this:
defmodule Mastery.Boundary.TemplateValidator do import Mastery.Boundary.Validatordef errors(fields) when is_list(fields) dofields = Map.new(fields)[]|> require(fields, :name, &validate_name/1)|> require(fields, :category, &validate_name/1)|> optional(fields, :instructions, &validate_instructions/1)|> require(fields, :raw, &validate_raw/1)|> require(fields, :generators, &validate_generators/1)|> require(fields, :checker, &validate_checker/1)enddef errors(_fields), do: [{nil, "A keyword list of fields is required"}]
The technique works exactly as it did in the QuizValidator
.
Let’s try out a few validations on the template as a whole:
Executable
alias Mastery.Boundary.TemplateValidator
checker = fn(sub, answer) ->sub[:left] + sub[:right] == String.to_integer(answer)end
template =[name: :single_digit_addition,category: :addition,instructions: "Add the numbers",raw: "<%= @left %> + <%= @right %>",generators: %{left: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],right: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]},checker: checker]
TemplateValidator.errors(template)
template =[name: :single_digit_addition,instructions: "Add the numbers",raw: "<%= @left %> + <%= @right %>",generators: %{left: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],right: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]},checker: checker]
TemplateValidator.errors(template)
Output
iex(1)> alias Mastery.Boundary.{TemplateValidator}
[Mastery.Boundary.TemplateValidator]
iex(2)> checker = fn(sub, answer) ->
...(2)> sub[:left] + sub[:right] == String.to_integer(answer)
...(2)> end
#Function<13.126501267/2 in :erl_eval.expr/5>
iex(3)> template =
...(3)> [
...(3)> name: :single_digit_addition,
...(3)> category:
...