-
-
Notifications
You must be signed in to change notification settings - Fork 14
Applying tdd on select-only exercise #219
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
base: main
Are you sure you want to change the base?
Conversation
| .read ./intro-select.sql | ||
|
|
||
| -- Compare expected vs actual | ||
| .shell diff expected_output.txt user_output.txt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The diff output is certainly not user-friendly. Instead of diff, we could run a custom Python script here that would generate a friendlier diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either way, note that this would work with the existing test runner.
|
I'm not a fan of the multi-file approach. If we introduce |
This reverts commit 93bc000.
|
The latest version has the user enter all {
"version": 3,
"status": "fail",
"tests": [
{
"description": "ALL records => SELECT * FROM weather_readings",
"status": "pass"
},
{
"description": "Just location and temperature columns => SELECT location, temperature FROM weather_readings",
"status": "pass"
},
{
"description": "Without \"FROM\" => SELECT 'Hello, world.'",
"status": "fail",
"message": "Expected: [{\"'Hello, world.'\": \"Hello, world.\"}]",
"output": "Actual: [{\"say_hi\": \"Hello, world.\"}]"
},
{
"description": "All records from Seatle location => SELECT * FROM weather_readings WHERE location = 'Seattle'",
"status": "pass"
},
{
"description": "All records where humidity in range => SELECT * FROM weather_readings WHERE humidity BETWEEN 60 AND 70",
"status": "pass"
},
{
"description": "Just location column => SELECT location FROM weather_readings",
"status": "pass"
},
{
"description": "Only unique locations => SELECT DISTINCT location FROM weather_readings",
"status": "pass"
}
]
} |
| {"date":"2025-10-22","location":"Seattle","temperature":56.2,"humidity":66}, | ||
| {"date":"2025-10-22","location":"Boise","temperature":60.4,"humidity":55}, | ||
| {"date":"2025-10-23","location":"Portland","temperature":54.6,"humidity":70}, | ||
| {"date":"2025-10-23","location":"Seattle","temperature":57.79999999999999,"humidity":68}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason, this comes out as 57.79999999999 instead of the original 57.8 in the input data (see data.csv). Any ideas from the SQLite gurus on how to make it come out as 57.8?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Floating point numbers are hard for computers.
SQLite promises to preserve the 15 most significant digits of a floating point value.
ref
Numbers like 57.8 (or 0.8) cannot actually be handled very well by computers using the common representations. The original only looks like 57.8 when input or rounded. Float comparisons generally go better when you compare that the two values are close enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can bypass this problem by picking nicer values, eg fractions which can be represented as a / (2^b).
sqlite> .mode json
sqlite> SELECT 57.8;
[{"57.8":57.79999999999999716}]
sqlite> SELECT 57.5;
[{"57.5":57.5}]
|
Adding a Python dependency to the test runner makes the image much, much larger. Without Python, I believe much of what you're doing in Python can be done pretty easily using Using the # out
[{"date":"2025-10-22","location":"Portland","temperature":53.1,"humidity":72},{"date":"2025-10-22","location":"Seattle","temperature":56.2,"humidity":66},{"date":"2025-10-22","location":"Boise","temperature":60.4,"humidity":55},{"date":"2025-10-23","location":"Portland","temperature":54.6,"humidity":70},{"date":"2025-10-23","location":"Seattle","temperature":57.79999999999999,"humidity":68},{"date":"2025-10-23","location":"Boise","temperature":62.0,"humidity":58}]
[{"location":"Portland","temperature":53.1},{"location":"Seattle","temperature":56.2},{"location":"Boise","temperature":60.4},{"location":"Portland","temperature":54.6},{"location":"Seattle","temperature":57.79999999999999},{"location":"Boise","temperature":62.0}]
[{"'Hello world.'":"Hello, world."}]
[{"date":"2025-10-22","location":"Seattle","temperature":56.2,"humidity":66},{"date":"2025-10-23","location":"Seattle","temperature":57.79999999999999,"humidity":68}]
[{"date":"2025-10-22","location":"Seattle","temperature":56.2,"humidity":66},{"date":"2025-10-23","location":"Portland","temperature":54.6,"humidity":70},{"date":"2025-10-23","location":"Seattle","temperature":57.79999999999999,"humidity":68}]
[{"location":"Portland"},{"location":"Seattle"},{"location":"Boise"},{"location":"Portland"},{"location":"Seattle"},{"location":"Boise"}]
[{"location":"Portland"},{"location":"Seattle"},{"location":"Boise"}]# test.jq
def range(upto):
def _range:
if . < upto then ., ((.+1)|_range) else empty end;
0 | _range;
[
range($want[0]|length) as $number
| $want[0] | .[$number | tonumber].expected as $expected
| $want[0] | .[$number | tonumber].description as $description
| $out|.[$number | tonumber] as $got
| if $got != $expected then {$description, $expected, $got, "status": "fail"} else {$description, "status": "pass"} end
]» jq -c --slurpfile out out --slurpfile want test_data.json -n -f test.jq 2>&1
[
{"description": "ALL records => SELECT * FROM weather_readings", "status": "pass"},
{"description": "Just location and temperature columns => SELECT location, temperature FROM weather_readings", "status": "pass"},
{
"description": "Without \"FROM\" => SELECT 'Hello, world.'",
"expected": [{"'Hello, world.'": "Hello, world."}],
"got": [{"'Hello world.'": "Hello, world."}],
"status": "fail"
},
{"description": "All records from Seatle location => SELECT * FROM weather_readings WHERE location = 'Seattle'", "status": "pass"},
{"description": "All records where humidity in range => SELECT * FROM weather_readings WHERE humidity BETWEEN 60 AND 70", "status": "pass"},
{"description": "Just location column => SELECT location FROM weather_readings", "status": "pass"},
{"description": "Only unique locations => SELECT DISTINCT location FROM weather_readings", "status": "pass"}
]My main worry here is with lining up the various outputs vs tests in a list. It's not obvious that the I think this might be viable, but we'd also need some additional guardrails.
-- Do not remove the comments! The comments line up with the test outputs.
-- Write your solution to each task beneath the comment.
-- 1: Select all records.
-- 2: Select the location and temperature.
-- 3: Say Hello!
... |
|
@IsaacG, thanks for the jq prototype. I think it looks promising! I will use your code as a starting point, and work on adding the guardrails you mentioned.
I agree, and I think the numbers should correspond to individual tasks within the exercise, like the tasks in exercises such as the Role Playing Game in the Elm track (among many others). |
An alternative to #218, which uses Python to evaluate the test results.
Advantages: