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

ExpanderTest.pudu

Pudu67 lines4.6 KB

GitHub ↗
1/** @Test.Domain.Expander.Suite — references to other variables */2module PuduLangEnvironment.Domain.ExpanderTest34import Std.Io as Io5import Std.Map as Map6import Std.Test as Test7import PuduLangEnvironment.Domain.Expander as Expander89/// The value expanded over fixed known and process values.10fn expanded(value: Str) -> Str {11  let known = Map.fromPairs(&[("NAME", "pudu"), ("EMPTY", ""), ("PATHY", "a$NAME")])12  let process = Map.fromPairs(&[("HOME", "/home/me"), ("NAME", "shell"), ("BLANK", "")])13  Expander.expand(value, &known, &process)14}1516/// Runs the suite.17fn main() -> Int {18  let checks = Test.suite("Domain.Expander", &[19      Test.equals("text without references is unchanged", &expanded("plain text"), &"plain text"),20      Test.equals("a bare reference is replaced", &expanded("$NAME"), &"pudu"),21      Test.equals("a braced reference is replaced", &expanded("$\{NAME\}!"), &"pudu!"),22      Test.equals("a bare name ends at the first character that cannot continue it", &expanded("$NAME-x $NAME.y"), &"pudu-x pudu.y"),23      Test.equals("a bare name takes digits and underscores", &expanded("$HOME_2"), &""),24      Test.equals("a bare name may start with an underscore", &expanded("$_X|"), &"|"),25      Test.equals("known values come before the process", &expanded("$NAME"), &"pudu"),26      Test.equals("the process answers unknown names", &expanded("$HOME/bin"), &"/home/me/bin"),27      Test.equals("an unknown name answers nothing", &expanded("[$MISSING]"), &"[]"),28      Test.equals("an answered value is not expanded again", &expanded("$PATHY"), &"a$NAME"),29      Test.equals("a $ before a digit is literal", &expanded("$1"), &"$1"),30      Test.equals("a $ before punctuation is literal", &expanded("cost $-5"), &"cost $-5"),31      Test.equals("a trailing $ is literal", &expanded("a$"), &"a$"),32      Test.equals("an unclosed brace leaves $ literal", &expanded("$\{NAME"), &"$\{NAME"),33      Test.equals("an unclosed brace keeps reading after it", &expanded("$\{x $NAME"), &"$\{x pudu"),34      Test.equals("a name inside braces is trimmed", &expanded("$\{ NAME \}"), &"pudu"),35      Test.equals(":- answers the default when unset", &expanded("$\{MISSING:-fallback\}"), &"fallback"),36      Test.equals(":- answers the default when empty", &expanded("$\{EMPTY:-fallback\}"), &"fallback"),37      Test.equals(":- answers the default when the process value is empty", &expanded("$\{BLANK:-fallback\}"), &"fallback"),38      Test.equals(":- answers the value when set", &expanded("$\{NAME:-fallback\}"), &"pudu"),39      Test.equals("- answers the default when unset", &expanded("$\{MISSING-fallback\}"), &"fallback"),40      Test.equals("- answers the empty value when set but empty", &expanded("[$\{EMPTY-fallback\}]"), &"[]"),41      Test.equals("- answers the value when set", &expanded("$\{NAME-fallback\}"), &"pudu"),42      Test.equals("a default is expanded", &expanded("$\{MISSING:-$HOME/x\}"), &"/home/me/x"),43      Test.equals("a default may hold a braced reference", &expanded("$\{MISSING:-$\{NAME\}\}"), &"pudu"),44      Test.equals("a default may be empty", &expanded("[$\{MISSING:-\}]"), &"[]"),45      Test.equals("a default keeps its spaces", &expanded("$\{MISSING:- a b \}"), &" a b "),46      Test.equals("an operator inside nested braces is not the operator", &expanded("$\{MISSING:-$\{A-b\}\}"), &"b"),47      Test.equals("a default holding a colon is kept whole", &expanded("$\{MISSING:-http://x\}"), &"http://x"),48      Test.equals("an empty name answers the default", &expanded("$\{:-d\}$\{-e\}"), &"de"),49      Test.equals("an empty name without a default answers nothing", &expanded("[$\{\}]"), &"[]"),50      Test.equals("an operator after nested braces is the operator", &expanded("[$\{X\{-\}:-d\}]"), &"[d]"),51      Test.equals("a trailing colon is part of the name", &expanded("[$\{NAME:\}]"), &"[]"),52      Test.equals("a colon alone is part of the name", &expanded("[$\{NAME:x\}]"), &"[]"),53      Test.equals("one backslash makes $ literal", &expanded("\\$NAME"), &"$NAME"),54      Test.equals("two backslashes are halved and the reference expands", &expanded("\\\\$NAME"), &"\\pudu"),55      Test.equals("three backslashes keep one and make $ literal", &expanded("\\\\\\$NAME"), &"\\$NAME"),56      Test.equals("four backslashes are halved", &expanded("\\\\\\\\$NAME"), &"\\\\pudu"),57      Test.equals("backslashes not before $ are kept", &expanded("a\\\\b\\c"), &"a\\\\b\\c"),58      Test.equals("trailing backslashes are kept", &expanded("x\\\\"), &"x\\\\"),59      Test.equals("non-ASCII text is kept", &expanded("ñandú $NAME é"), &"ñandú pudu é")60    ])61  let ran = Test.run(&checks)62  for failure in Test.failuresOf(&ran) {63    let _reported = Io.writeErrorLine(failure)64  }65  Test.report(&ran)66}67