{ "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", "overview": "Lambdas are a special-cased data type for use in interpolations and\nsections.\n\nWhen used as the data value for an Interpolation tag, the lambda MUST be\ntreatable as an arity 0 function, and invoked as such. The returned value\nMUST be rendered against the default delimiters, then interpolated in place\nof the lambda.\n\nWhen used as the data value for a Section tag, the lambda MUST be treatable\nas an arity 1 function, and invoked as such (passing a String containing the\nunprocessed section contents). The returned value MUST be rendered against\nthe current delimiters, then interpolated in place of the section.\n", "tests": [ { "name": "Interpolation", "desc": "A lambda's return value should be interpolated.", "data": { "lambda": { "__tag__": "code", "ruby": "proc { \"world\" }", "raku": "sub { \"world\" }", "perl": "sub { \"world\" }", "js": "function() { return \"world\" }", "php": "return \"world\";", "python": "lambda: \"world\"", "clojure": "(fn [] \"world\")", "lisp": "(lambda () \"world\")", "pwsh": "\"world\"" } }, "template": "Hello, {{lambda}}!", "expected": "Hello, world!" }, { "name": "Interpolation - Expansion", "desc": "A lambda's return value should be parsed.", "data": { "planet": "world", "lambda": { "__tag__": "code", "ruby": "proc { \"{{planet}}\" }", "raku": "sub { q+{{planet}}+ }", "perl": "sub { \"{{planet}}\" }", "js": "function() { return \"{{planet}}\" }", "php": "return \"{{planet}}\";", "python": "lambda: \"{{planet}}\"", "clojure": "(fn [] \"{{planet}}\")", "lisp": "(lambda () \"{{planet}}\")", "pwsh": "\"{{planet}}\"" } }, "template": "Hello, {{lambda}}!", "expected": "Hello, world!" }, { "name": "Interpolation - Alternate Delimiters", "desc": "A lambda's return value should parse with the default delimiters.", "data": { "planet": "world", "lambda": { "__tag__": "code", "ruby": "proc { \"|planet| => {{planet}}\" }", "raku": "sub { q+|planet| => {{planet}}+ }", "perl": "sub { \"|planet| => {{planet}}\" }", "js": "function() { return \"|planet| => {{planet}}\" }", "php": "return \"|planet| => {{planet}}\";", "python": "lambda: \"|planet| => {{planet}}\"", "clojure": "(fn [] \"|planet| => {{planet}}\")", "lisp": "(lambda () \"|planet| => {{planet}}\")", "pwsh": "\"|planet| => {{planet}}\"" } }, "template": "{{= | | =}}\nHello, (|&lambda|)!", "expected": "Hello, (|planet| => world)!" }, { "name": "Interpolation - Multiple Calls", "desc": "Interpolated lambdas should not be cached.", "data": { "lambda": { "__tag__": "code", "ruby": "proc { $calls ||= 0; $calls += 1 }", "raku": "sub { state $calls += 1 }", "perl": "sub { no strict; $calls += 1 }", "js": "function() { return (g=(function(){return this})()).calls=(g.calls||0)+1 }", "php": "global $calls; return ++$calls;", "python": "lambda: globals().update(calls=globals().get(\"calls\",0)+1) or calls", "clojure": "(def g (atom 0)) (fn [] (swap! g inc))", "lisp": "(let ((g 0)) (lambda () (incf g)))", "pwsh": "if (($null -eq $script:calls) -or ($script:calls -ge 3)){$script:calls=0}; ++$script:calls; $script:calls" } }, "template": "{{lambda}} == {{{lambda}}} == {{lambda}}", "expected": "1 == 2 == 3" }, { "name": "Escaping", "desc": "Lambda results should be appropriately escaped.", "data": { "lambda": { "__tag__": "code", "ruby": "proc { \">\" }", "raku": "sub { \">\" }", "perl": "sub { \">\" }", "js": "function() { return \">\" }", "php": "return \">\";", "python": "lambda: \">\"", "clojure": "(fn [] \">\")", "lisp": "(lambda () \">\")", "pwsh": "\">\"" } }, "template": "<{{lambda}}{{{lambda}}}", "expected": "<>>" }, { "name": "Section", "desc": "Lambdas used for sections should receive the raw section string.", "data": { "x": "Error!", "lambda": { "__tag__": "code", "ruby": "proc { |text| text == \"{{x}}\" ? \"yes\" : \"no\" }", "raku": "sub { $^section eq q+{{x}}+ ?? \"yes\" !! \"no\" }", "perl": "sub { $_[0] eq \"{{x}}\" ? \"yes\" : \"no\" }", "js": "function(txt) { return (txt == \"{{x}}\" ? \"yes\" : \"no\") }", "php": "return ($text == \"{{x}}\") ? \"yes\" : \"no\";", "python": "lambda text: text == \"{{x}}\" and \"yes\" or \"no\"", "clojure": "(fn [text] (if (= text \"{{x}}\") \"yes\" \"no\"))", "lisp": "(lambda (text) (if (string= text \"{{x}}\") \"yes\" \"no\"))", "pwsh": "if ($args[0] -eq \"{{x}}\") {\"yes\"} else {\"no\"}" } }, "template": "<{{#lambda}}{{x}}{{/lambda}}>", "expected": "" }, { "name": "Section - Expansion", "desc": "Lambdas used for sections should have their results parsed.", "data": { "planet": "Earth", "lambda": { "__tag__": "code", "ruby": "proc { |text| \"#{text}{{planet}}#{text}\" }", "raku": "sub { $^section ~ q+{{planet}}+ ~ $^section }", "perl": "sub { $_[0] . \"{{planet}}\" . $_[0] }", "js": "function(txt) { return txt + \"{{planet}}\" + txt }", "php": "return $text . \"{{planet}}\" . $text;", "python": "lambda text: \"%s{{planet}}%s\" % (text, text)", "clojure": "(fn [text] (str text \"{{planet}}\" text))", "lisp": "(lambda (text) (format nil \"~a{{planet}}~a\" text text))", "pwsh": "\"$($args[0]){{planet}}$($args[0])\"" } }, "template": "<{{#lambda}}-{{/lambda}}>", "expected": "<-Earth->" }, { "name": "Section - Alternate Delimiters", "desc": "Lambdas used for sections should parse with the current delimiters.", "data": { "planet": "Earth", "lambda": { "__tag__": "code", "ruby": "proc { |text| \"#{text}{{planet}} => |planet|#{text}\" }", "raku": "sub { $^section ~ q+{{planet}} => |planet|+ ~ $^section }", "perl": "sub { $_[0] . \"{{planet}} => |planet|\" . $_[0] }", "js": "function(txt) { return txt + \"{{planet}} => |planet|\" + txt }", "php": "return $text . \"{{planet}} => |planet|\" . $text;", "python": "lambda text: \"%s{{planet}} => |planet|%s\" % (text, text)", "clojure": "(fn [text] (str text \"{{planet}} => |planet|\" text))", "lisp": "(lambda (text) (format nil \"~a{{planet}} => |planet|~a\" text text))", "pwsh": "\"$($args[0]){{planet}} => |planet|$($args[0])\"" } }, "template": "{{= | | =}}<|#lambda|-|/lambda|>", "expected": "<-{{planet}} => Earth->" }, { "name": "Section - Multiple Calls", "desc": "Lambdas used for sections should not be cached.", "data": { "lambda": { "__tag__": "code", "ruby": "proc { |text| \"__#{text}__\" }", "raku": "sub { \"__\" ~ $^section ~ \"__\" }", "perl": "sub { \"__\" . $_[0] . \"__\" }", "js": "function(txt) { return \"__\" + txt + \"__\" }", "php": "return \"__\" . $text . \"__\";", "python": "lambda text: \"__%s__\" % (text)", "clojure": "(fn [text] (str \"__\" text \"__\"))", "lisp": "(lambda (text) (format nil \"__~a__\" text))", "pwsh": "\"__$($args[0])__\"" } }, "template": "{{#lambda}}FILE{{/lambda}} != {{#lambda}}LINE{{/lambda}}", "expected": "__FILE__ != __LINE__" }, { "name": "Inverted Section", "desc": "Lambdas used for inverted sections should be considered truthy.", "data": { "static": "static", "lambda": { "__tag__": "code", "ruby": "proc { |text| false }", "raku": "sub { 0 }", "perl": "sub { 0 }", "js": "function(txt) { return false }", "php": "return false;", "python": "lambda text: 0", "clojure": "(fn [text] false)", "lisp": "(lambda (text) (declare (ignore text)) nil)", "pwsh": "$false" } }, "template": "<{{^lambda}}{{static}}{{/lambda}}>", "expected": "<>" } ] }