Skip to content

Rewrite of the test generator#27

Draft
TheRealOwenRees wants to merge 26 commits intoexercism:mainfrom
TheRealOwenRees:rescript-test-generator
Draft

Rewrite of the test generator#27
TheRealOwenRees wants to merge 26 commits intoexercism:mainfrom
TheRealOwenRees:rescript-test-generator

Conversation

@TheRealOwenRees
Copy link
Contributor

Draft

Before I go any further, I would like some feedback on how we might handle test templates moving forward.

  • I have added a test_templates directory, where test templates are now written in pure ReScript
  • a utility function has been added to retrieve the input keys from the canonical data
  • I have not yet implemented a way to automatically create the slug for tests (perhaps pascal case to kebab case and strip the _test part.)
  • it requires both a comparator function and a string template function (genAssertionName) to be written, but then the use of these in your test template is simpler.

I have re-implemented a few of the exercises using this test generator for your review.

@TheRealOwenRees TheRealOwenRees marked this pull request as draft March 16, 2026 15:23
@github-actions
Copy link

This PR touches files which potentially affect the outcome of the tests of an exercise. This will cause all students' solutions to affected exercises to be re-tested.

If this PR does not affect the result of the test (or, for example, adds an edge case that is not worth rerunning all tests for), please add the following to the merge-commit message which will stops student's tests from re-running. Please copy-paste to avoid typos.

[no important files changed]

For more information, refer to the documentation. If you are unsure whether to add the message or not, please ping @exercism/maintainers-admin in a comment. Thank you!

@BNAndras
Copy link
Member

Yeah, you could pull out the slug from either the test file itself or the containing exercise folder.

* The `digits` argument determines the tolerance (10^-digits).
* Defaults to 2 decimal places (0.01 tolerance).
*/
let floatEqual = (~message=?, ~digits=2, a: float, b: float) => {
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
let floatEqual = (~message=?, ~digits=2, a: float, b: float) => {
let approximatelyEqual = (~message=?, ~digits=2, a: float, b: float) => {

Assertion.approximatelyEqual conveys intent better than Assertion.floatEqual.

`Assertions.assertEqual(~message="${message}", ${actual}, ${expected})`
}

let dictEqual = (~message=?, a: Dict.t<'a>, b: Dict.t<'a>) => {
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
let dictEqual = (~message=?, a: Dict.t<'a>, b: Dict.t<'a>) => {
let dictDeepEqual = (~message=?, a: Dict.t<'a>, b: Dict.t<'a>) => {

This makes it clearer we're checking the keys and values as well.

* The `digits` argument determines the tolerance (10^-digits).
* Defaults to 2 decimal places (0.01 tolerance).
*/
let floatEqual = (~message=?, ~digits=2, a: float, b: float) => {
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
let floatEqual = (~message=?, ~digits=2, a: float, b: float) => {
let approximatelyEqual = (~message=?, ~digits=2, a: float, b: float) => {

This conveys intent clearly.

`Assertions.assertEqual(~message="${message}", ${actual}, ${expected})`
}

let dictEqual = (~message=?, a: Dict.t<'a>, b: Dict.t<'a>) => {
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
let dictEqual = (~message=?, a: Dict.t<'a>, b: Dict.t<'a>) => {
let dictDeepEqual = (~message=?, a: Dict.t<'a>, b: Dict.t<'a>) => {

This clarifies we're comparing the dict keys and values although perhaps we want to make this recursive if it's not too much trouble. That's more than what we need currently of course. However it might be nice to just have a generic recursive assertion for anything with elements.

@TheRealOwenRees
Copy link
Contributor Author

TheRealOwenRees commented Mar 16, 2026

Other than the feedback, is this somewhat in the direction you had previously mentioned? It is not pretty at the moment, and I will invest a lot more time into it if it is to move ahead.

@TheRealOwenRees
Copy link
Contributor Author

I am going through the exercises one by one. Once I reach the exercises which use comparators other than equal, I will update them as highlighted in the feedback

@BNAndras
Copy link
Member

Yeah, having the assertion functions as actual ReScript code means we can check them. As strings, we don't have that option.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am a bit stuck here. Having the comparator functions as strings is the only way I can see to inject them into the exercise test files. Copying the old Assertions module into each exercise's test directory isn't feasible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is an abstracted version of the comparator function that we can use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants