Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-environment

Environment files for Pudu: load .env variables safely with layered files, discovery, expansion, typed reads, and secrets kept out of every message

0.1.0Apache-2.01

InstallClose

OptionsTest.pudu

Pudu56 lines4.5 KB

GitHub ↗
1/** @Test.Options.Suite — defaults, conflicts, and the fluent chain */2module PuduLangEnvironment.OptionsTest34import Std.Io as Io5import Std.Test as Test6import PuduLangEnvironment.Domain.Encoding as Encoding7import PuduLangEnvironment.Options as Options8import PuduLangEnvironment.Source as Source910/// Runs the suite.11fn main() -> Int {12  let base = Options.defaults()13  let chained = base.withStrict().withTrimValues().withoutOverwrite().withExportSyntax().withoutInlineComments().withExpansion().withEncoding(Encoding.Latin1).inDirectory("conf")14  let undone = chained.withoutStrict().withoutTrimValues().withOverwrite().withoutExportSyntax().withInlineComments().withoutExpansion().withEncoding(Encoding.Utf8).inDirectory(".")15  let sources = [Source.Text("inline", "A=1")]16  let checks = Test.suite("Options", &[17      Test.equals("defaults are lenient and read .env", &(base.strict, base.files, base.directory), &(false, [".env"], ".")),18      Test.equals("defaults overwrite and read inline comments only", &(base.overwrite, base.inlineComments, base.trimValues, base.exportSyntax, base.expansion), &(true, true, false, false, false)),19      Test.equals("defaults do not probe or cascade", &(base.probe, base.cascade, base.environmentName, base.sources.isEmpty()), &(None, false, None, true)),20      Test.equals("defaults are valid", &Options.validate(&base), &[]),21      Test.equals("the chain sets every flag", &(chained.strict, chained.trimValues, chained.overwrite, chained.exportSyntax, chained.inlineComments, chained.expansion, chained.directory), &(true, true, false, true, false, true, "conf")),22      Test.equals("the chain sets the encoding", &chained.encoding, &Encoding.Latin1),23      Test.equals("the chain undoes every flag", &undone, &base),24      Test.equals("files are kept in order", &base.withFiles(&["a.env", "b.env"]).files, &["a.env", "b.env"]),25      Test.equals("no files means .env", &base.withFiles(&["x"]).withFiles(&[]).files, &[".env"]),26      Test.equals("probing uses four levels by default", &base.withProbe().probe, &Some(4)),27      Test.equals("probing levels may be set", &base.withProbeLevels(2).probe, &Some(2)),28      Test.equals("probing may be turned off", &base.withProbe().withoutProbe().probe, &None),29      Test.equals("the cascade may be turned on and off", &(base.withCascade().cascade, base.withCascade().withoutCascade().cascade), &(true, false)),30      Test.equals("naming an environment turns the cascade on", &(base.withEnvironment("test").cascade, base.withEnvironment("test").environmentName), &(true, Some("test"))),31      Test.equals("sources are kept", &base.withSources(&sources).sources, &sources),32      Test.equals("files with probing are refused", &Options.validate(&base.withFiles(&["a"]).withProbe()), &["files cannot be given while probing"]),33      Test.equals("files with the cascade are refused", &Options.validate(&base.withFiles(&["a"]).withCascade()), &["files cannot be given with the environment cascade"]),34      Test.equals("sources with files are refused", &Options.validate(&base.withFiles(&["a"]).withSources(&sources)), &["sources and files cannot both be given"]),35      Test.equals("sources with probing are refused", &Options.validate(&base.withSources(&sources).withProbe()), &["sources cannot be given while probing"]),36      Test.equals("sources with the cascade are refused", &Options.validate(&base.withSources(&sources).withCascade()), &["sources cannot be given with the environment cascade"]),37      Test.equals("negative probe levels are refused", &Options.validate(&base.withProbeLevels(-1)), &["probe levels must not be negative"]),38      Test.equals("zero probe levels are accepted", &Options.validate(&base.withProbeLevels(0)), &[]),39      Test.equals("an empty file list is refused", &Options.validate(&Options.Options{..base, files: []}), &["files must name at least one file"]),40      Test.equals("the default file combines with probing and the cascade", &Options.validate(&base.withProbe().withCascade()), &[]),41      Test.equals("every conflict is reported at once", &Options.validate(&base.withFiles(&["a"]).withSources(&sources).withProbeLevels(-2).withCascade()), &[42          "files cannot be given while probing",43          "files cannot be given with the environment cascade",44          "sources and files cannot both be given",45          "sources cannot be given while probing",46          "sources cannot be given with the environment cascade",47          "probe levels must not be negative"48        ])49    ])50  let ran = Test.run(&checks)51  for failure in Test.failuresOf(&ran) {52    let _reported = Io.writeErrorLine(failure)53  }54  Test.report(&ran)55}56