Module:paramètres/testcases

Tous les tests ont réussi, 18 tests ignorés (rafraichir)

  Texte Attendu Obtenu
testAlias :
Passed Alias défini uniquement {"test"} {"test"}
  Texte Attendu Obtenu
testAliasNoOverride :
Passed Alias et argument de base définis {"test"} {"test"}
  Texte Attendu Obtenu
testAliasToAlias :
Passed (Test d’erreur) Alias vers alias Erreur interne : Paramètre « 3 », alias vers un autre alias (« 2 ») Erreur interne : Paramètre « 3 », alias vers un autre alias (« 2 »)
Passed (Test d’erreur) Alias vers alias, pas args Erreur interne : Paramètre « 3 », alias vers un autre alias (« 2 ») Erreur interne : Paramètre « 3 », alias vers un autre alias (« 2 »)
  Texte Attendu Obtenu
testAliasToItself :
Passed (Test d’erreur) Alias vers lui-même Erreur interne : Paramètre « 1 », alias vers lui-même Erreur interne : Paramètre « 1 », alias vers lui-même
Passed (Test d’erreur) Alias vers lui-même, pas args Erreur interne : Paramètre « 1 », alias vers lui-même Erreur interne : Paramètre « 1 », alias vers lui-même
  Texte Attendu Obtenu
testAliasToNonexistant :
Passed (Test d’erreur) Alias vers non défini Erreur interne : Paramètre « 1 », alias vers un paramètre non défini « 2 » Erreur interne : Paramètre « 1 », alias vers un paramètre non défini « 2 »
Passed (Test d’erreur) Alias vers non défini, pas args Erreur interne : Paramètre « 1 », alias vers un paramètre non défini « 2 » Erreur interne : Paramètre « 1 », alias vers un paramètre non défini « 2 »
  Texte Attendu Obtenu
testAliasToRequired :
Passed Alias vers requis, alias renseigné {"valeur"} {"valeur"}
  Texte Attendu Obtenu
testCheckerNoValue :
Passed Prédicat sur paramètre non renseigné {} {}
  Texte Attendu Obtenu
testCheckerNumber :
Passed Prédicat sur nombre {0} {0}
  Texte Attendu Obtenu
testCheckerNumberInvalid :
Passed (Test d’erreur) Checker, valeur invalide, nombre Valeur invalide pour le paramètre « 1 » ("-1") de type nombre Valeur invalide pour le paramètre « 1 » ("-1") de type nombre
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("-1") de type nombre'}, false} {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("-1") de type nombre'}, false}
  Texte Attendu Obtenu
testCheckerString :
Passed Prédicat sur chaîne {"a"} {"a"}
  Texte Attendu Obtenu
testCheckerStringInvalid :
Passed (Test d’erreur) Checker, valeur invalide, chaîne Valeur invalide pour le paramètre « 1 » ("b") de type chaîne Valeur invalide pour le paramètre « 1 » ("b") de type chaîne
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("b") de type chaîne'}, false} {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("b") de type chaîne'}, false}
  Texte Attendu Obtenu
testCheckerThroughAlias :
Passed (Test d’erreur) Checker, valeur invalide, alias Valeur invalide pour le paramètre « test » ("b") de type chaîne Valeur invalide pour le paramètre « test » ("b") de type chaîne
Passed (Test d’erreur silencieuse) Paramètre erroné « test » {{"test", "invalid value", 'Valeur invalide pour le paramètre « test » ("b") de type chaîne'}, false} {{"test", "invalid value", 'Valeur invalide pour le paramètre « test » ("b") de type chaîne'}, false}
  Texte Attendu Obtenu
testDefault :
Passed Valeur par défaut {"test"} {"test"}
  Texte Attendu Obtenu
testEmptyValue :
Passed Arg = "" {} {}
  Texte Attendu Obtenu
testEnum :
Passed Énumération {"a"} {"a"}
  Texte Attendu Obtenu
testEnumAndChecker :
Passed (Test d’erreur) Énumération et checker Erreur interne : Le paramètre « 1 » est une énumération avec une précondition Erreur interne : Le paramètre « 1 » est une énumération avec une précondition
Passed (Test d’erreur) Énumération et checker, pas args Erreur interne : Le paramètre « 1 » est une énumération avec une précondition Erreur interne : Le paramètre « 1 » est une énumération avec une précondition
  Texte Attendu Obtenu
testEnumEmptyString :
Passed Énumération chaîne vide {} {}
  Texte Attendu Obtenu
testEnumInvalidTypeNumber :
Passed (Test d’erreur) Énumération, valeur invalide, nombre Valeur invalide pour le paramètre « 1 » ("a") de type nombre Valeur invalide pour le paramètre « 1 » ("a") de type nombre
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("a") de type nombre'}, false} {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("a") de type nombre'}, false}
  Texte Attendu Obtenu
testEnumInvalidValue :
Passed (Test d’erreur) Énumération, valeur invalide Valeur invalide pour le paramètre « 1 » ("c") Valeur invalide pour le paramètre « 1 » ("c")
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "value not in enum", 'Valeur invalide pour le paramètre « 1 » ("c")'}, false} {{1, "value not in enum", 'Valeur invalide pour le paramètre « 1 » ("c")'}, false}
  Texte Attendu Obtenu
testEnumInvalidValues :
Passed (Test d’erreur) Énumération, valeur invalide Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("1") de type chaîne Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("1") de type chaîne
  Texte Attendu Obtenu
testEnumInvalidValuesBoolean :
Passed (Test d’erreur) Énumération, valeur invalide, booléen Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type booléen Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type booléen
  Texte Attendu Obtenu
testEnumInvalidValuesFloat :
Passed (Test d’erreur) Énumération, valeur invalide, flottant Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type flottant Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type flottant
  Texte Attendu Obtenu
testEnumInvalidValuesInt :
Passed (Test d’erreur) Énumération, valeur invalide, entier Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type entier Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type entier
  Texte Attendu Obtenu
testEnumInvalidValuesNumber :
Passed (Test d’erreur) Énumération, valeur invalide, nombre Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type nombre Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type nombre
  Texte Attendu Obtenu
testEnumNil :
Passed Énumération nil {} {}
  Texte Attendu Obtenu
testEnumNumber :
Passed Énumération de nombres {1} {1}
  Texte Attendu Obtenu
testInvalidTypeBoolean :
Passed (Test d’erreur) Type invalide, booléen Valeur invalide pour le paramètre « 1 » ("test") de type booléen Valeur invalide pour le paramètre « 1 » ("test") de type booléen
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("test") de type booléen'}, false} {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("test") de type booléen'}, false}
  Texte Attendu Obtenu
testInvalidTypeFloat :
Passed (Test d’erreur) Type invalide, flottant Valeur invalide pour le paramètre « 1 » ("test") de type flottant Valeur invalide pour le paramètre « 1 » ("test") de type flottant
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("test") de type flottant'}, false} {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("test") de type flottant'}, false}
  Texte Attendu Obtenu
testInvalidTypeInt :
Passed (Test d’erreur) Type invalide, entier Valeur invalide pour le paramètre « 1 » ("42.5") de type entier Valeur invalide pour le paramètre « 1 » ("42.5") de type entier
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("42.5") de type entier'}, false} {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("42.5") de type entier'}, false}
  Texte Attendu Obtenu
testInvalidTypeNumber :
Passed (Test d’erreur) Type invalide, nombre Valeur invalide pour le paramètre « 1 » ("test") de type nombre Valeur invalide pour le paramètre « 1 » ("test") de type nombre
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("test") de type nombre'}, false} {{1, "invalid value", 'Valeur invalide pour le paramètre « 1 » ("test") de type nombre'}, false}
  Texte Attendu Obtenu
testListNamed :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListNamedArgOverlap :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListNamedDuplicates :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListNamedLast :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListNamedLastIsAlias :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListNamedLastIsAlias2 :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListNamedLastMissing :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListNamedMaxLengthExceeded :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositional :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositionalArgOverlap :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositionalDuplicates :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositionalLast :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositionalLastIsAlias :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositionalLastIsAlias2 :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositionalLastMissing :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositionalMaxLength :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositionalMaxLengthExceeded :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testListPositionalStartNot1 :
Failed Test(s) ignoré(s)
  Texte Attendu Obtenu
testMissingRequired :
Passed (Test d’erreur) Paramètre requis manquant Paramètre requis « 1 » absent Paramètre requis « 1 » absent
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "missing required parameter", "Paramètre requis « 1 » absent"}, false} {{1, "missing required parameter", "Paramètre requis « 1 » absent"}, false}
  Texte Attendu Obtenu
testNoArg :
Passed Argument absent {} {}
  Texte Attendu Obtenu
testRequiredAllowEmpty :
Passed Requis et allow_empty, arg de base manquant {} {}
Passed Requis et allow_empty, arg de base manquant {} {}
  Texte Attendu Obtenu
testRequiredEmpty :
Passed (Test d’erreur) Paramètre requis vide Paramètre requis « 1 » vide Paramètre requis « 1 » vide
Passed (Test d’erreur silencieuse) Paramètre erroné « 1 » {{1, "empty required parameter", "Paramètre requis « 1 » vide"}, false} {{1, "empty required parameter", "Paramètre requis « 1 » vide"}, false}
  Texte Attendu Obtenu
testRequiredOnAliasNoArg :
Passed Requis et alias, arg de base manquant {} {}
  Texte Attendu Obtenu
testType :
Passed number {1} {1}
Passed boolean « 1 » {true} {true}
Passed string (type absent) {"test"} {"test"}
Passed boolean « 0 » {false} {false}
Passed boolean « oui » {true} {true}
Passed int {1} {1}
Passed boolean « vrai » {true} {true}
Passed float {1} {1}
Passed string (type = nil) {"test"} {"test"}
Passed boolean « faux » {false} {false}
Passed boolean « non » {false} {false}
  Texte Attendu Obtenu
testTypeThroughAlias :
Passed (Test d’erreur) Type, valeur invalide, alias Valeur invalide pour le paramètre « test » ("test") de type entier Valeur invalide pour le paramètre « test » ("test") de type entier
Passed (Test d’erreur silencieuse) Paramètre erroné « test » {{"test", "invalid value", 'Valeur invalide pour le paramètre « test » ("test") de type entier'}, false} {{"test", "invalid value", 'Valeur invalide pour le paramètre « test » ("test") de type entier'}, false}
  Texte Attendu Obtenu
testUnknown :
Passed (Test d’erreur) Paramètre inconnu Paramètre « 2 » inconnu Paramètre « 2 » inconnu
Passed (Test d’erreur silencieuse) Paramètre erroné « 2 » {{2, "unknown parameter", "Paramètre « 2 » inconnu"}, false} {{2, "unknown parameter", "Paramètre « 2 » inconnu"}, false}
  Texte Attendu Obtenu
testUnknownType :
Passed (Test d’erreur) Type inconnu Erreur interne : Type inconnu pour le paramètre « 1 » ("test") Erreur interne : Type inconnu pour le paramètre « 1 » ("test")
Passed (Test d’erreur) Type inconnu, pas args Erreur interne : Type inconnu pour le paramètre « 1 » ("test") Erreur interne : Type inconnu pour le paramètre « 1 » ("test")
  Texte Attendu Obtenu
testWhitespaceOnlyValue :
Passed Arg = " " {} {}



local tests = require("Module:UnitTests")
local m_params = require("Module:paramètres")

-- Utility functions --

--- Tests wether the "process" method returns the right value
--- for the given arguments.
--- @param args table The arguments passed to the "process" function.
--- @param p table The defined parameters.
--- @param expectedValue table The expected value.
--- @param testName string The test’s name.
local function test(self, args, p, expectedValue, testName)
  self:equals_deep(testName or "", m_params.process(args, p), expectedValue)
end

--- Tests wether the "process" method raise a given error for the given
--- set of arguments. If this is not the case, the test fails. It also
--- tests wether the quiet mode returns the right values.
--- @param args table The arguments passed to the "process" function.
--- @param p table The defined parameters.
--- @param expectedErrorMessage string The expected error message.
--- @param expectedParam table|nil The expected values for quiet mode;
---                                omitting it or passing nil will deactivate the test.
local function handleError(self, testName, args, p, expectedErrorMessage, expectedParam)
  self:expect_error(testName, m_params.process, { args, p }, expectedErrorMessage)

  if expectedParam then
    local result, success = m_params.process(args, p, true)
    table.insert(expectedParam, expectedErrorMessage)
    self:equals_deep(
        "''(Test d’erreur silencieuse)'' Paramètre erroné « " .. expectedParam[1] .. " »",
        { result, success },
        { expectedParam, false }
    )
  end
end

-- Tests --

function tests:testEmptyValue()
  local p = {
    [1] = {},
  }
  local args = {
    [1] = ""
  }
  local e = {
    [1] = nil
  }

  test(self, args, p, e, 'Arg = ""')
end

function tests:testWhitespaceOnlyValue()
  local p = {
    [1] = {},
  }
  local args = {
    [1] = " "
  }
  local e = {
    [1] = nil
  }

  test(self, args, p, e, 'Arg = " "')
end

function tests:testNoArg()
  local p = {
    [1] = {},
  }
  local args = {}
  local e = {}

  test(self, args, p, e, "Argument absent")
end

function tests:testAlias()
  local p = {
    [1] = {},
    ["lang"] = { alias_of = 1 }
  }
  local args = {
    ["lang"] = "test"
  }
  local e = {
    [1] = "test"
  }

  test(self, args, p, e, "Alias défini uniquement")
end

function tests:testAliasToRequired()
  local p = {
    [1] = { required = true },
    ["test"] = { alias_of = 1 }
  }
  local args = {
    ["test"] = "valeur"
  }
  local e = {
    [1] = "valeur"
  }

  test(self, args, p, e, "Alias vers requis, alias renseigné")
end

function tests:testAliasNoOverride()
  local p = {
    [1] = {},
    ["lang"] = { alias_of = 1 }
  }
  local args = {
    [1] = "test",
    ["lang"] = "test2"
  }
  local e = {
    [1] = "test"
  }

  test(self, args, p, e, "Alias et argument de base définis")
end

function tests:testDefault()
  local p = {
    [1] = { default = "test" }
  }
  local args = {}
  local e = {
    [1] = "test"
  }

  test(self, args, p, e, "Valeur par défaut")
end

function tests:testRequiredOnAliasNoArg()
  local p = {
    [1] = { },
    ["test"] = { required = true, alias_of = 1 }
  }
  local args = {}
  local e = {}

  test(self, args, p, e, "Requis et alias, arg de base manquant")
end

function tests:testType()
  local cases = {
    ["number"] = {
      { [1] = { type = m_params.NUMBER } },
      { [1] = "42" },
      { [1] = 42 }
    },
    ["number"] = {
      { [1] = { type = m_params.NUMBER } },
      { [1] = "42.5" },
      { [1] = 42.5 }
    },
    ["number"] = {
      { [1] = { type = m_params.NUMBER } },
      { [1] = "0x1" },
      { [1] = 1 }
    },
    ["int"] = {
      { [1] = { type = m_params.INT } },
      { [1] = "42" },
      { [1] = 42 }
    },
    ["int"] = {
      { [1] = { type = m_params.INT } },
      { [1] = "0x1" },
      { [1] = 1 }
    },
    ["float"] = {
      { [1] = { type = m_params.FLOAT } },
      { [1] = "42.5" },
      { [1] = 42.5 }
    },
    ["float"] = {
      { [1] = { type = m_params.FLOAT } },
      { [1] = "42" },
      { [1] = 42 }
    },
    ["float"] = {
      { [1] = { type = m_params.FLOAT } },
      { [1] = "0x1" },
      { [1] = 1 }
    },
    ["boolean « 1 »"] = {
      { [1] = { type = m_params.BOOLEAN } },
      { [1] = "1" },
      { [1] = true }
    },
    ["boolean « oui »"] = {
      { [1] = { type = m_params.BOOLEAN } },
      { [1] = "oui" },
      { [1] = true }
    },
    ["boolean « vrai »"] = {
      { [1] = { type = m_params.BOOLEAN } },
      { [1] = "vrai" },
      { [1] = true }
    },
    ["boolean « 0 »"] = {
      { [1] = { type = m_params.BOOLEAN } },
      { [1] = "0" },
      { [1] = false }
    },
    ["boolean « non »"] = {
      { [1] = { type = m_params.BOOLEAN } },
      { [1] = "non" },
      { [1] = false }
    },
    ["boolean « faux »"] = {
      { [1] = { type = m_params.BOOLEAN } },
      { [1] = "faux" },
      { [1] = false }
    },
    ["string (type = nil)"] = {
      { [1] = { type = nil } },
      { [1] = "test" },
      { [1] = "test" }
    },
    ["string (type absent)"] = {
      { [1] = {} },
      { [1] = "test" },
      { [1] = "test" }
    }
  }

  for test_name, case in pairs(cases) do
    local p, args, e = case[1], case[2], case[3]
    test(self, args, p, e, test_name)
  end
end

function tests:testRequiredAllowEmpty()
  local p = {
    [1] = { required = true, allow_empty = true }
  }
  local args = {}
  local e = {}

  local result, _ = m_params.process(args, p)
  self:equals_deep("Requis et allow_empty, arg de base manquant", result, e)
  test(self, args, p, e, "Requis et allow_empty, arg de base manquant")
end

function tests:testListPositional()
  tests:ignore()
  local p = {
    [1] = { list = true }
  }
  local args = {
    [1] = "test1",
    [2] = "test2"
  }
  local e = {
    [1] = { "test1", "test2" }
  }

  test(self, args, p, e, "Liste positionnelle")
end

function tests:testListNamed()
  tests:ignore()
  local p = {
    ["e"] = { list = true }
  }
  local args = {
    ["e1"] = "test1",
    ["e2"] = "test2"
  }
  local e = {
    ["e"] = { "test1", "test2" }
  }

  test(self, args, p, e, "Liste nommée")
end

function tests:testListPositionalMaxLength()
  tests:ignore()
  local p = {
    [1] = { list = true, max_length = 3 }
  }
  local args = {
    [1] = "test1",
    [2] = "test2"
  }
  local e = {
    [1] = { "test1", "test2" }
  }

  test(self, args, p, e, "Liste positionnelle")
end

function tests:testListNamed()
  tests:ignore()
  local p = {
    ["e"] = { list = true, max_length = 3 }
  }
  local args = {
    ["e1"] = "test1",
    ["e2"] = "test2"
  }
  local e = {
    ["e"] = { "test1", "test2" }
  }

  test(self, args, p, e, "Liste nommée")
end

function tests:testListPositionalLast()
  tests:ignore()
  local p = {
    [1] = { list = true },
    [-1] = { required = true }
  }
  local args = {
    [1] = "test1",
    [2] = "test2"
  }
  local e = {
    [1] = { "test1", "test2" }
  }

  test(self, args, p, e, "Liste positionnelle, dernier élément")
end

function tests:testListPositionalLastIsAlias()
  tests:ignore()
  local p = {
    [1] = { list = true },
    [-1] = { alias_of = "lang" },
    ["lang"] = { required = true }
  }
  local args = {
    [1] = "test1",
    [2] = "test2",
    [3] = "fr"
  }
  local e = {
    [1] = { "test1", "test2" },
    ["lang"] = "fr"
  }

  test(self, args, p, e, "Liste positionnelle, dernier élément est un alias")
end

function tests:testListPositionalLastIsAlias2()
  tests:ignore()
  local p = {
    [1] = { list = true },
    [-1] = { alias_of = "lang" },
    ["lang"] = { required = true }
  }
  local args = {
    [1] = "test1",
    [2] = "test2",
    ["lang"] = "fr"
  }
  local e = {
    [1] = { "test1", "test2" },
    ["lang"] = "fr"
  }

  test(self, args, p, e, "Liste positionnelle, dernier élément est un alias")
end

function tests:testListNamedLast()
  tests:ignore()
  local p = {
    ["e"] = { list = true },
    ["e-1"] = { required = true }
  }
  local args = {
    ["e1"] = "test1",
    ["e2"] = "test2"
  }
  local e = {
    ["e"] = { "test1", "test2" }
  }

  test(self, args, p, e, "Liste nommée, dernier élément")
end

function tests:testListNamedLastIsAlias()
  tests:ignore()
  local p = {
    ["e"] = { list = true },
    ["e-1"] = { alias_of = "lang" },
    ["lang"] = { required = true }
  }
  local args = {
    ["e1"] = "test1",
    ["e2"] = "test2",
    ["e3"] = "fr"
  }
  local e = {
    ["e"] = { "test1", "test2" },
    ["lang"] = "fr"
  }

  test(self, args, p, e, "Liste nommée, dernier élément est un alias")
end

function tests:testListNamedLastIsAlias2()
  tests:ignore()
  local p = {
    ["e"] = { list = true },
    ["e-1"] = { alias_of = "lang" },
    ["lang"] = { required = true }
  }
  local args = {
    ["e1"] = "test1",
    ["e2"] = "test2",
    ["lang"] = "fr"
  }
  local e = {
    ["e"] = { "test1", "test2" },
    ["lang"] = "fr"
  }

  test(self, args, p, e, "Liste nommée, dernier élément est un alias")
end

function tests:testListPositionalStartNot1()
  tests:ignore()
  local p = {
    [1] = {},
    [2] = { list = true }
  }
  local args = {
    [1] = "test1",
    [2] = "test2",
    [3] = "test3"
  }
  local e = {
    [1] = "test1",
    [2] = { "test2", "test3" }
  }

  test(self, args, p, e, "Liste positionnelle, indice début > 1")
end

function tests:testEnum()
  local p = {
    [1] = { enum = { "a", "b" } }
  }
  local args = {
    [1] = "a"
  }
  local e = {
    [1] = "a"
  }

  test(self, args, p, e, "Énumération")
end

function tests:testEnumNumber()
  local p = {
    [1] = { enum = { 1, 2 }, type = m_params.NUMBER }
  }
  local args = {
    [1] = "1"
  }
  local e = {
    [1] = 1
  }

  test(self, args, p, e, "Énumération de nombres")
end

function tests:testEnumEmptyString()
  local p = {
    [1] = { enum = { "a", nil } }
  }
  local args = {
    [1] = ""
  }
  local e = {
    [1] = nil
  }

  test(self, args, p, e, "Énumération chaîne vide")
end

function tests:testEnumNil()
  local p = {
    [1] = { enum = { "a", nil } }
  }
  local args = {
    [1] = nil
  }
  local e = {
    [1] = nil
  }

  test(self, args, p, e, "Énumération nil")
end

function tests:testCheckerString()
  local p = {
    [1] = { checker = function(s)
      return s == "a"
    end }
  }
  local args = {
    [1] = "a"
  }
  local e = {
    [1] = "a"
  }

  test(self, args, p, e, "Prédicat sur chaîne")
end

function tests:testCheckerNumber()
  local p = {
    [1] = { type = m_params.NUMBER, checker = function(n)
      return 0 <= n and n < 10
    end }
  }
  local args = {
    [1] = 0
  }
  local e = {
    [1] = 0
  }

  test(self, args, p, e, "Prédicat sur nombre")
end

function tests:testCheckerNoValue()
  local p = {
    [1] = { checker = function(s)
      return s == "a"
    end }
  }
  local args = {
  }
  local e = {
  }

  test(self, args, p, e, "Prédicat sur paramètre non renseigné")
end

-- Error tests --

function tests:testMissingRequired()
  local p = {
    [1] = { required = true }
  }
  local args = {}

  handleError(self, "Paramètre requis manquant", args, p, "Paramètre requis « 1 » absent", { 1, m_params.MISSING_PARAM })
end

function tests:testRequiredEmpty()
  local p = {
    [1] = { required = true }
  }
  local args = {
    [1] = ""
  }

  handleError(self, "Paramètre requis vide", args, p, "Paramètre requis « 1 » vide", { 1, m_params.EMPTY_PARAM })
end

function tests:testUnknown()
  local p = {
    [1] = {}
  }
  local args = {
    [2] = "test"
  }

  handleError(self, "Paramètre inconnu", args, p, "Paramètre « 2 » inconnu", { 2, m_params.UNKNOWN_PARAM })
end

function tests:testInvalidTypeNumber()
  local p = {
    [1] = { type = m_params.NUMBER }
  }
  local args = {
    [1] = "test"
  }

  handleError(self, "Type invalide, nombre", args, p, 'Valeur invalide pour le paramètre « 1 » ("test") de type nombre', { 1, m_params.INVALID_VALUE })
end

function tests:testInvalidTypeInt()
  local p = {
    [1] = { type = m_params.INT }
  }
  local args = {
    [1] = "42.5"
  }

  handleError(self, "Type invalide, entier", args, p, 'Valeur invalide pour le paramètre « 1 » ("42.5") de type entier', { 1, m_params.INVALID_VALUE })
end

function tests:testInvalidTypeFloat()
  local p = {
    [1] = { type = m_params.FLOAT }
  }
  local args = {
    [1] = "test"
  }

  handleError(self, "Type invalide, flottant", args, p, 'Valeur invalide pour le paramètre « 1 » ("test") de type flottant', { 1, m_params.INVALID_VALUE })
end

function tests:testInvalidTypeBoolean()
  local p = {
    [1] = { type = m_params.BOOLEAN }
  }
  local args = {
    [1] = "test"
  }

  handleError(self, "Type invalide, booléen", args, p, 'Valeur invalide pour le paramètre « 1 » ("test") de type booléen', { 1, m_params.INVALID_VALUE })
end

function tests:testCheckerStringInvalid()
  local p = {
    [1] = { checker = function(s)
      return s == "a"
    end }
  }
  local args = {
    [1] = "b"
  }

  handleError(self, "Checker, valeur invalide, chaîne", args, p, 'Valeur invalide pour le paramètre « 1 » ("b") de type chaîne', { 1, m_params.INVALID_VALUE })
end

function tests:testCheckerNumberInvalid()
  local p = {
    [1] = { type = m_params.NUMBER, checker = function(n)
      return 0 <= n and n < 10
    end }
  }
  local args = {
    [1] = -1
  }

  handleError(self, "Checker, valeur invalide, nombre", args, p, 'Valeur invalide pour le paramètre « 1 » ("-1") de type nombre', { 1, m_params.INVALID_VALUE })
end

function tests:testCheckerThroughAlias()
  local p = {
    [1] = { checker = function(n)
      return n == "a"
    end },
    ["test"] = { alias_of = 1 }
  }
  local args = {
    ["test"] = "b"
  }

  handleError(self, "Checker, valeur invalide, alias", args, p, 'Valeur invalide pour le paramètre « test » ("b") de type chaîne', { "test", m_params.INVALID_VALUE })
end

function tests:testTypeThroughAlias()
  local p = {
    [1] = { type = m_params.INT },
    ["test"] = { alias_of = 1 }
  }
  local args = {
    ["test"] = "test"
  }

  handleError(self, "Type, valeur invalide, alias", args, p, 'Valeur invalide pour le paramètre « test » ("test") de type entier', { "test", m_params.INVALID_VALUE })
end

function tests:testListPositionalLastMissing()
  tests:ignore()
  local p = {
    [1] = { list = true },
    [-1] = { required = true }
  }
  local args = {}

  handleError(self, "Liste positionnelle, dernier requis manquant", args, p, 'Paramètre requis « -1 » absent', { -1, m_params.MISSING_PARAM })
end

function tests:testListNamedLastMissing()
  tests:ignore()
  local p = {
    ["e"] = { list = true },
    ["e-1"] = { required = true }
  }
  local args = {}

  handleError(self, "Liste nommée, dernier requis manquant", args, p, 'Paramètre requis « e-1 » absent', { "e-1", m_params.MISSING_PARAM })
end

function tests:testListPositionalMaxLengthExceeded()
  tests:ignore()
  local p = {
    [1] = { list = true, max_length = 3 }
  }
  local args = {
    [1] = "test1",
    [2] = "test2",
    [3] = "test3",
    [4] = "test4",
  }

  handleError(self, "Liste positionnelle, taille max dépassée", args, p, 'Taille de la liste « 1 » dépassée (4 > 3)', { "1", m_params.LIST_SIZE_EXCEEDED })
end

function tests:testListNamedMaxLengthExceeded()
  tests:ignore()
  local p = {
    ["e"] = { list = true, max_length = 3 }
  }
  local args = {
    ["e1"] = "test1",
    ["e2"] = "test2",
    ["e3"] = "test3",
    ["e4"] = "test4",
  }

  handleError(self, "Liste nommée, taille max dépassée", args, p, 'Taille de la liste « e » dépassée (4 > 3)', { "e", m_params.LIST_SIZE_EXCEEDED })
end

function tests:testListPositionalDuplicates()
  tests:ignore()
  local p = {
    [1] = { list = true, no_duplicates = true }
  }
  local args = {
    [1] = "test1",
    [2] = "test1",
  }

  handleError(self, "Liste positionnelle, pas de doublons", args, p, 'Valeur en double dans la liste « 1 »', { "e", m_params.DUPLICATE_VALUE })
end

function tests:testListNamedDuplicates()
  tests:ignore()
  local p = {
    ["e"] = { list = true, no_duplicates = true }
  }
  local args = {
    ["e1"] = "test1",
    ["e2"] = "test1",
  }

  handleError(self, "Liste nommée, pas de doublons", args, p, 'Valeur en double dans la liste « e »', { "e", m_params.DUPLICATE_VALUE })
end

function tests:testEnumInvalidValue()
  local p = {
    [1] = { enum = { "a", "b" } }
  }
  local args = {
    [1] = "c"
  }

  handleError(self, "Énumération, valeur invalide", args, p, 'Valeur invalide pour le paramètre « 1 » ("c")', { 1, m_params.VALUE_NOT_IN_ENUM })
end

function tests:testEnumInvalidTypeNumber()
  local p = {
    [1] = { enum = { 1, 2 }, type = m_params.NUMBER }
  }
  local args = {
    [1] = "a"
  }

  handleError(self, "Énumération, valeur invalide, nombre", args, p, 'Valeur invalide pour le paramètre « 1 » ("a") de type nombre', { 1, m_params.INVALID_VALUE })
end

-- Internal errors --

function tests:testListPositionalArgOverlap()
  tests:ignore()
  local p = {
    [1] = { list = true },
    [2] = {}
  }
  local args = {
    [1] = "test1"
  }

  handleError(self, "Conflit paramètre et liste positionnelle", args, p, "Erreur interne : Paramètre « 2 » déjà défini par la liste « 1 »", { "e1", m_params.LIST_PARAM_OVERLAP })
end

function tests:testListNamedArgOverlap()
  tests:ignore()
  local p = {
    ["e"] = { list = true },
    ["e1"] = {}
  }
  local args = {
    ["e1"] = "test1"
  }

  handleError(self, "Conflit paramètre et liste nommée", args, p, "Erreur interne : Paramètre « e1 » déjà défini par la liste « e »", { "e1", m_params.LIST_PARAM_OVERLAP })
end

function tests:testUnknownType()
  local p = {
    [1] = { type = "test" }
  }
  local args = {
    [1] = "test"
  }

  handleError(self, "Type inconnu", args, p, 'Erreur interne : Type inconnu pour le paramètre « 1 » ("test")')
  handleError(self, "Type inconnu, pas args", {}, p, 'Erreur interne : Type inconnu pour le paramètre « 1 » ("test")')
end

function tests:testAliasToNonexistant()
  local p = {
    [1] = { alias_of = 2 }
  }
  local args = {
    [1] = "test"
  }

  handleError(self, "Alias vers non défini", args, p, "Erreur interne : Paramètre « 1 », alias vers un paramètre non défini « 2 »")
  handleError(self, "Alias vers non défini, pas args", {}, p, "Erreur interne : Paramètre « 1 », alias vers un paramètre non défini « 2 »")
end

function tests:testAliasToAlias()
  local p = {
    [1] = {},
    [2] = { alias_of = 1 },
    [3] = { alias_of = 2 }
  }
  local args = {
    [1] = "test"
  }

  handleError(self, "Alias vers alias", args, p, "Erreur interne : Paramètre « 3 », alias vers un autre alias (« 2 »)")
  handleError(self, "Alias vers alias, pas args", {}, p, "Erreur interne : Paramètre « 3 », alias vers un autre alias (« 2 »)")
end

function tests:testAliasToItself()
  local p = {
    [1] = { alias_of = 1 }
  }
  local args = {
    [1] = "test"
  }

  handleError(self, "Alias vers lui-même", args, p, "Erreur interne : Paramètre « 1 », alias vers lui-même")
  handleError(self, "Alias vers lui-même, pas args", {}, p, "Erreur interne : Paramètre « 1 », alias vers lui-même")
end

function tests:testEnumAndChecker()
  local p = {
    [1] = { enum = { "a", "b" }, checker = function(_)
      return true
    end }
  }
  local args = {
    [1] = "a"
  }

  handleError(self, "Énumération et checker", args, p, "Erreur interne : Le paramètre « 1 » est une énumération avec une précondition")
  handleError(self, "Énumération et checker, pas args", {}, p, "Erreur interne : Le paramètre « 1 » est une énumération avec une précondition")
end

function tests:testEnumInvalidValues()
  local p = {
    [1] = { enum = { 1, 2 } }
  }
  local args = {
    [1] = "a"
  }

  handleError(self, "Énumération, valeur invalide", args, p, 'Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("1") de type chaîne')
end

function tests:testEnumInvalidValuesNumber()
  local p = {
    [1] = { enum = { "a", "b" }, type = m_params.NUMBER }
  }
  local args = {
    [1] = "1"
  }

  handleError(self, "Énumération, valeur invalide, nombre", args, p, 'Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type nombre')
end

function tests:testEnumInvalidValuesInt()
  local p = {
    [1] = { enum = { "a", "b" }, type = m_params.INT }
  }
  local args = {
    [1] = "1"
  }

  handleError(self, "Énumération, valeur invalide, entier", args, p, 'Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type entier')
end

function tests:testEnumInvalidValuesFloat()
  local p = {
    [1] = { enum = { "a", "b" }, type = m_params.FLOAT }
  }
  local args = {
    [1] = "1.0"
  }

  handleError(self, "Énumération, valeur invalide, flottant", args, p, 'Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type flottant')
end

function tests:testEnumInvalidValuesBoolean()
  local p = {
    [1] = { enum = { "a", "b" }, type = m_params.BOOLEAN }
  }
  local args = {
    [1] = "vrai"
  }

  handleError(self, "Énumération, valeur invalide, booléen", args, p, 'Erreur interne : Valeur énumérée invalide pour le paramètre « 1 » ("a") de type booléen')
end

return tests