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 generator docs #739

Merged
merged 9 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
68 changes: 68 additions & 0 deletions docs/GENERATORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Generators

The Clojure track uses a [test generator](https://exercism.org/docs/building/tooling/test-generators) to auto-generate (some) of the practice exercise's tests.
tasxatzial marked this conversation as resolved.
Show resolved Hide resolved
ErikSchierboom marked this conversation as resolved.
Show resolved Hide resolved
It uses the fact that most exercises defined in the [problem-specifications repo](https://github.com/exercism/problem-specifications/) also have a `canonical-data.json` file, which contains standardized test inputs and outputs that can be used to implement the exercise.

## Steps

To generate a practice exercise's tests, the test generator:

1. Reads the exercise's test cases from its [`canonical-data.json` file]
2. Use `tests.toml` file to omit and excluded test cases
3. Transform the test cases (optional)
4. Render the test cases using the exercise's generator template
5. Write the rendered template to the exercise's test file
ErikSchierboom marked this conversation as resolved.
Show resolved Hide resolved

### Step 1: read `canonical-data.json` file

The test generator parses the test cases from the exercise's `canonical-data.json` using the [clojure/data.json library](https://github.com/clojure/data.json).

As some canonical data uses nesting, the parsed test case gets an additional `path` field, which contains the `description` properties of any parents as well as the test case's `description` property itself.
ErikSchierboom marked this conversation as resolved.
Show resolved Hide resolved

Note: keys are parsed as keywords.

### Step 2: omit excluded tests from `tests.toml` file

Each exercise has a `tests.toml` file, in which individual tests can be excluded/disabled.
The test generator will remove any test cases that are marked as excluded (`include = false`).

### Step 3: transform the test cases (optional)

Some exercises might need some (minor) tweaks before rendering the data.
ErikSchierboom marked this conversation as resolved.
Show resolved Hide resolved
For example, you might want to make the description less verbose.

To tweak the test cases, define a `.meta/generator.clj` file with a `<slug>-generator` namespace .
You then defined a function called `transform` that takes (and returns) a single value: the parsed test cases.
ErikSchierboom marked this conversation as resolved.
Show resolved Hide resolved

Example:

```clojure
(ns difference-of-squares-generator)

(defn- update-path [path]
(take-last 1 path))

(defn transform [test-cases]
(map #(update % :path update-path) test-cases))
```

This step is entirely optional.

### Step 4: render the test cases

The (potentially transformed) test cases are then passed to the `.meta/generator.tpl` file, which defines how the tests should be rendered based on the test cases.
ErikSchierboom marked this conversation as resolved.
Show resolved Hide resolved

### Step 5: write the rendered template to the exercise's test file

Finally, the rendered template's output is written to the exercise's test file.
ErikSchierboom marked this conversation as resolved.
Show resolved Hide resolved

## Templates

The templates are rendered using the [hbs library](https://github.com/sunng87/hbs), which supports handlebars syntax (using [handlebars.java](https://github.com/jknack/handlebars.java/)).

## Command-line interface

There are two ways in which the test generator can be run:

1. `bin/generate-tests`: generate the tests for all exercises with a test generator
2. `bin/generate-tests <slug>`: generate the tests for the specified exercise
ErikSchierboom marked this conversation as resolved.
Show resolved Hide resolved
7 changes: 7 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
"path": "docs/RESOURCES.md",
"title": "Useful Clojure resources",
"blurb": "A collection of useful resources to help you master Clojure"
},
{
"uuid": "b091add0-0047-42ad-ae0c-adeebf984365",
"slug": "generators",
"path": "docs/GENERATORS.md",
"title": "Learn about test generators",
"blurb": "Learn how the Clojure track uses test generators to generate tests for exercises"
}
]
}