aboutsummaryrefslogtreecommitdiffstats
path: root/tests/template/sections.yml
diff options
context:
space:
mode:
Diffstat (limited to 'tests/template/sections.yml')
-rw-r--r--tests/template/sections.yml256
1 files changed, 256 insertions, 0 deletions
diff --git a/tests/template/sections.yml b/tests/template/sections.yml
new file mode 100644
index 0000000..f62d9cb
--- /dev/null
+++ b/tests/template/sections.yml
@@ -0,0 +1,256 @@
+overview: |
+ Section tags and End Section tags are used in combination to wrap a section
+ of the template for iteration
+
+ These tags' content MUST be a non-whitespace character sequence NOT
+ containing the current closing delimiter; each Section tag MUST be followed
+ by an End Section tag with the same content within the same section.
+
+ This tag's content names the data to replace the tag. Name resolution is as
+ follows:
+ 1) Split the name on periods; the first part is the name to resolve, any
+ remaining parts should be retained.
+ 2) Walk the context stack from top to bottom, finding the first context
+ that is a) a hash containing the name as a key OR b) an object responding
+ to a method with the given name.
+ 3) If the context is a hash, the data is the value associated with the
+ name.
+ 4) If the context is an object and the method with the given name has an
+ arity of 1, the method SHOULD be called with a String containing the
+ unprocessed contents of the sections; the data is the value returned.
+ 5) Otherwise, the data is the value returned by calling the method with
+ the given name.
+ 6) If any name parts were retained in step 1, each should be resolved
+ against a context stack containing only the result from the former
+ resolution. If any part fails resolution, the result should be considered
+ falsey, and should interpolate as the empty string.
+ If the data is not of a list type, it is coerced into a list as follows: if
+ the data is truthy (e.g. `!!data == true`), use a single-element list
+ containing the data, otherwise use an empty list.
+
+ For each element in the data list, the element MUST be pushed onto the
+ context stack, the section MUST be rendered, and the element MUST be popped
+ off the context stack.
+
+ Section and End Section tags SHOULD be treated as standalone when
+ appropriate.
+tests:
+ - name: Truthy
+ desc: Truthy sections should have their contents rendered.
+ data: { boolean: true }
+ template: '"{{#boolean}}This should be rendered.{{/boolean}}"'
+ expected: '"This should be rendered."'
+
+ - name: Falsey
+ desc: Falsey sections should have their contents omitted.
+ data: { boolean: false }
+ template: '"{{#boolean}}This should not be rendered.{{/boolean}}"'
+ expected: '""'
+
+ - name: Context
+ desc: Objects and hashes should be pushed onto the context stack.
+ data: { context: { name: 'Joe' } }
+ template: '"{{#context}}Hi {{name}}.{{/context}}"'
+ expected: '"Hi Joe."'
+
+ - name: Deeply Nested Contexts
+ desc: All elements on the context stack should be accessible.
+ data:
+ a: { one: 1 }
+ b: { two: 2 }
+ c: { three: 3 }
+ d: { four: 4 }
+ e: { five: 5 }
+ template: |
+ {{#a}}
+ {{one}}
+ {{#b}}
+ {{one}}{{two}}{{one}}
+ {{#c}}
+ {{one}}{{two}}{{three}}{{two}}{{one}}
+ {{#d}}
+ {{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
+ {{#e}}
+ {{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}
+ {{/e}}
+ {{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
+ {{/d}}
+ {{one}}{{two}}{{three}}{{two}}{{one}}
+ {{/c}}
+ {{one}}{{two}}{{one}}
+ {{/b}}
+ {{one}}
+ {{/a}}
+ expected: |
+ 1
+ 121
+ 12321
+ 1234321
+ 123454321
+ 1234321
+ 12321
+ 121
+ 1
+
+ - name: List
+ desc: Lists should be iterated; list items should visit the context stack.
+ data: { list: [ { item: 1 }, { item: 2 }, { item: 3 } ] }
+ template: '"{{#list}}{{item}}{{/list}}"'
+ expected: '"123"'
+
+ - name: Empty List
+ desc: Empty lists should behave like falsey values.
+ data: { list: [ ] }
+ template: '"{{#list}}Yay lists!{{/list}}"'
+ expected: '""'
+
+ - name: Doubled
+ desc: Multiple sections per template should be permitted.
+ data: { bool: true, two: 'second' }
+ template: |
+ {{#bool}}
+ * first
+ {{/bool}}
+ * {{two}}
+ {{#bool}}
+ * third
+ {{/bool}}
+ expected: |
+ * first
+ * second
+ * third
+
+ - name: Nested (Truthy)
+ desc: Nested truthy sections should have their contents rendered.
+ data: { bool: true }
+ template: "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |"
+ expected: "| A B C D E |"
+
+ - name: Nested (Falsey)
+ desc: Nested falsey sections should be omitted.
+ data: { bool: false }
+ template: "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |"
+ expected: "| A E |"
+
+ - name: Context Misses
+ desc: Failed context lookups should be considered falsey.
+ data: { }
+ template: "[{{#missing}}Found key 'missing'!{{/missing}}]"
+ expected: "[]"
+
+ # Implicit Iterators
+
+ - name: Implicit Iterator - String
+ desc: Implicit iterators should directly interpolate strings.
+ data:
+ list: [ 'a', 'b', 'c', 'd', 'e' ]
+ template: '"{{#list}}({{.}}){{/list}}"'
+ expected: '"(a)(b)(c)(d)(e)"'
+
+ - name: Implicit Iterator - Integer
+ desc: Implicit iterators should cast integers to strings and interpolate.
+ data:
+ list: [ 1, 2, 3, 4, 5 ]
+ template: '"{{#list}}({{.}}){{/list}}"'
+ expected: '"(1)(2)(3)(4)(5)"'
+
+ - name: Implicit Iterator - Decimal
+ desc: Implicit iterators should cast decimals to strings and interpolate.
+ data:
+ list: [ 1.10, 2.20, 3.30, 4.40, 5.50 ]
+ template: '"{{#list}}({{.}}){{/list}}"'
+ expected: '"(1.1)(2.2)(3.3)(4.4)(5.5)"'
+
+ # Dotted Names
+
+ - name: Dotted Names - Truthy
+ desc: Dotted names should be valid for Section tags.
+ data: { a: { b: { c: true } } }
+ template: '"{{#a.b.c}}Here{{/a.b.c}}" == "Here"'
+ expected: '"Here" == "Here"'
+
+ - name: Dotted Names - Falsey
+ desc: Dotted names should be valid for Section tags.
+ data: { a: { b: { c: false } } }
+ template: '"{{#a.b.c}}Here{{/a.b.c}}" == ""'
+ expected: '"" == ""'
+
+ - name: Dotted Names - Broken Chains
+ desc: Dotted names that cannot be resolved should be considered falsey.
+ data: { a: { } }
+ template: '"{{#a.b.c}}Here{{/a.b.c}}" == ""'
+ expected: '"" == ""'
+
+ # Whitespace Sensitivity
+
+ - name: Surrounding Whitespace
+ desc: Sections should not alter surrounding whitespace.
+ data: { boolean: true }
+ template: " | {{#boolean}}\t|\t{{/boolean}} | \n"
+ expected: " | \t|\t | \n"
+
+ - name: Internal Whitespace
+ desc: Sections should not alter internal whitespace.
+ data: { boolean: true }
+ template: " | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n"
+ expected: " | \n | \n"
+
+ - name: Indented Inline Sections
+ desc: Single-line sections should not alter surrounding whitespace.
+ data: { boolean: true }
+ template: " {{#boolean}}YES{{/boolean}}\n {{#boolean}}GOOD{{/boolean}}\n"
+ expected: " YES\n GOOD\n"
+
+ - name: Standalone Lines
+ desc: Standalone lines should be removed from the template.
+ data: { boolean: true }
+ template: |
+ | This Is
+ {{#boolean}}
+ |
+ {{/boolean}}
+ | A Line
+ expected: |
+ | This Is
+ |
+ | A Line
+
+ - name: Indented Standalone Lines
+ desc: Indented standalone lines should be removed from the template.
+ data: { boolean: true }
+ template: |
+ | This Is
+ {{#boolean}}
+ |
+ {{/boolean}}
+ | A Line
+ expected: |
+ | This Is
+ |
+ | A Line
+
+ - name: Standalone Line Endings
+ desc: '"\r\n" should be considered a newline for standalone tags.'
+ data: { boolean: true }
+ template: "|\r\n{{#boolean}}\r\n{{/boolean}}\r\n|"
+ expected: "|\r\n|"
+
+ - name: Standalone Without Previous Line
+ desc: Standalone tags should not require a newline to precede them.
+ data: { boolean: true }
+ template: " {{#boolean}}\n#{{/boolean}}\n/"
+ expected: "#\n/"
+
+ - name: Standalone Without Newline
+ desc: Standalone tags should not require a newline to follow them.
+ data: { boolean: true }
+ template: "#{{#boolean}}\n/\n {{/boolean}}"
+ expected: "#\n/\n"
+
+ # Whitespace Insensitivity
+
+ - name: Padding
+ desc: Superfluous in-tag whitespace should be ignored.
+ data: { boolean: true }
+ template: '|{{# boolean }}={{/ boolean }}|'
+ expected: '|=|'