Need help? Join our Discord — ask questions, share projects, and connect with the Quill community.
Real-World Example: API Testing with Quill
This is a real test suite that validates the Trade Buddy marketplace API — a live production API for a student trading platform. Every test below is written entirely in Quill, demonstrating that readable code and powerful testing are not mutually exclusive.
38
Tests
215
Lines of Quill
~400
Equivalent lines of JavaScript
Setup and Configuration
The test suite starts by declaring the API base URL and defining reusable helper functions. In Quill, creating a variable is as simple as writing name is value, and functions are defined with the to keyword. No imports, no boilerplate, no semicolons.
-- Trade Buddy API Test Suite-- Run: quill test examples/tradebuddy-tests.quillapi_url is "https://mytradebuddy.com/api"-- Helper FunctionstoisValidEmail addr:
if addr contains "@"and addr contains ".":
give backyesgive backnotoisValidCategory cat:
valid are ["Electronics", "Books", "Video Games", "Toys",
"Household Items", "Kitchen Items", "Furniture",
"Sports Equipment", "Clothing & Accessories",
"Jewelry & Watches", "Board Games",
"School Uniform", "Stationery"]
give back includes(valid, cat)
toisValidType t:
valid are ["Sell", "Donate", "Wanted"]
give back includes(valid, t)
toformatPrice amount:
if amount is 0:
give back"Free"give back"AED {amount}"
Quill Feature: English-Like Syntax
Notice how if addr contains "@" and addr contains "." reads like a sentence. Quill uses yes/no instead of true/false, give back instead of return, and is instead of =. The goal is code that anyone can read, even without programming experience.
Unit Tests for Helper Functions
Before testing the API, we validate our helper functions in isolation. Quill's test keyword creates a named test block, and expect asserts a condition. If any expectation fails, the test fails with a clear message.
test"isValidEmail accepts valid emails":
expect isValidEmail("user@example.com") is yesexpect isValidEmail("student@school.edu") is yestest"isValidEmail rejects invalid emails":
expect isValidEmail("not-an-email") is noexpect isValidEmail("missing-at.com") is notest"isValidCategory recognizes all categories":
expect isValidCategory("Electronics") is yesexpect isValidCategory("Books") is yesexpect isValidCategory("Video Games") is yestest"isValidCategory rejects unknown categories":
expect isValidCategory("Pets") is noexpect isValidCategory("Cars") is notest"formatPrice shows Free for zero":
expect formatPrice(0) is "Free"test"formatPrice formats non-zero amounts":
expect formatPrice(25) is "AED 25"expect formatPrice(99.99) is "AED 99.99"test"countByType counts correctly":
sample are [{type: "Sell"}, {type: "Donate"}, {type: "Sell"}]
expect countByType(sample, "Sell") is 2expect countByType(sample, "Donate") is 1expect countByType(sample, "Wanted") is 0
Quill Feature: Built-In Testing
No test framework to install. No configuration files. Just write test "name": and expect value is expected. Run with quill test your-file.quill and you get clear pass/fail output.
Authentication Tests
These tests verify the login, signup, and logout endpoints. We check that invalid credentials return failures, missing fields are caught, and error responses have the expected shape. The await keyword handles async HTTP calls naturally.
test"login with invalid credentials returns failure":
response is await postJSON("{api_url}/auth.php?action=login",
{email: "fake@nonexistent.com", password: "wrongpassword123"})
expect response.success is notest"login with missing email returns failure":
response is await postJSON("{api_url}/auth.php?action=login",
{password: "test1234"})
expect response.success is notest"login error response contains error field":
response is await postJSON("{api_url}/auth.php?action=login",
{email: "fake@test.com", password: "wrong"})
expect response.success is noexpect isText(response.error) is yestest"signup without name fails":
response is await postJSON("{api_url}/auth.php?action=signup",
{email: "test@example.com", password: "securepass"})
expect response.success is notest"signup without email fails":
response is await postJSON("{api_url}/auth.php?action=signup",
{name: "Test User", password: "securepass"})
expect response.success is notest"logout without token fails":
response is await postJSON("{api_url}/auth.php?action=logout", {})
expect response.success is no
Quill Feature: Async Made Simple
Quill uses await to pause and wait for network requests, just like you would wait for a reply in a conversation. No .then() chains, no callback functions — just response is await postJSON(url, data).
Listings and Data Validation Tests
These tests fetch the public listings endpoint and verify that every listing has the correct fields, valid types and categories, and proper pricing. The for each loop checks every single listing in the response.
test"listings endpoint returns success":
data is await fetchJSON("{api_url}/listings.php")
expect data.success is yestest"each listing has a valid type":
data is await fetchJSON("{api_url}/listings.php")
for each item in data.listings:
expect isValidType(item.type) is yestest"each listing has a valid category":
data is await fetchJSON("{api_url}/listings.php")
for each item in data.listings:
expect isValidCategory(item.category) is yestest"sell listings have numeric prices":
data is await fetchJSON("{api_url}/listings.php")
sells is filter(data.listings, with i: i.type is "Sell")
for each item in sells:
expect isNumber(item.price) is yesexpect item.price is greater than 0test"each listing has a seller name":
data is await fetchJSON("{api_url}/listings.php")
for each item in data.listings:
expect isText(item.sellerName) is yesexpect length(item.sellerName) is greater than 0
Quill Feature: Lambdas with "with"
Filtering a list uses the with keyword: filter(listings, with i: i.type is "Sell"). It reads almost like English: "filter listings, with each item where the type is Sell." Compare that to JavaScript's listings.filter(i => i.type === "Sell").
Data Integrity Tests
Beyond checking individual fields, these tests verify the dataset as a whole: no duplicate IDs, non-empty titles, valid date formats, and no negative prices. These are the kinds of tests that catch real bugs in production data.
test"no duplicate listing IDs":
data is await fetchJSON("{api_url}/listings.php")
ids is map_list(data.listings, with i: i.id)
expect length(unique(ids)) is length(ids)
test"listing titles are non-empty strings":
data is await fetchJSON("{api_url}/listings.php")
for each item in data.listings:
expect isText(item.title) is yesexpect length(trim(item.title)) is greater than 0test"listing prices are not negative":
data is await fetchJSON("{api_url}/listings.php")
for each item in data.listings:
if isNumber(item.price):
expect item.price is greater than -1
Response Shape Tests
API contract validation ensures the server always returns the JSON structure your application expects. These tests guard against breaking changes in the API by verifying fields, types, and the overall shape of every response.
test"listings response is a valid object":
data is await fetchJSON("{api_url}/listings.php")
expect isObject(data) is yestest"listings response has success field":
data is await fetchJSON("{api_url}/listings.php")
expect data.success is yestest"login error has correct JSON structure":
response is await postJSON("{api_url}/auth.php?action=login",
{email: "bad", password: "bad"})
expect isObject(response) is yesexpect response.success is noexpect isText(response.error) is yestest"listing objects have consistent shape":
data is await fetchJSON("{api_url}/listings.php")
if length(data.listings) is greater than 0:
first is data.listings[0]
expect isText(first.id) is yesexpect isText(first.title) is yesexpect isText(first.type) is yesexpect isText(first.category) is yesexpect isText(first.description) is yesexpect isText(first.sellerName) is yes
Quill vs JavaScript: Side by Side
Here is the same logic written in both languages. Quill is designed to be immediately understandable, even to someone who has never programmed before.
Example 1: A simple test
Quill
test"login with bad creds fails":
response is await postJSON(url, {
email: "fake@test.com",
password: "wrong"
})
expect response.success is no