common/exercises/bowling/canonical-data.json in trackler-2.0.8.2 vs common/exercises/bowling/canonical-data.json in trackler-2.0.8.3
- old
+ new
@@ -1,134 +1,172 @@
{
- "#": [
+ "exercise": "bowling",
+ "version": "1",
+ "comments": [
"Students should implement roll and score methods.",
"Roll should accept a single integer.",
"Score should return the game's final score, when possible",
- "For brevity the tests display all the rolls in an array;",
- "each element of the rolls array should be passed to the roll method",
- "The final tests define situations where the score can not be returned",
- "The expection for these tests is -1, indicating an error",
- "In these cases you should expect an error as is idiomatic for your language",
- "When to error is also left up to your implementation. There are two options",
- " - Error as soon as an invalid roll is made",
- " - Error when scoring a game with an invalid roll",
- "You can also error in both cases."
+ "For brevity the tests display all the previous rolls in an array;",
+ "each element of the previous_rolls array should be passed to the roll method",
+ "and each of those previous rolls is expected to succeed.",
+ "",
+ "Two properties are tested:",
+ "",
+ "`score`: All rolls succeed, and taking the score gives the expected result.",
+ "The expected result may be an integer score or an error.",
+ "",
+ "`roll`: All previous_rolls succeed, and rolling the number of pins in `roll` produces the expected result.",
+ "Currently, all cases of this type result in errors.",
+ "",
+ "In all error cases you should expect an error as is idiomatic for your language",
+ "whether that be via exceptions, optional values, or otherwise."
],
- "score": {
- "description": [
- "returns the final score of a bowling game"
- ],
- "cases": [{
- "description": "should be able to score a game with all zeros",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": 0
- }, {
- "description": "should be able to score a game with no strikes or spares",
- "rolls": [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6],
- "expected": 90
- }, {
- "description": "a spare followed by zeros is worth ten points",
- "rolls": [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": 10
- }, {
- "description": "points scored in the roll after a spare are counted twice",
- "rolls": [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": 16
- }, {
- "description": "consecutive spares each get a one roll bonus",
- "rolls": [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": 31
- }, {
- "description": "a spare in the last frame gets a one roll bonus that is counted once",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7],
- "expected": 17
- }, {
- "description": "a strike earns ten points in a frame with a single roll",
- "rolls": [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": 10
- }, {
- "description": "points scored in the two rolls after a strike are counted twice as a bonus",
- "rolls": [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": 26
- }, {
- "description": "consecutive strikes each get the two roll bonus",
- "rolls": [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": 81
- }, {
- "description": "a strike in the last frame gets a two roll bonus that is counted once",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1],
- "expected": 18
- }, {
- "description": "rolling a spare with the two roll bonus does not get a bonus roll",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3],
- "expected": 20
- }, {
- "description": "strikes with the two roll bonus do not get bonus rolls",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10],
- "expected": 30
- }, {
- "description": "a strike with the one roll bonus after a spare in the last frame does not get a bonus",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10],
- "expected": 20
- }, {
- "description": "all strikes is a perfect game",
- "rolls": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
- "expected": 300
- }, {
- "description": "rolls can not score negative points",
- "rolls": [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": -1
- }, {
- "description": "a roll can not score more than 10 points",
- "rolls": [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": -1
- }, {
- "description": "two rolls in a frame can not score more than 10 points",
- "rolls": [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": -1
- }, {
- "description": "bonus roll after a strike in the last frame can not score more than 10 points",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11],
- "expected": -1
- }, {
- "description": "two bonus rolls after a strike in the last frame can not score more than 10 points",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6],
- "expected": -1
- }, {
- "description": "two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6],
- "expected": 26
- }, {
- "description": "the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10],
- "expected": -1
- }, {
- "description": "second bonus roll after a strike in the last frame can not score than 10 points",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 11],
- "expected": -1
- }, {
- "description": "an unstarted game can not be scored",
- "rolls": [],
- "expected": -1
- }, {
- "description": "an incomplete game can not be scored",
- "rolls": [0, 0],
- "expected": -1
- }, {
- "description": "a game with more than ten frames can not be scored",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- "expected": -1
- }, {
- "description": "bonus rolls for a strike in the last frame must be rolled before score can be calculated",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
- "expected": -1
- }, {
- "description": "both bonus rolls for a strike in the last frame must be rolled before score can be calculated",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10],
- "expected": -1
- }, {
- "description": "bonus roll for a spare in the last frame must be rolled before score can be calculated",
- "rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3],
- "expected": -1
- }]
- }
+ "cases": [{
+ "description": "should be able to score a game with all zeros",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "expected": 0
+ }, {
+ "description": "should be able to score a game with no strikes or spares",
+ "property": "score",
+ "previous_rolls": [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6],
+ "expected": 90
+ }, {
+ "description": "a spare followed by zeros is worth ten points",
+ "property": "score",
+ "previous_rolls": [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "expected": 10
+ }, {
+ "description": "points scored in the roll after a spare are counted twice",
+ "property": "score",
+ "previous_rolls": [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "expected": 16
+ }, {
+ "description": "consecutive spares each get a one roll bonus",
+ "property": "score",
+ "previous_rolls": [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "expected": 31
+ }, {
+ "description": "a spare in the last frame gets a one roll bonus that is counted once",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7],
+ "expected": 17
+ }, {
+ "description": "a strike earns ten points in a frame with a single roll",
+ "property": "score",
+ "previous_rolls": [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "expected": 10
+ }, {
+ "description": "points scored in the two rolls after a strike are counted twice as a bonus",
+ "property": "score",
+ "previous_rolls": [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "expected": 26
+ }, {
+ "description": "consecutive strikes each get the two roll bonus",
+ "property": "score",
+ "previous_rolls": [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "expected": 81
+ }, {
+ "description": "a strike in the last frame gets a two roll bonus that is counted once",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1],
+ "expected": 18
+ }, {
+ "description": "rolling a spare with the two roll bonus does not get a bonus roll",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3],
+ "expected": 20
+ }, {
+ "description": "strikes with the two roll bonus do not get bonus rolls",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10],
+ "expected": 30
+ }, {
+ "description": "a strike with the one roll bonus after a spare in the last frame does not get a bonus",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10],
+ "expected": 20
+ }, {
+ "description": "all strikes is a perfect game",
+ "property": "score",
+ "previous_rolls": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
+ "expected": 300
+ }, {
+ "description": "rolls can not score negative points",
+ "property": "roll",
+ "previous_rolls": [],
+ "roll": -1,
+ "expected": {"error": "Negative roll is invalid"}
+ }, {
+ "description": "a roll can not score more than 10 points",
+ "property": "roll",
+ "previous_rolls": [],
+ "roll": 11,
+ "expected": {"error": "Pin count exceeds pins on the lane"}
+ }, {
+ "description": "two rolls in a frame can not score more than 10 points",
+ "property": "roll",
+ "previous_rolls": [5],
+ "roll": 6,
+ "expected": {"error": "Pin count exceeds pins on the lane"}
+ }, {
+ "description": "bonus roll after a strike in the last frame can not score more than 10 points",
+ "property": "roll",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
+ "roll": 11,
+ "expected": {"error": "Pin count exceeds pins on the lane"}
+ }, {
+ "description": "two bonus rolls after a strike in the last frame can not score more than 10 points",
+ "property": "roll",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5],
+ "roll": 6,
+ "expected": {"error": "Pin count exceeds pins on the lane"}
+ }, {
+ "description": "two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6],
+ "expected": 26
+ }, {
+ "description": "the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike",
+ "property": "roll",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6],
+ "roll": 10,
+ "expected": {"error": "Pin count exceeds pins on the lane"}
+ }, {
+ "description": "second bonus roll after a strike in the last frame can not score than 10 points",
+ "property": "roll",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10],
+ "roll": 11,
+ "expected": {"error": "Pin count exceeds pins on the lane"}
+ }, {
+ "description": "an unstarted game can not be scored",
+ "property": "score",
+ "previous_rolls": [],
+ "expected": {"error": "Score cannot be taken until the end of the game"}
+ }, {
+ "description": "an incomplete game can not be scored",
+ "property": "score",
+ "previous_rolls": [0, 0],
+ "expected": {"error": "Score cannot be taken until the end of the game"}
+ }, {
+ "description": "cannot roll if game already has ten frames",
+ "property": "roll",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "roll": 0,
+ "expected": {"error": "Cannot roll after game is over"}
+ }, {
+ "description": "bonus rolls for a strike in the last frame must be rolled before score can be calculated",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10],
+ "expected": {"error": "Score cannot be taken until the end of the game"}
+ }, {
+ "description": "both bonus rolls for a strike in the last frame must be rolled before score can be calculated",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10],
+ "expected": {"error": "Score cannot be taken until the end of the game"}
+ }, {
+ "description": "bonus roll for a spare in the last frame must be rolled before score can be calculated",
+ "property": "score",
+ "previous_rolls": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3],
+ "expected": {"error": "Score cannot be taken until the end of the game"}
+ }]
}