interpolation.yml 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. overview: |
  2. Interpolation tags are used to integrate dynamic content into the template.
  3. The tag's content MUST be a non-whitespace character sequence NOT containing
  4. the current closing delimiter.
  5. This tag's content names the data to replace the tag. A single period (`.`)
  6. indicates that the item currently sitting atop the context stack should be
  7. used; otherwise, name resolution is as follows:
  8. 1) Split the name on periods; the first part is the name to resolve, any
  9. remaining parts should be retained.
  10. 2) Walk the context stack from top to bottom, finding the first context
  11. that is a) a hash containing the name as a key OR b) an object responding
  12. to a method with the given name.
  13. 3) If the context is a hash, the data is the value associated with the
  14. name.
  15. 4) If the context is an object, the data is the value returned by the
  16. method with the given name.
  17. 5) If any name parts were retained in step 1, each should be resolved
  18. against a context stack containing only the result from the former
  19. resolution. If any part fails resolution, the result should be considered
  20. falsey, and should interpolate as the empty string.
  21. Data should be coerced into a string (and escaped, if appropriate) before
  22. interpolation.
  23. The Interpolation tags MUST NOT be treated as standalone.
  24. tests:
  25. - name: No Interpolation
  26. desc: Mustache-free templates should render as-is.
  27. data: { }
  28. template: |
  29. Hello from {Mustache}!
  30. expected: |
  31. Hello from {Mustache}!
  32. - name: Basic Interpolation
  33. desc: Unadorned tags should interpolate content into the template.
  34. data: { subject: "world" }
  35. template: |
  36. Hello, {{subject}}!
  37. expected: |
  38. Hello, world!
  39. - name: HTML Escaping
  40. desc: Basic interpolation should be HTML escaped.
  41. data: { forbidden: '& " < >' }
  42. template: |
  43. These characters should be HTML escaped: {{forbidden}}
  44. expected: |
  45. These characters should be HTML escaped: &amp; &quot; &lt; &gt;
  46. - name: Triple Mustache
  47. desc: Triple mustaches should interpolate without HTML escaping.
  48. data: { forbidden: '& " < >' }
  49. template: |
  50. These characters should not be HTML escaped: {{{forbidden}}}
  51. expected: |
  52. These characters should not be HTML escaped: & " < >
  53. - name: Ampersand
  54. desc: Ampersand should interpolate without HTML escaping.
  55. data: { forbidden: '& " < >' }
  56. template: |
  57. These characters should not be HTML escaped: {{&forbidden}}
  58. expected: |
  59. These characters should not be HTML escaped: & " < >
  60. - name: Basic Integer Interpolation
  61. desc: Integers should interpolate seamlessly.
  62. data: { mph: 85 }
  63. template: '"{{mph}} miles an hour!"'
  64. expected: '"85 miles an hour!"'
  65. - name: Triple Mustache Integer Interpolation
  66. desc: Integers should interpolate seamlessly.
  67. data: { mph: 85 }
  68. template: '"{{{mph}}} miles an hour!"'
  69. expected: '"85 miles an hour!"'
  70. - name: Ampersand Integer Interpolation
  71. desc: Integers should interpolate seamlessly.
  72. data: { mph: 85 }
  73. template: '"{{&mph}} miles an hour!"'
  74. expected: '"85 miles an hour!"'
  75. - name: Basic Decimal Interpolation
  76. desc: Decimals should interpolate seamlessly with proper significance.
  77. data: { power: 1.210 }
  78. template: '"{{power}} jiggawatts!"'
  79. expected: '"1.21 jiggawatts!"'
  80. - name: Triple Mustache Decimal Interpolation
  81. desc: Decimals should interpolate seamlessly with proper significance.
  82. data: { power: 1.210 }
  83. template: '"{{{power}}} jiggawatts!"'
  84. expected: '"1.21 jiggawatts!"'
  85. - name: Ampersand Decimal Interpolation
  86. desc: Decimals should interpolate seamlessly with proper significance.
  87. data: { power: 1.210 }
  88. template: '"{{&power}} jiggawatts!"'
  89. expected: '"1.21 jiggawatts!"'
  90. # Context Misses
  91. - name: Basic Context Miss Interpolation
  92. desc: Failed context lookups should default to empty strings.
  93. data: { }
  94. template: "I ({{cannot}}) be seen!"
  95. expected: "I () be seen!"
  96. - name: Triple Mustache Context Miss Interpolation
  97. desc: Failed context lookups should default to empty strings.
  98. data: { }
  99. template: "I ({{{cannot}}}) be seen!"
  100. expected: "I () be seen!"
  101. - name: Ampersand Context Miss Interpolation
  102. desc: Failed context lookups should default to empty strings.
  103. data: { }
  104. template: "I ({{&cannot}}) be seen!"
  105. expected: "I () be seen!"
  106. # Dotted Names
  107. - name: Dotted Names - Basic Interpolation
  108. desc: Dotted names should be considered a form of shorthand for sections.
  109. data: { person: { name: 'Joe' } }
  110. template: '"{{person.name}}" == "{{#person}}{{name}}{{/person}}"'
  111. expected: '"Joe" == "Joe"'
  112. - name: Dotted Names - Triple Mustache Interpolation
  113. desc: Dotted names should be considered a form of shorthand for sections.
  114. data: { person: { name: 'Joe' } }
  115. template: '"{{{person.name}}}" == "{{#person}}{{{name}}}{{/person}}"'
  116. expected: '"Joe" == "Joe"'
  117. - name: Dotted Names - Ampersand Interpolation
  118. desc: Dotted names should be considered a form of shorthand for sections.
  119. data: { person: { name: 'Joe' } }
  120. template: '"{{&person.name}}" == "{{#person}}{{&name}}{{/person}}"'
  121. expected: '"Joe" == "Joe"'
  122. - name: Dotted Names - Arbitrary Depth
  123. desc: Dotted names should be functional to any level of nesting.
  124. data:
  125. a: { b: { c: { d: { e: { name: 'Phil' } } } } }
  126. template: '"{{a.b.c.d.e.name}}" == "Phil"'
  127. expected: '"Phil" == "Phil"'
  128. - name: Dotted Names - Broken Chains
  129. desc: Any falsey value prior to the last part of the name should yield ''.
  130. data:
  131. a: { }
  132. template: '"{{a.b.c}}" == ""'
  133. expected: '"" == ""'
  134. - name: Dotted Names - Broken Chain Resolution
  135. desc: Each part of a dotted name should resolve only against its parent.
  136. data:
  137. a: { b: { } }
  138. c: { name: 'Jim' }
  139. template: '"{{a.b.c.name}}" == ""'
  140. expected: '"" == ""'
  141. - name: Dotted Names - Initial Resolution
  142. desc: The first part of a dotted name should resolve as any other name.
  143. data:
  144. a: { b: { c: { d: { e: { name: 'Phil' } } } } }
  145. b: { c: { d: { e: { name: 'Wrong' } } } }
  146. template: '"{{#a}}{{b.c.d.e.name}}{{/a}}" == "Phil"'
  147. expected: '"Phil" == "Phil"'
  148. - name: Dotted Names - Context Precedence
  149. desc: Dotted names should be resolved against former resolutions.
  150. data:
  151. a: { b: { } }
  152. b: { c: 'ERROR' }
  153. template: '{{#a}}{{b.c}}{{/a}}'
  154. expected: ''
  155. # Whitespace Sensitivity
  156. - name: Interpolation - Surrounding Whitespace
  157. desc: Interpolation should not alter surrounding whitespace.
  158. data: { string: '---' }
  159. template: '| {{string}} |'
  160. expected: '| --- |'
  161. - name: Triple Mustache - Surrounding Whitespace
  162. desc: Interpolation should not alter surrounding whitespace.
  163. data: { string: '---' }
  164. template: '| {{{string}}} |'
  165. expected: '| --- |'
  166. - name: Ampersand - Surrounding Whitespace
  167. desc: Interpolation should not alter surrounding whitespace.
  168. data: { string: '---' }
  169. template: '| {{&string}} |'
  170. expected: '| --- |'
  171. - name: Interpolation - Standalone
  172. desc: Standalone interpolation should not alter surrounding whitespace.
  173. data: { string: '---' }
  174. template: " {{string}}\n"
  175. expected: " ---\n"
  176. - name: Triple Mustache - Standalone
  177. desc: Standalone interpolation should not alter surrounding whitespace.
  178. data: { string: '---' }
  179. template: " {{{string}}}\n"
  180. expected: " ---\n"
  181. - name: Ampersand - Standalone
  182. desc: Standalone interpolation should not alter surrounding whitespace.
  183. data: { string: '---' }
  184. template: " {{&string}}\n"
  185. expected: " ---\n"
  186. # Whitespace Insensitivity
  187. - name: Interpolation With Padding
  188. desc: Superfluous in-tag whitespace should be ignored.
  189. data: { string: "---" }
  190. template: '|{{ string }}|'
  191. expected: '|---|'
  192. - name: Triple Mustache With Padding
  193. desc: Superfluous in-tag whitespace should be ignored.
  194. data: { string: "---" }
  195. template: '|{{{ string }}}|'
  196. expected: '|---|'
  197. - name: Ampersand With Padding
  198. desc: Superfluous in-tag whitespace should be ignored.
  199. data: { string: "---" }
  200. template: '|{{& string }}|'
  201. expected: '|---|'