-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #131 from epage/spec
Generate tests from spec document
- Loading branch information
Showing
106 changed files
with
2,521 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import pathlib | ||
import shutil | ||
import re | ||
|
||
|
||
ROOT = pathlib.Path(__file__).parent | ||
VALID_ROOT = ROOT / f"tests/valid/spec" | ||
INVALID_ROOT = ROOT / f"tests/invalid/spec" | ||
|
||
|
||
def main(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument( | ||
"--input", | ||
metavar="MD", | ||
type=pathlib.Path, default=ROOT / "assets/specs/en/v1.0.0.md", | ||
help="Spec to parse for test cases", | ||
) | ||
args = parser.parse_args() | ||
|
||
try: | ||
shutil.rmtree(VALID_ROOT) | ||
except FileNotFoundError: | ||
pass | ||
try: | ||
shutil.rmtree(INVALID_ROOT) | ||
except FileNotFoundError: | ||
pass | ||
|
||
markdown = args.input.read_text() | ||
lines = markdown.splitlines() | ||
|
||
header = "common" | ||
case_index = 0 | ||
|
||
line_index = 0 | ||
while line_index < len(lines): | ||
try: | ||
line_index, header = parse_header(line_index, lines) | ||
except ParseError: | ||
pass | ||
else: | ||
print(f"Parsing {header}") | ||
case_index = 0 | ||
continue | ||
|
||
try: | ||
line_index, info, block = parse_block(line_index, lines) | ||
except ParseError: | ||
pass | ||
else: | ||
if info in ["toml", ""] and block.startswith("# INVALID"): | ||
write_invalid_case(header, case_index, block) | ||
case_index += 1 | ||
elif info == "toml": | ||
if has_active_invalid(block): | ||
write_invalid_case(header, case_index, block) | ||
else: | ||
write_valid_case(header, case_index, block) | ||
case_index += 1 | ||
continue | ||
|
||
line_index += 1 | ||
|
||
|
||
class ParseError(RuntimeError): | ||
pass | ||
|
||
|
||
def parse_header(line_index, lines): | ||
try: | ||
header = lines[line_index] | ||
if not header: | ||
raise ParseError() | ||
|
||
line_index += 1 | ||
dashes = lines[line_index] | ||
if not re.fullmatch("-+", dashes): | ||
raise ParseError() | ||
|
||
line_index += 1 | ||
blank = lines[line_index] | ||
if blank: | ||
raise ParseError() | ||
|
||
line_index += 1 | ||
except IndexError: | ||
raise ParseError() | ||
|
||
header = header.lower().replace(" ", "-").replace("/", "-") | ||
return line_index, header | ||
|
||
|
||
FENCE = "```" | ||
|
||
|
||
def parse_block(line_index, lines): | ||
info = "" | ||
try: | ||
fence = lines[line_index] | ||
if not fence.startswith(FENCE): | ||
raise ParseError() | ||
info = fence.removeprefix(FENCE) | ||
|
||
block = [] | ||
line = "" | ||
while line != FENCE: | ||
block.append(line) | ||
line_index += 1 | ||
line = lines[line_index] | ||
|
||
line_index += 1 | ||
except IndexError: | ||
raise ParseError() | ||
|
||
return line_index, info, "\n".join(block) | ||
|
||
|
||
def write_invalid_case(header, index, block): | ||
path = INVALID_ROOT / f"{header}-{index}.toml" | ||
path.parent.mkdir(parents=True, exist_ok=True) | ||
path.write_text(block) | ||
|
||
|
||
def write_valid_case(header, index, block): | ||
path = VALID_ROOT / f"{header}-{index}.toml" | ||
path.parent.mkdir(parents=True, exist_ok=True) | ||
path.write_text(block) | ||
|
||
invalid_index = 0 | ||
lines = block.splitlines() | ||
for i, line in enumerate(lines): | ||
if "# INVALID" in line: | ||
new_lines = lines[:] | ||
assert line.startswith("# "), f"{line}" | ||
new_lines[i] = line.removeprefix("# ") | ||
write_invalid_case(header, f"{index}-{invalid_index}", "\n".join(new_lines)) | ||
invalid_index += 1 | ||
|
||
|
||
def has_active_invalid(block): | ||
lines = block.splitlines() | ||
for line in lines: | ||
if "# INVALID" in line and not line.startswith("# "): | ||
return True | ||
return False | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
[product] | ||
type = { name = "Nail" } | ||
type.edible = false # INVALID |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
[product] | ||
type.name = "Nail" | ||
type = { edible = false } # INVALID |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
key = # INVALID |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
= "no key name" # INVALID | ||
"" = "blank" # VALID but discouraged | ||
'' = 'blank' # VALID but discouraged |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
str4 = """Here are two quotation marks: "". Simple enough.""" | ||
str5 = """Here are three quotation marks: """.""" # INVALID | ||
str5 = """Here are three quotation marks: ""\".""" | ||
str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\".""" | ||
|
||
# "This," she said, "is just a pointless statement." | ||
str7 = """"This," she said, "is just a pointless statement."""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
quot15 = '''Here are fifteen quotation marks: """""""""""""""''' | ||
|
||
apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID | ||
apos15 = "Here are fifteen apostrophes: '''''''''''''''" | ||
|
||
# 'That,' she said, 'is still pointless.' | ||
str = ''''That,' she said, 'is still pointless.'''' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
[fruit] | ||
apple.color = "red" | ||
apple.taste.sweet = true | ||
|
||
[fruit.apple] # INVALID | ||
# [fruit.apple.taste] # INVALID | ||
|
||
[fruit.apple.texture] # you can add sub-tables | ||
smooth = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
[fruit] | ||
apple.color = "red" | ||
apple.taste.sweet = true | ||
|
||
# [fruit.apple] # INVALID | ||
[fruit.apple.taste] # INVALID | ||
|
||
[fruit.apple.texture] # you can add sub-tables | ||
smooth = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
{ | ||
"nested_arrays_of_ints": [ | ||
[ | ||
{ | ||
"type": "integer", | ||
"value": "1" | ||
}, | ||
{ | ||
"type": "integer", | ||
"value": "2" | ||
} | ||
], | ||
[ | ||
{ | ||
"type": "integer", | ||
"value": "3" | ||
}, | ||
{ | ||
"type": "integer", | ||
"value": "4" | ||
}, | ||
{ | ||
"type": "integer", | ||
"value": "5" | ||
} | ||
] | ||
], | ||
"colors": [ | ||
{ | ||
"type": "string", | ||
"value": "red" | ||
}, | ||
{ | ||
"type": "string", | ||
"value": "yellow" | ||
}, | ||
{ | ||
"type": "string", | ||
"value": "green" | ||
} | ||
], | ||
"numbers": [ | ||
{ | ||
"type": "float", | ||
"value": "0.1" | ||
}, | ||
{ | ||
"type": "float", | ||
"value": "0.2" | ||
}, | ||
{ | ||
"type": "float", | ||
"value": "0.5" | ||
}, | ||
{ | ||
"type": "integer", | ||
"value": "1" | ||
}, | ||
{ | ||
"type": "integer", | ||
"value": "2" | ||
}, | ||
{ | ||
"type": "integer", | ||
"value": "5" | ||
} | ||
], | ||
"contributors": [ | ||
{ | ||
"type": "string", | ||
"value": "Foo Bar <[email protected]>" | ||
}, | ||
{ | ||
"name": { | ||
"type": "string", | ||
"value": "Baz Qux" | ||
}, | ||
"url": { | ||
"type": "string", | ||
"value": "https://example.com/bazqux" | ||
}, | ||
"email": { | ||
"type": "string", | ||
"value": "[email protected]" | ||
} | ||
} | ||
], | ||
"integers": [ | ||
{ | ||
"type": "integer", | ||
"value": "1" | ||
}, | ||
{ | ||
"type": "integer", | ||
"value": "2" | ||
}, | ||
{ | ||
"type": "integer", | ||
"value": "3" | ||
} | ||
], | ||
"nested_mixed_array": [ | ||
[ | ||
{ | ||
"type": "integer", | ||
"value": "1" | ||
}, | ||
{ | ||
"type": "integer", | ||
"value": "2" | ||
} | ||
], | ||
[ | ||
{ | ||
"type": "string", | ||
"value": "a" | ||
}, | ||
{ | ||
"type": "string", | ||
"value": "b" | ||
}, | ||
{ | ||
"type": "string", | ||
"value": "c" | ||
} | ||
] | ||
], | ||
"string_array": [ | ||
{ | ||
"type": "string", | ||
"value": "all" | ||
}, | ||
{ | ||
"type": "string", | ||
"value": "strings" | ||
}, | ||
{ | ||
"type": "string", | ||
"value": "are the same" | ||
}, | ||
{ | ||
"type": "string", | ||
"value": "type" | ||
} | ||
] | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
|
||
integers = [ 1, 2, 3 ] | ||
colors = [ "red", "yellow", "green" ] | ||
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ] | ||
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ] | ||
string_array = [ "all", 'strings', """are the same""", '''type''' ] | ||
|
||
# Mixed-type arrays are allowed | ||
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ] | ||
contributors = [ | ||
"Foo Bar <[email protected]>", | ||
{ name = "Baz Qux", email = "[email protected]", url = "https://example.com/bazqux" } | ||
] |
Oops, something went wrong.