summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranomal00us <95467104+anomal00us@users.noreply.github.com>2022-07-17 12:01:16 +0200
committerroot <root@delphi.lan>2022-08-08 21:07:09 +0200
commit22c3bf1ad7983360e4f20b953cd3ab88d941d5d7 (patch)
tree61e17000174ddca230ee37fb0e31a87bcc0771c6
parenta15b333b08e3f0db5a62baf6d6d55f364f380a5a (diff)
downloadmustache-spec-22c3bf1ad7983360e4f20b953cd3ab88d941d5d7.tar.gz
Dynamic partials update (squashed) (coauthored)
Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com> Update specs/~dynamic-names.yml Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
-rw-r--r--specs/~dynamic-names.json (renamed from specs/~dynamic-partials.json)37
-rw-r--r--specs/~dynamic-names.yml158
-rw-r--r--specs/~dynamic-partials.yml140
3 files changed, 186 insertions, 149 deletions
diff --git a/specs/~dynamic-partials.json b/specs/~dynamic-names.json
index f260a15..57c1665 100644
--- a/specs/~dynamic-partials.json
+++ b/specs/~dynamic-names.json
@@ -1,20 +1,30 @@
{
- "overview": "Dynamic partials tags are used to dynamically expand an external template into\nthe current template.\n\nThe tag's content MUST be a non-whitespace character sequence NOT containing\nthe current closing delimiter.\n\nThis tag's content names a key in the context whose value is the name of the\npartial that will be loaded. If the dynamically named partial cannot be found,\nthe empty string SHOULD be used instead, as in interpolations. Set Delimiter\ntags MUST NOT affect the parsing of a partial. The partial MUST be rendered\nagainst the context stack local to the tag. Failed resolutions of the key\n(context lookups) should be considered falsey and should interpolate as the\nempty string. If the partial, whose name is retrieved from the context stack,\ncannot be found, the empty string SHOULD be used instead, as in\ninterpolations.\n\nDynamic partial tags SHOULD be treated as standalone when appropriate. If\nthis tag is used standalone, any whitespace preceding the tag should treated\nas indentation, and prepended to each line of the partial before rendering:\nwhitespace handling around dynamic partials SHOULD be identical to whitespace\nhandling around static (normal) partials.\n",
+ "overview": "Dynamic Names are a special way to dynamically refer to a tag name.\n\nDynamic Names MUST be a non-whitespace character sequence NOT containing\nthe current closing delimiter.\n\nThis tag's content refers to a key in the context whose value will be used in\nplace of the Dynamic Name itself as content of the tag. The name resolution is\nas follows:\n 1) Split the name on periods; the first part is the name to resolve, any\n remaining parts should be retained.\n 2) Walk the context stack from top to bottom, finding the first context\n that is a) a hash containing the name as a key OR b) an object responding\n to a method with the given name.\n 3) If the context is a hash, the data is the value associated with the\n name.\n 4) If the context is an object, the data is the value returned by the\n method with the given name.\n 5) If any name parts were retained in step 1, each should be resolved\n against a context stack containing only the result from the former\n resolution. If any part fails resolution, the result should be considered\n falsey, and should interpolate as the empty string.\nThe resolved data should be coerced into a string before being used as\ncontent.\n\nSet Delimiter tags MUST NOT affect the resolution of a Dynamic Name. The\nDynamic Names MUST be rendered against the context stack local to the tag.\nFailed resolutions of the key (context lookups) should be considered falsey\nand should interpolate as the empty string.\n\nDynamic Names can be combined with every other tag: those tags' content is the\nresolution of the Dynamic Name. Dynamic Names cannot be resolved more than\nonce (Dynamic Names cannot be nested).\n",
"tests": [
{
- "name": "Basic Behavior",
+ "name": "Basic Behavior - Interpolation",
+ "desc": "The asterisk operator is used for dynamic names.",
+ "data": {
+ "dynamic": "Hello, world!"
+ },
+ "template": "\"{{*dynamic}}\"",
+ "partials": {},
+ "expected": "\"Hello, world!\""
+ },
+ {
+ "name": "Basic Behavior - Partial",
"desc": "The asterisk operator is used for dynamic partials.",
"data": {
"dynamic": "content"
},
- "template": "\"{{*dynamic}}\"",
+ "template": "\"{{>*dynamic}}\"",
"partials": {
"content": "Hello, world!"
},
"expected": "\"Hello, world!\""
},
{
- "name": "Context Misses",
+ "name": "Context Misses - Interpolation",
"desc": "Failed context lookups should be considered falsey.",
"data": {},
"template": "\"{{*missing}}\"",
@@ -22,22 +32,22 @@
"expected": "\"\""
},
{
- "name": "Context Misses Again",
+ "name": "Context Misses - Partial",
"desc": "Failed context lookups should be considered falsey.",
"data": {},
- "template": "\"{{*missing}}\"",
+ "template": "\"{{>*missing}}\"",
"partials": {
"missing": "Hello, world!"
},
"expected": "\"\""
},
{
- "name": "Failed Lookup",
+ "name": "Failed Lookup - Partial",
"desc": "The empty string should be used when the named partial is not found.",
"data": {
"dynamic": "content"
},
- "template": "\"{{*dynamic}}\"",
+ "template": "\"{{>*dynamic}}\"",
"partials": {
"foobar": "Hello, world!"
},
@@ -59,7 +69,16 @@
{
"name": "Recursion",
"desc": "The asterisk operator should properly recurse.",
- "data": "{\n template: 'node',\n content: 'X',\n nodes: [ { content: 'Y', nodes: [] } ]\n}\n",
+ "data": {
+ "template": "node",
+ "content": "X",
+ "nodes": [
+ {
+ "content": "Y",
+ "nodes": []
+ }
+ ]
+ },
"template": "{{*template}}",
"partials": {
"node": "{{content}}<{{#nodes}}{{*template}}{{/nodes}}>"
diff --git a/specs/~dynamic-names.yml b/specs/~dynamic-names.yml
new file mode 100644
index 0000000..3005907
--- /dev/null
+++ b/specs/~dynamic-names.yml
@@ -0,0 +1,158 @@
+overview: |
+ Dynamic Names are a special notation to dynamically determine a tag's content.
+
+ Dynamic Names MUST be a non-whitespace character sequence NOT containing
+ the current closing delimiter. A Dynamic Name consists of an asterisk,
+ followed by a dotted name. The latter follows the same notation as in an
+ Interpolation tag.
+
+ This tag's content refers to a key in the context whose value will be used in
+ place of the Dynamic Name itself as content of the tag. The name resolution is
+ identical to name resolution in Interpolation tags, 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, the data is the value returned by the
+ method with the given name.
+ 5) 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.
+ The resolved data should be coerced into a string before being used as
+ content.
+
+ Set Delimiter tags MUST NOT affect the resolution of a Dynamic Name. The
+ Dynamic Names MUST be resolved against the context stack local to the tag.
+ Failed resolution of the dynamic name should result in nothing being rendered.
+
+ Engines that implement Dynamic Names MUST support their use in Partial tags.
+ In engines that also implement the optional inheritance spec, Dynamic Names
+ inside Parent tags should be supported as well. Dynamic Names cannot be
+ resolved more than once (Dynamic Names cannot be nested).
+tests:
+ - name: Basic Behavior - Interpolation
+ desc: The asterisk operator is used for dynamic names.
+ data: { dynamic: 'Hello, world!' }
+ template: '"{{*dynamic}}"'
+ partials: { }
+ expected: '"Hello, world!"'
+
+ - name: Basic Behavior - Partial
+ desc: The asterisk operator is used for dynamic partials.
+ data: { dynamic: 'content' }
+ template: '"{{>*dynamic}}"'
+ partials: { content: 'Hello, world!' }
+ expected: '"Hello, world!"'
+
+ - name: Context Misses - Interpolation
+ desc: Failed context lookups should be considered falsey.
+ data: { }
+ template: '"{{*missing}}"'
+ partials: { }
+ expected: '""'
+
+ - name: Context Misses - Partial
+ desc: Failed context lookups should be considered falsey.
+ data: { }
+ template: '"{{>*missing}}"'
+ partials: { missing: 'Hello, world!' }
+ expected: '""'
+
+ - name: Failed Lookup - Partial
+ desc: The empty string should be used when the named partial is not found.
+ data: { dynamic: 'content' }
+ template: '"{{>*dynamic}}"'
+ partials: { foobar: 'Hello, world!' }
+ expected: '""'
+
+ - name: Context
+ desc: The dynamic partial should operate within the current context.
+ data: { text: 'Hello, world!', example: 'partial' }
+ template: '"{{>*example}}"'
+ partials: { partial: '*{{text}}*' }
+ expected: '"*Hello, world!*"'
+
+ - name: Recursion
+ desc: Dynamic partials should properly recurse.
+ data:
+ template: 'node'
+ content: 'X'
+ nodes: [ { content: 'Y', nodes: [] } ]
+ template: '{{>*template}}'
+ partials: { node: '{{content}}<{{#nodes}}{{>*template}}{{/nodes}}>' }
+ expected: 'X<Y<>>'
+
+ # Whitespace Sensitivity
+
+ - name: Surrounding Whitespace
+ desc: |
+ A dynamic partials should not alter surrounding whitespace; any
+ whitespace preceding the tag should treated as indentation while any
+ whitepsace succeding the tag should be left untouched.
+ data: { partial: 'foobar' }
+ template: '| {{>*partial}} |'
+ partials: { foobar: "\t|\t" }
+ expected: "| \t|\t |"
+
+ - name: Inline Indentation
+ desc: |
+ Whitespace should be left untouched: whitespaces preceding the tag
+ should be treated as indentation.
+ data: { dynamic: 'partial', data: '|' }
+ template: " {{data}} {{>* dynamic}}\n"
+ partials: { partial: ">\n>" }
+ expected: " | >\n>\n"
+
+ - name: Standalone Line Endings
+ desc: '"\r\n" should be considered a newline for standalone tags.'
+ data: { dynamic: 'partial' }
+ template: "|\r\n{{>*dynamic}}\r\n|"
+ partials: { partial: ">" }
+ expected: "|\r\n>|"
+
+ - name: Standalone Without Previous Line
+ desc: Standalone tags should not require a newline to precede them.
+ data: { dynamic: 'partial' }
+ template: " {{>*dynamic}}\n>"
+ partials: { partial: ">\n>"}
+ expected: " >\n >>"
+
+ - name: Standalone Without Newline
+ desc: Standalone tags should not require a newline to follow them.
+ data: { dynamic: 'partial' }
+ template: ">\n {{>*dynamic}}"
+ partials: { partial: ">\n>" }
+ expected: ">\n >\n >"
+
+ - name: Standalone Indentation
+ desc: Each line of the partial should be indented before rendering.
+ data: { dynamic: 'partial', content: "<\n->" }
+ template: |
+ \
+ {{>*dynamic}}
+ /
+ partials:
+ partial: |
+ |
+ {{{content}}}
+ |
+ expected: |
+ \
+ |
+ <
+ ->
+ |
+ /
+
+ # Whitespace Insensitivity
+
+ - name: Padding Whitespace
+ desc: Superfluous in-tag whitespace should be ignored.
+ data: { dynamic: 'partial', boolean: true }
+ template: "|{{> *dynamic }}|"
+ partials: { partial: "[]" }
+ expected: '|[]|'
diff --git a/specs/~dynamic-partials.yml b/specs/~dynamic-partials.yml
deleted file mode 100644
index c61113e..0000000
--- a/specs/~dynamic-partials.yml
+++ /dev/null
@@ -1,140 +0,0 @@
-overview: |
- Dynamic partials tags are used to dynamically expand an external template into
- the current template.
-
- The tag's content MUST be a non-whitespace character sequence NOT containing
- the current closing delimiter.
-
- This tag's content names a key in the context whose value is the name of the
- partial that will be loaded. If the dynamically named partial cannot be found,
- the empty string SHOULD be used instead, as in interpolations. Set Delimiter
- tags MUST NOT affect the parsing of a partial. The partial MUST be rendered
- against the context stack local to the tag. Failed resolutions of the key
- (context lookups) should be considered falsey and should interpolate as the
- empty string. If the partial, whose name is retrieved from the context stack,
- cannot be found, the empty string SHOULD be used instead, as in
- interpolations.
-
- Dynamic partial tags SHOULD be treated as standalone when appropriate. If
- this tag is used standalone, any whitespace preceding the tag should treated
- as indentation, and prepended to each line of the partial before rendering:
- whitespace handling around dynamic partials SHOULD be identical to whitespace
- handling around static (normal) partials.
-tests:
- - name: Basic Behavior
- desc: The asterisk operator is used for dynamic partials.
- data: { dynamic: 'content' }
- template: '"{{*dynamic}}"'
- partials: { content: 'Hello, world!' }
- expected: '"Hello, world!"'
-
- - name: Context Misses
- desc: Failed context lookups should be considered falsey.
- data: { }
- template: '"{{*missing}}"'
- partials: { }
- expected: '""'
-
- - name: Context Misses Again
- desc: Failed context lookups should be considered falsey.
- data: { }
- template: '"{{*missing}}"'
- partials: { missing: 'Hello, world!' }
- expected: '""'
-
- - name: Failed Lookup
- desc: The empty string should be used when the named partial is not found.
- data: { dynamic: 'content' }
- template: '"{{*dynamic}}"'
- partials: { foobar: 'Hello, world!' }
- expected: '""'
-
- - name: Context
- desc: The asterisk operator should operate within the current context.
- data: { text: 'Hello, world!', example: 'partial' }
- template: '"{{*example}}"'
- partials: { partial: '*{{text}}*' }
- expected: '"*Hello, world!*"'
-
- - name: Recursion
- desc: The asterisk operator should properly recurse.
- data: |
- {
- template: 'node',
- content: 'X',
- nodes: [ { content: 'Y', nodes: [] } ]
- }
- template: '{{*template}}'
- partials: { node: '{{content}}<{{#nodes}}{{*template}}{{/nodes}}>' }
- expected: 'X<Y<>>'
-
- # Whitespace Sensitivity
-
- - name: Surrounding Whitespace
- desc: |
- The asterisk operator should not alter surrounding whitespace; any
- whitespace preceding the tag should treated as indentation while any
- whitepsace succeding the tag should be left untouched.
- data: { partial: 'foobar' }
- template: '| {{*partial}} |'
- partials: { foobar: "\t|\t" }
- expected: "| \t|\t |"
-
- - name: Inline Indentation
- desc: |
- Whitespace should be left untouched: whitespaces preceding the tag
- should be treated as indentation.
- data: { dynamic: 'partial', data: '|' }
- template: " {{data}} {{* dynamic}}\n"
- partials: { partial: ">\n>" }
- expected: " | >\n>\n"
-
- - name: Standalone Line Endings
- desc: '"\r\n" should be considered a newline for standalone tags.'
- data: { dynamic: 'partial' }
- template: "|\r\n{{*dynamic}}\r\n|"
- partials: { partial: ">" }
- expected: "|\r\n>|"
-
- - name: Standalone Without Previous Line
- desc: Standalone tags should not require a newline to precede them.
- data: { dynamic: 'partial' }
- template: " {{*dynamic}}\n>"
- partials: { partial: ">\n>"}
- expected: " >\n >>"
-
- - name: Standalone Without Newline
- desc: Standalone tags should not require a newline to follow them.
- data: { dynamic: 'partial' }
- template: ">\n {{*dynamic}}"
- partials: { partial: ">\n>" }
- expected: ">\n >\n >"
-
- - name: Standalone Indentation
- desc: Each line of the partial should be indented before rendering.
- data: { dynamic: 'partial', content: "<\n->" }
- template: |
- \
- {{*dynamic}}
- /
- partials:
- partial: |
- |
- {{{content}}}
- |
- expected: |
- \
- |
- <
- ->
- |
- /
-
- # Whitespace Insensitivity
-
- - name: Padding Whitespace
- desc: Superfluous in-tag whitespace should be ignored.
- data: { dynamic: 'partial', boolean: true }
- template: "|{{* dynamic }}|"
- partials: { partial: "[]" }
- expected: '|[]|'