Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add template inheritance spec #75

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions specs/inheritance.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"overview":"Parent tags are used to expand an external template into the current template,\nwith optional parameters delimited by block tags.\n\nThese tags' content MUST be a non-whitespace character sequence NOT containing\nthe current closing delimiter; each Parent tag MUST be followed by an End\nSection tag with the same content within the matching parent tag.\n\nBlock tags are used inside of parent tags to assign data onto the context stack \nprior to rendering the parent template. Outside of parent tags, block tags are\nused to indicate where value set in the parent tag should be placed. If no value\nis set then the content in between the block tags, if any, is rendered.\n","tests":[{"name":"Default","desc":"Default content should be rendered if the block isn't overridden","data":{},"template":"{{$title}}Default title{{/title}}\n","expected":"Default title\n"},{"name":"Variable","desc":"Default content renders variables","data":{"bar":"baz"},"template":"{{$foo}}default {{bar}} content{{/foo}}\n","expected":"default baz content\n"},{"name":"Triple Mustache","desc":"Default content renders triple mustache variables","data":{"bar":"<baz>"},"template":"{{$foo}}default {{{bar}}} content{{/foo}}\n","expected":"default <baz> content\n"},{"name":"Sections","desc":"Default content renders sections","data":{"bar":{"baz":"qux"}},"template":"{{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}}\n","expected":"default qux content\n"},{"name":"Negative Sections","desc":"Default content renders negative sections","data":{"baz":"three"},"template":"{{$foo}}default {{^bar}}{{baz}}{{/bar}} content{{/foo}}\n","expected":"default three content\n"},{"name":"Mustache Injection","desc":"Mustache injection in default content","data":{"bar":{"baz":"{{qux}}"}},"template":"{{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}}\n","expected":"default {{qux}} content\n"},{"name":"Inherit","desc":"Default content rendered inside included templates","data":{},"template":"{{<include}}{{/include}}\n","partials":{"include":"{{$foo}}default content{{/foo}}"},"expected":"default content"},{"name":"Overridden content","desc":"Overridden content","data":{},"template":"{{<super}}{{$title}}sub template title{{/title}}{{/super}}","partials":{"super":"...{{$title}}Default title{{/title}}..."},"expected":"...sub template title..."},{"name":"Data does not override block","desc":"Provided data does not override data passed into parent","data":{"var":"var in data"},"template":"{{<include}}{{$var}}var in template{{/var}}{{/include}}","partials":{"include":"{{$var}}var in include{{/var}}"},"expected":"var in template"},{"name":"Data does not override block default","desc":"Provided data does not override default value of block","data":{"var":"var in data"},"template":"{{<include}}{{/include}}","partials":{"include":"{{$var}}var in include{{/var}}"},"expected":"var in include"},{"name":"Overridden partial","desc":"Overridden partial","data":{},"template":"test {{<partial}}{{$stuff}}override{{/stuff}}{{/partial}}","partials":{"partial":"{{$stuff}}...{{/stuff}}"},"expected":"test override"},{"name":"Two overridden partials","desc":"Two overridden partials with different content","data":{},"template":"test {{<partial}}{{$stuff}}override1{{/stuff}}{{/partial}} {{<partial}}{{$stuff}}override2{{/stuff}}{{/partial}}\n","partials":{"partial":"|{{$stuff}}...{{/stuff}}{{$default}} default{{/default}}|"},"expected":"test |override1 default| |override2 default|\n"},{"name":"Override partial with newlines","desc":"Override partial with newlines","data":{},"template":"{{<partial}}{{$ballmer}}\npeaked\n\n:(\n{{/ballmer}}{{/partial}}","partials":{"partial":"{{$ballmer}}peaking{{/ballmer}}"},"expected":"peaked\n\n:(\n"},{"name":"Inherit indentation","desc":"Override one substitution but not the other","data":{},"template":"{{<partial}}{{$stuff2}}override two{{/stuff2}}{{/partial}}","partials":{"partial":"{{$stuff}}new default one{{/stuff}}, {{$stuff2}}new default two{{/stuff2}}"},"expected":"new default one, override two"},{"name":"Super template","desc":"Super templates behave identically to partials when called with no parameters","data":{},"template":"{{>include}}|{{<include}}{{/include}}","partials":{"include":"{{$foo}}default content{{/foo}}"},"expected":"default content|default content"},{"name":"Recursion","desc":"Recursion in inherited templates","data":{},"template":"{{<include}}{{$foo}}override{{/foo}}{{/include}}","partials":{"include":"{{$foo}}default content{{/foo}} {{$bar}}{{<include2}}{{/include2}}{{/bar}}","include2":"{{$foo}}include2 default content{{/foo}} {{<include}}{{$bar}}don't recurse{{/bar}}{{/include}}"},"expected":"override override override don't recurse"},{"name":"Multi-level inheritance","desc":"Top-level substitutions take precedence in multi-level inheritance","data":{},"template":"{{<parent}}{{$a}}c{{/a}}{{/parent}}","partials":{"parent":"{{<older}}{{$a}}p{{/a}}{{/older}}","older":"{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}","grandParent":"{{$a}}g{{/a}}"},"expected":"c"},{"name":"Multi-level inheritance, no sub child","desc":"Top-level substitutions take precedence in multi-level inheritance","data":{},"template":"{{<parent}}{{/parent}}","partials":{"parent":"{{<older}}{{$a}}p{{/a}}{{/older}}","older":"{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}","grandParent":"{{$a}}g{{/a}}"},"expected":"p"},{"name":"Text inside super","desc":"Ignores text inside super templates, but does parse $ tags","data":{},"template":"{{<include}} asdfasd {{$foo}}hmm{{/foo}} asdfasdfasdf {{/include}}","partials":{"include":"{{$foo}}default content{{/foo}}"},"expected":"hmm"},{"name":"Text inside super","desc":"Allows text inside a super tag, but ignores it","data":{},"template":"{{<include}} asdfasd asdfasdfasdf {{/include}}","partials":{"include":"{{$foo}}default content{{/foo}}"},"expected":"default content"}],"__ATTN__":"Do not edit this file; changes belong in the appropriate YAML file."}
192 changes: 192 additions & 0 deletions specs/inheritance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
overview: |
Parent tags are used to expand an external template into the current template,
with optional parameters delimited by block tags.

These tags' content MUST be a non-whitespace character sequence NOT containing
the current closing delimiter; each Parent tag MUST be followed by an End
Section tag with the same content within the matching parent tag.

Block tags are used inside of parent tags to assign data onto the context stack
prior to rendering the parent template. Outside of parent tags, block tags are
used to indicate where value set in the parent tag should be placed. If no value
is set then the content in between the block tags, if any, is rendered.
tests:
- name: Default
desc: Default content should be rendered if the block isn't overridden
data: { }
template: |
{{$title}}Default title{{/title}}
expected: |
Default title

- name: Variable
desc: Default content renders variables
data: { bar: 'baz' }
template: |
{{$foo}}default {{bar}} content{{/foo}}
expected: |
default baz content

- name: Triple Mustache
desc: Default content renders triple mustache variables
data: { bar: '<baz>' }
template: |
{{$foo}}default {{{bar}}} content{{/foo}}
expected: |
default <baz> content

- name: Sections
desc: Default content renders sections
data: { bar: {baz: 'qux'} }
template: |
{{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}}
expected: |
default qux content

- name: Negative Sections
desc: Default content renders negative sections
data: { baz: 'three' }
template: |
{{$foo}}default {{^bar}}{{baz}}{{/bar}} content{{/foo}}
expected: |
default three content

- name: Mustache Injection
desc: Mustache injection in default content
data: {bar: {baz: '{{qux}}'} }
template: |
{{$foo}}default {{#bar}}{{baz}}{{/bar}} content{{/foo}}
expected: |
default {{qux}} content

- name: Inherit
desc: Default content rendered inside included templates
data: { }
template: |
{{<include}}{{/include}}
partials:
include: "{{$foo}}default content{{/foo}}"
expected: "default content"

- name: Overridden content
desc: Overridden content
data: { }
template: "{{<super}}{{$title}}sub template title{{/title}}{{/super}}"
partials:
super: "...{{$title}}Default title{{/title}}..."
expected: "...sub template title..."

- name: Data does not override block
desc: Provided data does not override data passed into parent
data: { var: 'var in data' }
template: "{{<include}}{{$var}}var in template{{/var}}{{/include}}"
partials:
include: "{{$var}}var in include{{/var}}"
expected: "var in template"

- name: Data does not override block default
desc: Provided data does not override default value of block
data: { var: 'var in data' }
template: "{{<include}}{{/include}}"
partials:
include: "{{$var}}var in include{{/var}}"
expected: "var in include"

- name: Overridden partial
desc: Overridden partial
data: { }
template: "test {{<partial}}{{$stuff}}override{{/stuff}}{{/partial}}"
partials:
partial: "{{$stuff}}...{{/stuff}}"
expected: "test override"
Comment on lines +95 to +101
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the wording "partial" is rather unfortunate here, as neither the parent nor the template involves {{>partial}} syntax. I suggest the following instead.

Suggested change
- name: Overridden partial
desc: Overridden partial
data: { }
template: "test {{<partial}}{{$stuff}}override{{/stuff}}{{/partial}}"
partials:
partial: "{{$stuff}}...{{/stuff}}"
expected: "test override"
- name: Overriden content with text in front
desc: Overriden content with text in front of parent
data: { }
template: "test {{<parent}}{{$stuff}}override{{/stuff}}{{/parent}}"
partials:
parent: "{{$stuff}}...{{/stuff}}"
expected: "test override"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I retract the above comment.


- name: Two overridden partials
desc: Two overridden partials with different content
Comment on lines +103 to +104
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- name: Two overridden partials
desc: Two overridden partials with different content
- name: Overrides in twice inherited parent
desc: Overrides in twice inherited parent with different content

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I retract the above comment.

data: { }
template: |
test {{<partial}}{{$stuff}}override1{{/stuff}}{{/partial}} {{<partial}}{{$stuff}}override2{{/stuff}}{{/partial}}
partials:
partial: "|{{$stuff}}...{{/stuff}}{{$default}} default{{/default}}|"
expected: |
test |override1 default| |override2 default|
- name: Override partial with newlines
desc: Override partial with newlines
Comment on lines +112 to +113
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- name: Override partial with newlines
desc: Override partial with newlines
- name: Override parent with newlines
desc: Override parent with newlines

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I retract the above comment.

data: { }
template: "{{<partial}}{{$ballmer}}\npeaked\n\n:(\n{{/ballmer}}{{/partial}}"
partials:
partial: "{{$ballmer}}peaking{{/ballmer}}"
expected: "peaked\n\n:(\n"

- name: Inherit indentation
desc: Inherit indentation when overriding a partial
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
desc: Inherit indentation when overriding a partial
desc: Inherit indentation when overriding a parent

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I retract the above comment.

data: { }
template: "{{<partial}}{{$nineties}}hammer time{{/nineties}}{{/partial}}"
partials:
partial: |
stop:
{{$nineties}}collaborate and listen{{/nineties}}
expected: |
stop:
hammer time

- name: Only one override
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- name: Only one override
- name: Only one override

desc: Override one substitution but not the other
data: { }
template: "{{<partial}}{{$stuff2}}override two{{/stuff2}}{{/partial}}"
partials:
partial: "{{$stuff}}new default one{{/stuff}}, {{$stuff2}}new default two{{/stuff2}}"
expected: "new default one, override two"

- name: Super template
desc: Super templates behave identically to partials when called with no parameters
data: { }
template: "{{>include}}|{{<include}}{{/include}}"
partials:
include: "{{$foo}}default content{{/foo}}"
expected: "default content|default content"

- name: Recursion
desc: Recursion in inherited templates
data: {}
template: "{{<include}}{{$foo}}override{{/foo}}{{/include}}"
partials:
include: "{{$foo}}default content{{/foo}} {{$bar}}{{<include2}}{{/include2}}{{/bar}}"
include2: "{{$foo}}include2 default content{{/foo}} {{<include}}{{$bar}}don't recurse{{/bar}}{{/include}}"
expected: "override override override don't recurse"

- name: Multi-level inheritance
desc: Top-level substitutions take precedence in multi-level inheritance
data: { }
template: "{{<parent}}{{$a}}c{{/a}}{{/parent}}"
partials:
parent: "{{<older}}{{$a}}p{{/a}}{{/older}}"
older: "{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}"
grandParent: "{{$a}}g{{/a}}"
expected: c

- name: Multi-level inheritance, no sub child
desc: Top-level substitutions take precedence in multi-level inheritance
data: { }
template: "{{<parent}}{{/parent}}"
partials:
parent: "{{<older}}{{$a}}p{{/a}}{{/older}}"
older: "{{<grandParent}}{{$a}}o{{/a}}{{/grandParent}}"
grandParent: "{{$a}}g{{/a}}"
expected: p

- name: Text inside super
desc: Ignores text inside super templates, but does parse $ tags
data: { }
template: "{{<include}} asdfasd {{$foo}}hmm{{/foo}} asdfasdfasdf {{/include}}"
partials:
include: "{{$foo}}default content{{/foo}}"
expected:
hmm

- name: Text inside super
desc: Allows text inside a super tag, but ignores it
data: {}
template: "{{<include}} asdfasd asdfasdfasdf {{/include}}"
partials:
include: "{{$foo}}default content{{/foo}}"
expected: default content