1overview: | 2 Lambdas are a special-cased data type for use in interpolations and 3 sections. 4 5 When used as the data value for an Interpolation tag, the lambda MUST be 6 treatable as an arity 0 function, and invoked as such. The returned value 7 MUST be rendered against the default delimiters, then interpolated in place 8 of the lambda. 9 10 When used as the data value for a Section tag, the lambda MUST be treatable 11 as an arity 1 function, and invoked as such (passing a String containing the 12 unprocessed section contents). The returned value MUST be rendered against 13 the current delimiters, then interpolated in place of the section. 14tests: 15 - name: Interpolation 16 desc: A lambda's return value should be interpolated. 17 data: 18 lambda: !code 19 ruby: 'proc { "world" }' 20 perl: 'sub { "world" }' 21 js: 'function() { return "world" }' 22 php: 'return "world";' 23 python: 'lambda: "world"' 24 template: "Hello, {{lambda}}!" 25 expected: "Hello, world!" 26 27 - name: Interpolation - Expansion 28 desc: A lambda's return value should be parsed. 29 data: 30 planet: "world" 31 lambda: !code 32 ruby: 'proc { "{{planet}}" }' 33 perl: 'sub { "{{planet}}" }' 34 js: 'function() { return "{{planet}}" }' 35 php: 'return "{{planet}}";' 36 python: 'lambda: "{{planet}}"' 37 template: "Hello, {{lambda}}!" 38 expected: "Hello, world!" 39 40 - name: Interpolation - Alternate Delimiters 41 desc: A lambda's return value should parse with the default delimiters. 42 data: 43 planet: "world" 44 lambda: !code 45 ruby: 'proc { "|planet| => {{planet}}" }' 46 perl: 'sub { "|planet| => {{planet}}" }' 47 js: 'function() { return "|planet| => {{planet}}" }' 48 php: 'return "|planet| => {{planet}}";' 49 python: 'lambda: "|planet| => {{planet}}"' 50 template: "{{= | | =}}\nHello, (|&lambda|)!" 51 expected: "Hello, (|planet| => world)!" 52 53 - name: Interpolation - Multiple Calls 54 desc: Interpolated lambdas should not be cached. 55 data: 56 lambda: !code 57 ruby: 'proc { $calls ||= 0; $calls += 1 }' 58 perl: 'sub { no strict; $calls += 1 }' 59 js: 'function() { return (g=(function(){return this})()).calls=(g.calls||0)+1 }' 60 php: 'global $calls; return ++$calls;' 61 python: 'lambda: globals().update(calls=globals().get("calls",0)+1) or calls' 62 template: '{{lambda}} == {{{lambda}}} == {{lambda}}' 63 expected: '1 == 2 == 3' 64 65 - name: Escaping 66 desc: Lambda results should be appropriately escaped. 67 data: 68 lambda: !code 69 ruby: 'proc { ">" }' 70 perl: 'sub { ">" }' 71 js: 'function() { return ">" }' 72 php: 'return ">";' 73 python: 'lambda: ">"' 74 template: "<{{lambda}}{{{lambda}}}" 75 expected: "<>>" 76 77 - name: Section 78 desc: Lambdas used for sections should receive the raw section string. 79 data: 80 x: 'Error!' 81 lambda: !code 82 ruby: 'proc { |text| text == "{{x}}" ? "yes" : "no" }' 83 perl: 'sub { $_[0] eq "{{x}}" ? "yes" : "no" }' 84 js: 'function(txt) { return (txt == "{{x}}" ? "yes" : "no") }' 85 php: 'return ($text == "{{x}}") ? "yes" : "no";' 86 python: 'lambda text: text == "{{x}}" and "yes" or "no"' 87 template: "<{{#lambda}}{{x}}{{/lambda}}>" 88 expected: "<yes>" 89 90 - name: Section - Expansion 91 desc: Lambdas used for sections should have their results parsed. 92 data: 93 planet: "Earth" 94 lambda: !code 95 ruby: 'proc { |text| "#{text}{{planet}}#{text}" }' 96 perl: 'sub { $_[0] . "{{planet}}" . $_[0] }' 97 js: 'function(txt) { return txt + "{{planet}}" + txt }' 98 php: 'return $text . "{{planet}}" . $text;' 99 python: 'lambda text: "%s{{planet}}%s" % (text, text)' 100 template: "<{{#lambda}}-{{/lambda}}>" 101 expected: "<-Earth->" 102 103 - name: Section - Alternate Delimiters 104 desc: Lambdas used for sections should parse with the current delimiters. 105 data: 106 planet: "Earth" 107 lambda: !code 108 ruby: 'proc { |text| "#{text}{{planet}} => |planet|#{text}" }' 109 perl: 'sub { $_[0] . "{{planet}} => |planet|" . $_[0] }' 110 js: 'function(txt) { return txt + "{{planet}} => |planet|" + txt }' 111 php: 'return $text . "{{planet}} => |planet|" . $text;' 112 python: 'lambda text: "%s{{planet}} => |planet|%s" % (text, text)' 113 template: "{{= | | =}}<|#lambda|-|/lambda|>" 114 expected: "<-{{planet}} => Earth->" 115 116 - name: Section - Multiple Calls 117 desc: Lambdas used for sections should not be cached. 118 data: 119 lambda: !code 120 ruby: 'proc { |text| "__#{text}__" }' 121 perl: 'sub { "__" . $_[0] . "__" }' 122 js: 'function(txt) { return "__" + txt + "__" }' 123 php: 'return "__" . $text . "__";' 124 python: 'lambda text: "__%s__" % (text)' 125 template: '{{#lambda}}FILE{{/lambda}} != {{#lambda}}LINE{{/lambda}}' 126 expected: '__FILE__ != __LINE__' 127 128 - name: Inverted Section 129 desc: Lambdas used for inverted sections should be considered truthy. 130 data: 131 static: 'static' 132 lambda: !code 133 ruby: 'proc { |text| false }' 134 perl: 'sub { 0 }' 135 js: 'function(txt) { return false }' 136 php: 'return false;' 137 python: 'lambda text: 0' 138 template: "<{{^lambda}}{{static}}{{/lambda}}>" 139 expected: "<>" 140