Functions
Task: write a calculation once and use it wherever the page needs it.
yaml
# Recipe: a q:function, called from attributes and from the HTML.
paths:
components: ./componentsA q:function takes q:params like an action: each argument is converted to its type and checked against its rules on every call, and default fills one left out. returnType checks what comes back. A function can be called in any expression of the page, including inside another call.
xml
<q:component name="Prices">
<!-- Arguments are checked against the q:params on every call. -->
<q:function name="withTax" returnType="number">
<q:param name="amount" type="number" required="true" min="0" />
<q:param name="rate" type="number" default="0.1" />
<q:return value="{round(amount * (1 + rate), 2)}" />
</q:function>
<q:function name="label">
<q:param name="amount" type="number" required="true" />
<q:return value="{'free' if amount == 0 else '$' + str(amount)}" />
</q:function>
<q:set name="book" value="{withTax(20)}" />
<html>
<body>
<p>Book: {label(book)}</p>
<p>Food: {label(withTax(10, 0.05))}</p>
<p>Sample: {label(withTax(0))}</p>
</body>
</html>
</q:component>xml
<q:test name="a function called from q:set and from the HTML" page="/">
<test:visit />
<test:expect var="book" value="22.0" />
<test:expect text="Book: $22.0" />
</q:test>
<q:test name="an argument by position replaces the default" page="/">
<test:visit />
<test:expect text="Food: $10.5" />
</q:test>
<q:test name="functions compose" page="/">
<test:visit />
<test:expect text="Sample: free" />
</q:test>text
tests/prices.test.q
PASS a function called from q:set and from the HTML
PASS an argument by position replaces the default
PASS functions compose
3 passed, 0 failed