summaryrefslogtreecommitdiff
path: root/src/templating/test-specs
diff options
context:
space:
mode:
Diffstat (limited to 'src/templating/test-specs')
-rw-r--r--src/templating/test-specs/test-specs-cjson.ref425
-rw-r--r--src/templating/test-specs/test-specs-jansson.ref429
-rw-r--r--src/templating/test-specs/test-specs-json-c.ref425
-rw-r--r--src/templating/test-specs/test-specs.c520
4 files changed, 1799 insertions, 0 deletions
diff --git a/src/templating/test-specs/test-specs-cjson.ref b/src/templating/test-specs/test-specs-cjson.ref
new file mode 100644
index 000000000..8897c66cc
--- /dev/null
+++ b/src/templating/test-specs/test-specs-cjson.ref
@@ -0,0 +1,425 @@
+
+loading test-specs/spec/specs/comments.json
+processing file test-specs/spec/specs/comments.json
+[0] Inline
+ Comment blocks should be removed from the template.
+ => SUCCESS
+[1] Multiline
+ Multiline comments should be permitted.
+ => SUCCESS
+[2] Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[3] Indented Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[4] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[5] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[6] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[7] Multiline Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[8] Indented Multiline Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[9] Indented Inline
+ Inline comments should not strip whitespace
+ => SUCCESS
+[10] Surrounding Whitespace
+ Comment removal should preserve surrounding whitespace.
+ => SUCCESS
+[11] Variable Name Collision
+ Comments must never render, even if variable with same name exists.
+ => SUCCESS
+
+loading test-specs/spec/specs/delimiters.json
+processing file test-specs/spec/specs/delimiters.json
+[0] Pair Behavior
+ The equals sign (used on both sides) should permit delimiter changes.
+ => SUCCESS
+[1] Special Characters
+ Characters with special meaning regexen should be valid delimiters.
+ => SUCCESS
+[2] Sections
+ Delimiters set outside sections should persist.
+ => SUCCESS
+[3] Inverted Sections
+ Delimiters set outside inverted sections should persist.
+ => SUCCESS
+[4] Partial Inheritence
+ Delimiters set in a parent template should not affect a partial.
+ => SUCCESS
+[5] Post-Partial Behavior
+ Delimiters set in a partial should not affect the parent template.
+ => SUCCESS
+[6] Surrounding Whitespace
+ Surrounding whitespace should be left untouched.
+ => SUCCESS
+[7] Outlying Whitespace (Inline)
+ Whitespace should be left untouched.
+ => SUCCESS
+[8] Standalone Tag
+ Standalone lines should be removed from the template.
+ => SUCCESS
+[9] Indented Standalone Tag
+ Indented standalone lines should be removed from the template.
+ => SUCCESS
+[10] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[11] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[12] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[13] Pair with Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/interpolation.json
+processing file test-specs/spec/specs/interpolation.json
+[0] No Interpolation
+ Mustache-free templates should render as-is.
+ => SUCCESS
+[1] Basic Interpolation
+ Unadorned tags should interpolate content into the template.
+ => SUCCESS
+[2] HTML Escaping
+ Basic interpolation should be HTML escaped.
+ => SUCCESS
+[3] Triple Mustache
+ Triple mustaches should interpolate without HTML escaping.
+ => SUCCESS
+[4] Ampersand
+ Ampersand should interpolate without HTML escaping.
+ => SUCCESS
+[5] Basic Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[6] Triple Mustache Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[7] Ampersand Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[8] Basic Decimal Interpolation
+ Decimals should interpolate seamlessly with proper significance.
+ => SUCCESS
+[9] Triple Mustache Decimal Interpolation
+ Decimals should interpolate seamlessly with proper significance.
+ => SUCCESS
+[10] Ampersand Decimal Interpolation
+ Decimals should interpolate seamlessly with proper significance.
+ => SUCCESS
+[11] Basic Null Interpolation
+ Nulls should interpolate as the empty string.
+ => SUCCESS
+[12] Triple Mustache Null Interpolation
+ Nulls should interpolate as the empty string.
+ => SUCCESS
+[13] Ampersand Null Interpolation
+ Nulls should interpolate as the empty string.
+ => SUCCESS
+[14] Basic Context Miss Interpolation
+ Failed context lookups should default to empty strings.
+ => SUCCESS
+[15] Triple Mustache Context Miss Interpolation
+ Failed context lookups should default to empty strings.
+ => SUCCESS
+[16] Ampersand Context Miss Interpolation
+ Failed context lookups should default to empty strings.
+ => SUCCESS
+[17] Dotted Names - Basic Interpolation
+ Dotted names should be considered a form of shorthand for sections.
+ => SUCCESS
+[18] Dotted Names - Triple Mustache Interpolation
+ Dotted names should be considered a form of shorthand for sections.
+ => SUCCESS
+[19] Dotted Names - Ampersand Interpolation
+ Dotted names should be considered a form of shorthand for sections.
+ => SUCCESS
+[20] Dotted Names - Arbitrary Depth
+ Dotted names should be functional to any level of nesting.
+ => SUCCESS
+[21] Dotted Names - Broken Chains
+ Any falsey value prior to the last part of the name should yield ''.
+ => SUCCESS
+[22] Dotted Names - Broken Chain Resolution
+ Each part of a dotted name should resolve only against its parent.
+ => SUCCESS
+[23] Dotted Names - Initial Resolution
+ The first part of a dotted name should resolve as any other name.
+ => SUCCESS
+[24] Dotted Names - Context Precedence
+ Dotted names should be resolved against former resolutions.
+ => SUCCESS
+[25] Implicit Iterators - Basic Interpolation
+ Unadorned tags should interpolate content into the template.
+ => SUCCESS
+[26] Implicit Iterators - HTML Escaping
+ Basic interpolation should be HTML escaped.
+ => SUCCESS
+[27] Implicit Iterators - Triple Mustache
+ Triple mustaches should interpolate without HTML escaping.
+ => SUCCESS
+[28] Implicit Iterators - Ampersand
+ Ampersand should interpolate without HTML escaping.
+ => SUCCESS
+[29] Implicit Iterators - Basic Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[30] Interpolation - Surrounding Whitespace
+ Interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[31] Triple Mustache - Surrounding Whitespace
+ Interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[32] Ampersand - Surrounding Whitespace
+ Interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[33] Interpolation - Standalone
+ Standalone interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[34] Triple Mustache - Standalone
+ Standalone interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[35] Ampersand - Standalone
+ Standalone interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[36] Interpolation With Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+[37] Triple Mustache With Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+[38] Ampersand With Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/inverted.json
+processing file test-specs/spec/specs/inverted.json
+[0] Falsey
+ Falsey sections should have their contents rendered.
+ => SUCCESS
+[1] Truthy
+ Truthy sections should have their contents omitted.
+ => SUCCESS
+[2] Null is falsey
+ Null is falsey.
+ => SUCCESS
+[3] Context
+ Objects and hashes should behave like truthy values.
+ => SUCCESS
+[4] List
+ Lists should behave like truthy values.
+ => SUCCESS
+[5] Empty List
+ Empty lists should behave like falsey values.
+ => SUCCESS
+[6] Doubled
+ Multiple inverted sections per template should be permitted.
+ => SUCCESS
+[7] Nested (Falsey)
+ Nested falsey sections should have their contents rendered.
+ => SUCCESS
+[8] Nested (Truthy)
+ Nested truthy sections should be omitted.
+ => SUCCESS
+[9] Context Misses
+ Failed context lookups should be considered falsey.
+ => SUCCESS
+[10] Dotted Names - Truthy
+ Dotted names should be valid for Inverted Section tags.
+ => SUCCESS
+[11] Dotted Names - Falsey
+ Dotted names should be valid for Inverted Section tags.
+ => SUCCESS
+[12] Dotted Names - Broken Chains
+ Dotted names that cannot be resolved should be considered falsey.
+ => SUCCESS
+[13] Surrounding Whitespace
+ Inverted sections should not alter surrounding whitespace.
+ => SUCCESS
+[14] Internal Whitespace
+ Inverted should not alter internal whitespace.
+ => SUCCESS
+[15] Indented Inline Sections
+ Single-line sections should not alter surrounding whitespace.
+ => SUCCESS
+[16] Standalone Lines
+ Standalone lines should be removed from the template.
+ => SUCCESS
+[17] Standalone Indented Lines
+ Standalone indented lines should be removed from the template.
+ => SUCCESS
+[18] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[19] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[20] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[21] Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/partials.json
+processing file test-specs/spec/specs/partials.json
+[0] Basic Behavior
+ The greater-than operator should expand to the named partial.
+ => SUCCESS
+[1] Failed Lookup
+ The empty string should be used when the named partial is not found.
+ => SUCCESS
+[2] Context
+ The greater-than operator should operate within the current context.
+ => SUCCESS
+[3] Recursion
+ The greater-than operator should properly recurse.
+ => SUCCESS
+[4] Nested
+ The greater-than operator should work from within partials.
+ => SUCCESS
+[5] Surrounding Whitespace
+ The greater-than operator should not alter surrounding whitespace.
+ => SUCCESS
+[6] Inline Indentation
+ Whitespace should be left untouched.
+ => SUCCESS
+[7] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[8] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[9] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[10] Standalone Indentation
+ Each line of the partial should be indented before rendering.
+ => SUCCESS
+[11] Padding Whitespace
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/sections.json
+processing file test-specs/spec/specs/sections.json
+[0] Truthy
+ Truthy sections should have their contents rendered.
+ => SUCCESS
+[1] Falsey
+ Falsey sections should have their contents omitted.
+ => SUCCESS
+[2] Null is falsey
+ Null is falsey.
+ => SUCCESS
+[3] Context
+ Objects and hashes should be pushed onto the context stack.
+ => SUCCESS
+[4] Parent contexts
+ Names missing in the current context are looked up in the stack.
+ => SUCCESS
+[5] Variable test
+ Non-false sections have their value at the top of context,
+accessible as {{.}} or through the parent context. This gives
+a simple way to display content conditionally if a variable exists.
+
+ => SUCCESS
+[6] List Contexts
+ All elements on the context stack should be accessible within lists.
+ => SUCCESS
+[7] Deeply Nested Contexts
+ All elements on the context stack should be accessible.
+ => SUCCESS
+[8] List
+ Lists should be iterated; list items should visit the context stack.
+ => SUCCESS
+[9] Empty List
+ Empty lists should behave like falsey values.
+ => SUCCESS
+[10] Doubled
+ Multiple sections per template should be permitted.
+ => SUCCESS
+[11] Nested (Truthy)
+ Nested truthy sections should have their contents rendered.
+ => SUCCESS
+[12] Nested (Falsey)
+ Nested falsey sections should be omitted.
+ => SUCCESS
+[13] Context Misses
+ Failed context lookups should be considered falsey.
+ => SUCCESS
+[14] Implicit Iterator - String
+ Implicit iterators should directly interpolate strings.
+ => SUCCESS
+[15] Implicit Iterator - Integer
+ Implicit iterators should cast integers to strings and interpolate.
+ => SUCCESS
+[16] Implicit Iterator - Decimal
+ Implicit iterators should cast decimals to strings and interpolate.
+ => SUCCESS
+[17] Implicit Iterator - Array
+ Implicit iterators should allow iterating over nested arrays.
+ => SUCCESS
+[18] Implicit Iterator - HTML Escaping
+ Implicit iterators with basic interpolation should be HTML escaped.
+ => SUCCESS
+[19] Implicit Iterator - Triple mustache
+ Implicit iterators in triple mustache should interpolate without HTML escaping.
+ => SUCCESS
+[20] Implicit Iterator - Ampersand
+ Implicit iterators in an Ampersand tag should interpolate without HTML escaping.
+ => SUCCESS
+[21] Implicit Iterator - Root-level
+ Implicit iterators should work on root-level lists.
+ => SUCCESS
+[22] Dotted Names - Truthy
+ Dotted names should be valid for Section tags.
+ => SUCCESS
+[23] Dotted Names - Falsey
+ Dotted names should be valid for Section tags.
+ => SUCCESS
+[24] Dotted Names - Broken Chains
+ Dotted names that cannot be resolved should be considered falsey.
+ => SUCCESS
+[25] Surrounding Whitespace
+ Sections should not alter surrounding whitespace.
+ => SUCCESS
+[26] Internal Whitespace
+ Sections should not alter internal whitespace.
+ => SUCCESS
+[27] Indented Inline Sections
+ Single-line sections should not alter surrounding whitespace.
+ => SUCCESS
+[28] Standalone Lines
+ Standalone lines should be removed from the template.
+ => SUCCESS
+[29] Indented Standalone Lines
+ Indented standalone lines should be removed from the template.
+ => SUCCESS
+[30] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[31] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[32] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[33] Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+summary:
+ error 0
+ differ 0
+ success 133
diff --git a/src/templating/test-specs/test-specs-jansson.ref b/src/templating/test-specs/test-specs-jansson.ref
new file mode 100644
index 000000000..a1cef19c1
--- /dev/null
+++ b/src/templating/test-specs/test-specs-jansson.ref
@@ -0,0 +1,429 @@
+
+loading test-specs/spec/specs/comments.json
+processing file test-specs/spec/specs/comments.json
+[0] Inline
+ Comment blocks should be removed from the template.
+ => SUCCESS
+[1] Multiline
+ Multiline comments should be permitted.
+ => SUCCESS
+[2] Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[3] Indented Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[4] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[5] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[6] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[7] Multiline Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[8] Indented Multiline Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[9] Indented Inline
+ Inline comments should not strip whitespace
+ => SUCCESS
+[10] Surrounding Whitespace
+ Comment removal should preserve surrounding whitespace.
+ => SUCCESS
+[11] Variable Name Collision
+ Comments must never render, even if variable with same name exists.
+ => SUCCESS
+
+loading test-specs/spec/specs/delimiters.json
+processing file test-specs/spec/specs/delimiters.json
+[0] Pair Behavior
+ The equals sign (used on both sides) should permit delimiter changes.
+ => SUCCESS
+[1] Special Characters
+ Characters with special meaning regexen should be valid delimiters.
+ => SUCCESS
+[2] Sections
+ Delimiters set outside sections should persist.
+ => SUCCESS
+[3] Inverted Sections
+ Delimiters set outside inverted sections should persist.
+ => SUCCESS
+[4] Partial Inheritence
+ Delimiters set in a parent template should not affect a partial.
+ => SUCCESS
+[5] Post-Partial Behavior
+ Delimiters set in a partial should not affect the parent template.
+ => SUCCESS
+[6] Surrounding Whitespace
+ Surrounding whitespace should be left untouched.
+ => SUCCESS
+[7] Outlying Whitespace (Inline)
+ Whitespace should be left untouched.
+ => SUCCESS
+[8] Standalone Tag
+ Standalone lines should be removed from the template.
+ => SUCCESS
+[9] Indented Standalone Tag
+ Indented standalone lines should be removed from the template.
+ => SUCCESS
+[10] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[11] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[12] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[13] Pair with Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/interpolation.json
+processing file test-specs/spec/specs/interpolation.json
+[0] No Interpolation
+ Mustache-free templates should render as-is.
+ => SUCCESS
+[1] Basic Interpolation
+ Unadorned tags should interpolate content into the template.
+ => SUCCESS
+[2] HTML Escaping
+ Basic interpolation should be HTML escaped.
+ => SUCCESS
+[3] Triple Mustache
+ Triple mustaches should interpolate without HTML escaping.
+ => SUCCESS
+[4] Ampersand
+ Ampersand should interpolate without HTML escaping.
+ => SUCCESS
+[5] Basic Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[6] Triple Mustache Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[7] Ampersand Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[8] Basic Decimal Interpolation
+ Decimals should interpolate seamlessly with proper significance.
+ => SUCCESS
+[9] Triple Mustache Decimal Interpolation
+ Decimals should interpolate seamlessly with proper significance.
+ => SUCCESS
+[10] Ampersand Decimal Interpolation
+ Decimals should interpolate seamlessly with proper significance.
+ => SUCCESS
+[11] Basic Null Interpolation
+ Nulls should interpolate as the empty string.
+ => SUCCESS
+[12] Triple Mustache Null Interpolation
+ Nulls should interpolate as the empty string.
+ => SUCCESS
+[13] Ampersand Null Interpolation
+ Nulls should interpolate as the empty string.
+ => SUCCESS
+[14] Basic Context Miss Interpolation
+ Failed context lookups should default to empty strings.
+ => SUCCESS
+[15] Triple Mustache Context Miss Interpolation
+ Failed context lookups should default to empty strings.
+ => SUCCESS
+[16] Ampersand Context Miss Interpolation
+ Failed context lookups should default to empty strings.
+ => SUCCESS
+[17] Dotted Names - Basic Interpolation
+ Dotted names should be considered a form of shorthand for sections.
+ => SUCCESS
+[18] Dotted Names - Triple Mustache Interpolation
+ Dotted names should be considered a form of shorthand for sections.
+ => SUCCESS
+[19] Dotted Names - Ampersand Interpolation
+ Dotted names should be considered a form of shorthand for sections.
+ => SUCCESS
+[20] Dotted Names - Arbitrary Depth
+ Dotted names should be functional to any level of nesting.
+ => SUCCESS
+[21] Dotted Names - Broken Chains
+ Any falsey value prior to the last part of the name should yield ''.
+ => SUCCESS
+[22] Dotted Names - Broken Chain Resolution
+ Each part of a dotted name should resolve only against its parent.
+ => SUCCESS
+[23] Dotted Names - Initial Resolution
+ The first part of a dotted name should resolve as any other name.
+ => SUCCESS
+[24] Dotted Names - Context Precedence
+ Dotted names should be resolved against former resolutions.
+ => SUCCESS
+[25] Implicit Iterators - Basic Interpolation
+ Unadorned tags should interpolate content into the template.
+ => SUCCESS
+[26] Implicit Iterators - HTML Escaping
+ Basic interpolation should be HTML escaped.
+ => SUCCESS
+[27] Implicit Iterators - Triple Mustache
+ Triple mustaches should interpolate without HTML escaping.
+ => SUCCESS
+[28] Implicit Iterators - Ampersand
+ Ampersand should interpolate without HTML escaping.
+ => SUCCESS
+[29] Implicit Iterators - Basic Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[30] Interpolation - Surrounding Whitespace
+ Interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[31] Triple Mustache - Surrounding Whitespace
+ Interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[32] Ampersand - Surrounding Whitespace
+ Interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[33] Interpolation - Standalone
+ Standalone interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[34] Triple Mustache - Standalone
+ Standalone interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[35] Ampersand - Standalone
+ Standalone interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[36] Interpolation With Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+[37] Triple Mustache With Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+[38] Ampersand With Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/inverted.json
+processing file test-specs/spec/specs/inverted.json
+[0] Falsey
+ Falsey sections should have their contents rendered.
+ => SUCCESS
+[1] Truthy
+ Truthy sections should have their contents omitted.
+ => SUCCESS
+[2] Null is falsey
+ Null is falsey.
+ => SUCCESS
+[3] Context
+ Objects and hashes should behave like truthy values.
+ => SUCCESS
+[4] List
+ Lists should behave like truthy values.
+ => SUCCESS
+[5] Empty List
+ Empty lists should behave like falsey values.
+ => SUCCESS
+[6] Doubled
+ Multiple inverted sections per template should be permitted.
+ => SUCCESS
+[7] Nested (Falsey)
+ Nested falsey sections should have their contents rendered.
+ => SUCCESS
+[8] Nested (Truthy)
+ Nested truthy sections should be omitted.
+ => SUCCESS
+[9] Context Misses
+ Failed context lookups should be considered falsey.
+ => SUCCESS
+[10] Dotted Names - Truthy
+ Dotted names should be valid for Inverted Section tags.
+ => SUCCESS
+[11] Dotted Names - Falsey
+ Dotted names should be valid for Inverted Section tags.
+ => SUCCESS
+[12] Dotted Names - Broken Chains
+ Dotted names that cannot be resolved should be considered falsey.
+ => SUCCESS
+[13] Surrounding Whitespace
+ Inverted sections should not alter surrounding whitespace.
+ => SUCCESS
+[14] Internal Whitespace
+ Inverted should not alter internal whitespace.
+ => SUCCESS
+[15] Indented Inline Sections
+ Single-line sections should not alter surrounding whitespace.
+ => SUCCESS
+[16] Standalone Lines
+ Standalone lines should be removed from the template.
+ => SUCCESS
+[17] Standalone Indented Lines
+ Standalone indented lines should be removed from the template.
+ => SUCCESS
+[18] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[19] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[20] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[21] Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/partials.json
+processing file test-specs/spec/specs/partials.json
+[0] Basic Behavior
+ The greater-than operator should expand to the named partial.
+ => SUCCESS
+[1] Failed Lookup
+ The empty string should be used when the named partial is not found.
+ => SUCCESS
+[2] Context
+ The greater-than operator should operate within the current context.
+ => SUCCESS
+[3] Recursion
+ The greater-than operator should properly recurse.
+ => SUCCESS
+[4] Nested
+ The greater-than operator should work from within partials.
+ => SUCCESS
+[5] Surrounding Whitespace
+ The greater-than operator should not alter surrounding whitespace.
+ => SUCCESS
+[6] Inline Indentation
+ Whitespace should be left untouched.
+ => SUCCESS
+[7] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[8] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[9] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[10] Standalone Indentation
+ Each line of the partial should be indented before rendering.
+ => SUCCESS
+[11] Padding Whitespace
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/sections.json
+processing file test-specs/spec/specs/sections.json
+[0] Truthy
+ Truthy sections should have their contents rendered.
+ => SUCCESS
+[1] Falsey
+ Falsey sections should have their contents omitted.
+ => SUCCESS
+[2] Null is falsey
+ Null is falsey.
+ => SUCCESS
+[3] Context
+ Objects and hashes should be pushed onto the context stack.
+ => SUCCESS
+[4] Parent contexts
+ Names missing in the current context are looked up in the stack.
+ => SUCCESS
+[5] Variable test
+ Non-false sections have their value at the top of context,
+accessible as {{.}} or through the parent context. This gives
+a simple way to display content conditionally if a variable exists.
+
+ => SUCCESS
+[6] List Contexts
+ All elements on the context stack should be accessible within lists.
+ => SUCCESS
+[7] Deeply Nested Contexts
+ All elements on the context stack should be accessible.
+ => SUCCESS
+[8] List
+ Lists should be iterated; list items should visit the context stack.
+ => SUCCESS
+[9] Empty List
+ Empty lists should behave like falsey values.
+ => SUCCESS
+[10] Doubled
+ Multiple sections per template should be permitted.
+ => SUCCESS
+[11] Nested (Truthy)
+ Nested truthy sections should have their contents rendered.
+ => SUCCESS
+[12] Nested (Falsey)
+ Nested falsey sections should be omitted.
+ => SUCCESS
+[13] Context Misses
+ Failed context lookups should be considered falsey.
+ => SUCCESS
+[14] Implicit Iterator - String
+ Implicit iterators should directly interpolate strings.
+ => SUCCESS
+[15] Implicit Iterator - Integer
+ Implicit iterators should cast integers to strings and interpolate.
+ => SUCCESS
+[16] Implicit Iterator - Decimal
+ Implicit iterators should cast decimals to strings and interpolate.
+ => DIFFERS
+ .. DATA[{"list":[1.1000000000000001,2.2000000000000002,3.2999999999999998,4.4000000000000004,5.5]}]
+ .. TEMPLATE["{{#list}}({{.}}){{/list}}"]
+ .. EXPECTED["(1.1)(2.2)(3.3)(4.4)(5.5)"]
+ .. GOT["(1.1000000000000001)(2.2000000000000002)(3.2999999999999998)(4.4000000000000004)(5.5)"]
+[17] Implicit Iterator - Array
+ Implicit iterators should allow iterating over nested arrays.
+ => SUCCESS
+[18] Implicit Iterator - HTML Escaping
+ Implicit iterators with basic interpolation should be HTML escaped.
+ => SUCCESS
+[19] Implicit Iterator - Triple mustache
+ Implicit iterators in triple mustache should interpolate without HTML escaping.
+ => SUCCESS
+[20] Implicit Iterator - Ampersand
+ Implicit iterators in an Ampersand tag should interpolate without HTML escaping.
+ => SUCCESS
+[21] Implicit Iterator - Root-level
+ Implicit iterators should work on root-level lists.
+ => SUCCESS
+[22] Dotted Names - Truthy
+ Dotted names should be valid for Section tags.
+ => SUCCESS
+[23] Dotted Names - Falsey
+ Dotted names should be valid for Section tags.
+ => SUCCESS
+[24] Dotted Names - Broken Chains
+ Dotted names that cannot be resolved should be considered falsey.
+ => SUCCESS
+[25] Surrounding Whitespace
+ Sections should not alter surrounding whitespace.
+ => SUCCESS
+[26] Internal Whitespace
+ Sections should not alter internal whitespace.
+ => SUCCESS
+[27] Indented Inline Sections
+ Single-line sections should not alter surrounding whitespace.
+ => SUCCESS
+[28] Standalone Lines
+ Standalone lines should be removed from the template.
+ => SUCCESS
+[29] Indented Standalone Lines
+ Indented standalone lines should be removed from the template.
+ => SUCCESS
+[30] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[31] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[32] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[33] Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+summary:
+ error 0
+ differ 1
+ success 132
diff --git a/src/templating/test-specs/test-specs-json-c.ref b/src/templating/test-specs/test-specs-json-c.ref
new file mode 100644
index 000000000..8897c66cc
--- /dev/null
+++ b/src/templating/test-specs/test-specs-json-c.ref
@@ -0,0 +1,425 @@
+
+loading test-specs/spec/specs/comments.json
+processing file test-specs/spec/specs/comments.json
+[0] Inline
+ Comment blocks should be removed from the template.
+ => SUCCESS
+[1] Multiline
+ Multiline comments should be permitted.
+ => SUCCESS
+[2] Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[3] Indented Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[4] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[5] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[6] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[7] Multiline Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[8] Indented Multiline Standalone
+ All standalone comment lines should be removed.
+ => SUCCESS
+[9] Indented Inline
+ Inline comments should not strip whitespace
+ => SUCCESS
+[10] Surrounding Whitespace
+ Comment removal should preserve surrounding whitespace.
+ => SUCCESS
+[11] Variable Name Collision
+ Comments must never render, even if variable with same name exists.
+ => SUCCESS
+
+loading test-specs/spec/specs/delimiters.json
+processing file test-specs/spec/specs/delimiters.json
+[0] Pair Behavior
+ The equals sign (used on both sides) should permit delimiter changes.
+ => SUCCESS
+[1] Special Characters
+ Characters with special meaning regexen should be valid delimiters.
+ => SUCCESS
+[2] Sections
+ Delimiters set outside sections should persist.
+ => SUCCESS
+[3] Inverted Sections
+ Delimiters set outside inverted sections should persist.
+ => SUCCESS
+[4] Partial Inheritence
+ Delimiters set in a parent template should not affect a partial.
+ => SUCCESS
+[5] Post-Partial Behavior
+ Delimiters set in a partial should not affect the parent template.
+ => SUCCESS
+[6] Surrounding Whitespace
+ Surrounding whitespace should be left untouched.
+ => SUCCESS
+[7] Outlying Whitespace (Inline)
+ Whitespace should be left untouched.
+ => SUCCESS
+[8] Standalone Tag
+ Standalone lines should be removed from the template.
+ => SUCCESS
+[9] Indented Standalone Tag
+ Indented standalone lines should be removed from the template.
+ => SUCCESS
+[10] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[11] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[12] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[13] Pair with Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/interpolation.json
+processing file test-specs/spec/specs/interpolation.json
+[0] No Interpolation
+ Mustache-free templates should render as-is.
+ => SUCCESS
+[1] Basic Interpolation
+ Unadorned tags should interpolate content into the template.
+ => SUCCESS
+[2] HTML Escaping
+ Basic interpolation should be HTML escaped.
+ => SUCCESS
+[3] Triple Mustache
+ Triple mustaches should interpolate without HTML escaping.
+ => SUCCESS
+[4] Ampersand
+ Ampersand should interpolate without HTML escaping.
+ => SUCCESS
+[5] Basic Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[6] Triple Mustache Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[7] Ampersand Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[8] Basic Decimal Interpolation
+ Decimals should interpolate seamlessly with proper significance.
+ => SUCCESS
+[9] Triple Mustache Decimal Interpolation
+ Decimals should interpolate seamlessly with proper significance.
+ => SUCCESS
+[10] Ampersand Decimal Interpolation
+ Decimals should interpolate seamlessly with proper significance.
+ => SUCCESS
+[11] Basic Null Interpolation
+ Nulls should interpolate as the empty string.
+ => SUCCESS
+[12] Triple Mustache Null Interpolation
+ Nulls should interpolate as the empty string.
+ => SUCCESS
+[13] Ampersand Null Interpolation
+ Nulls should interpolate as the empty string.
+ => SUCCESS
+[14] Basic Context Miss Interpolation
+ Failed context lookups should default to empty strings.
+ => SUCCESS
+[15] Triple Mustache Context Miss Interpolation
+ Failed context lookups should default to empty strings.
+ => SUCCESS
+[16] Ampersand Context Miss Interpolation
+ Failed context lookups should default to empty strings.
+ => SUCCESS
+[17] Dotted Names - Basic Interpolation
+ Dotted names should be considered a form of shorthand for sections.
+ => SUCCESS
+[18] Dotted Names - Triple Mustache Interpolation
+ Dotted names should be considered a form of shorthand for sections.
+ => SUCCESS
+[19] Dotted Names - Ampersand Interpolation
+ Dotted names should be considered a form of shorthand for sections.
+ => SUCCESS
+[20] Dotted Names - Arbitrary Depth
+ Dotted names should be functional to any level of nesting.
+ => SUCCESS
+[21] Dotted Names - Broken Chains
+ Any falsey value prior to the last part of the name should yield ''.
+ => SUCCESS
+[22] Dotted Names - Broken Chain Resolution
+ Each part of a dotted name should resolve only against its parent.
+ => SUCCESS
+[23] Dotted Names - Initial Resolution
+ The first part of a dotted name should resolve as any other name.
+ => SUCCESS
+[24] Dotted Names - Context Precedence
+ Dotted names should be resolved against former resolutions.
+ => SUCCESS
+[25] Implicit Iterators - Basic Interpolation
+ Unadorned tags should interpolate content into the template.
+ => SUCCESS
+[26] Implicit Iterators - HTML Escaping
+ Basic interpolation should be HTML escaped.
+ => SUCCESS
+[27] Implicit Iterators - Triple Mustache
+ Triple mustaches should interpolate without HTML escaping.
+ => SUCCESS
+[28] Implicit Iterators - Ampersand
+ Ampersand should interpolate without HTML escaping.
+ => SUCCESS
+[29] Implicit Iterators - Basic Integer Interpolation
+ Integers should interpolate seamlessly.
+ => SUCCESS
+[30] Interpolation - Surrounding Whitespace
+ Interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[31] Triple Mustache - Surrounding Whitespace
+ Interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[32] Ampersand - Surrounding Whitespace
+ Interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[33] Interpolation - Standalone
+ Standalone interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[34] Triple Mustache - Standalone
+ Standalone interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[35] Ampersand - Standalone
+ Standalone interpolation should not alter surrounding whitespace.
+ => SUCCESS
+[36] Interpolation With Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+[37] Triple Mustache With Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+[38] Ampersand With Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/inverted.json
+processing file test-specs/spec/specs/inverted.json
+[0] Falsey
+ Falsey sections should have their contents rendered.
+ => SUCCESS
+[1] Truthy
+ Truthy sections should have their contents omitted.
+ => SUCCESS
+[2] Null is falsey
+ Null is falsey.
+ => SUCCESS
+[3] Context
+ Objects and hashes should behave like truthy values.
+ => SUCCESS
+[4] List
+ Lists should behave like truthy values.
+ => SUCCESS
+[5] Empty List
+ Empty lists should behave like falsey values.
+ => SUCCESS
+[6] Doubled
+ Multiple inverted sections per template should be permitted.
+ => SUCCESS
+[7] Nested (Falsey)
+ Nested falsey sections should have their contents rendered.
+ => SUCCESS
+[8] Nested (Truthy)
+ Nested truthy sections should be omitted.
+ => SUCCESS
+[9] Context Misses
+ Failed context lookups should be considered falsey.
+ => SUCCESS
+[10] Dotted Names - Truthy
+ Dotted names should be valid for Inverted Section tags.
+ => SUCCESS
+[11] Dotted Names - Falsey
+ Dotted names should be valid for Inverted Section tags.
+ => SUCCESS
+[12] Dotted Names - Broken Chains
+ Dotted names that cannot be resolved should be considered falsey.
+ => SUCCESS
+[13] Surrounding Whitespace
+ Inverted sections should not alter surrounding whitespace.
+ => SUCCESS
+[14] Internal Whitespace
+ Inverted should not alter internal whitespace.
+ => SUCCESS
+[15] Indented Inline Sections
+ Single-line sections should not alter surrounding whitespace.
+ => SUCCESS
+[16] Standalone Lines
+ Standalone lines should be removed from the template.
+ => SUCCESS
+[17] Standalone Indented Lines
+ Standalone indented lines should be removed from the template.
+ => SUCCESS
+[18] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[19] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[20] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[21] Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/partials.json
+processing file test-specs/spec/specs/partials.json
+[0] Basic Behavior
+ The greater-than operator should expand to the named partial.
+ => SUCCESS
+[1] Failed Lookup
+ The empty string should be used when the named partial is not found.
+ => SUCCESS
+[2] Context
+ The greater-than operator should operate within the current context.
+ => SUCCESS
+[3] Recursion
+ The greater-than operator should properly recurse.
+ => SUCCESS
+[4] Nested
+ The greater-than operator should work from within partials.
+ => SUCCESS
+[5] Surrounding Whitespace
+ The greater-than operator should not alter surrounding whitespace.
+ => SUCCESS
+[6] Inline Indentation
+ Whitespace should be left untouched.
+ => SUCCESS
+[7] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[8] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[9] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[10] Standalone Indentation
+ Each line of the partial should be indented before rendering.
+ => SUCCESS
+[11] Padding Whitespace
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+loading test-specs/spec/specs/sections.json
+processing file test-specs/spec/specs/sections.json
+[0] Truthy
+ Truthy sections should have their contents rendered.
+ => SUCCESS
+[1] Falsey
+ Falsey sections should have their contents omitted.
+ => SUCCESS
+[2] Null is falsey
+ Null is falsey.
+ => SUCCESS
+[3] Context
+ Objects and hashes should be pushed onto the context stack.
+ => SUCCESS
+[4] Parent contexts
+ Names missing in the current context are looked up in the stack.
+ => SUCCESS
+[5] Variable test
+ Non-false sections have their value at the top of context,
+accessible as {{.}} or through the parent context. This gives
+a simple way to display content conditionally if a variable exists.
+
+ => SUCCESS
+[6] List Contexts
+ All elements on the context stack should be accessible within lists.
+ => SUCCESS
+[7] Deeply Nested Contexts
+ All elements on the context stack should be accessible.
+ => SUCCESS
+[8] List
+ Lists should be iterated; list items should visit the context stack.
+ => SUCCESS
+[9] Empty List
+ Empty lists should behave like falsey values.
+ => SUCCESS
+[10] Doubled
+ Multiple sections per template should be permitted.
+ => SUCCESS
+[11] Nested (Truthy)
+ Nested truthy sections should have their contents rendered.
+ => SUCCESS
+[12] Nested (Falsey)
+ Nested falsey sections should be omitted.
+ => SUCCESS
+[13] Context Misses
+ Failed context lookups should be considered falsey.
+ => SUCCESS
+[14] Implicit Iterator - String
+ Implicit iterators should directly interpolate strings.
+ => SUCCESS
+[15] Implicit Iterator - Integer
+ Implicit iterators should cast integers to strings and interpolate.
+ => SUCCESS
+[16] Implicit Iterator - Decimal
+ Implicit iterators should cast decimals to strings and interpolate.
+ => SUCCESS
+[17] Implicit Iterator - Array
+ Implicit iterators should allow iterating over nested arrays.
+ => SUCCESS
+[18] Implicit Iterator - HTML Escaping
+ Implicit iterators with basic interpolation should be HTML escaped.
+ => SUCCESS
+[19] Implicit Iterator - Triple mustache
+ Implicit iterators in triple mustache should interpolate without HTML escaping.
+ => SUCCESS
+[20] Implicit Iterator - Ampersand
+ Implicit iterators in an Ampersand tag should interpolate without HTML escaping.
+ => SUCCESS
+[21] Implicit Iterator - Root-level
+ Implicit iterators should work on root-level lists.
+ => SUCCESS
+[22] Dotted Names - Truthy
+ Dotted names should be valid for Section tags.
+ => SUCCESS
+[23] Dotted Names - Falsey
+ Dotted names should be valid for Section tags.
+ => SUCCESS
+[24] Dotted Names - Broken Chains
+ Dotted names that cannot be resolved should be considered falsey.
+ => SUCCESS
+[25] Surrounding Whitespace
+ Sections should not alter surrounding whitespace.
+ => SUCCESS
+[26] Internal Whitespace
+ Sections should not alter internal whitespace.
+ => SUCCESS
+[27] Indented Inline Sections
+ Single-line sections should not alter surrounding whitespace.
+ => SUCCESS
+[28] Standalone Lines
+ Standalone lines should be removed from the template.
+ => SUCCESS
+[29] Indented Standalone Lines
+ Indented standalone lines should be removed from the template.
+ => SUCCESS
+[30] Standalone Line Endings
+ "\r\n" should be considered a newline for standalone tags.
+ => SUCCESS
+[31] Standalone Without Previous Line
+ Standalone tags should not require a newline to precede them.
+ => SUCCESS
+[32] Standalone Without Newline
+ Standalone tags should not require a newline to follow them.
+ => SUCCESS
+[33] Padding
+ Superfluous in-tag whitespace should be ignored.
+ => SUCCESS
+
+summary:
+ error 0
+ differ 0
+ success 133
diff --git a/src/templating/test-specs/test-specs.c b/src/templating/test-specs/test-specs.c
new file mode 100644
index 000000000..15c94a80e
--- /dev/null
+++ b/src/templating/test-specs/test-specs.c
@@ -0,0 +1,520 @@
+/*
+ Author: José Bollo <jobol@nonadev.net>
+
+ https://gitlab.com/jobol/mustach
+
+ SPDX-License-Identifier: ISC
+*/
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "mustach-wrap.h"
+
+#define TEST_JSON_C 1
+#define TEST_JANSSON 2
+#define TEST_CJSON 3
+
+static const char *errors[] = {
+ "??? unreferenced ???",
+ "system",
+ "unexpected end",
+ "empty tag",
+ "tag too long",
+ "bad separators",
+ "too depth",
+ "closing",
+ "bad unescape tag",
+ "invalid interface",
+ "item not found",
+ "partial not found"
+};
+
+const char *mustach_error_string(int status)
+{
+ return status >= 0 ? "no error"
+ : errors[status <= -(int)(sizeof errors / sizeof * errors) ? 0 : -status];
+}
+
+static const char *errmsg = 0;
+static int flags = 0;
+static FILE *output = 0;
+
+static void help(char *prog)
+{
+ char *name = basename(prog);
+#define STR(x) #x
+ printf("%s version %s\n", name, STR(VERSION));
+#undef STR
+ printf("usage: %s test-files...\n", name);
+ exit(0);
+}
+
+#if TEST == TEST_CJSON
+
+static const size_t BLOCKSIZE = 8192;
+
+static char *readfile(const char *filename, size_t *length)
+{
+ int f;
+ struct stat s;
+ char *result;
+ size_t size, pos;
+ ssize_t rc;
+
+ result = NULL;
+ if (filename[0] == '-' && filename[1] == 0)
+ f = dup(0);
+ else
+ f = open(filename, O_RDONLY);
+ if (f < 0) {
+ fprintf(stderr, "Can't open file: %s\n", filename);
+ exit(1);
+ }
+
+ fstat(f, &s);
+ switch (s.st_mode & S_IFMT) {
+ case S_IFREG:
+ size = s.st_size;
+ break;
+ case S_IFSOCK:
+ case S_IFIFO:
+ size = BLOCKSIZE;
+ break;
+ default:
+ fprintf(stderr, "Bad file: %s\n", filename);
+ exit(1);
+ }
+
+ pos = 0;
+ result = malloc(size + 1);
+ do {
+ if (result == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ rc = read(f, &result[pos], (size - pos) + 1);
+ if (rc < 0) {
+ fprintf(stderr, "Error while reading %s\n", filename);
+ exit(1);
+ }
+ if (rc > 0) {
+ pos += (size_t)rc;
+ if (pos > size) {
+ size = pos + BLOCKSIZE;
+ result = realloc(result, size + 1);
+ }
+ }
+ } while(rc > 0);
+
+ close(f);
+ if (length != NULL)
+ *length = pos;
+ result[pos] = 0;
+ return result;
+}
+#endif
+
+typedef struct {
+ unsigned nerror;
+ unsigned ndiffers;
+ unsigned nsuccess;
+ unsigned ninvalid;
+} counters;
+
+static int load_json(const char *filename);
+static int process(counters *c);
+static void close_json();
+static int get_partial(const char *name, struct mustach_sbuf *sbuf);
+
+int main(int ac, char **av)
+{
+ char *f;
+ char *prog = *av;
+ int s;
+ counters c;
+
+ (void)ac; /* unused */
+ flags = Mustach_With_SingleDot | Mustach_With_IncPartial;
+ output = stdout;
+ mustach_wrap_get_partial = get_partial;
+
+ memset(&c, 0, sizeof c);
+ while (*++av) {
+ if (!strcmp(*av, "-h") || !strcmp(*av, "--help"))
+ help(prog);
+ f = (av[0][0] == '-' && !av[0][1]) ? "/dev/stdin" : av[0];
+ fprintf(output, "\nloading %s\n", f);
+ s = load_json(f);
+ if (s < 0) {
+ fprintf(stderr, "error when loading %s!\n", f);
+ if(errmsg)
+ fprintf(stderr, " reason: %s\n", errmsg);
+ exit(1);
+ }
+ fprintf(output, "processing file %s\n", f);
+ s = process(&c);
+ if (s < 0) {
+ fprintf(stderr, "error bad test file %s!\n", f);
+ exit(1);
+ }
+ close_json();
+ }
+ fprintf(output, "\nsummary:\n");
+ if (c.ninvalid)
+ fprintf(output, " invalid %u\n", c.ninvalid);
+ fprintf(output, " error %u\n", c.nerror);
+ fprintf(output, " differ %u\n", c.ndiffers);
+ fprintf(output, " success %u\n", c.nsuccess);
+ if (c.nerror)
+ return 2;
+ if (c.ndiffers)
+ return 1;
+ return 0;
+}
+
+void emit(FILE *f, const char *s)
+{
+ for(;;s++) {
+ switch(*s) {
+ case 0: return;
+ case '\\': fprintf(f, "\\\\"); break;
+ case '\t': fprintf(f, "\\t"); break;
+ case '\n': fprintf(f, "\\n"); break;
+ case '\r': fprintf(f, "\\r"); break;
+ default: fprintf(f, "%c", *s); break;
+ }
+ }
+}
+
+#if TEST == TEST_JSON_C
+
+#include "mustach-json-c.h"
+
+static struct json_object *o;
+
+static struct json_object *partials;
+static int get_partial(const char *name, struct mustach_sbuf *sbuf)
+{
+ struct json_object *x;
+ if (partials == NULL || !json_object_object_get_ex(partials, name, &x))
+ return MUSTACH_ERROR_PARTIAL_NOT_FOUND;
+ sbuf->value = json_object_get_string(x);
+ return MUSTACH_OK;
+}
+
+static int load_json(const char *filename)
+{
+ o = json_object_from_file(filename);
+#if JSON_C_VERSION_NUM >= 0x000D00
+ errmsg = json_util_get_last_err();
+ if (errmsg != NULL)
+ return -1;
+#endif
+ if (o == NULL) {
+ errmsg = "null json";
+ return -1;
+ }
+ return 0;
+}
+static int process(counters *c)
+{
+ const char *t, *e;
+ char *got;
+ unsigned i, n;
+ size_t length;
+ int s;
+ json_object *tests, *unit, *name, *desc, *data, *template, *expected;
+
+ if (!json_object_object_get_ex(o, "tests", &tests) || json_object_get_type(tests) != json_type_array)
+ return -1;
+
+ i = 0;
+ n = (unsigned)json_object_array_length(tests);
+ while (i < n) {
+ unit = json_object_array_get_idx(tests, i);
+ if (json_object_get_type(unit) != json_type_object
+ || !json_object_object_get_ex(unit, "name", &name)
+ || !json_object_object_get_ex(unit, "desc", &desc)
+ || !json_object_object_get_ex(unit, "data", &data)
+ || !json_object_object_get_ex(unit, "template", &template)
+ || !json_object_object_get_ex(unit, "expected", &expected)
+ || json_object_get_type(name) != json_type_string
+ || json_object_get_type(desc) != json_type_string
+ || json_object_get_type(template) != json_type_string
+ || json_object_get_type(expected) != json_type_string) {
+ fprintf(stderr, "invalid test %u\n", i);
+ c->ninvalid++;
+ }
+ else {
+ fprintf(output, "[%u] %s\n", i, json_object_get_string(name));
+ fprintf(output, "\t%s\n", json_object_get_string(desc));
+ if (!json_object_object_get_ex(unit, "partials", &partials))
+ partials = NULL;
+ t = json_object_get_string(template);
+ e = json_object_get_string(expected);
+ s = mustach_json_c_mem(t, 0, data, flags, &got, &length);
+ if (s == 0 && strcmp(got, e) == 0) {
+ fprintf(output, "\t=> SUCCESS\n");
+ c->nsuccess++;
+ }
+ else {
+ if (s < 0) {
+ fprintf(output, "\t=> ERROR %s\n", mustach_error_string(s));
+ c->nerror++;
+ }
+ else {
+ fprintf(output, "\t=> DIFFERS\n");
+ c->ndiffers++;
+ }
+ if (partials)
+ fprintf(output, "\t.. PARTIALS[%s]\n", json_object_to_json_string_ext(partials, 0));
+ fprintf(output, "\t.. DATA[%s]\n", json_object_to_json_string_ext(data, 0));
+ fprintf(output, "\t.. TEMPLATE[");
+ emit(output, t);
+ fprintf(output, "]\n");
+ fprintf(output, "\t.. EXPECTED[");
+ emit(output, e);
+ fprintf(output, "]\n");
+ if (s == 0) {
+ fprintf(output, "\t.. GOT[");
+ emit(output, got);
+ fprintf(output, "]\n");
+ }
+ }
+ free(got);
+ }
+ i++;
+ }
+ return 0;
+}
+static void close_json()
+{
+ json_object_put(o);
+}
+
+#elif TEST == TEST_JANSSON
+
+#include "mustach-jansson.h"
+
+static json_t *o;
+static json_error_t e;
+
+static json_t *partials;
+static int get_partial(const char *name, struct mustach_sbuf *sbuf)
+{
+ json_t *x;
+ if (partials == NULL || !(x = json_object_get(partials, name)))
+ return MUSTACH_ERROR_PARTIAL_NOT_FOUND;
+ sbuf->value = json_string_value(x);
+ return MUSTACH_OK;
+}
+
+static int load_json(const char *filename)
+{
+ o = json_load_file(filename, JSON_DECODE_ANY, &e);
+ if (o == NULL) {
+ errmsg = e.text;
+ return -1;
+ }
+ return 0;
+}
+static int process(counters *c)
+{
+ const char *t, *e;
+ char *got, *tmp;
+ int i, n;
+ size_t length;
+ int s;
+ json_t *tests, *unit, *name, *desc, *data, *template, *expected;
+
+ tests = json_object_get(o, "tests");
+ if (!tests || json_typeof(tests) != JSON_ARRAY)
+ return -1;
+
+ i = 0;
+ n = json_array_size(tests);
+ while (i < n) {
+ unit = json_array_get(tests, i);
+ if (!unit || json_typeof(unit) != JSON_OBJECT
+ || !(name = json_object_get(unit, "name"))
+ || !(desc = json_object_get(unit, "desc"))
+ || !(data = json_object_get(unit, "data"))
+ || !(template = json_object_get(unit, "template"))
+ || !(expected = json_object_get(unit, "expected"))
+ || json_typeof(name) != JSON_STRING
+ || json_typeof(desc) != JSON_STRING
+ || json_typeof(template) != JSON_STRING
+ || json_typeof(expected) != JSON_STRING) {
+ fprintf(stderr, "invalid test %u\n", i);
+ c->ninvalid++;
+ }
+ else {
+ fprintf(output, "[%u] %s\n", i, json_string_value(name));
+ fprintf(output, "\t%s\n", json_string_value(desc));
+ partials = json_object_get(unit, "partials");
+ t = json_string_value(template);
+ e = json_string_value(expected);
+ s = mustach_jansson_mem(t, 0, data, flags, &got, &length);
+ if (s == 0 && strcmp(got, e) == 0) {
+ fprintf(output, "\t=> SUCCESS\n");
+ c->nsuccess++;
+ }
+ else {
+ if (s < 0) {
+ fprintf(output, "\t=> ERROR %s\n", mustach_error_string(s));
+ c->nerror++;
+ }
+ else {
+ fprintf(output, "\t=> DIFFERS\n");
+ c->ndiffers++;
+ }
+ if (partials) {
+ tmp = json_dumps(partials, JSON_ENCODE_ANY | JSON_COMPACT);
+ fprintf(output, "\t.. PARTIALS[%s]\n", tmp);
+ free(tmp);
+ }
+ tmp = json_dumps(data, JSON_ENCODE_ANY | JSON_COMPACT);
+ fprintf(output, "\t.. DATA[%s]\n", tmp);
+ free(tmp);
+ fprintf(output, "\t.. TEMPLATE[");
+ emit(output, t);
+ fprintf(output, "]\n");
+ fprintf(output, "\t.. EXPECTED[");
+ emit(output, e);
+ fprintf(output, "]\n");
+ if (s == 0) {
+ fprintf(output, "\t.. GOT[");
+ emit(output, got);
+ fprintf(output, "]\n");
+ }
+ }
+ free(got);
+ }
+ i++;
+ }
+ return 0;
+}
+static void close_json()
+{
+ json_decref(o);
+}
+
+#elif TEST == TEST_CJSON
+
+#include "mustach-cjson.h"
+
+static cJSON *o;
+static cJSON *partials;
+static int get_partial(const char *name, struct mustach_sbuf *sbuf)
+{
+ cJSON *x;
+ if (partials == NULL || !(x = cJSON_GetObjectItemCaseSensitive(partials, name)))
+ return MUSTACH_ERROR_PARTIAL_NOT_FOUND;
+ sbuf->value = x->valuestring;
+ return MUSTACH_OK;
+}
+
+static int load_json(const char *filename)
+{
+ char *t;
+ size_t length;
+
+ t = readfile(filename, &length);
+ o = t ? cJSON_ParseWithLength(t, length) : NULL;
+ free(t);
+ return -!o;
+}
+static int process(counters *c)
+{
+ const char *t, *e;
+ char *got, *tmp;
+ int i, n;
+ size_t length;
+ int s;
+ cJSON *tests, *unit, *name, *desc, *data, *template, *expected;
+
+ tests = cJSON_GetObjectItemCaseSensitive(o, "tests");
+ if (!tests || tests->type != cJSON_Array)
+ return -1;
+
+ i = 0;
+ n = cJSON_GetArraySize(tests);
+ while (i < n) {
+ unit = cJSON_GetArrayItem(tests, i);
+ if (!unit || unit->type != cJSON_Object
+ || !(name = cJSON_GetObjectItemCaseSensitive(unit, "name"))
+ || !(desc = cJSON_GetObjectItemCaseSensitive(unit, "desc"))
+ || !(data = cJSON_GetObjectItemCaseSensitive(unit, "data"))
+ || !(template = cJSON_GetObjectItemCaseSensitive(unit, "template"))
+ || !(expected = cJSON_GetObjectItemCaseSensitive(unit, "expected"))
+ || name->type != cJSON_String
+ || desc->type != cJSON_String
+ || template->type != cJSON_String
+ || expected->type != cJSON_String) {
+ fprintf(stderr, "invalid test %u\n", i);
+ c->ninvalid++;
+ }
+ else {
+ fprintf(output, "[%u] %s\n", i, name->valuestring);
+ fprintf(output, "\t%s\n", desc->valuestring);
+ partials = cJSON_GetObjectItemCaseSensitive(unit, "partials");
+ t = template->valuestring;
+ e = expected->valuestring;
+ s = mustach_cJSON_mem(t, 0, data, flags, &got, &length);
+ if (s == 0 && strcmp(got, e) == 0) {
+ fprintf(output, "\t=> SUCCESS\n");
+ c->nsuccess++;
+ }
+ else {
+ if (s < 0) {
+ fprintf(output, "\t=> ERROR %s\n", mustach_error_string(s));
+ c->nerror++;
+ }
+ else {
+ fprintf(output, "\t=> DIFFERS\n");
+ c->ndiffers++;
+ }
+ if (partials) {
+ tmp = cJSON_PrintUnformatted(partials);
+ fprintf(output, "\t.. PARTIALS[%s]\n", tmp);
+ free(tmp);
+ }
+ tmp = cJSON_PrintUnformatted(data);
+ fprintf(output, "\t.. DATA[%s]\n", tmp);
+ free(tmp);
+ fprintf(output, "\t.. TEMPLATE[");
+ emit(output, t);
+ fprintf(output, "]\n");
+ fprintf(output, "\t.. EXPECTED[");
+ emit(output, e);
+ fprintf(output, "]\n");
+ if (s == 0) {
+ fprintf(output, "\t.. GOT[");
+ emit(output, got);
+ fprintf(output, "]\n");
+ }
+ }
+ free(got);
+ }
+ i++;
+ }
+ return 0;
+}
+static void close_json()
+{
+ cJSON_Delete(o);
+}
+
+#else
+#error "no defined json library"
+#endif