-
-
Notifications
You must be signed in to change notification settings - Fork 550
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
circular-buffer: Add canonical data #488
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,343 @@ | ||
{ | ||
"#": [ | ||
"In general, these circular buffers are expected to be stateful,", | ||
"and each language will operate on them differently.", | ||
"Tests tend to perform a series of operations, some of which expect a certain result.", | ||
"As such, this common test suite can only say in abstract terms what should be done.", | ||
"", | ||
"Tests will contain a number of operations. The operation will be specified in the `operation` key.", | ||
"Based on the operation, other keys may be present.", | ||
"read: Reading from the buffer should succeed if and only if `should_succeed` is true.", | ||
" If it should succeed, it should produce the item at `expected`. ", | ||
" If it should fail, `expected` will not be present. ", | ||
"write: Writing the item located at `item` should succeed if and only if `should_succeed` is true.", | ||
"overwrite: Write the item located at `item` into the buffer, removing the oldest item if necessary.", | ||
"clear: Clear the buffer.", | ||
"", | ||
"Failure of either `read` or `write` may be indicated in a manner appropriate for your language:", | ||
"Raising an exception, returning (int, error), returning Option<int>, etc.", | ||
"", | ||
"Finally, note that all values are integers.", | ||
"If your language contains generics, you may consider allowing buffers to contain other types.", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note the addition of this, which should look suspiciously similar to https://github.com/exercism/x-common/blob/master/exercises/react/canonical-data.json#L38-L40 Is this valuable to point out? Well, some tracks already have it, and I didn't want this JSON file to imply that they should remove those tests or make their test suites discourage generics. In the latter case, tracks may even get questions. |
||
"Tests for that are not included here.", | ||
"" | ||
], | ||
"cases": [ | ||
{ | ||
"description": "reading empty buffer should fail", | ||
"capacity": 1, | ||
"operations": [ | ||
{ | ||
"operation": "read", | ||
"should_succeed": false | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "can read an item just written", | ||
"capacity": 1, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 1 | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "each item may only be read once", | ||
"capacity": 1, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 1 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": false | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "items are read in the order they are written", | ||
"capacity": 2, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 2, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 1 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 2 | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "full buffer can't be written to", | ||
"capacity": 1, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 2, | ||
"should_succeed": false | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "a read frees up capacity for another write", | ||
"capacity": 1, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 1 | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 2, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 2 | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "read position is maintained even across multiple writes", | ||
"capacity": 3, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 2, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 1 | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 3, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 2 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 3 | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "items cleared out of buffer can't be read", | ||
"capacity": 1, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "clear" | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": false | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "clear frees up capacity for another write", | ||
"capacity": 1, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "clear" | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 2, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 2 | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "clear does nothing on empty buffer", | ||
"capacity": 1, | ||
"operations": [ | ||
{ | ||
"operation": "clear" | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 1 | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "overwrite acts like write on non-full buffer", | ||
"capacity": 2, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "overwrite", | ||
"item": 2 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 1 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 2 | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "overwrite removes the oldest item on full buffer", | ||
"capacity": 2, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 2, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "overwrite", | ||
"item": 3 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 2 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 3 | ||
} | ||
] | ||
}, | ||
{ | ||
"description": "overwrite doesn't remove an already-read item", | ||
"capacity": 3, | ||
"operations": [ | ||
{ | ||
"operation": "write", | ||
"item": 1, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 2, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 3, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 1 | ||
}, | ||
{ | ||
"operation": "write", | ||
"item": 4, | ||
"should_succeed": true | ||
}, | ||
{ | ||
"operation": "overwrite", | ||
"item": 5 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 3 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 4 | ||
}, | ||
{ | ||
"operation": "read", | ||
"should_succeed": true, | ||
"expected": 5 | ||
} | ||
] | ||
} | ||
] | ||
} |
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.
Do we need to say anything like 'failure may be indicated by raising an exception or similar language dependent runtime error'
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.
I added it just to be sure. I have a nagging feeling that if similar sentences appear in too many places...
then we might extract them all out to the contributing guide's section on porting an exercise. But I don't know what the right answer to that is yet, so for now I'll add the sentence.
(or maybe we are worried that a porter will not read that particular section of the contributing guide? I don't know)
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.
anecdata: When I'm porting, I tend to just read the canonical-data and the readme.
I don't re-read the contributing guide often.
(I'm probably non-typical enough for this to be irrelevant information.)