1{ 2 "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", 3 "tests": [ 4 { 5 "expected": "Hello, world!", 6 "data": { 7 "lambda": { 8 "python": "lambda: \"world\"", 9 "perl": "sub { \"world\" }", 10 "php": "return \"world\";", 11 "ruby": "proc { \"world\" }", 12 "js": "function() { return \"world\" }" 13 "R": "function() { \"world\" }" 14 } 15 }, 16 "name": "Interpolation", 17 "template": "Hello, {{lambda}}!", 18 "desc": "A lambda's return value should be interpolated." 19 }, 20 { 21 "expected": "Hello, world!", 22 "data": { 23 "planet": "world", 24 "lambda": { 25 "python": "lambda: \"{{planet}}\"", 26 "perl": "sub { \"{{planet}}\" }", 27 "php": "return \"{{planet}}\";", 28 "ruby": "proc { \"{{planet}}\" }", 29 "js": "function() { return \"{{planet}}\" }" 30 "R": "function() { \"{{planet}}\" }" 31 } 32 }, 33 "name": "Interpolation - Expansion", 34 "template": "Hello, {{lambda}}!", 35 "desc": "A lambda's return value should be parsed." 36 }, 37 { 38 "expected": "Hello, (|planet| => world)!", 39 "data": { 40 "planet": "world", 41 "lambda": { 42 "python": "lambda: \"|planet| => {{planet}}\"", 43 "perl": "sub { \"|planet| => {{planet}}\" }", 44 "php": "return \"|planet| => {{planet}}\";", 45 "ruby": "proc { \"|planet| => {{planet}}\" }", 46 "js": "function() { return \"|planet| => {{planet}}\" }" 47 "R": "function() { \"|planet| => {{planet}}\" }" 48 } 49 }, 50 "name": "Interpolation - Alternate Delimiters", 51 "template": "{{= | | =}}\nHello, (|&lambda|)!", 52 "desc": "A lambda's return value should parse with the default delimiters." 53 }, 54 { 55 "expected": "1 == 2 == 3", 56 "data": { 57 "lambda": { 58 "python": "lambda: globals().update(calls=globals().get(\"calls\",0)+1) or calls", 59 "perl": "sub { no strict; $calls += 1 }", 60 "php": "global $calls; return ++$calls;", 61 "ruby": "proc { $calls ||= 0; $calls += 1 }", 62 "js": "function() { return (g=(function(){return this})()).calls=(g.calls||0)+1 }" 63 "R": "function(){if (!exists(\"x\")) x <<- 0; x <<- x + 1; x}" 64 } 65 }, 66 "name": "Interpolation - Multiple Calls", 67 "template": "{{lambda}} == {{{lambda}}} == {{lambda}}", 68 "desc": "Interpolated lambdas should not be cached." 69 }, 70 { 71 "expected": "<>>", 72 "data": { 73 "lambda": { 74 "python": "lambda: \">\"", 75 "perl": "sub { \">\" }", 76 "php": "return \">\";", 77 "ruby": "proc { \">\" }", 78 "js": "function() { return \">\" }" 79 "R": "function() { \">\"}" 80 } 81 }, 82 "name": "Escaping", 83 "template": "<{{lambda}}{{{lambda}}}", 84 "desc": "Lambda results should be appropriately escaped." 85 }, 86 { 87 "expected": "<yes>", 88 "data": { 89 "x": "Error!", 90 "lambda": { 91 "python": "lambda text: text == \"{{x}}\" and \"yes\" or \"no\"", 92 "perl": "sub { $_[0] eq \"{{x}}\" ? \"yes\" : \"no\" }", 93 "php": "return ($text == \"{{x}}\") ? \"yes\" : \"no\";", 94 "ruby": "proc { |text| text == \"{{x}}\" ? \"yes\" : \"no\" }", 95 "js": "function(txt) { return (txt == \"{{x}}\" ? \"yes\" : \"no\") }" 96 "R": "function(txt) { ifelse(txt == \"{{x}}\",\"yes\",\"no\") }" 97 } 98 }, 99 "name": "Section", 100 "template": "<{{#lambda}}{{x}}{{/lambda}}>", 101 "desc": "Lambdas used for sections should receive the raw section string." 102 }, 103 { 104 "expected": "<-Earth->", 105 "data": { 106 "planet": "Earth", 107 "lambda": { 108 "python": "lambda text: \"%s{{planet}}%s\" % (text, text)", 109 "perl": "sub { $_[0] . \"{{planet}}\" . $_[0] }", 110 "php": "return $text . \"{{planet}}\" . $text;", 111 "ruby": "proc { |text| \"#{text}{{planet}}#{text}\" }", 112 "js": "function(txt) { return txt + \"{{planet}}\" + txt }" 113 "R": "function(txt) { paste(txt, \"{{planet}}\", txt, sep=\"\"}" 114 } 115 }, 116 "name": "Section - Expansion", 117 "template": "<{{#lambda}}-{{/lambda}}>", 118 "desc": "Lambdas used for sections should have their results parsed." 119 }, 120 { 121 "expected": "<-{{planet}} => Earth->", 122 "data": { 123 "planet": "Earth", 124 "lambda": { 125 "python": "lambda text: \"%s{{planet}} => |planet|%s\" % (text, text)", 126 "perl": "sub { $_[0] . \"{{planet}} => |planet|\" . $_[0] }", 127 "php": "return $text . \"{{planet}} => |planet|\" . $text;", 128 "ruby": "proc { |text| \"#{text}{{planet}} => |planet|#{text}\" }", 129 "js": "function(txt) { return txt + \"{{planet}} => |planet|\" + txt }" 130 } 131 }, 132 "name": "Section - Alternate Delimiters", 133 "template": "{{= | | =}}<|#lambda|-|/lambda|>", 134 "desc": "Lambdas used for sections should parse with the current delimiters." 135 }, 136 { 137 "expected": "__FILE__ != __LINE__", 138 "data": { 139 "lambda": { 140 "python": "lambda text: \"__%s__\" % (text)", 141 "perl": "sub { \"__\" . $_[0] . \"__\" }", 142 "php": "return \"__\" . $text . \"__\";", 143 "ruby": "proc { |text| \"__#{text}__\" }", 144 "js": "function(txt) { return \"__\" + txt + \"__\" }" 145 } 146 }, 147 "name": "Section - Multiple Calls", 148 "template": "{{#lambda}}FILE{{/lambda}} != {{#lambda}}LINE{{/lambda}}", 149 "desc": "Lambdas used for sections should not be cached." 150 }, 151 { 152 "expected": "<>", 153 "data": { 154 "static": "static", 155 "lambda": { 156 "python": "lambda text: 0", 157 "perl": "sub { 0 }", 158 "php": "return false;", 159 "ruby": "proc { |text| false }", 160 "js": "function(txt) { return false }" 161 } 162 }, 163 "name": "Inverted Section", 164 "template": "<{{^lambda}}{{static}}{{/lambda}}>", 165 "desc": "Lambdas used for inverted sections should be considered truthy." 166 } 167 ] 168}